199 Commits
ef4afdc6b5
...
c556fe867d
28 changed files with 3177 additions and 10 deletions
-
22pom.xml
-
19src/main/java/de/tims/fleetstorm/GameManager.java
-
227src/main/java/de/tims/fleetstorm/ai/Logic.java
-
268src/main/java/de/tims/fleetstorm/gui/GameLogic.java
-
61src/main/java/de/tims/fleetstorm/matchfield/Coordinate.java
-
113src/main/java/de/tims/fleetstorm/matchfield/Matchfield.java
-
313src/main/java/de/tims/gameexplorer/GameExplorer.java
-
45src/main/java/de/tims/player_management/Player.java
-
95src/main/java/de/tims/player_management/PlayerManager.java
-
183src/main/java/de/tims/tictactoe/GameLogic.java
-
22src/main/java/de/tims/tictactoe/ShowGUI.java
-
34src/main/java/de/tims/tictactoe/ai/AIEasy.java
-
190src/main/java/de/tims/tictactoe/ai/AIHard.java
-
5src/main/java/de/tims/tictactoe/ai/TicTacToeAI.java
-
0src/main/java/resources/player_data.csv
-
21src/test/java/de/tims/fleetstorm/GameManagerTest.java
-
366src/test/java/de/tims/fleetstorm/ai/LogicTest.java
-
36src/test/java/de/tims/fleetstorm/gui/LogicTest.java
-
82src/test/java/de/tims/fleetstorm/matchfield/CoordinateTest.java
-
144src/test/java/de/tims/fleetstorm/matchfield/MatchfieldCreationTest.java
-
133src/test/java/de/tims/fleetstorm/matchfield/MatchfieldShipTest.java
-
110src/test/java/de/tims/player_management/PlayerManagerTest.java
-
32src/test/java/de/tims/player_management/PlayerTest.java
-
337src/test/java/de/tims/tictactoe/GameLogicTest.java
-
62src/test/java/de/tims/tictactoe/ai/AIEasyTest.java
-
262src/test/java/de/tims/tictactoe/ai/AIHardTest.java
-
3src/test/java/resources/player_testdata.csv
-
2src/test/java/resources/player_testdata2.csv
@ -0,0 +1,19 @@ |
|||
package de.tims.fleetstorm; |
|||
|
|||
public class GameManager { |
|||
|
|||
private int gameState; |
|||
|
|||
public static final int PREPARATION = 1; |
|||
public static final int RUNNING = 2; |
|||
public static final int OVER = 3; |
|||
|
|||
public void start() { |
|||
this.gameState = GameManager.PREPARATION; |
|||
} |
|||
|
|||
public int getGameState() { |
|||
return gameState; |
|||
} |
|||
|
|||
} |
@ -1,9 +1,232 @@ |
|||
package de.tims.fleetstorm.ai; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Random; |
|||
|
|||
import de.tims.fleetstorm.matchfield.Coordinate; |
|||
import de.tims.fleetstorm.matchfield.Matchfield; |
|||
|
|||
public class Logic { |
|||
|
|||
public int[] chooseField() { |
|||
return new int[] {}; |
|||
private Matchfield matchfield; |
|||
private ArrayList<Coordinate> everySecondField; |
|||
|
|||
private Coordinate lastShot; |
|||
private Coordinate target; |
|||
private boolean foundShip; |
|||
private boolean clearedAbove; |
|||
private boolean clearedBelow; |
|||
private boolean clearedRight; |
|||
private boolean clearedLeft; |
|||
|
|||
public Logic() { |
|||
foundShip = false; |
|||
clearedAbove = false; |
|||
clearedBelow = false; |
|||
clearedRight = false; |
|||
clearedLeft = false; |
|||
} |
|||
|
|||
public Coordinate chooseField() { |
|||
Coordinate out; |
|||
|
|||
if (foundShip) { |
|||
// Clear Y-Axis |
|||
if (!clearedAbove) { |
|||
target = matchfield.getAbove(target); |
|||
out = target; |
|||
if (target == null || target.getState() == Coordinate.EMPTY) { |
|||
clearedAbove = true; |
|||
target = lastShot; |
|||
} |
|||
return out; |
|||
} |
|||
|
|||
if (!clearedBelow) { |
|||
target = matchfield.getBelow(target); |
|||
out = target; |
|||
if (target == null || target.getState() == Coordinate.EMPTY) { |
|||
clearedBelow = true; |
|||
target = lastShot; |
|||
} |
|||
isShipOnYAxis(); |
|||
return out; |
|||
} |
|||
|
|||
// Clear x-Axis |
|||
if (!clearedRight) { |
|||
target = matchfield.getRight(target); |
|||
out = target; |
|||
if (target == null || target.getState() == Coordinate.EMPTY) { |
|||
clearedRight = true; |
|||
target = lastShot; |
|||
} |
|||
return out; |
|||
} |
|||
|
|||
if (!clearedLeft) { |
|||
target = matchfield.getLeft(target); |
|||
out = target; |
|||
if (target == null || target.getState() == Coordinate.EMPTY) { |
|||
clearedLeft = true; |
|||
target = lastShot; |
|||
} |
|||
sinkShip(); |
|||
return out; |
|||
} |
|||
} |
|||
|
|||
ArrayList<Coordinate> possibleFields = new ArrayList<Coordinate>(); |
|||
for (int i = 0; i < everySecondField.size(); i++) { |
|||
if (everySecondField.get(i).getState() != Coordinate.SHOT |
|||
&& everySecondField.get(i).getState() != Coordinate.HIT) { |
|||
possibleFields.add(everySecondField.get(i)); |
|||
} |
|||
} |
|||
Random randy = new Random(); |
|||
lastShot = possibleFields.get(randy.nextInt(possibleFields.size())); |
|||
target = possibleFields.get(randy.nextInt(possibleFields.size())); |
|||
if (lastShot.getState() == Coordinate.SHIP) { |
|||
foundShip = true; |
|||
} |
|||
return lastShot; |
|||
} |
|||
|
|||
public void isShipOnYAxis() { |
|||
if ((clearedAbove && clearedBelow) && ((matchfield.getAbove(lastShot) == null |
|||
|| (matchfield.getAbove(lastShot).getState() == Coordinate.HIT)) |
|||
|| (matchfield.getBelow(lastShot) == null |
|||
|| (matchfield.getBelow(lastShot).getState() == Coordinate.HIT)))) { |
|||
clearedLeft = true; |
|||
clearedRight = true; |
|||
sinkShip(); |
|||
} |
|||
} |
|||
|
|||
public ArrayList<Coordinate> getEverySecondField() { |
|||
ArrayList<Coordinate> out = new ArrayList<Coordinate>(); |
|||
for (int x = 0; x < Math.sqrt(this.matchfield.getSize()); x++) { |
|||
for (int y = 0; y < Math.sqrt(this.matchfield.getSize()); y++) { |
|||
if ((x % 2 == 0 && y % 2 == 0) || (x % 2 == 1 && y % 2 == 1)) { |
|||
out.add(this.matchfield.getField(x, y)); |
|||
} |
|||
} |
|||
} |
|||
return out; |
|||
} |
|||
|
|||
public void findShip() { |
|||
if (lastShot.getState() == Coordinate.HIT) { |
|||
foundShip = true; |
|||
} |
|||
} |
|||
|
|||
public void sinkShip() { |
|||
if (foundShip && clearedAbove && clearedBelow && clearedLeft && clearedRight) { |
|||
this.foundShip = false; |
|||
this.clearedAbove = false; |
|||
this.clearedBelow = false; |
|||
this.clearedLeft = false; |
|||
this.clearedRight = false; |
|||
} |
|||
} |
|||
|
|||
public void clearAbove(Coordinate shot) { |
|||
target = matchfield.getAbove(shot); |
|||
if (target.getState() == Coordinate.EMPTY) { |
|||
clearedAbove = true; |
|||
} |
|||
} |
|||
|
|||
public void clearBelow(Coordinate shot) { |
|||
target = matchfield.getBelow(shot); |
|||
if (target.getState() == Coordinate.EMPTY) { |
|||
clearedBelow = true; |
|||
} |
|||
} |
|||
|
|||
public void clearRight(Coordinate shot) { |
|||
target = matchfield.getRight(shot); |
|||
if (target.getState() == Coordinate.EMPTY) { |
|||
clearedRight = true; |
|||
} |
|||
} |
|||
|
|||
public void clearLeft(Coordinate shot) { |
|||
target = matchfield.getLeft(shot); |
|||
if (target.getState() == Coordinate.EMPTY) { |
|||
clearedLeft = true; |
|||
} |
|||
} |
|||
|
|||
// Getter And Setter |
|||
|
|||
public void setEverySecondField(ArrayList<Coordinate> everySecondField) { |
|||
this.everySecondField = everySecondField; |
|||
} |
|||
|
|||
public void setLastShot(Coordinate coordinate) { |
|||
lastShot = this.matchfield.getField(coordinate); |
|||
} |
|||
|
|||
public Coordinate getLastShot() { |
|||
return lastShot; |
|||
} |
|||
|
|||
public void setFoundShip(boolean b) { |
|||
this.foundShip = b; |
|||
} |
|||
|
|||
public boolean getFoundShip() { |
|||
return this.foundShip; |
|||
} |
|||
|
|||
public void setClearedAbove(boolean b) { |
|||
this.clearedAbove = b; |
|||
} |
|||
|
|||
public boolean getClearedAbove() { |
|||
return this.clearedAbove; |
|||
} |
|||
|
|||
public void setClearedBelow(boolean b) { |
|||
this.clearedBelow = b; |
|||
} |
|||
|
|||
public boolean getClearedBelow() { |
|||
return this.clearedBelow; |
|||
} |
|||
|
|||
public void setClearedRight(boolean b) { |
|||
this.clearedRight = b; |
|||
} |
|||
|
|||
public boolean getClearedRight() { |
|||
return this.clearedRight; |
|||
} |
|||
|
|||
public void setClearedLeft(boolean b) { |
|||
this.clearedLeft = b; |
|||
} |
|||
|
|||
public boolean getClearedLeft() { |
|||
return this.clearedLeft; |
|||
} |
|||
|
|||
public void setTarget(Coordinate target) { |
|||
this.target = target; |
|||
} |
|||
|
|||
public Coordinate getTarget() { |
|||
return target; |
|||
} |
|||
|
|||
public void setMatchfield(Matchfield matchfield) { |
|||
this.matchfield = matchfield; |
|||
this.everySecondField = getEverySecondField(); |
|||
} |
|||
|
|||
public Matchfield getMatchfield() { |
|||
return matchfield; |
|||
} |
|||
} |
@ -0,0 +1,268 @@ |
|||
package de.tims.fleetstorm.gui; |
|||
|
|||
import java.awt.BorderLayout; |
|||
import java.awt.Color; |
|||
import java.awt.Font; |
|||
import java.awt.event.MouseAdapter; |
|||
import java.awt.event.MouseEvent; |
|||
import java.util.ArrayList; |
|||
|
|||
import javax.swing.JFrame; |
|||
import javax.swing.JLabel; |
|||
import javax.swing.JPanel; |
|||
import javax.swing.SwingConstants; |
|||
import javax.swing.border.MatteBorder; |
|||
|
|||
import de.tims.fleetstorm.ai.Logic; |
|||
import de.tims.fleetstorm.matchfield.Coordinate; |
|||
import de.tims.fleetstorm.matchfield.Matchfield; |
|||
|
|||
public class GameLogic extends JPanel { |
|||
|
|||
// GameManager stuff |
|||
private int gameState; |
|||
private Matchfield matchfield; |
|||
private Matchfield enemyMatchfield; |
|||
private int matchfieldSize = 10; |
|||
private boolean playerMove; |
|||
private Logic aiLogic; |
|||
|
|||
public static final int PREPARATION = 1; |
|||
public static final int RUNNING = 2; |
|||
public static final int GAME_OVER = 3; |
|||
|
|||
// GUI stuff |
|||
private ArrayList<JPanel> playerFields; |
|||
private ArrayList<JPanel> enemyFields; |
|||
|
|||
public GameLogic(int gapToFrameBorderX, int gapToFrameBorderY, int fieldWidth, int spaceBetween) { |
|||
this.playerFields = new ArrayList<>(); |
|||
this.enemyFields = new ArrayList<>(); |
|||
|
|||
setSize(640, 480); |
|||
|
|||
fieldWrapper = new JPanel(); |
|||
fieldWrapper.setBounds(10, 11, 305, 458); |
|||
fieldWrapper.setLayout(null); |
|||
setLayout(null); |
|||
add(fieldWrapper); |
|||
|
|||
enemyFieldWrapper = new JPanel(); |
|||
enemyFieldWrapper.setLayout(null); |
|||
enemyFieldWrapper.setBounds(326, 11, 305, 458); |
|||
add(enemyFieldWrapper); |
|||
|
|||
this.generateFieldsForGUI(gapToFrameBorderX, gapToFrameBorderY, fieldWidth, spaceBetween, fieldWrapper, |
|||
this.playerFields, false); |
|||
|
|||
JLabel ownFieldLabel = new JLabel("Eigenes Spielfeld"); |
|||
ownFieldLabel.setBounds(10, 11, 114, 14); |
|||
fieldWrapper.add(ownFieldLabel); |
|||
this.generateFieldsForGUI(gapToFrameBorderX, gapToFrameBorderY, fieldWidth, spaceBetween, enemyFieldWrapper, |
|||
this.enemyFields, true); |
|||
|
|||
JLabel enemyFieldLabel = new JLabel("Gegnerisches Spielfeld"); |
|||
enemyFieldLabel.setBounds(10, 11, 168, 14); |
|||
enemyFieldWrapper.add(enemyFieldLabel); |
|||
} |
|||
|
|||
private void generateFieldsForGUI(int gapToFrameBorderX, int gapToFrameBorderY, int fieldWidth, int spaceBetween, |
|||
JPanel panel, ArrayList<JPanel> fields, boolean registerMouseListener) { |
|||
|
|||
for (int x = 0; x < this.matchfieldSize; x++) { |
|||
for (int y = 0; y < this.matchfieldSize; y++) { |
|||
JPanel field = new JPanel(); |
|||
|
|||
int xPos = gapToFrameBorderX + x * fieldWidth + (x * spaceBetween); |
|||
int yPos = gapToFrameBorderY + y * fieldWidth + (y * spaceBetween); |
|||
|
|||
field.setBounds(xPos, yPos, fieldWidth, fieldWidth); |
|||
field.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0))); |
|||
field.setName(x + ":" + y); |
|||
|
|||
fields.add(field); |
|||
panel.add(field); |
|||
|
|||
if (!registerMouseListener) |
|||
continue; |
|||
|
|||
field.addMouseListener(new MouseAdapter() { |
|||
|
|||
public void mouseClicked(MouseEvent e) { |
|||
int[] coords = getCoordinateFromLabel(field); |
|||
int coordX = coords[0]; |
|||
int coordY = coords[1]; |
|||
|
|||
Coordinate chosenField = enemyMatchfield.getField(coordX, coordY); |
|||
|
|||
boolean shotSuccess = chosenField.shoot(); |
|||
|
|||
boolean areAllShipsHit = enemyMatchfield.areAllShipsHit(); |
|||
if (areAllShipsHit) { |
|||
gameOver(true); |
|||
return; |
|||
} |
|||
|
|||
if (shotSuccess && chosenField.getState() != Coordinate.HIT) { |
|||
nextMove(false); |
|||
} else { |
|||
nextMove(true); |
|||
} |
|||
|
|||
} |
|||
}); |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
private JLabel getXLabel() { |
|||
JLabel x = new JLabel("x"); |
|||
x.setForeground(Color.WHITE); |
|||
return x; |
|||
} |
|||
|
|||
private int[] getCoordinateFromLabel(JPanel panel) { |
|||
String panelName = panel.getName(); |
|||
String[] panelNameSplit = panelName.split(":"); |
|||
int coordX = Integer.parseInt(panelNameSplit[0]); |
|||
int coordY = Integer.parseInt(panelNameSplit[1]); |
|||
return new int[] { coordX, coordY }; |
|||
} |
|||
|
|||
private void updateFields() { |
|||
this.updateField(enemyMatchfield, this.enemyFields); |
|||
this.updateField(matchfield, this.playerFields); |
|||
} |
|||
|
|||
private void updateField(Matchfield matchfield, ArrayList<JPanel> fields) { |
|||
|
|||
for (JPanel coordinatePanel : fields) { |
|||
int[] coords = getCoordinateFromLabel(coordinatePanel); |
|||
int coordX = coords[0]; |
|||
int coordY = coords[1]; |
|||
|
|||
// reset field |
|||
coordinatePanel.setBackground(null); |
|||
coordinatePanel.removeAll(); |
|||
|
|||
int state = matchfield.getField(coordX, coordY).getState(); |
|||
|
|||
switch (state) { |
|||
case Coordinate.SHIP: |
|||
if (playerMove) |
|||
coordinatePanel.setBackground(new Color(91, 58, 41)); |
|||
break; |
|||
case Coordinate.SHOT: |
|||
coordinatePanel.setBackground(new Color(0, 94, 184)); |
|||
break; |
|||
case Coordinate.HIT: |
|||
coordinatePanel.setBackground(new Color(91, 58, 41)); |
|||
coordinatePanel.add(getXLabel()); |
|||
break; |
|||
} |
|||
|
|||
coordinatePanel.revalidate(); |
|||
coordinatePanel.repaint(); |
|||
} |
|||
|
|||
} |
|||
|
|||
/** |
|||
* This function is only for testing |
|||
*/ |
|||
private static GameLogic gui; |
|||
private JPanel fieldWrapper; |
|||
private JPanel enemyFieldWrapper; |
|||
|
|||
public static void main(String[] args) { |
|||
JFrame frame = new JFrame("Test GUI"); |
|||
gui = new GameLogic(12, 35, 25, 1); |
|||
frame.setContentPane(gui); |
|||
frame.setSize(640, 480); |
|||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
|||
frame.setResizable(true); |
|||
frame.setVisible(true); |
|||
|
|||
gui.start(false); |
|||
} |
|||
|
|||
public void start(boolean test) { |
|||
this.gameState = GameLogic.PREPARATION; |
|||
this.playerMove = true; |
|||
|
|||
// create player matchfield and set ships |
|||
this.matchfield = new Matchfield(matchfieldSize); |
|||
this.matchfield.createMatchfield(); |
|||
this.matchfield.setShip(new Coordinate(4, 6), 2, 0); |
|||
this.matchfield.setShip(new Coordinate(1, 3), 3, 0); |
|||
this.matchfield.setShip(new Coordinate(9, 1), 4, 1); |
|||
this.matchfield.setShip(new Coordinate(0, 0), 5, 0); |
|||
|
|||
this.aiLogic = new Logic(); |
|||
this.aiLogic.setMatchfield(this.matchfield); |
|||
|
|||
// create enemy matchfield, set ships and initialize AI (with player's |
|||
// matchfield) |
|||
this.enemyMatchfield = new Matchfield(matchfieldSize); |
|||
this.enemyMatchfield.createMatchfield(); |
|||
this.enemyMatchfield.setShip(new Coordinate(8, 9), 2, 0); |
|||
this.enemyMatchfield.setShip(new Coordinate(0, 2), 3, 1); |
|||
this.enemyMatchfield.setShip(new Coordinate(7, 0), 4, 1); |
|||
this.enemyMatchfield.setShip(new Coordinate(3, 6), 5, 0); |
|||
|
|||
// enter game loop |
|||
this.gameState = GameLogic.RUNNING; |
|||
if (!test) |
|||
this.nextMove(true); |
|||
} |
|||
|
|||
public void nextMove(boolean playerMove) { |
|||
this.playerMove = playerMove; |
|||
|
|||
if (this.playerMove) { |
|||
gui.updateFields(); |
|||
// waiting here for mouse click event.... |
|||
} else { |
|||
|
|||
Coordinate aiChosenField = null; |
|||
while (aiChosenField == null) { |
|||
aiChosenField = this.aiLogic.chooseField(); |
|||
} |
|||
|
|||
aiChosenField.shoot(); |
|||
|
|||
gui.updateFields(); |
|||
|
|||
boolean areAllShipsHit = this.matchfield.areAllShipsHit(); |
|||
if (areAllShipsHit) { |
|||
this.gameOver(false); |
|||
return; |
|||
} |
|||
|
|||
boolean aiHasNextMove = aiChosenField.getState() != Coordinate.HIT; |
|||
this.nextMove(aiHasNextMove); |
|||
} |
|||
|
|||
} |
|||
|
|||
protected void gameOver(boolean playerWinner) { |
|||
this.gameState = GameLogic.GAME_OVER; |
|||
|
|||
this.removeAll(); |
|||
this.setLayout(new BorderLayout()); |
|||
|
|||
JLabel wonLabel = new JLabel(playerWinner ? "Du hast gewonnen!" : "Du hast verloren!"); |
|||
wonLabel.setHorizontalAlignment(SwingConstants.CENTER); |
|||
wonLabel.setVerticalAlignment(SwingConstants.CENTER); |
|||
wonLabel.setFont(new Font("Tahoma", Font.BOLD, 18)); |
|||
this.add(wonLabel, SwingConstants.CENTER); |
|||
|
|||
this.revalidate(); |
|||
this.repaint(); |
|||
} |
|||
|
|||
public int getGameState() { |
|||
return gameState; |
|||
} |
|||
} |
@ -0,0 +1,61 @@ |
|||
package de.tims.fleetstorm.matchfield; |
|||
|
|||
public class Coordinate { |
|||
private int x; |
|||
private int y; |
|||
private int state; |
|||
|
|||
public static final int EMPTY = 0; |
|||
public static final int SHIP = 1; |
|||
public static final int SHOT = 2; |
|||
public static final int HIT = 3; |
|||
|
|||
public Coordinate(int x, int y) { |
|||
this.x = x; |
|||
this.y = y; |
|||
this.state = 0; |
|||
} |
|||
|
|||
public Integer getX() { |
|||
return x; |
|||
} |
|||
|
|||
public Integer getY() { |
|||
return y; |
|||
} |
|||
|
|||
public int getState() { |
|||
return this.state; |
|||
} |
|||
|
|||
public void setState(int state) { |
|||
this.state = state; |
|||
} |
|||
|
|||
@Override |
|||
public boolean equals(Object obj) { |
|||
if (!(obj instanceof Coordinate)) { |
|||
return false; |
|||
} |
|||
return this.x == ((Coordinate) obj).getX() && this.y == ((Coordinate) obj).getY(); |
|||
} |
|||
|
|||
public void print() { |
|||
System.out.println("X = " + this.x + ", Y = " + this.y + ", State = " + this.state); |
|||
} |
|||
|
|||
public boolean shoot() { |
|||
if (this.state == Coordinate.SHOT || this.state == Coordinate.HIT) |
|||
return false; |
|||
|
|||
if (this.state == Coordinate.SHIP) { |
|||
this.state = Coordinate.HIT; |
|||
return true; |
|||
} |
|||
|
|||
this.state = Coordinate.SHOT; |
|||
|
|||
return true; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,113 @@ |
|||
package de.tims.fleetstorm.matchfield; |
|||
|
|||
public class Matchfield { |
|||
|
|||
private Coordinate[][] matchfield; |
|||
private int size; |
|||
|
|||
public Matchfield(int size) { |
|||
this.size = size; |
|||
this.matchfield = new Coordinate[this.size][this.size]; |
|||
} |
|||
|
|||
public Coordinate[][] createMatchfield() { |
|||
for (int i = 0; i < size; i++) { |
|||
for (int j = 0; j < size; j++) { |
|||
this.matchfield[i][j] = new Coordinate(i, j); |
|||
} |
|||
} |
|||
|
|||
return this.matchfield; |
|||
} |
|||
|
|||
public int getSize() { |
|||
return this.matchfield.length * this.matchfield[0].length; |
|||
} |
|||
|
|||
public int getState(int x, int y) { |
|||
return this.matchfield[x][y].getState(); |
|||
} |
|||
|
|||
public void setState(int x, int y, int state) { |
|||
this.matchfield[x][y].setState(state); |
|||
} |
|||
|
|||
public void setState(Coordinate coordinate, int state) { |
|||
this.matchfield[coordinate.getX()][coordinate.getY()].setState(state); |
|||
} |
|||
|
|||
public Coordinate getField(Coordinate coordinate) { |
|||
return matchfield[coordinate.getX()][coordinate.getY()]; |
|||
} |
|||
|
|||
public Coordinate getField(int x, int y) { |
|||
return this.matchfield[x][y]; |
|||
} |
|||
|
|||
public Coordinate getRight(Coordinate center) { |
|||
if (center.getX() == matchfield.length - 1) { |
|||
return null; |
|||
} |
|||
return this.matchfield[center.getX() + 1][center.getY()]; |
|||
} |
|||
|
|||
public Coordinate getLeft(Coordinate center) { |
|||
if (center.getX() == 0) { |
|||
return null; |
|||
} |
|||
return this.matchfield[center.getX() - 1][center.getY()]; |
|||
} |
|||
|
|||
public Coordinate getAbove(Coordinate center) { |
|||
if (center.getY() == matchfield.length - 1) { |
|||
return null; |
|||
} |
|||
return matchfield[center.getX()][center.getY() + 1]; |
|||
} |
|||
|
|||
public Coordinate getBelow(Coordinate center) { |
|||
if (center.getY() == 0) { |
|||
return null; |
|||
} |
|||
return matchfield[center.getX()][center.getY() - 1]; |
|||
} |
|||
|
|||
/** |
|||
* direction 0 => x axis (to the right) direction 1 => y axis (to the bottom) |
|||
*/ |
|||
public boolean setShip(Coordinate coordinate, int length, int direction) { |
|||
|
|||
for (int i = 0; i < length; i++) { |
|||
|
|||
Coordinate field = this.getField(coordinate); |
|||
if (field.getState() == Coordinate.SHIP) |
|||
return false; |
|||
|
|||
field.setState(Coordinate.SHIP); |
|||
if (direction == 0) |
|||
coordinate = this.getRight(coordinate); |
|||
if (direction == 1) |
|||
coordinate = this.getAbove(coordinate); |
|||
|
|||
if (coordinate == null) |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
public boolean areAllShipsHit() { |
|||
int shipCounter = 0; |
|||
|
|||
for (int i = 0; i < size; i++) { |
|||
for (int j = 0; j < size; j++) { |
|||
int fieldState = this.matchfield[i][j].getState(); |
|||
if (fieldState == Coordinate.SHIP) |
|||
shipCounter++; |
|||
} |
|||
} |
|||
|
|||
return shipCounter == 0; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,313 @@ |
|||
package de.tims.gameexplorer; |
|||
|
|||
import java.awt.*; |
|||
import java.awt.event.*; |
|||
|
|||
import javax.swing.*; |
|||
|
|||
import de.tims.player_management.Player; |
|||
import de.tims.player_management.PlayerManager; |
|||
|
|||
public class GameExplorer { |
|||
|
|||
private JFrame frame; |
|||
private JPanel explorerPanel; |
|||
private JPanel loginPanel; |
|||
private JPanel gamePanel; |
|||
private JPanel navigationPanel; |
|||
private JPanel fleetstormPanel; |
|||
private JPanel fourwinsPanel; |
|||
private JPanel tictactoePanel; |
|||
private JPanel leaderboardPanel; |
|||
private JPanel border1; |
|||
private JPanel border2; |
|||
private JPanel border3; |
|||
private JPanel border4; |
|||
private JPanel border5; |
|||
private JPanel border6; |
|||
private JButton loginBtn; |
|||
private JButton fleetstormBtn; |
|||
private JButton fourwinsBtn; |
|||
private JButton tictactoeBtn; |
|||
private JButton leaderboardBtn; |
|||
private JButton backBtn; |
|||
private JLabel username; |
|||
private JLabel loginWarning; |
|||
private JLabel chosenGame; |
|||
private JTextField usernameInput; |
|||
private Dimension minSize; |
|||
private Dimension loginBtnSize; |
|||
private Dimension btnSize; |
|||
private GridBagConstraints gbc; |
|||
|
|||
private static final String playerFile = "src/main/java/resources/player_data.csv"; |
|||
|
|||
private enum Game { FLEETSTORM, FOURWINS, TICTACTOE, LEADERBOARD }; |
|||
private Game actualGame; |
|||
private PlayerManager manager; |
|||
private Player actualPlayer; |
|||
|
|||
public GameExplorer() { |
|||
manager = new PlayerManager(); |
|||
|
|||
frame = new JFrame("1000 infomagische Spiele"); |
|||
|
|||
minSize = new Dimension(400, 300); |
|||
loginBtnSize = new Dimension(91, 20); |
|||
btnSize = new Dimension(160, 40); |
|||
gbc = new GridBagConstraints(); |
|||
|
|||
buildExplorerPanel(); |
|||
buildLoginPanel(); |
|||
buildNavigationPanel(); |
|||
buildGamePanels(); |
|||
|
|||
frame.add(loginPanel); |
|||
|
|||
frame.setMinimumSize(minSize); |
|||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
|||
frame.setSize(640, 480); |
|||
frame.setResizable(true); |
|||
frame.setVisible(true); |
|||
} |
|||
|
|||
private void buildExplorerPanel() { |
|||
explorerPanel = new JPanel(); |
|||
explorerPanel.setLayout(new GridBagLayout()); |
|||
|
|||
fleetstormBtn = new JButton("Schiffe versenken"); |
|||
fleetstormBtn.setPreferredSize(btnSize); |
|||
fleetstormBtn.addActionListener(new GameAction()); |
|||
fourwinsBtn = new JButton("Vier gewinnt"); |
|||
fourwinsBtn.setPreferredSize(btnSize); |
|||
fourwinsBtn.addActionListener(new GameAction()); |
|||
tictactoeBtn = new JButton("TicTacToe"); |
|||
tictactoeBtn.setPreferredSize(btnSize); |
|||
tictactoeBtn.addActionListener(new GameAction()); |
|||
leaderboardBtn = new JButton("Leaderboard"); |
|||
leaderboardBtn.setPreferredSize(btnSize); |
|||
leaderboardBtn.addActionListener(new GameAction()); |
|||
|
|||
border1 = new JPanel(); |
|||
border1.setOpaque(false); |
|||
border2 = new JPanel(); |
|||
border2.setOpaque(false); |
|||
border3 = new JPanel(); |
|||
border3.setOpaque(false); |
|||
border4 = new JPanel(); |
|||
border4.setOpaque(false); |
|||
border5 = new JPanel(); |
|||
border5.setOpaque(false); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 0; |
|||
gbc.weighty = 0.2; |
|||
explorerPanel.add(border1, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 1; |
|||
gbc.weighty = 0.0; |
|||
explorerPanel.add(fleetstormBtn, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 2; |
|||
gbc.weighty = 0.2; |
|||
explorerPanel.add(border2, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 3; |
|||
gbc.weighty = 0.0; |
|||
explorerPanel.add(fourwinsBtn, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 4; |
|||
gbc.weighty = 0.2; |
|||
explorerPanel.add(border3, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 5; |
|||
gbc.weighty = 0.0; |
|||
explorerPanel.add(tictactoeBtn, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 6; |
|||
gbc.weighty = 0.2; |
|||
explorerPanel.add(border4, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 7; |
|||
gbc.weighty = 0.0; |
|||
explorerPanel.add(leaderboardBtn, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 8; |
|||
gbc.weighty = 0.2; |
|||
explorerPanel.add(border5, gbc); |
|||
} |
|||
|
|||
private void buildLoginPanel() { |
|||
loginPanel = new JPanel(); |
|||
loginPanel.setLayout(new GridBagLayout()); |
|||
|
|||
loginBtn = new JButton("Login"); |
|||
loginBtn.setPreferredSize(loginBtnSize); |
|||
loginBtn.addActionListener(new LoginAction()); |
|||
username = new JLabel("Name eingeben:"); |
|||
loginWarning = new JLabel(); |
|||
usernameInput = new JTextField(8); |
|||
|
|||
gbc.weighty = 0; |
|||
gbc.gridx = 0; |
|||
gbc.gridy = 0; |
|||
gbc.insets = new Insets(0, 0, 5, 0); |
|||
loginPanel.add(username, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 1; |
|||
gbc.insets = new Insets(5, 0, 5, 0); |
|||
loginPanel.add(usernameInput, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 2; |
|||
gbc.insets = new Insets(5, 0, 5, 0); |
|||
loginPanel.add(loginBtn, gbc); |
|||
|
|||
gbc.gridx = 0; |
|||
gbc.gridy = 3; |
|||
gbc.insets = new Insets(5, 0, 0, 0); |
|||
loginPanel.add(loginWarning, gbc); |
|||
} |
|||
|
|||
private void buildNavigationPanel() { |
|||
navigationPanel = new JPanel(); |
|||
navigationPanel.setLayout(new GridBagLayout()); |
|||
|
|||
backBtn = new JButton("< Zurück"); |
|||
backBtn.addActionListener(new BackAction()); |
|||
|
|||
chosenGame = new JLabel(); |
|||
|
|||
border6 = new JPanel(); |
|||
border6.setOpaque(false); |
|||
|
|||
gbc.weighty = 0.0; |
|||
gbc.gridx = 0; |
|||
gbc.gridy = 0; |
|||
gbc.weightx = 0.0; |
|||
gbc.insets = new Insets(5, 20, 5, 0); |
|||
navigationPanel.add(backBtn, gbc); |
|||
|
|||
gbc.gridx = 1; |
|||
gbc.gridy = 0; |
|||
gbc.weightx = 1.0; |
|||
gbc.insets = new Insets(0, 0, 0, 0); |
|||
navigationPanel.add(border6, gbc); |
|||
|
|||
gbc.gridx = 2; |
|||
gbc.gridy = 0; |
|||
gbc.weightx = 0.0; |
|||
gbc.insets = new Insets(5, 0, 5, 20); |
|||
navigationPanel.add(chosenGame, gbc); |
|||
} |
|||
|
|||
private void buildGamePanels() { |
|||
gamePanel = new JPanel(); |
|||
gamePanel.setLayout(new BorderLayout()); |
|||
|
|||
gamePanel.add(navigationPanel, BorderLayout.PAGE_START); |
|||
|
|||
//use of dummy panels because real panels have not been implemented yet |
|||
fleetstormPanel = new JPanel(); |
|||
fleetstormPanel.setBackground(Color.BLUE); |
|||
|
|||
fourwinsPanel = new JPanel(); |
|||
fourwinsPanel.setBackground(Color.GREEN); |
|||
|
|||
tictactoePanel = new JPanel(); |
|||
tictactoePanel.setBackground(Color.YELLOW); |
|||
|
|||
leaderboardPanel = new JPanel(); |
|||
leaderboardPanel.setBackground(Color.RED); |
|||
} |
|||
|
|||
private class LoginAction implements ActionListener { |
|||
@Override |
|||
public void actionPerformed(ActionEvent e) { |
|||
String userInput = usernameInput.getText(); |
|||
|
|||
if (!userInput.equals("")) { |
|||
loginWarning.setText(""); |
|||
|
|||
manager.loadPlayers(playerFile); |
|||
actualPlayer = manager.selectPlayer(userInput); |
|||
|
|||
frame.remove(loginPanel); |
|||
frame.add(explorerPanel); |
|||
frame.revalidate(); |
|||
frame.repaint(); |
|||
|
|||
System.out.println("Actual Player: " + actualPlayer.getName() + ", Points: " + actualPlayer.getPoints()); |
|||
} else { |
|||
loginWarning.setText("Kein Name eingegeben!"); |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
private class GameAction implements ActionListener { |
|||
@Override |
|||
public void actionPerformed(ActionEvent e) { |
|||
//each button adds a different dummy panel to the gamePanel |
|||
if (e.getSource() == fleetstormBtn) { |
|||
actualGame = Game.FLEETSTORM; |
|||
chosenGame.setText("Schiffe versenken"); |
|||
gamePanel.add(fleetstormPanel, BorderLayout.CENTER); |
|||
} else if (e.getSource() == fourwinsBtn) { |
|||
actualGame = Game.FOURWINS; |
|||
chosenGame.setText("Vier gewinnt"); |
|||
gamePanel.add(fourwinsPanel, BorderLayout.CENTER); |
|||
} else if (e.getSource() == tictactoeBtn) { |
|||
actualGame = Game.TICTACTOE; |
|||
chosenGame.setText("TicTacToe"); |
|||
gamePanel.add(tictactoePanel, BorderLayout.CENTER); |
|||
} else if (e.getSource() == leaderboardBtn) { |
|||
actualGame = Game.LEADERBOARD; |
|||
chosenGame.setText("Leaderboard"); |
|||
gamePanel.add(leaderboardPanel, BorderLayout.CENTER); |
|||
} |
|||
|
|||
frame.remove(explorerPanel); |
|||
frame.add(gamePanel); |
|||
frame.revalidate(); |
|||
frame.repaint(); |
|||
} |
|||
} |
|||
|
|||
private class BackAction implements ActionListener { |
|||
@Override |
|||
public void actionPerformed(ActionEvent e) { |
|||
switch (actualGame) { |
|||
case FLEETSTORM: |
|||
gamePanel.remove(fleetstormPanel); |
|||
break; |
|||
case FOURWINS: |
|||
gamePanel.remove(fourwinsPanel); |
|||
break; |
|||
case TICTACTOE: |
|||
gamePanel.remove(tictactoePanel); |
|||
break; |
|||
case LEADERBOARD: |
|||
gamePanel.remove(leaderboardPanel); |
|||
} |
|||
|
|||
frame.remove(gamePanel); |
|||
frame.add(explorerPanel); |
|||
frame.revalidate(); |
|||
frame.repaint(); |
|||
} |
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
new GameExplorer(); |
|||
} |
|||
} |
@ -0,0 +1,45 @@ |
|||
package de.tims.player_management; |
|||
|
|||
public class Player { |
|||
|
|||
private String name; |
|||
private int points; |
|||
|
|||
public Player(String name, int points) { |
|||
this.name = name; |
|||
this.points = points; |
|||
} |
|||
|
|||
public String getName() { |
|||
return name; |
|||
} |
|||
|
|||
public int getPoints() { |
|||
return this.points; |
|||
} |
|||
|
|||
public void addPoints(int pointsToAdd) { |
|||
this.points = (this.points + pointsToAdd > 0) ? this.points + pointsToAdd : 0; |
|||
} |
|||
|
|||
@Override |
|||
public boolean equals(Object o) { |
|||
if (o == this) { |
|||
return true; |
|||
} |
|||
|
|||
if ((o == null) || this.getClass() != o.getClass()) { |
|||
return false; |
|||
} |
|||
|
|||
Player player2 = (Player) o; |
|||
|
|||
return this.points == player2.points && this.name.equals(player2.getName()); |
|||
} |
|||
|
|||
@Override |
|||
public int hashCode() { |
|||
return points + name.hashCode(); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,95 @@ |
|||
package de.tims.player_management; |
|||
|
|||
import java.io.File; |
|||
import java.io.FileReader; |
|||
import java.io.FileWriter; |
|||
import java.io.IOException; |
|||
import java.util.LinkedList; |
|||
import java.util.List; |
|||
|
|||
public class PlayerManager { |
|||
|
|||
private List<Player> players; |
|||
private static final int PLAYER_ATTRIBUTES = 2; |
|||
|
|||
public List<Player> getPlayers() { |
|||
return players; |
|||
} |
|||
|
|||
public void setPlayers(List<Player> players) { |
|||
this.players = players; |
|||
} |
|||
|
|||
public Player selectPlayer(String playerName) { |
|||
for (Player p : this.players) { |
|||
if (playerName.equals(p.getName())) { |
|||
return p; |
|||
} |
|||
} |
|||
|
|||
Player newPlayer = new Player(playerName, 0); |
|||
|
|||
players.add(newPlayer); |
|||
|
|||
return newPlayer; |
|||
} |
|||
|
|||
public void loadPlayers(String fileName) { |
|||
players = new LinkedList<Player>(); |
|||
|
|||
File playerData = new File(fileName); |
|||
|
|||
try { |
|||
FileReader fr = new FileReader(playerData); |
|||
|
|||
int c = -1; |
|||
String playerName; |
|||
int playerPoints; |
|||
StringBuilder nameBuilder = new StringBuilder(); |
|||
StringBuilder pointBuilder = new StringBuilder(); |
|||
StringBuilder[] sb = {nameBuilder, pointBuilder}; |
|||
|
|||
do { |
|||
for (int i = 0; i < PLAYER_ATTRIBUTES; i++) { |
|||
do { |
|||
c = fr.read(); |
|||
if (c != ';' && c != '\n' && c != -1) { |
|||
sb[i].append((char) c); |
|||
} |
|||
} while (c != ';' && c != '\n' && c != -1); |
|||
} |
|||
|
|||
if (!nameBuilder.toString().equals("") && !pointBuilder.toString().equals("")) { |
|||
playerName = nameBuilder.toString(); |
|||
playerPoints = Integer.parseInt(pointBuilder.toString()); |
|||
|
|||
players.add(new Player(playerName, playerPoints)); |
|||
|
|||
nameBuilder.delete(0, nameBuilder.length()); |
|||
pointBuilder.delete(0, pointBuilder.length()); |
|||
} |
|||
} while (c != -1); |
|||
|
|||
fr.close(); |
|||
} catch (IOException e) { |
|||
return; |
|||
} |
|||
} |
|||
|
|||
public void savePlayers(String fileName) { |
|||
File playerData = new File(fileName); |
|||
|
|||
try { |
|||
FileWriter fw = new FileWriter(playerData, false); |
|||
|
|||
for (Player elem : players) { |
|||
fw.write(elem.getName() + ";" + elem.getPoints() + "\n"); |
|||
} |
|||
|
|||
fw.close(); |
|||
} catch (IOException e) { |
|||
return; |
|||
} |
|||
} |
|||
|
|||
} |
@ -0,0 +1,183 @@ |
|||
package de.tims.tictactoe; |
|||
|
|||
import java.awt.GridLayout; |
|||
import java.awt.event.ActionEvent; |
|||
import java.awt.event.ActionListener; |
|||
|
|||
import javax.swing.JButton; |
|||
import javax.swing.JOptionPane; |
|||
import javax.swing.JPanel; |
|||
|
|||
public class GameLogic implements ActionListener { |
|||
|
|||
private static final char EMPTY_FIELD = '-'; |
|||
private static final char PLAYER_1 = 'x'; |
|||
private static final char PLAYER_2 = 'o'; |
|||
private char[][] board; |
|||
private final char[] occupiedFields = { PLAYER_1, PLAYER_2 }; |
|||
private char currentPlayer = PLAYER_1; |
|||
private boolean gui = false; |
|||
|
|||
private JButton[][] fields; |
|||
private JPanel contentPanel; |
|||
|
|||
public GameLogic(int size) { |
|||
if (size < 3) { |
|||
size = 3; |
|||
} |
|||
this.board = new char[size][size]; |
|||
this.resetBoard(); |
|||
} |
|||
|
|||
public GameLogic(char[][] board) { |
|||
this.board = board; |
|||
} |
|||
|
|||
public char[][] getBoard() { |
|||
return this.board; |
|||
} |
|||
|
|||
public int countFields() { |
|||
return this.board[0].length * this.board.length; |
|||
} |
|||
|
|||
public void setField(int column, int row, char player) { |
|||
if (this.fieldIsEmpty(column, row)) { |
|||
this.board[column][row] = player; |
|||
if (gui) { |
|||
this.fields[column][row].setText("" + this.getCurrentPlayer()); |
|||
this.updateGUI(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public boolean fieldIsEmpty(int column, int row) { |
|||
for (char field : this.occupiedFields) { |
|||
if (this.board[column][row] == field) |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
public boolean checkForWin(char player) { |
|||
boolean won = false; |
|||
int countFields = 0; |
|||
|
|||
// check columns |
|||
for (int i = 0; i < this.board.length; i++) { |
|||
for (int j = 0; j < this.board[0].length; j++) { |
|||
if (this.board[j][i] == player) |
|||
countFields++; |
|||
} |
|||
if (countFields == this.board.length) |
|||
return won = true; |
|||
countFields = 0; |
|||
} |
|||
// check rows |
|||
for (int i = 0; i < this.board[0].length; i++) { |
|||
for (int j = 0; j < this.board.length; j++) { |
|||
if (this.board[i][j] == player) |
|||
countFields++; |
|||
} |
|||
if (countFields == this.board.length) |
|||
return won = true; |
|||
countFields = 0; |
|||
} |
|||
|
|||
// check diagonal left |
|||
for (int i = this.board.length - 1, j = this.board.length - 1; i >= 0; i--, j--) { |
|||
if (this.board[i][j] == player) |
|||
countFields++; |
|||
} |
|||
if (countFields == this.board.length) |
|||
return won = true; |
|||
countFields = 0; |
|||
|
|||
// check diagonal right |
|||
for (int i = this.board.length - 1, j = 0; i >= 0; i--, j++) { |
|||
if (this.board[i][j] == player) |
|||
countFields++; |
|||
} |
|||
if (countFields == this.board.length) |
|||
return won = true; |
|||
|
|||
return won; |
|||
} |
|||
|
|||
public boolean checkEndOfGame() { |
|||
return this.checkForWin(PLAYER_1) || this.checkForWin(PLAYER_2); |
|||
} |
|||
|
|||
public char getCurrentPlayer() { |
|||
return this.currentPlayer; |
|||
} |
|||
|
|||
public void switchPlayer() { |
|||
this.currentPlayer = this.currentPlayer == PLAYER_1 ? PLAYER_2 : PLAYER_1; |
|||
} |
|||
|
|||
public void resetBoard() { |
|||
for (int i = 0; i < this.board.length; i++) { |
|||
for (int j = 0; j < this.board.length; j++) { |
|||
this.board[i][j] = EMPTY_FIELD; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public JPanel generateGUI() { |
|||
this.fields = new JButton[this.board.length][this.board.length]; |
|||
this.contentPanel = new JPanel(); |
|||
this.contentPanel.setLayout(new GridLayout(this.board.length, this.board.length)); |
|||
|
|||
for (int i = 0; i < this.fields.length; i++) { |
|||
for (int j = 0; j < this.fields.length; j++) { |
|||
this.fields[i][j] = new JButton(); |
|||
this.fields[i][j].addActionListener(this); |
|||
this.contentPanel.add(this.fields[i][j]); |
|||
} |
|||
} |
|||
this.gui = true; |
|||
return this.contentPanel; |
|||
} |
|||
|
|||
public JButton getGUIField(int column, int row) { |
|||
return this.fields[column][row]; |
|||
} |
|||
|
|||
private void updateGUI() { |
|||
if (this.checkEndOfGame()) { |
|||
for (int i = 0; i < this.fields.length; i++) { |
|||
for (int j = 0; j < this.fields.length; j++) { |
|||
this.fields[i][j].setEnabled(false); |
|||
} |
|||
} |
|||
JOptionPane.showMessageDialog(contentPanel, "Spieler " + this.currentPlayer + " hat gewonnen."); |
|||
this.resetGUI(); |
|||
} |
|||
this.switchPlayer(); |
|||
} |
|||
|
|||
private void resetGUI() { |
|||
for (int i = 0; i < this.fields.length; i++) { |
|||
for (int j = 0; j < this.fields.length; j++) { |
|||
this.resetBoard(); |
|||
this.fields[i][j].setText(""); |
|||
this.fields[i][j].setEnabled(true); |
|||
} |
|||
} |
|||
this.switchPlayer(); |
|||
} |
|||
|
|||
@Override |
|||
public void actionPerformed(ActionEvent e) { |
|||
for (int i = 0; i < this.fields.length; i++) { |
|||
for (int j = 0; j < this.fields[0].length; j++) { |
|||
if (e.getSource() == this.fields[i][j]) { |
|||
this.setField(i, j, currentPlayer); |
|||
this.fields[i][j].getText(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
@ -0,0 +1,22 @@ |
|||
package de.tims.tictactoe; |
|||
|
|||
import javax.swing.JFrame; |
|||
|
|||
public class ShowGUI { |
|||
|
|||
private JFrame frame; |
|||
|
|||
public ShowGUI() { |
|||
this.frame = new JFrame("TicTacToe"); |
|||
this.frame.setSize(600, 600); |
|||
|
|||
GameLogic game = new GameLogic(3); |
|||
this.frame.add(game.generateGUI()); |
|||
this.frame.setVisible(true); |
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
new ShowGUI(); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,34 @@ |
|||
package de.tims.tictactoe.ai; |
|||
|
|||
import de.tims.tictactoe.GameLogic; |
|||
|
|||
import java.util.Random; |
|||
|
|||
public class AIEasy implements TicTacToeAI { |
|||
private static final char AI_CHAR = 'o'; |
|||
private static final char EMPTY_CHAR = '-'; |
|||
|
|||
private Random rand; |
|||
private GameLogic gl; |
|||
private int boardSize; |
|||
|
|||
public AIEasy(GameLogic gl) { |
|||
this.gl = gl; |
|||
boardSize = gl.getBoard().length; |
|||
rand = new Random(); |
|||
} |
|||
|
|||
@Override |
|||
public void calculateNextMove() { |
|||
char[][] board = gl.getBoard(); |
|||
int row; |
|||
int col; |
|||
do { |
|||
row = rand.nextInt(boardSize); |
|||
col = rand.nextInt(boardSize); |
|||
} while (board[row][col] != EMPTY_CHAR); |
|||
|
|||
gl.setField(row, col, AI_CHAR); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,190 @@ |
|||
package de.tims.tictactoe.ai; |
|||
|
|||
import de.tims.tictactoe.GameLogic; |
|||
|
|||
public class AIHard implements TicTacToeAI { |
|||
private static final char AI_CHAR = 'o'; |
|||
private static final char EMPTY_CHAR = '-'; |
|||
private static final char PLAYER_CHAR = 'x'; |
|||
private static final int BOARD_SIZE = 3; |
|||
|
|||
private GameLogic gl; |
|||
|
|||
public AIHard(GameLogic gl) throws IllegalArgumentException { |
|||
if (gl.getBoard().length != BOARD_SIZE) { |
|||
throw new IllegalArgumentException("Hard AI only supports 3x3 boards!"); |
|||
} |
|||
this.gl = gl; |
|||
} |
|||
|
|||
@Override |
|||
public void calculateNextMove() { |
|||
char[][] board = gl.getBoard(); |
|||
int row; |
|||
int col; |
|||
|
|||
int charsInRow = 0; |
|||
int charsInCol = 0; |
|||
int charsInDiag = 0; |
|||
char actualChar; |
|||
|
|||
for (int i = 0; i < 2; i++) { |
|||
actualChar = (i == 0) ? AI_CHAR : PLAYER_CHAR; |
|||
|
|||
for (int j = 0; j < BOARD_SIZE; j++) { |
|||
charsInRow = countCharsInRow(j, actualChar); |
|||
charsInCol = countCharsInCol(j, actualChar); |
|||
|
|||
if (j < 2) { |
|||
charsInDiag = countCharsInDiag(j, actualChar); |
|||
if (charsInDiag == BOARD_SIZE - 1) { |
|||
for (int k = 0; k < BOARD_SIZE; k++) { |
|||
row = k; |
|||
col = (j == 0) ? k : BOARD_SIZE - 1 - k; |
|||
|
|||
if (board[row][col] == EMPTY_CHAR) { |
|||
gl.setField(row, col, AI_CHAR); |
|||
return; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (charsInRow == BOARD_SIZE - 1 || charsInCol == BOARD_SIZE - 1) { |
|||
for (int k = 0; k < BOARD_SIZE; k++) { |
|||
if (charsInRow == BOARD_SIZE - 1) { |
|||
row = j; |
|||
col = k; |
|||
|
|||
if (board[row][col] == EMPTY_CHAR) { |
|||
gl.setField(row, col, AI_CHAR); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
if (charsInCol == BOARD_SIZE - 1) { |
|||
row = k; |
|||
col = j; |
|||
|
|||
if (board[row][col] == EMPTY_CHAR) { |
|||
gl.setField(row, col, AI_CHAR); |
|||
return; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (board[BOARD_SIZE / 2][BOARD_SIZE / 2] == EMPTY_CHAR) { |
|||
gl.setField(BOARD_SIZE / 2, BOARD_SIZE / 2, AI_CHAR); |
|||
return; |
|||
} else if (board[BOARD_SIZE / 2][BOARD_SIZE / 2] == AI_CHAR && (board[0][0] == AI_CHAR || board[0][BOARD_SIZE - 1] == AI_CHAR || board[BOARD_SIZE - 1][0] == AI_CHAR || board[BOARD_SIZE - 1][BOARD_SIZE - 1] == AI_CHAR)) { |
|||
int onwCharsInRow = 0; |
|||
int ownCharsInCol = 0; |
|||
int emptyCharsInRow = 0; |
|||
int emptyCharsInCol = 0; |
|||
|
|||
for (int i = BOARD_SIZE - 2; i > 0; i--) { |
|||
for (int j = 0; j < BOARD_SIZE; j += BOARD_SIZE - 1) { |
|||
for (int k = 1; k < BOARD_SIZE - 1; k++) { |
|||
for (int l = 0; l < 2; l++) { |
|||
row = (l == 0) ? j : k; |
|||
col = (l == 0) ? k : j; |
|||
|
|||
onwCharsInRow = countCharsInRow(row, AI_CHAR); |
|||
ownCharsInCol = countCharsInCol(col, AI_CHAR); |
|||
emptyCharsInRow = countCharsInRow(row, EMPTY_CHAR); |
|||
emptyCharsInCol = countCharsInCol(col, EMPTY_CHAR); |
|||
|
|||
if (onwCharsInRow >= i && ownCharsInCol >= i && emptyCharsInRow >= BOARD_SIZE - onwCharsInRow && emptyCharsInCol == BOARD_SIZE - ownCharsInCol) { |
|||
gl.setField(row, col, AI_CHAR); |
|||
return; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} else { |
|||
boolean emptyEdgeFound = false; |
|||
row = -1; |
|||
col = -1; |
|||
int prioRow = -1; |
|||
int prioCol = -1; |
|||
|
|||
for (int i = 0; i < BOARD_SIZE; i = i + BOARD_SIZE - 1) { |
|||
for (int j = 0; j < BOARD_SIZE; j = j + BOARD_SIZE - 1) { |
|||
if (board[i][j] == EMPTY_CHAR) { |
|||
row = (row == -1) ? i : row; |
|||
col = (col == -1) ? j : col; |
|||
|
|||
if (countCharsInRow(i, PLAYER_CHAR) != 0 || countCharsInCol(j, PLAYER_CHAR) != 0) { |
|||
prioRow = i; |
|||
prioCol = j; |
|||
emptyEdgeFound = true; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (emptyEdgeFound) { |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (row != -1 && col != -1) { |
|||
row = (prioRow != -1) ? prioRow : row; |
|||
col = (prioCol != -1) ? prioCol : col; |
|||
|
|||
gl.setField(row, col, AI_CHAR); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
for (row = 0; row < BOARD_SIZE; row++) { |
|||
for (col = 0; col < BOARD_SIZE; col++) { |
|||
if (board[row][col] == EMPTY_CHAR) { |
|||
gl.setField(row, col, AI_CHAR); |
|||
return; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public int countCharsInRow(int index, char charToCount) { |
|||
int count = 0; |
|||
char[][] board = gl.getBoard(); |
|||
|
|||
for (int i = 0; i < BOARD_SIZE; i++) { |
|||
count += (board[index][i] == charToCount) ? 1 : 0; |
|||
} |
|||
|
|||
return count; |
|||
} |
|||
|
|||
public int countCharsInCol(int index, char charToCount) { |
|||
int count = 0; |
|||
char[][] board = gl.getBoard(); |
|||
|
|||
for (int i = 0; i < BOARD_SIZE; i++) { |
|||
count += (board[i][index] == charToCount) ? 1 : 0; |
|||
} |
|||
|
|||
return count; |
|||
} |
|||
|
|||
public int countCharsInDiag(int index, char charToCount) throws IndexOutOfBoundsException { |
|||
if (index < 0 || index > 1) { |
|||
throw new IndexOutOfBoundsException("Only 0 and 1 are allowed values for index!"); |
|||
} |
|||
|
|||
int count = 0; |
|||
char[][] board = gl.getBoard(); |
|||
|
|||
for (int i = 0; i < BOARD_SIZE; i++) { |
|||
count += (board[i][(index == 0) ? i : BOARD_SIZE - 1 - i] == charToCount) ? 1 : 0; |
|||
} |
|||
|
|||
return count; |
|||
} |
|||
} |
@ -0,0 +1,5 @@ |
|||
package de.tims.tictactoe.ai; |
|||
|
|||
public interface TicTacToeAI { |
|||
void calculateNextMove(); |
|||
} |
@ -0,0 +1,21 @@ |
|||
package de.tims.fleetstorm; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
|
|||
class GameManagerTest { |
|||
|
|||
GameManager gameManager = new GameManager(); |
|||
|
|||
@Test |
|||
void testIfGameStateIsPreparationAfterStart() { |
|||
gameManager.start(); |
|||
int expectedState = GameManager.PREPARATION; |
|||
|
|||
int calculatedState = gameManager.getGameState(); |
|||
|
|||
assertEquals(expectedState, calculatedState); |
|||
} |
|||
|
|||
} |
@ -1,16 +1,376 @@ |
|||
package de.tims.fleetstorm.ai; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals; |
|||
import static org.junit.jupiter.api.Assertions.assertNotEquals; |
|||
import static org.junit.jupiter.api.Assertions.assertNotNull; |
|||
|
|||
import java.util.ArrayList; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
|
|||
import de.tims.fleetstorm.matchfield.Coordinate; |
|||
import de.tims.fleetstorm.matchfield.Matchfield; |
|||
|
|||
class LogicTest { |
|||
Logic logic = new Logic(); |
|||
|
|||
@Test |
|||
void testFielIsNotNull() { |
|||
int[] calcResult = logic.chooseField(); |
|||
void testFieldIsNotNull() { |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield; |
|||
int size = 5; |
|||
matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
logic.setMatchfield(matchfield); |
|||
// ArrayList<Coordinate> everySecondField = logic.getEverySecondField(); |
|||
|
|||
Coordinate calcResult = logic.chooseField(); |
|||
assertNotNull(calcResult); |
|||
} |
|||
|
|||
@Test |
|||
void testChoosenFieldHasNotStateShot() { |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield; |
|||
int size = 5; |
|||
matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
logic.setMatchfield(matchfield); |
|||
|
|||
ArrayList<Coordinate> everySecondField = logic.getEverySecondField(); |
|||
for (int i = 0; i < everySecondField.size(); i++) { |
|||
everySecondField.get(i).setState(Coordinate.SHOT); |
|||
} |
|||
matchfield.setState(2, 2, Coordinate.EMPTY); |
|||
logic.setEverySecondField(everySecondField); |
|||
|
|||
int calcState = logic.chooseField().getState(); |
|||
assertNotEquals(calcState, Coordinate.SHOT); |
|||
} |
|||
|
|||
@Test |
|||
void testGetEverySecondField() { |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield; |
|||
int size = 4; |
|||
matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
logic.setMatchfield(matchfield); |
|||
|
|||
ArrayList<Coordinate> everySecondField = logic.getEverySecondField(); |
|||
ArrayList<Coordinate> expectedResult = new ArrayList<Coordinate>(); |
|||
|
|||
expectedResult.add(new Coordinate(0, 0)); |
|||
expectedResult.add(new Coordinate(0, 2)); |
|||
expectedResult.add(new Coordinate(1, 1)); |
|||
expectedResult.add(new Coordinate(1, 3)); |
|||
expectedResult.add(new Coordinate(2, 0)); |
|||
expectedResult.add(new Coordinate(2, 2)); |
|||
expectedResult.add(new Coordinate(3, 1)); |
|||
expectedResult.add(new Coordinate(3, 3)); |
|||
|
|||
assertEquals(everySecondField, expectedResult); |
|||
} |
|||
|
|||
@Test |
|||
void testGetAndSetLastShot() { |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield; |
|||
int size = 4; |
|||
matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
logic.setMatchfield(matchfield); |
|||
|
|||
Coordinate expectedResult = new Coordinate(2, 2); |
|||
logic.setLastShot(expectedResult); |
|||
Coordinate result = logic.getLastShot(); |
|||
|
|||
assertEquals(result, expectedResult); |
|||
} |
|||
|
|||
@Test |
|||
void testSetMatchfield() { |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield; |
|||
int size = 4; |
|||
matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
|
|||
Matchfield result = logic.getMatchfield(); |
|||
assertEquals(result, null); |
|||
logic.setMatchfield(matchfield); |
|||
result = logic.getMatchfield(); |
|||
assertNotNull(result); |
|||
} |
|||
|
|||
@Test |
|||
void testFindShip() { |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield; |
|||
int size = 4; |
|||
matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
logic.setMatchfield(matchfield); |
|||
|
|||
logic.setLastShot(new Coordinate(2, 2)); |
|||
logic.getLastShot().setState(Coordinate.HIT); |
|||
logic.findShip(); |
|||
assertEquals(logic.getFoundShip(), true); |
|||
} |
|||
|
|||
@Test |
|||
void testGetAndsetFoundShip() { |
|||
Logic logic = new Logic(); |
|||
logic.setFoundShip(true); |
|||
assertEquals(logic.getFoundShip(), true); |
|||
} |
|||
|
|||
@Test |
|||
void testClearAbove() { |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield; |
|||
Coordinate shot = new Coordinate(2, 2); |
|||
int size = 4; |
|||
matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
logic.setMatchfield(matchfield); |
|||
logic.setLastShot(shot); |
|||
matchfield.getField(shot).setState(Coordinate.EMPTY); |
|||
|
|||
logic.clearAbove(shot); |
|||
|
|||
assertEquals(logic.getClearedAbove(), true); |
|||
} |
|||
|
|||
@Test |
|||
void testClearBelow() { |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield; |
|||
Coordinate shot = new Coordinate(2, 2); |
|||
int size = 4; |
|||
matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
logic.setMatchfield(matchfield); |
|||
logic.setLastShot(shot); |
|||
matchfield.getField(shot).setState(Coordinate.EMPTY); |
|||
|
|||
logic.clearBelow(shot); |
|||
|
|||
assertEquals(logic.getClearedBelow(), true); |
|||
} |
|||
|
|||
@Test |
|||
void testClearRight() { |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield; |
|||
Coordinate shot = new Coordinate(2, 2); |
|||
int size = 4; |
|||
matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
logic.setMatchfield(matchfield); |
|||
logic.setLastShot(shot); |
|||
matchfield.getField(shot).setState(Coordinate.EMPTY); |
|||
|
|||
logic.clearRight(shot); |
|||
|
|||
assertEquals(logic.getClearedRight(), true); |
|||
} |
|||
|
|||
@Test |
|||
void testClearLeft() { |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield; |
|||
Coordinate shot = new Coordinate(2, 2); |
|||
int size = 4; |
|||
matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
logic.setMatchfield(matchfield); |
|||
logic.setLastShot(shot); |
|||
matchfield.getField(shot).setState(Coordinate.EMPTY); |
|||
|
|||
logic.clearLeft(shot); |
|||
|
|||
assertEquals(logic.getClearedLeft(), true); |
|||
} |
|||
|
|||
@Test |
|||
void testConstructor() { |
|||
Logic logic = new Logic(); |
|||
|
|||
assertEquals(logic.getFoundShip(), false); |
|||
assertEquals(logic.getClearedAbove(), false); |
|||
assertEquals(logic.getClearedBelow(), false); |
|||
assertEquals(logic.getClearedLeft(), false); |
|||
assertEquals(logic.getClearedRight(), false); |
|||
} |
|||
|
|||
@Test |
|||
void testSetterClearedAbove() { |
|||
Logic logic = new Logic(); |
|||
logic.setClearedAbove(true); |
|||
|
|||
assertEquals(logic.getClearedAbove(), true); |
|||
} |
|||
|
|||
@Test |
|||
void testSetterClearedBelow() { |
|||
Logic logic = new Logic(); |
|||
logic.setClearedBelow(true); |
|||
|
|||
assertEquals(logic.getClearedBelow(), true); |
|||
} |
|||
|
|||
@Test |
|||
void testSetterClearedRight() { |
|||
Logic logic = new Logic(); |
|||
logic.setClearedRight(true); |
|||
|
|||
assertEquals(logic.getClearedRight(), true); |
|||
} |
|||
|
|||
@Test |
|||
void testSetterClearedLeft() { |
|||
Logic logic = new Logic(); |
|||
logic.setClearedLeft(true); |
|||
|
|||
assertEquals(logic.getClearedLeft(), true); |
|||
} |
|||
|
|||
@Test |
|||
void testSinkShip() { |
|||
Logic logic = new Logic(); |
|||
|
|||
logic.setFoundShip(true); |
|||
logic.setClearedAbove(true); |
|||
logic.setClearedBelow(true); |
|||
logic.setClearedRight(true); |
|||
logic.setClearedLeft(true); |
|||
|
|||
logic.sinkShip(); |
|||
|
|||
assertEquals(logic.getFoundShip(), false); |
|||
assertEquals(logic.getClearedAbove(), false); |
|||
assertEquals(logic.getClearedBelow(), false); |
|||
assertEquals(logic.getClearedLeft(), false); |
|||
assertEquals(logic.getClearedRight(), false); |
|||
|
|||
} |
|||
|
|||
@Test |
|||
void testChooseFieldAboveAfterHit() { |
|||
Logic logic = new Logic(); |
|||
int size = 4; |
|||
Coordinate center = new Coordinate(2, 2); |
|||
Coordinate expectedResult = new Coordinate(2, 3); |
|||
Matchfield matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
matchfield.setState(center, Coordinate.HIT); |
|||
matchfield.setState(expectedResult, Coordinate.HIT); |
|||
logic.setMatchfield(matchfield); |
|||
logic.setLastShot(center); |
|||
logic.setTarget(center); |
|||
logic.setFoundShip(true); |
|||
|
|||
Coordinate result = logic.chooseField(); |
|||
assertEquals(result, expectedResult); |
|||
} |
|||
|
|||
@Test |
|||
void testChooseFieldBelowAfterHit() { |
|||
Logic logic = new Logic(); |
|||
int size = 4; |
|||
Coordinate center = new Coordinate(2, 2); |
|||
Coordinate expectedResult = new Coordinate(2, 1); |
|||
Matchfield matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
matchfield.setState(center, Coordinate.HIT); |
|||
matchfield.setState(expectedResult, Coordinate.HIT); |
|||
logic.setMatchfield(matchfield); |
|||
logic.setLastShot(center); |
|||
logic.setTarget(center); |
|||
logic.setFoundShip(true); |
|||
logic.chooseField();// first Shot |
|||
Coordinate result = logic.chooseField(); // second Shot |
|||
|
|||
assertEquals(result, expectedResult); |
|||
} |
|||
|
|||
@Test |
|||
void testChooseFieldRightAfterHit() { |
|||
Logic logic = new Logic(); |
|||
int size = 4; |
|||
Coordinate center = new Coordinate(2, 2); |
|||
Coordinate expectedResult = new Coordinate(3, 2); |
|||
Matchfield matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
matchfield.setState(center, Coordinate.HIT); |
|||
matchfield.setState(expectedResult, Coordinate.HIT); |
|||
logic.setMatchfield(matchfield); |
|||
logic.setLastShot(center); |
|||
logic.setTarget(center); |
|||
logic.setFoundShip(true); |
|||
|
|||
logic.chooseField(); // first Shot |
|||
logic.chooseField(); // second Shot |
|||
Coordinate result = logic.chooseField(); |
|||
|
|||
assertEquals(result, expectedResult); |
|||
} |
|||
|
|||
@Test |
|||
void testChooseFieldLeftAfterHit() { |
|||
Logic logic = new Logic(); |
|||
int size = 4; |
|||
Coordinate center = new Coordinate(2, 2); |
|||
Coordinate expectedResult = new Coordinate(1, 2); |
|||
Matchfield matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
matchfield.setState(center, Coordinate.HIT); |
|||
matchfield.setState(expectedResult, Coordinate.HIT); |
|||
logic.setMatchfield(matchfield); |
|||
logic.setLastShot(center); |
|||
logic.setTarget(center); |
|||
logic.setFoundShip(true); |
|||
|
|||
logic.chooseField(); // first Shot |
|||
logic.chooseField(); // second Shot |
|||
logic.chooseField(); // third Shot Coordinate |
|||
Coordinate result = logic.chooseField(); |
|||
assertEquals(result, expectedResult); |
|||
} |
|||
|
|||
@Test |
|||
void testShipIsOnYAxis() { |
|||
int size = 10; |
|||
Logic logic = new Logic(); |
|||
Matchfield matchfield = new Matchfield(size); |
|||
Coordinate s1 = new Coordinate(5, 4); |
|||
Coordinate s2 = new Coordinate(5, 5); |
|||
Coordinate s3 = new Coordinate(5, 6); |
|||
|
|||
matchfield.createMatchfield(); |
|||
matchfield.setState(s1, Coordinate.SHIP); |
|||
matchfield.setState(s2, Coordinate.HIT); |
|||
matchfield.setState(s3, Coordinate.SHIP); |
|||
|
|||
logic.setMatchfield(matchfield); |
|||
logic.setLastShot(s2); |
|||
logic.setTarget(s2); |
|||
logic.setFoundShip(true); |
|||
|
|||
logic.chooseField(); // First shot (s3) |
|||
logic.getMatchfield().setState(s3, Coordinate.HIT); // |
|||
logic.chooseField(); // Second Shot |
|||
logic.getMatchfield().setState(new Coordinate(5, 7), Coordinate.SHOT); |
|||
|
|||
logic.chooseField(); // Third Shot (s1) |
|||
logic.getMatchfield().setState(s1, Coordinate.HIT); // |
|||
logic.chooseField(); // fourth Shot |
|||
|
|||
assertEquals(logic.getFoundShip(), false); |
|||
assertEquals(logic.getClearedAbove(), false); |
|||
assertEquals(logic.getClearedBelow(), false); |
|||
assertEquals(logic.getClearedLeft(), false); |
|||
assertEquals(logic.getClearedRight(), false); |
|||
|
|||
} |
|||
} |
@ -0,0 +1,36 @@ |
|||
package de.tims.fleetstorm.gui; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals; |
|||
|
|||
import org.junit.jupiter.api.BeforeEach; |
|||
import org.junit.jupiter.api.Test; |
|||
|
|||
class LogicTest { |
|||
|
|||
GameLogic guiLogic = new GameLogic(0, 0, 0, 0); |
|||
|
|||
@BeforeEach |
|||
void setup() { |
|||
guiLogic.start(true); |
|||
} |
|||
|
|||
@Test |
|||
void testIfGameStateIsRunningAfterStart() { |
|||
int expectedState = GameLogic.RUNNING; |
|||
|
|||
int calculatedState = guiLogic.getGameState(); |
|||
|
|||
assertEquals(expectedState, calculatedState); |
|||
} |
|||
|
|||
@Test |
|||
void testIfGameStateIsGameOverAfterGameOverFunction() { |
|||
int expectedState = GameLogic.GAME_OVER; |
|||
|
|||
guiLogic.gameOver(true); |
|||
int calculatedState = guiLogic.getGameState(); |
|||
|
|||
assertEquals(expectedState, calculatedState); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,82 @@ |
|||
package de.tims.fleetstorm.matchfield; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.*; |
|||
import static org.assertj.core.api.Assertions.assertThat; |
|||
|
|||
import java.util.stream.Stream; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.Arguments; |
|||
import org.junit.jupiter.params.provider.MethodSource; |
|||
|
|||
class CoordinateTest { |
|||
|
|||
int x = 1; |
|||
int y = 3; |
|||
|
|||
Coordinate coordinate = new Coordinate(x, y); |
|||
|
|||
@Test |
|||
void testGetCorrectValuesForXY() { |
|||
assertEquals(coordinate.getX(), x); |
|||
assertEquals(coordinate.getY(), y); |
|||
} |
|||
|
|||
@Test |
|||
void testCoordinatehasDefaultStates() { |
|||
assertEquals(coordinate.getState(), Coordinate.EMPTY); |
|||
assertEquals(coordinate.getState(), 0); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "All Getters/Setters are working") |
|||
@MethodSource("AllGettersAreWorking") |
|||
void testGetAndSetForAllStates(String testName, int state, int stateCode, int expectedResult) { |
|||
coordinate.setState(state); |
|||
int result = coordinate.getState(); |
|||
assertThat(result).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
static Stream<Arguments> AllGettersAreWorking() { |
|||
return Stream.of(Arguments.of("State = SHIP", 1, Coordinate.SHIP, Coordinate.SHIP), |
|||
Arguments.of("State = SHOT", 2, Coordinate.SHOT, Coordinate.SHOT), |
|||
Arguments.of("State = HIT", 3, Coordinate.HIT, Coordinate.HIT), |
|||
Arguments.of("State = EMPTY", 0, Coordinate.EMPTY, Coordinate.EMPTY)); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "test if shoot function sets correct field states") |
|||
@MethodSource("ShootFunctionFieldStates") |
|||
void testShootFunctionSetsCorrectFieldStates(String testName, Coordinate coordinateToTest, int expectedState) { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
matchfield.createMatchfield(); |
|||
|
|||
// set dummy ship |
|||
matchfield.setShip(new Coordinate(0, 0), 5, 0); |
|||
|
|||
Coordinate realCoordinate = matchfield.getField(coordinateToTest); |
|||
realCoordinate.shoot(); |
|||
int calculatedResult = realCoordinate.getState(); |
|||
assertThat(calculatedResult).describedAs(testName).isEqualTo(expectedState); |
|||
} |
|||
|
|||
static Stream<Arguments> ShootFunctionFieldStates() { |
|||
return Stream.of(Arguments.of("Field State is HIT", new Coordinate(0, 0), Coordinate.HIT), |
|||
Arguments.of("Field State is SHOT", new Coordinate(0, 1), Coordinate.SHOT)); |
|||
} |
|||
|
|||
@Test |
|||
void testIfShootCheckWhenFieldIsAlreadyShot() { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
matchfield.createMatchfield(); |
|||
|
|||
// set dummy ship |
|||
matchfield.setShip(new Coordinate(3, 3), 4, 1); |
|||
|
|||
assertTrue(matchfield.getField(0, 0).shoot()); |
|||
assertFalse(matchfield.getField(0, 0).shoot()); |
|||
|
|||
matchfield.getField(3, 4).shoot(); |
|||
assertFalse(matchfield.getField(3, 4).shoot()); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,144 @@ |
|||
package de.tims.fleetstorm.matchfield; |
|||
|
|||
import static org.assertj.core.api.Assertions.assertThat; |
|||
import static org.junit.jupiter.api.Assertions.assertEquals; |
|||
import static org.junit.jupiter.api.Assertions.assertNotNull; |
|||
|
|||
import java.util.stream.Stream; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.Arguments; |
|||
import org.junit.jupiter.params.provider.MethodSource; |
|||
|
|||
class MatchfieldCreationTest { |
|||
|
|||
@Test |
|||
void testMatchfieldCreateNotEmpty() { |
|||
Matchfield matchfield = new Matchfield(0); |
|||
Coordinate[][] calcResult = matchfield.createMatchfield(); |
|||
assertNotNull(calcResult); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "matchfield creation has correct size") |
|||
@MethodSource("testMatchfieldSize") |
|||
void testMatchfieldCreationHasCorrectSize(String testName, int size, int expectedResult) { |
|||
Matchfield matchfield = new Matchfield(size); |
|||
matchfield.createMatchfield(); |
|||
|
|||
int calcResult = matchfield.getSize(); |
|||
assertThat(calcResult).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
static Stream<Arguments> testMatchfieldSize() { |
|||
return Stream.of(Arguments.of("field size 10x10", 10, 100), Arguments.of("field size 15x15", 15, 225)); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "matchfield get field is correct") |
|||
@MethodSource("testMatchfieldGetFieldState") |
|||
void testMatchfieldGetCorrectState(String testName, int x, int y, int expectedResult) { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
matchfield.createMatchfield(); |
|||
|
|||
int calcResult = matchfield.getState(x, y); |
|||
assertThat(calcResult).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
static Stream<Arguments> testMatchfieldGetFieldState() { |
|||
return Stream.of(Arguments.of("field x:0 y:0 has empty state", 0, 0, Coordinate.EMPTY)); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "matchfield change field is correct") |
|||
@MethodSource("testMatchfieldSetStateIsCorrect") |
|||
void testMatchfieldGetCorrectState(String testName, int x, int y, int state, int expectedResult) { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
matchfield.createMatchfield(); |
|||
|
|||
matchfield.setState(x, y, state); |
|||
|
|||
int calcResult = matchfield.getState(x, y); |
|||
assertThat(calcResult).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
static Stream<Arguments> testMatchfieldSetStateIsCorrect() { |
|||
return Stream.of( |
|||
Arguments.of("field x:0 y:0 has state SHIP after setState()", 0, 0, Coordinate.SHIP, Coordinate.SHIP)); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "Get the Coordinate right") |
|||
@MethodSource("getCoordinateRight") |
|||
void testGetRight(String testName, Matchfield matchfield, Coordinate center, Coordinate expectedResult) { |
|||
|
|||
Coordinate result = matchfield.getRight(center); |
|||
assertThat(result).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
static Stream<Arguments> getCoordinateRight() { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
return Stream.of( |
|||
Arguments.of("right from (5/5) - should be (6,5)", matchfield, new Coordinate(5, 5), |
|||
matchfield.getField(6, 5)), |
|||
Arguments.of("right from (9/5) - should be null", matchfield, new Coordinate(9, 5), null)); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "Get the Coordinate left") |
|||
@MethodSource("getCoordinateLeft") |
|||
void testGetLeft(String testName, Matchfield matchfield, Coordinate center, Coordinate expectedResult) { |
|||
|
|||
Coordinate result = matchfield.getLeft(center); |
|||
assertThat(result).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
static Stream<Arguments> getCoordinateLeft() { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
return Stream.of( |
|||
Arguments.of("left from (5/5) - should be (4,5)", matchfield, new Coordinate(5, 5), |
|||
matchfield.getField(4, 5)), |
|||
Arguments.of("left from (0/5) - should be null", matchfield, new Coordinate(0, 5), null)); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "Get the Coordinate above") |
|||
@MethodSource("getCoordinateAbove") |
|||
void testGetAbove(String testName, Matchfield matchfield, Coordinate center, Coordinate expectedResult) { |
|||
|
|||
Coordinate result = matchfield.getAbove(center); |
|||
assertThat(result).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
static Stream<Arguments> getCoordinateAbove() { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
return Stream.of( |
|||
Arguments.of("above from (5/5) - should be (5,6)", matchfield, new Coordinate(5, 5), |
|||
matchfield.getField(5, 6)), |
|||
Arguments.of("above from (5/9) - should be null", matchfield, new Coordinate(5, 5), null)); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "Get the Coordinate below") |
|||
@MethodSource("getCoordinateBelow") |
|||
void testGetBelow(String testName, Matchfield matchfield, Coordinate center, Coordinate expectedResult) { |
|||
|
|||
Coordinate result = matchfield.getBelow(center); |
|||
assertThat(result).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
static Stream<Arguments> getCoordinateBelow() { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
return Stream.of( |
|||
Arguments.of("below from (5/5) - should be (5,4)", matchfield, new Coordinate(5, 5), |
|||
matchfield.getField(5, 4)), |
|||
Arguments.of("below from (5/0) - should be null", matchfield, new Coordinate(5, 0), null)); |
|||
} |
|||
|
|||
@Test |
|||
void testsetStateOverloaded() { |
|||
|
|||
Matchfield matchfield = new Matchfield(10); |
|||
matchfield.createMatchfield(); |
|||
int x = 3; |
|||
int y = 3; |
|||
matchfield.setState(new Coordinate(x, y), Coordinate.SHIP); |
|||
int result = matchfield.getState(x, y); |
|||
assertEquals(result, Coordinate.SHIP); |
|||
|
|||
} |
|||
} |
@ -0,0 +1,133 @@ |
|||
|
|||
package de.tims.fleetstorm.matchfield; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.*; |
|||
import static org.assertj.core.api.Assertions.assertThat; |
|||
|
|||
import java.util.stream.Stream; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.Arguments; |
|||
import org.junit.jupiter.params.provider.MethodSource; |
|||
|
|||
class MatchfieldShipTest { |
|||
|
|||
@ParameterizedTest(name = "ship was set on the correct positions") |
|||
@MethodSource("testShipPositioning") |
|||
void testMatchfieldShipSetHasCorrectPositions(String testName, int matchfieldSize, Coordinate coordinate, |
|||
int direction, int length, Coordinate[] coordinatesWithShip) { |
|||
Matchfield matchfield = new Matchfield(matchfieldSize); |
|||
matchfield.createMatchfield(); |
|||
|
|||
matchfield.setShip(coordinate, length, direction); |
|||
|
|||
int shipSetCounter = 0; |
|||
for (Coordinate toCheckCoordinate : coordinatesWithShip) { |
|||
if (matchfield.getField(toCheckCoordinate).getState() == Coordinate.SHIP) |
|||
shipSetCounter++; |
|||
} |
|||
|
|||
assertThat(shipSetCounter).describedAs(testName).isEqualTo(length); |
|||
} |
|||
|
|||
static Stream<Arguments> testShipPositioning() { |
|||
Coordinate[] coordinatesWithShip00_2_0 = new Coordinate[] { new Coordinate(0, 0), new Coordinate(1, 0) }; |
|||
Coordinate[] coordinatesWithShip01_3_0 = new Coordinate[] { new Coordinate(0, 1), new Coordinate(1, 1), |
|||
new Coordinate(2, 1) }; |
|||
Coordinate[] coordinatesWithShip02_4_1 = new Coordinate[] { new Coordinate(0, 2), new Coordinate(0, 3), |
|||
new Coordinate(0, 4), new Coordinate(0, 5) }; |
|||
|
|||
return Stream.of( |
|||
Arguments.of("set ship from 0:0, length 2, direction 0", 10, new Coordinate(0, 0), 0, 2, |
|||
coordinatesWithShip00_2_0), |
|||
Arguments.of("set ship from 0:1, length 3, direction 0", 10, new Coordinate(0, 1), 0, 3, |
|||
coordinatesWithShip01_3_0), |
|||
Arguments.of("set ship from 0:2, length 4, direction 1", 10, new Coordinate(0, 2), 1, 4, |
|||
coordinatesWithShip02_4_1)); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "ship positioning on invalid or valid coordinates") |
|||
@MethodSource("testShipPositioningFailed") |
|||
void testMatchfieldShipSetWithInvalidOrValidCoordinates(String testName, int matchfieldSize, Coordinate coordinate, |
|||
int direction, int length, boolean expectedResult) { |
|||
Matchfield matchfield = new Matchfield(matchfieldSize); |
|||
matchfield.createMatchfield(); |
|||
|
|||
boolean calculatedResult = matchfield.setShip(coordinate, length, direction); |
|||
|
|||
if (expectedResult) |
|||
assertThat(calculatedResult).describedAs(testName).isEqualTo(true); |
|||
|
|||
if (!expectedResult) |
|||
assertThat(calculatedResult).describedAs(testName).isEqualTo(false); |
|||
} |
|||
|
|||
static Stream<Arguments> testShipPositioningFailed() { |
|||
return Stream.of( |
|||
Arguments.of("invalid ship position from 9:0, length 2, direction 0", 10, new Coordinate(9, 0), 0, 2, |
|||
false), |
|||
Arguments.of("valid ship position from 8:0, length 5, direction 1", 10, new Coordinate(9, 0), 1, 5, |
|||
true)); |
|||
} |
|||
|
|||
@Test |
|||
void testShipPositionAlreadySetWithShip() { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
matchfield.createMatchfield(); |
|||
|
|||
matchfield.setShip(new Coordinate(0, 0), 5, 1); |
|||
assertThat(matchfield.setShip(new Coordinate(0, 1), 5, 1)).describedAs("set ship on coordinate with ship") |
|||
.isEqualTo(false); |
|||
|
|||
assertThat(matchfield.setShip(new Coordinate(1, 1), 4, 0)).describedAs("set ship on coordinate without ship") |
|||
.isEqualTo(true); |
|||
assertThat(matchfield.setShip(new Coordinate(4, 1), 2, 1)) |
|||
.describedAs("set second ship on coordinate without ship").isEqualTo(false); |
|||
} |
|||
|
|||
@Test |
|||
void testIfAllShipsHitReturnsFalseWhenNoShipIsHit() { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
matchfield.createMatchfield(); |
|||
|
|||
matchfield.setShip(new Coordinate(0, 0), 5, 1); |
|||
boolean calulatedResult = matchfield.areAllShipsHit(); |
|||
assertFalse(calulatedResult); |
|||
} |
|||
|
|||
@Test |
|||
void testIfAllShipsHitReturnsTrueWhenAllShipsAreHit() { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
matchfield.createMatchfield(); |
|||
|
|||
matchfield.setShip(new Coordinate(0, 0), 5, 1); |
|||
matchfield.getField(0, 0).setState(Coordinate.HIT); |
|||
matchfield.getField(0, 1).setState(Coordinate.HIT); |
|||
matchfield.getField(0, 2).setState(Coordinate.HIT); |
|||
matchfield.getField(0, 3).setState(Coordinate.HIT); |
|||
matchfield.getField(0, 4).setState(Coordinate.HIT); |
|||
|
|||
boolean calulatedResult = matchfield.areAllShipsHit(); |
|||
assertTrue(calulatedResult); |
|||
} |
|||
|
|||
@Test |
|||
void testIfAllShipsHitReturnsFalseWhenTwoShipsAreNotFullyHit() { |
|||
Matchfield matchfield = new Matchfield(10); |
|||
matchfield.createMatchfield(); |
|||
|
|||
matchfield.setShip(new Coordinate(0, 0), 5, 1); |
|||
matchfield.getField(0, 0).setState(Coordinate.HIT); |
|||
matchfield.getField(0, 1).setState(Coordinate.HIT); |
|||
matchfield.getField(0, 2).setState(Coordinate.HIT); |
|||
matchfield.getField(0, 3).setState(Coordinate.HIT); |
|||
matchfield.getField(0, 4).setState(Coordinate.HIT); |
|||
|
|||
matchfield.setShip(new Coordinate(3, 4), 2, 0); |
|||
matchfield.getField(4, 4).setState(Coordinate.HIT); |
|||
|
|||
boolean calulatedResult = matchfield.areAllShipsHit(); |
|||
assertFalse(calulatedResult); |
|||
} |
|||
} |
@ -0,0 +1,110 @@ |
|||
package de.tims.player_management; |
|||
|
|||
import static org.assertj.core.api.Assertions.*; |
|||
|
|||
import java.io.File; |
|||
import java.io.FileWriter; |
|||
import java.io.IOException; |
|||
import java.util.LinkedList; |
|||
import java.util.List; |
|||
import java.util.stream.Stream; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.Arguments; |
|||
import org.junit.jupiter.params.provider.MethodSource; |
|||
|
|||
class PlayerManagerTest { |
|||
|
|||
PlayerManager manager = new PlayerManager(); |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("testCasesForSelectPlayer") |
|||
void selectPlayerTest(String testName, List<Player> players, String playerName, Player expectedResult) { |
|||
manager.setPlayers(players); |
|||
Player calculatedResult = manager.selectPlayer(playerName); |
|||
assertThat(calculatedResult).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForSelectPlayer() { |
|||
return Stream.of(Arguments.of("NoPlayersYetReturnNewPlayer", new LinkedList<Player>(List.of()), |
|||
"Tobias", new Player("Tobias", 0)), |
|||
Arguments.of("NoPlayerWithNameInListReturnNewPlayer", new LinkedList<Player>(List.of(new Player("Steffen", 40), new Player("Lorenz", 60))), |
|||
"Tobias", new Player("Tobias", 0)), |
|||
Arguments.of("PlayerWithNameInListReturnPlayerInList", new LinkedList<Player>(List.of(new Player("Steffen", 40), new Player("Tobias", 50))), |
|||
"Tobias", new Player("Tobias", 50))); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("testCasesForLoadPlayers") |
|||
void loadPlayersTest(String testName, String fileContent, String fileName, List<Player> expectedResult) { |
|||
File playerData = new File(fileName); |
|||
|
|||
try { |
|||
FileWriter fw = new FileWriter(playerData, false); |
|||
fw.write(fileContent); |
|||
fw.close(); |
|||
} catch (IOException e) { |
|||
fail("Cannot open file"); |
|||
} |
|||
|
|||
manager.loadPlayers(fileName); |
|||
List<Player> calculatedResult = manager.getPlayers(); |
|||
assertThat(calculatedResult).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForLoadPlayers() { |
|||
return Stream.of(Arguments.of("EmptyFileReturnsEmtpyList", "", "src/test/java/resources/player_testdata.csv", List.of()), |
|||
Arguments.of("OnePlayerInFileReturnsListWithOneElement", "Tobias;50", "src/test/java/resources/player_testdata.csv", |
|||
List.of(new Player("Tobias", 50))), |
|||
Arguments.of("MorePlayersInFileReturnLongerList", "Tobias;50\nLorenz;40\nSteffen;60", "src/test/java/resources/player_testdata.csv", |
|||
List.of(new Player("Tobias", 50), new Player("Lorenz", 40), new Player("Steffen", 60)))); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("testCasesForSavePlayers") |
|||
void savePlayersTest(String testName, String fileName, List<Player> expectedResult) { |
|||
manager.setPlayers(expectedResult); |
|||
manager.savePlayers(fileName); |
|||
manager.loadPlayers(fileName); |
|||
List<Player> calculatedResult = manager.getPlayers(); |
|||
assertThat(calculatedResult).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForSavePlayers() { |
|||
return Stream.of(Arguments.of("EmptyListIsWrittenAsEmptyFile", "src/test/java/resources/player_testdata2.csv", List.of()), |
|||
Arguments.of("WriteElementsOfListToFile", "src/test/java/resources/player_testdata2.csv", |
|||
List.of(new Player("Tobias", 50), new Player("Steffen", 60)))); |
|||
} |
|||
|
|||
@Test |
|||
void selectPlayerAddsNewPlayersToList() { |
|||
LinkedList<Player> players = new LinkedList<Player>(); |
|||
players.add(new Player("Steffen", 40)); |
|||
players.add(new Player("Max", 60)); |
|||
|
|||
manager.setPlayers(players); |
|||
manager.selectPlayer("Tobias"); |
|||
|
|||
List<Player> expectedResult = List.of(new Player("Steffen", 40), new Player("Max", 60), new Player("Tobias", 0)); |
|||
List<Player> calculatedResult = manager.getPlayers(); |
|||
|
|||
assertThat(calculatedResult).describedAs("SelectNewPlayerAddsNewPlayerToPlayersList").isEqualTo(expectedResult); |
|||
} |
|||
|
|||
@Test |
|||
void selectExistingPlayerDoesntChangeTheList() { |
|||
LinkedList<Player> players = new LinkedList<Player>(); |
|||
players.add(new Player("Steffen", 40)); |
|||
players.add(new Player("Max", 60)); |
|||
|
|||
manager.setPlayers(players); |
|||
manager.selectPlayer("Max"); |
|||
|
|||
List<Player> expectedResult = List.of(new Player("Steffen", 40), new Player("Max", 60)); |
|||
List<Player> calculatedResult = manager.getPlayers(); |
|||
|
|||
assertThat(calculatedResult).describedAs("SelectNewPlayerAddsNewPlayerToPlayersList").isEqualTo(expectedResult); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,32 @@ |
|||
package de.tims.player_management; |
|||
|
|||
import static org.assertj.core.api.Assertions.*; |
|||
|
|||
import java.util.stream.Stream; |
|||
|
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.Arguments; |
|||
import org.junit.jupiter.params.provider.MethodSource; |
|||
|
|||
class PlayerTest { |
|||
|
|||
Player player; |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("testCasesForAddPoints") |
|||
void addPointsTest(String testName, int pointsBefore, int pointsToAdd, int expectedResult) { |
|||
player = new Player("TestPlayer", pointsBefore); |
|||
player.addPoints(pointsToAdd); |
|||
int calculatedResult = player.getPoints(); |
|||
assertThat(calculatedResult).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForAddPoints() { |
|||
return Stream.of(Arguments.of("NoPointsBeforeGet0Points", 0, 0, 0), |
|||
Arguments.of("NoPointsBeforeGet10Points", 0, 10, 10), |
|||
Arguments.of("10PointsBeforeAdd10Points", 10, 10, 20), |
|||
Arguments.of("10PointsBeforeLose10Points", 10, -10, 0), |
|||
Arguments.of("LoseMorePointsThanYouHave", 10, -20, 0)); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,337 @@ |
|||
package de.tims.tictactoe; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.assertArrayEquals; |
|||
import static org.junit.jupiter.api.Assertions.assertEquals; |
|||
|
|||
import java.awt.Component; |
|||
import java.util.stream.Stream; |
|||
|
|||
import javax.swing.JButton; |
|||
import javax.swing.JPanel; |
|||
|
|||
import org.junit.jupiter.api.BeforeAll; |
|||
import org.junit.jupiter.api.Test; |
|||
import org.junit.jupiter.api.TestInstance; |
|||
import org.junit.jupiter.api.TestInstance.Lifecycle; |
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.Arguments; |
|||
import org.junit.jupiter.params.provider.MethodSource; |
|||
|
|||
@TestInstance(Lifecycle.PER_CLASS) |
|||
class GameLogicTest { |
|||
|
|||
private final int SIZE = 3; |
|||
private GameLogic game; |
|||
|
|||
@BeforeAll |
|||
void setUpBeforeClass() throws Exception { |
|||
this.game = new GameLogic(SIZE); |
|||
} |
|||
|
|||
@Test |
|||
void createGameLogicTest() { |
|||
GameLogic expectedResult = this.game; |
|||
GameLogic realResult = new GameLogic(SIZE); |
|||
|
|||
assertEquals(expectedResult.getClass(), realResult.getClass()); |
|||
} |
|||
|
|||
@Test |
|||
void getBoardTest() { |
|||
// @formatter:off |
|||
char[][] expectedResult = new char[][]{{'-', '-', '-'}, |
|||
{'-', '-', '-'}, |
|||
{'-', '-', '-'}}; |
|||
// @formatter:on |
|||
char[][] realResult = this.game.getBoard(); |
|||
|
|||
assertArrayEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void createGameLogicWithGivenBoardTest() { |
|||
// @formatter:off |
|||
char[][] expectedResult = new char[][]{{'x', '-', '-'}, |
|||
{'-', 'o', '-'}, |
|||
{'x', '-', '-'}}; |
|||
// @formatter:on |
|||
char[][] givenBoard = expectedResult; |
|||
char[][] realResult = new GameLogic(givenBoard).getBoard(); |
|||
|
|||
assertArrayEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void generateGUITest() { |
|||
JPanel expectedResult = new JPanel(); |
|||
JPanel realResult = this.game.generateGUI(); |
|||
|
|||
assertEquals(expectedResult.getClass(), realResult.getClass()); |
|||
} |
|||
|
|||
@Test |
|||
void numberOfGUIFieldsTest() { |
|||
int expectedResult = (int) Math.pow(SIZE, 2); |
|||
int realResult = 0; |
|||
|
|||
JPanel gui = this.game.generateGUI(); |
|||
Component[] components = gui.getComponents(); |
|||
|
|||
for (Component component : components) { |
|||
if (component instanceof JButton) |
|||
realResult++; |
|||
} |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void getCurrentPlayerTest() { |
|||
GameLogic game = new GameLogic(SIZE); |
|||
char expectedResult = 'x'; |
|||
char realResult = game.getCurrentPlayer(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void switchPlayerTest() { |
|||
GameLogic game = new GameLogic(SIZE); |
|||
game.switchPlayer(); |
|||
|
|||
char expectedResult = 'o'; |
|||
char realResult = game.getCurrentPlayer(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void resetBoardTest() { |
|||
GameLogic game = new GameLogic(SIZE); |
|||
game.setField(1, 2, 'x'); |
|||
// @formatter:off |
|||
char[][] expectedResult = new char[][]{{'-', '-', '-'}, |
|||
{'-', '-', '-'}, |
|||
{'-', '-', '-'}}; |
|||
// @formatter:on |
|||
game.resetBoard(); |
|||
char[][] realResult = game.getBoard(); |
|||
|
|||
assertArrayEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "[{index}] {0} -> {2} fields") |
|||
@MethodSource("testCasesForCountPlayfields") |
|||
void fieldCountTest(String testName, int size, int expectedResult) { |
|||
GameLogic game = new GameLogic(size); |
|||
int realResult = game.countFields(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "[{index}] {0}") |
|||
@MethodSource("testCasesForSetField") |
|||
void setFieldTest(String testName, int column, int row, char player, char[][] expectedResult) { |
|||
this.game.setField(column, row, player); |
|||
char[][] realResult = this.game.getBoard(); |
|||
|
|||
assertArrayEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "[{index}] {0}") |
|||
@MethodSource("testCasesForCheckEmptyField") |
|||
void fieldIsEmptyTest(String testName, int columnToCheck, int rowToCheck, boolean expectedResult, char[][] board) { |
|||
GameLogic game = new GameLogic(board); |
|||
boolean realResult = game.fieldIsEmpty(columnToCheck, rowToCheck); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "[{index}] {0}: should be {2}") |
|||
@MethodSource("testCasesForCheckForWin") |
|||
void checkForWinTest(String testName, char player, boolean expectedResult, char[][] boardToCheck) { |
|||
boolean realResult = new GameLogic(boardToCheck).checkForWin(player); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "[{index}] {0}: should be {1}") |
|||
@MethodSource("testCasesForCheckEndOfGame") |
|||
void checkEndOfGameTest(String testName, boolean expectedResult, char[][] boardToCheck) { |
|||
boolean realResult = new GameLogic(boardToCheck).checkEndOfGame(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "[{index}] {0}: should be {1}") |
|||
@MethodSource("testCasesForCheckButtonState") |
|||
void buttonStateTest(String testName, boolean expectedResult, boolean doClick, int column, int row) throws InterruptedException { |
|||
GameLogic game = new GameLogic(SIZE); |
|||
game.generateGUI(); |
|||
JButton currentField = game.getGUIField(0, 0); |
|||
|
|||
if (doClick) |
|||
currentField.doClick(); |
|||
boolean realResult = !currentField.getText().isEmpty(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
// @formatter:off |
|||
private static Stream<Arguments> testCasesForCountPlayfields() { |
|||
return Stream.of(Arguments.of("1x1 board with too few fields", 1, 9), |
|||
Arguments.of("2x2 board with too few fields", 2, 9), |
|||
Arguments.of("3x3 board with 9 playfields", 3, 9), |
|||
Arguments.of("4x4 board with 16 playfields", 4, 16), |
|||
Arguments.of("5x5 board with 25 playfields", 5, 25)); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForSetField() { |
|||
return Stream.of( |
|||
Arguments.of("set field [0][0] for player 1", 0, 0, 'x', new char[][] |
|||
{{'x', '-', '-'}, |
|||
{'-', '-', '-'}, |
|||
{'-', '-', '-'}}), |
|||
Arguments.of("set field [1][0] for player 2", 1, 0, 'o', new char[][] |
|||
{{'x', '-', '-'}, |
|||
{'o', '-', '-'}, |
|||
{'-', '-', '-'}}), |
|||
Arguments.of("try to set occupied field [1][0] for player 1", 1, 0, 'x', new char[][] |
|||
{{'x', '-', '-'}, |
|||
{'o', '-', '-'}, |
|||
{'-', '-', '-'}}) |
|||
); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForCheckEmptyField() { |
|||
return Stream.of( |
|||
Arguments.of("check an empty field", 0, 0, true, new char[][] |
|||
{{'-', '-', '-'}, |
|||
{'-', '-', '-'}, |
|||
{'-', '-', '-'}}), |
|||
Arguments.of("check a field set by player 1", 0, 0, false, new char[][] |
|||
{{'x', '-', '-'}, |
|||
{'-', '-', '-'}, |
|||
{'-', '-', '-'}}), |
|||
Arguments.of("check a field set by player 2", 0, 0, false, new char[][] |
|||
{{'o', '-', '-'}, |
|||
{'-', '-', '-'}, |
|||
{'-', '-', '-'}}) |
|||
); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForCheckForWin() { |
|||
return Stream.of( |
|||
Arguments.of("check win in column 0 for player 1", 'x', true, new char[][] |
|||
{{'x', '-', '-'}, |
|||
{'x', '-', '-'}, |
|||
{'x', '-', '-'}}), |
|||
Arguments.of("check win in column 1 for player 1", 'x', true, new char[][] |
|||
{{'-', 'x', '-'}, |
|||
{'-', 'x', '-'}, |
|||
{'-', 'x', '-'}}), |
|||
Arguments.of("check win in column 2 for player 1", 'x', true, new char[][] |
|||
{{'-', '-', 'x'}, |
|||
{'-', '-', 'x'}, |
|||
{'-', '-', 'x'}}), |
|||
Arguments.of("check win in column 0 for player 2", 'o', true, new char[][] |
|||
{{'o', '-', '-'}, |
|||
{'o', '-', '-'}, |
|||
{'o', '-', '-'}}), |
|||
Arguments.of("check win in row 0 for player 1", 'x', true, new char[][] |
|||
{{'x', 'x', 'x'}, |
|||
{'-', '-', '-'}, |
|||
{'-', '-', '-'}}), |
|||
Arguments.of("check win in row 0 for player 2", 'o', true, new char[][] |
|||
{{'o', 'o', 'o'}, |
|||
{'-', '-', '-'}, |
|||
{'-', '-', '-'}}), |
|||
Arguments.of("check win in row 1 for player 2", 'o', true, new char[][] |
|||
{{'-', '-', '-'}, |
|||
{'o', 'o', 'o'}, |
|||
{'-', '-', '-'}}), |
|||
Arguments.of("check win in row 2 for player 2", 'o', true, new char[][] |
|||
{{'-', '-', '-'}, |
|||
{'-', '-', '-'}, |
|||
{'o', 'o', 'o'}}), |
|||
Arguments.of("check win in column 0 for player 1 with full board", 'x', true, new char[][] |
|||
{{'x', 'o', 'o'}, |
|||
{'x', 'o', 'x'}, |
|||
{'x', 'x', 'o'}}), |
|||
Arguments.of("check win in column 1 for player 2 with full board", 'o', true, new char[][] |
|||
{{'x', 'o', 'o'}, |
|||
{'x', 'o', 'x'}, |
|||
{'o', 'o', 'x'}}), |
|||
Arguments.of("check win in column 2 for player 2 with full board", 'o', true, new char[][] |
|||
{{'x', 'o', 'o'}, |
|||
{'x', 'x', 'o'}, |
|||
{'o', 'o', 'o'}}), |
|||
Arguments.of("check win in row 0 for player 1 with full board", 'x', true, new char[][] |
|||
{{'x', 'x', 'x'}, |
|||
{'x', 'o', 'o'}, |
|||
{'o', 'o', 'x'}}), |
|||
Arguments.of("check win in row 1 for player 1 with full board", 'x', true, new char[][] |
|||
{{'x', 'x', 'o'}, |
|||
{'x', 'x', 'x'}, |
|||
{'o', 'o', 'x'}}), |
|||
Arguments.of("check win in row 2 for player 2 with full board", 'o', true, new char[][] |
|||
{{'x', 'x', 'o'}, |
|||
{'o', 'x', 'x'}, |
|||
{'o', 'o', 'o'}}), |
|||
Arguments.of("check win in column 0 for player 2", 'o', false, new char[][] |
|||
{{'o', '-', '-'}, |
|||
{'o', '-', '-'}, |
|||
{'-', '-', '-'}}), |
|||
Arguments.of("check a draw for player 2", 'o', false, new char[][] |
|||
{{'o', 'o', 'x'}, |
|||
{'o', 'x', 'x'}, |
|||
{'x', 'x', 'o'}}), |
|||
Arguments.of("check a draw for player 1", 'x', false, new char[][] |
|||
{{'o', 'o', 'x'}, |
|||
{'o', 'o', 'x'}, |
|||
{'x', 'x', 'o'}}), |
|||
Arguments.of("check diagonal left win for player 1", 'x', true, new char[][] |
|||
{{'x', 'o', 'x'}, |
|||
{'x', 'x', 'o'}, |
|||
{'o', 'o', 'x'}}), |
|||
Arguments.of("check diagonal right win for player 2", 'o', true, new char[][] |
|||
{{'x', 'x', 'o'}, |
|||
{'x', 'o', 'o'}, |
|||
{'o', 'x', 'x'}}) |
|||
); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForCheckEndOfGame() { |
|||
return Stream.of( |
|||
Arguments.of("check empty board", false, new char[][] |
|||
{{'-', '-', '-'}, |
|||
{'-', '-', '-'}, |
|||
{'-', '-', '-'}}), |
|||
Arguments.of("end of game with win for player 1", true, new char[][] |
|||
{{'x', 'o', 'x'}, |
|||
{'x', 'x', 'o'}, |
|||
{'x', 'o', 'o'}}), |
|||
Arguments.of("end of game with win for player 2", true, new char[][] |
|||
{{'x', 'x', 'o'}, |
|||
{'o', 'o', 'o'}, |
|||
{'x', 'o', 'x'}}), |
|||
Arguments.of("check tied game", true, new char[][] |
|||
{{'x', 'x', 'o'}, |
|||
{'o', 'x', 'o'}, |
|||
{'x', 'o', 'x'}}), |
|||
Arguments.of("check not yet finished game", false, new char[][] |
|||
{{'x', 'x', '-'}, |
|||
{'o', 'o', '-'}, |
|||
{'x', 'o', 'x'}}) |
|||
); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForCheckButtonState() { |
|||
return Stream.of( |
|||
Arguments.of("trigger gui field [0][0]", true, true, 0, 0), |
|||
Arguments.of("dont't trigger gui field [1][1]", false, false, 1, 1) |
|||
); |
|||
} |
|||
// @formatter:on |
|||
|
|||
} |
@ -0,0 +1,62 @@ |
|||
package de.tims.tictactoe.ai; |
|||
|
|||
import static org.mockito.Mockito.*; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.junit.jupiter.api.extension.ExtendWith; |
|||
import org.mockito.ArgumentMatcher; |
|||
import org.mockito.Mock; |
|||
import org.mockito.junit.jupiter.MockitoExtension; |
|||
|
|||
import de.tims.tictactoe.GameLogic; |
|||
|
|||
@ExtendWith(MockitoExtension.class) |
|||
class AIEasyTest { |
|||
static int size = 3; |
|||
|
|||
@Mock |
|||
private GameLogic gl; |
|||
|
|||
@Test |
|||
void emptyBoardChooseRandomField() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIEasy(gl); |
|||
|
|||
//run method 100 times, because of random generator |
|||
for (int i = 0; i < 100; i++) { |
|||
ai.calculateNextMove(); |
|||
} |
|||
|
|||
verify(gl, times(100)).setField(intThat(new ChooseRandomFieldMatcher()), intThat(new ChooseRandomFieldMatcher()), eq(realChar)); |
|||
} |
|||
|
|||
@Test |
|||
void notEmptyBoardChooseRandomFreeField() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'x', '-', 'o'}, {'-', 'o', '-'}, {'-', 'x', 'x'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIEasy(gl); |
|||
|
|||
//run method 100 times, because of random generator |
|||
for (int i = 0; i < 100; i++) { |
|||
ai.calculateNextMove(); |
|||
} |
|||
|
|||
verify(gl, times(100)).setField(intThat(new ChooseRandomFieldMatcher()), intThat(new ChooseRandomFieldMatcher()), eq(realChar)); |
|||
//verify that the method is never called with a field which was already set |
|||
verify(gl, never()).setField(0, 0, realChar); |
|||
verify(gl, never()).setField(0, 2, realChar); |
|||
verify(gl, never()).setField(1, 1, realChar); |
|||
verify(gl, never()).setField(2, 1, realChar); |
|||
verify(gl, never()).setField(2, 2, realChar); |
|||
} |
|||
|
|||
private static class ChooseRandomFieldMatcher implements ArgumentMatcher<Integer> { |
|||
@Override |
|||
public boolean matches(Integer argument) { |
|||
return argument.intValue() >= 0 && argument.intValue() < size; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,262 @@ |
|||
package de.tims.tictactoe.ai; |
|||
|
|||
import static org.assertj.core.api.Assertions.*; |
|||
import static org.mockito.Mockito.*; |
|||
|
|||
import java.util.stream.Stream; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.junit.jupiter.api.extension.ExtendWith; |
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.Arguments; |
|||
import org.junit.jupiter.params.provider.MethodSource; |
|||
import org.mockito.Mock; |
|||
import org.mockito.junit.jupiter.MockitoExtension; |
|||
|
|||
import de.tims.tictactoe.GameLogic; |
|||
|
|||
@ExtendWith(MockitoExtension.class) |
|||
class AIHardTest { |
|||
static int size = 3; |
|||
|
|||
@Mock |
|||
private GameLogic gl; |
|||
|
|||
@Test |
|||
void emptyBoardChooseMiddleField() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(1, 1, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void middleFieldAlreadySetChooseEdgeField() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'-', '-', '-'}, {'-', 'x', '-'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(0, 0, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void opponentDidntChooseMiddleFieldSoAIDoes() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'-', '-', 'x'}, {'-', '-', '-'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(1, 1, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void setEdgeFieldInSecondMove() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'x', '-', '-'}, {'-', 'o', '-'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(0, 2, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void preventOpponentsWinInRow() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'o', '-', '-'}, {'x', 'x', '-'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(1, 2, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void preventOpponentsWinInCol() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'o', 'x', '-'}, {'-', 'x', '-'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(2, 1, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void preventOpponentsWinInDiag() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'x', '-', 'o'}, {'-', 'x', '-'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(2, 2, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void when2InRowSetThird() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'o', '-', 'o'}, {'-', 'x', '-'}, {'x', 'x', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(0, 1, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void when2InColSetThird() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'o', '-', 'x'}, {'-', 'x', '-'}, {'o', '-', 'x'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(1, 0, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void when2inDiagSetThird() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'o', '-', 'x'}, {'-', 'o', 'x'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(2, 2, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void opportunityToWinIsMoreImportantThanPreventingOpponentsWinInNextRound() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'x', '-', 'o'}, {'-', 'o', '-'}, {'x', 'x', 'o'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(1, 2, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void alwaysSetInTheNearestEdgeToOpponentsX() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'-', '-', '-'}, {'-', 'o', 'x'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(0, 2, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void chooseFieldWhichCreatesMostOpportunitiesToWin() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'-', 'x', 'o'}, {'-', 'o', '-'}, {'x', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(1, 2, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void setFirstFreeFieldIfNoBetterOpportunities() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'o', 'x', 'x'}, {'x', 'o', 'o'}, {'o', '-', 'x'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(2, 1, realChar); |
|||
} |
|||
|
|||
@Test |
|||
void ifRowAndColWithSameNumberContainEachContainTwoCharsDontIgnoreCol() { |
|||
char realChar = 'o'; |
|||
doReturn(new char[][] { {'x', 'o', 'x'}, {'-', 'o', '-'}, {'o', 'x', 'x'} }).when(gl).getBoard(); |
|||
|
|||
TicTacToeAI ai = new AIHard(gl); |
|||
ai.calculateNextMove(); |
|||
|
|||
verify(gl, times(1)).setField(1, 2, realChar); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("testCasesForCountCharsInRow") |
|||
void countCharsInRowTest(String testName, char[][] board, int rowNum, char charToCount, int expectedResult) { |
|||
doReturn(board).when(gl).getBoard(); |
|||
|
|||
AIHard ai = new AIHard(gl); |
|||
int realResult = ai.countCharsInRow(rowNum, charToCount); |
|||
|
|||
assertThat(realResult).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForCountCharsInRow() { |
|||
return Stream.of(Arguments.of("EmptyFieldReturns0", |
|||
new char[][] { {'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'} }, |
|||
0, 'o', 0), |
|||
Arguments.of("TwoCharsInRowReturnsTwo", |
|||
new char[][] { {'-', '-', '-'}, {'o', 'o', '-'}, {'-', '-', '-'} }, |
|||
1, 'o', 2)); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("testCasesForCountCharsInCol") |
|||
void countCharsInColTest(String testName, char[][] board, int colNum, char charToCount, int expectedResult) { |
|||
doReturn(board).when(gl).getBoard(); |
|||
|
|||
AIHard ai = new AIHard(gl); |
|||
int realResult = ai.countCharsInCol(colNum, charToCount); |
|||
|
|||
assertThat(realResult).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForCountCharsInCol() { |
|||
return Stream.of(Arguments.of("EmptyFieldReturns0", |
|||
new char[][] { {'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'} }, |
|||
0, 'o', 0), |
|||
Arguments.of("TwoCharsInRowReturnsTwo", |
|||
new char[][] { {'-', '-', '-'}, {'o', 'o', '-'}, {'-', '-', '-'} }, |
|||
1, 'o', 1)); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("testCasesForCountCharsInDiag") |
|||
void countCharsInDiagTest(String testName, char[][] board, int diagNum, char charToCount, int expectedResult) { |
|||
doReturn(board).when(gl).getBoard(); |
|||
|
|||
AIHard ai = new AIHard(gl); |
|||
int realResult = ai.countCharsInDiag(diagNum, charToCount); |
|||
|
|||
assertThat(realResult).describedAs(testName).isEqualTo(expectedResult); |
|||
} |
|||
|
|||
private static Stream<Arguments> testCasesForCountCharsInDiag() { |
|||
return Stream.of(Arguments.of("EmptyFieldReturns0", |
|||
new char[][] { {'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'} }, |
|||
0, 'o', 0), |
|||
Arguments.of("TwoCharsInRowReturnsTwo", |
|||
new char[][] { {'-', '-', 'o'}, {'o', 'o', '-'}, {'-', '-', '-'} }, |
|||
1, 'o', 2)); |
|||
} |
|||
|
|||
@Test |
|||
void invalidIndexCausesIndexOutOfBoundsException() { |
|||
int index = 2; |
|||
char charToCount = 'o'; |
|||
String msg = "Only 0 and 1 are allowed values for index!"; |
|||
doReturn(new char[][] { {'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'} }).when(gl).getBoard(); |
|||
|
|||
AIHard ai = new AIHard(gl); |
|||
|
|||
assertThatThrownBy(() -> {ai.countCharsInDiag(index, charToCount);}).isInstanceOf(IndexOutOfBoundsException.class).hasMessage(msg); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,3 @@ |
|||
Tobias;50 |
|||
Lorenz;40 |
|||
Steffen;60 |
@ -0,0 +1,2 @@ |
|||
Tobias;50 |
|||
Steffen;60 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue