我是Java新手,我想学习和改进。
整个项目可以是在此视察
这是一个终端游戏“战舰”:电脑将船只随机设置在海洋上,你必须击落所有这些船只。
我有几个问题:
OceanImpl.java中,我创建了类,这些类的参数本身都是海洋脉冲-cass本身。这种依赖注入实现正确吗?如果没有,你会怎么做?SetOnOceanVertically和SetOnOceanHorizontally非常相似。是否有可能进一步重构它们?Game.java的Lookint,特别是行int[] userInput = Helper.getIntegerUserInputInRange(ocean.getXLength(), ocean.getYLength());,如果我想从命令行UI切换到GUI,或者从2D切换到3D,那么我至少也要写这一行。因此,我不能只是交换UI,并期望不要触及代码的其他部分。Main.java
package main;
import main.controller.Game;
import main.model.MaritimeElement;
import main.model.OceanImpl;
public class Main {
public static void main(String[] args) throws Exception {
Ocean ocean = new OceanImpl(6, 7);
ocean.setShipWhereThereIsPlace(MaritimeElement.AIRCRAFT_CARRIER);
ocean.setShipWhereThereIsPlace(MaritimeElement.AIRCRAFT_CARRIER);
ocean.setShipWhereThereIsPlace(MaritimeElement.CRUISER);
ocean.setShipWhereThereIsPlace(MaritimeElement.CRUISER);
ocean.setShipWhereThereIsPlace(MaritimeElement.DESTROYER);
ocean.setShipWhereThereIsPlace(MaritimeElement.DESTROYER);
Game game = new Game(ocean);
game.start();
}
}OceanImpl.java
package main.model;
import main.controller.*;
import main.controller.assertion.AssertionMaritime;
import main.controller.assertion.AssertionMaritimeImpl;
import main.controller.utils.Helper;
import java.awt.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class OceanImpl implements Ocean{
MaritimeElement[][] ocean;
Map<Point, MaritimeElement> shotsMade = new HashMap<>();
Set<Point> shipsPlaced = new HashSet<>();
RandomCoordinateFactory randomCoordinateFactory;
FindFreePosition findFreePosition;
AssertionMaritime assertShip = new AssertionMaritimeImpl();
SetOnOcean setOnOceanHorizontally;
SetOnOcean setOnOceanVertically;
SetOnOcean[] setOnOcean;
public OceanImpl(int xLength, int yLength) throws Exception {
assertShip.isLargerThanMinimumDimension(xLength, yLength);
ocean = Helper.initOcean(yLength, xLength);
randomCoordinateFactory = new RandomCoordinateFactory(ocean[0].length, ocean.length);
findFreePosition = new FindFreePosition(this, assertShip);
setOnOceanHorizontally = new SetOnOceanHorizontally(this);
setOnOceanVertically = new SetOnOceanVertically(this);
setOnOcean = new SetOnOcean[]{setOnOceanHorizontally, setOnOceanVertically};
}
@Override
public int getXLength() {return ocean[0].length;}
@Override
public int getYLength() {return ocean.length;}
@Override
public MaritimeElement getLocationStatusAt(int x, int y) {return ocean[y][x];}
@Override
public MaritimeElement shootAt(int[] userInput) throws Exception {
int x = userInput[0], y = userInput[1];
assertShip.isPointWithinRange(x,y, this.getXLength(), this.getYLength());
shotsMade.put(new Point(x,y), getLocationStatusAt(x,y));
shipsPlaced.remove(new Point(x,y));
return getLocationStatusAt(x,y);
}
@Override
public int howManyTargetsHit() {return shipsPlaced.size();}
@Override
public MaritimeElement getShotMade(int x, int y) {return shotsMade.get(new Point(x,y));}
@Override
public Result setShipWhereThereIsPlace(MaritimeElement ship) throws Exception {
int[] position = findFreePosition.getPosition(ship.val());
if (position[Coordinate.X.val()] != -1){
setOnOcean[position[Coordinate.ORIENTATION.val()]]
.setShip(position[Coordinate.X.val()],position[Coordinate.Y.val()],ship);
return Result.SUCCESS;
}
return Result.FAILED;
}
@Override
public void setMaritime(int x, int y, MaritimeElement ship) {
try {
ocean[y][x] = ship;
} catch(Exception e) {
e.getCause();
}
}
@Override
public void setShipsPlaced(int x, int y) {
shipsPlaced.add(new Point(x, y));
}
}Game.java
package main.controller;
import main.controller.assertion.AssertionMaritime;
import main.controller.assertion.AssertionMaritimeImpl;
import main.controller.utils.Helper;
import main.model.Ocean;
import main.model.OceanImpl;
import main.model.MaritimeElement;
import main.view.CommandLineInterface;
import main.view.UserInterface;
public class Game {
Ocean ocean;
UserInterface ui = new CommandLineInterface();
AssertionMaritime assertUser = new AssertionMaritimeImpl();
public Game(OceanImpl ocean) {
this.ocean = ocean;
}
public void start() throws Exception {
do {
ui.showOceanHidden(ocean);
int[] userInput = Helper.getIntegerUserInputInRange(ocean.getXLength(), ocean.getYLength());
MaritimeElement shotAtElement = ocean.shootAt(userInput);
displayResult(shotAtElement);
} while(ocean.howManyTargetsHit() != 0);
ui.displayFeedbackWin();
ui.showOcean(ocean);
}
private void displayResult(MaritimeElement shotAtElement) {
if (assertUser.isWater(shotAtElement)) {
ui.displayFeedbackShotMissed();
} else {
ui.displayFeedbackShotHit();
}
}
}SetOnOceanHorizontally.java
package main.controller;
import main.model.MaritimeElement;
import main.model.Ocean;
public class SetOnOceanHorizontally implements SetOnOcean {
Ocean ocean;
public SetOnOceanHorizontally(Ocean ocean) {
this.ocean = ocean;
}
@Override
public void setShip(int x, int y, MaritimeElement ship) {
for (int i = 0; i < ship.val(); i++) {
int xCoordinate = x + i, yCoordinate = y;
try {
ocean.setMaritime(xCoordinate, yCoordinate, ship);
} catch(Exception e) {
e.getCause();
}
ocean.setShipsPlaced(xCoordinate,yCoordinate);
}
}
}SetOnOceanVertically.java
package main.controller;
import main.model.MaritimeElement;
import main.model.Ocean;
public class SetOnOceanVertically implements SetOnOcean {
Ocean ocean;
public SetOnOceanVertically(Ocean ocean) {
this.ocean = ocean;
}
@Override
public void setShip(int x, int y, MaritimeElement ship) {
for (int i = 0; i < ship.val(); i++) {
int xCoordinate = x, yCoordinate = y + i;
try {
ocean.setMaritime(xCoordinate,yCoordinate, ship);
} catch(Exception e) {
e.getCause();
}
ocean.setShipsPlaced(xCoordinate,yCoordinate);
}
}
}RandomCoordinateFactory.java
package main.controller;
import java.awt.*;
public class RandomCoordinateFactory {
private int xLength;
private int yLength;
public RandomCoordinateFactory(int xLength, int yLength) {
this.xLength = xLength;
this.yLength = yLength;
}
private int getRandomHorizontalXPosition(int shipLength) { return (int)Math.floor(Math.random() * (xLength - shipLength));}
private int getRandomHorizontalYPosition() {
return (int)Math.floor(Math.random() * yLength);
}
private int getRandomVerticalXPosition() {
return (int)Math.floor(Math.random() * xLength);
}
private int getRandomVerticalYPosition(int shipLength) {return (int)Math.floor(Math.random() * (yLength - shipLength));}
public Point getStartPointForHorizontalShip(int shipLength) {
return new Point(getRandomHorizontalXPosition(shipLength), getRandomHorizontalYPosition());
}
public Point getStartPointForVerticalShip(int shipLength) {
return new Point(getRandomVerticalXPosition(), getRandomVerticalYPosition(shipLength));
}
}FindFreePosition.java
package main.controller;
import main.controller.assertion.AssertionMaritime;
import main.model.MaritimeElement;
import main.model.Ocean;
import main.model.Orientation;
import java.awt.*;
public class FindFreePosition {
Ocean ocean;
RandomCoordinateFactory randomPoint;
AssertionMaritime assertShip;
public FindFreePosition(Ocean ocean, AssertionMaritime assertShip) {
this.ocean = ocean;
this.assertShip = assertShip;
randomPoint = new RandomCoordinateFactory(ocean.getXLength(), ocean.getYLength());
}
public int[] getPosition(int shipLength) throws Exception {
int[][] startingPoints = findFreePositionsHorizontallyAndVertically(shipLength);
int selectRandomly = (int)(Math.random() * startingPoints.length);
if (startingPoints[selectRandomly][0] != -1) return startingPoints[selectRandomly];
throw new Exception("No space for ships found");
}
private int[][] findFreePositionsHorizontallyAndVertically(int shipLength) throws Exception {
Point startPointHorizontalShip = randomPoint.getStartPointForHorizontalShip(shipLength);
Point startPointVerticalShip = randomPoint.getStartPointForVerticalShip(shipLength);
int[] coordHorizontal = findFreePositionHorizontally(shipLength, startPointHorizontalShip.x, startPointHorizontalShip.y);
int[] coordVertical = findFreePositionVertically(shipLength, startPointVerticalShip.x, startPointVerticalShip.y);
return new int[][]{coordHorizontal, coordVertical};
}
private int[] findFreePositionVertically(int shipLength, int xOffset, int yOffset) throws Exception {
int x = xOffset,y = yOffset, k = 0, xIteration = 0;
int[] start = {-1,-1,Orientation.VERTICAL.getValue()};
while (x < ocean.getXLength() && xIteration < 2) {
while (y < ocean.getYLength()) {
MaritimeElement currentMaritimeElement = ocean.getLocationStatusAt(x,y);
if (k == 0) start = new int[]{x, y, Orientation.VERTICAL.getValue()};
if (assertShip.isWater(currentMaritimeElement)) k++;
if (k == shipLength) return start;
if (assertShip.isSpaceAvailable(currentMaritimeElement, ocean.getYLength(), shipLength, y, k)) {
k = 0;
start = new int[]{-1, -1, Orientation.VERTICAL.getValue()};
}
y++;
}
y = 0;
k = 0;
x++;
if (x >= ocean.getXLength()) xIteration++;
x = x % ocean.getXLength();
}
return start;
}
private int[] findFreePositionHorizontally(int shipLength, int xOffset, int yOffset) throws Exception {
int x = xOffset, y = yOffset, k = 0, yIteration = 0;;
int[] start = {-1,-1, Orientation.HORIZONTAL.getValue()};
while (y < ocean.getYLength() && yIteration < 2) {
while (x < ocean.getXLength()) {
MaritimeElement currentMaritimeElement = ocean.getLocationStatusAt(x,y);
if (k == 0) start = new int[]{x, y, Orientation.HORIZONTAL.getValue()};
if (assertShip.isWater(currentMaritimeElement)) k++;
if (k == shipLength) return start;
if (assertShip.isSpaceAvailable(currentMaritimeElement, ocean.getXLength(), shipLength, x, k)) {
k = 0;
start = new int[]{-1, -1, Orientation.HORIZONTAL.getValue()};
}
x++;
}
x = 0;
k = 0;
y++;
if (y >= ocean.getYLength()) yIteration++;
y = y % ocean.getYLength();
}
return start;
}
}CommandLindInterface.java
package main.view;
import main.controller.DrawMaritime;
import main.controller.DrawMaritimeImpl;
import main.model.MaritimeElement;
import main.model.Ocean;
public class CommandLineInterface implements UserInterface{
DrawMaritime drawMaritime = new DrawMaritimeImpl();
@Override
public void display(String message) {
System.out.println(message);
}
@Override
public void displayFeedbackWin() {
display("You won!");
}
@Override
public void displayFeedbackShotMissed() {
display("Missed");
}
@Override
public void displayFeedbackShotHit() {
display("Hit");
}
@Override
public void showOceanOpen(Ocean ocean) {
genericDrawOcean(ocean, drawShipsOpenly);
}
@Override
public void showOcean(Ocean ocean) {
genericDrawOcean(ocean, drawAllShips);
}
@Override
public void showOceanHidden(Ocean ocean) {
genericDrawOcean(ocean, drawShotsMade);
}
private void genericDrawOcean(Ocean ocean, DrawStuffOnOcean drawStuffOnOcean) {
for (int y = 0; y < ocean.getYLength(); y++) {
for (int x = 0; x < ocean.getXLength(); x++) {
if (y == 0 && x == 0) {
System.out.print("\t");
for (int i = 0; i < ocean.getXLength(); i++) {
System.out.print(i + "\t");
}
System.out.println();
}
if (x == 0) System.out.print(y + "\t");
drawStuffOnOcean.draw(ocean, y, x);
}
System.out.println();
}
}
interface DrawStuffOnOcean{
void draw(Ocean ocean, int y, int x);
}
DrawStuffOnOcean drawShipsOpenly = (Ocean ocean, int y, int x) -> {
MaritimeElement element = ocean.getLocationStatusAt(x,y);
if(element == MaritimeElement.WATER) {
drawMaritime.water();
} else if (element == MaritimeElement.DESTROYER) {
drawMaritime.destroyer();
} else if (element == MaritimeElement.CRUISER) {
drawMaritime.cruiser();
} else if (element == MaritimeElement.AIRCRAFT_CARRIER) {
drawMaritime.aircraftCarrier();
}
};
DrawStuffOnOcean drawAllShips = (Ocean ocean, int y, int x) -> {
MaritimeElement element = ocean.getLocationStatusAt(x,y);
MaritimeElement checkForShotsMade = ocean.getShotMade(x,y);
if (checkForShotsMade == null) {
drawMaritime.water();
} else {
if(element == MaritimeElement.WATER) {
drawMaritime.missShip();
} else if (element == MaritimeElement.DESTROYER) {
drawMaritime.destroyer();
} else if (element == MaritimeElement.CRUISER) {
drawMaritime.cruiser();
} else if (element == MaritimeElement.AIRCRAFT_CARRIER) {
drawMaritime.aircraftCarrier();
}
}
};
DrawStuffOnOcean drawShotsMade = (Ocean ocean, int y, int x) -> {
MaritimeElement element;
if (ocean.getShotMade(x,y) == null) {
drawMaritime.water();
} else {
element = ocean.getShotMade(x,y);
if(element == MaritimeElement.WATER) {
drawMaritime.missShip();
} else {
drawMaritime.hitShip();
}
}
};
}发布于 2017-05-23 20:43:35
提示:
README。Set开头的类名,以避免设置者从setSet开始,这会伤害眼睛。这不值得重构。Game.ocean,没有封装。An error occured消息。如果您没有传递一个异常,但是您需要处理它,抛出一个RuntimeException,或者通知像sentry.io这样的在线服务。try-catch(Exception)几乎从不正确..。pom.xml,但是在.idea中有与IDE相关的文件。我会提供一个基于命令行的跨平台、跨IDE构建命令,以便让其他人尽可能容易地构建和运行您的项目。你的问题:
https://codereview.stackexchange.com/questions/164048
复制相似问题