12 Commits

  1. 33
      src/main/java/Game/Game.java
  2. 173
      src/main/java/Game/TicTacToe/Board.java
  3. 81
      src/main/java/Game/Tictactoe.java
  4. 11
      src/main/java/Main.java
  5. 43
      src/test/java/Game/GameTest.java
  6. 128
      src/test/java/Game/TicTacToe/BoardTest.java
  7. 27
      src/test/java/Game/TictactoeTest.java

33
src/main/java/Game/Game.java

@ -0,0 +1,33 @@
package Game;
import java.util.ArrayList;
public abstract class Game {
protected ArrayList<String> outputBuffer = new ArrayList<>();
private boolean isFinished = false;
public abstract void update(String input);
public void print() {
for (String s : outputBuffer) {
System.out.println(s);
}
}
public boolean isFinished() {
return isFinished;
}
protected void setFinished(boolean isFinished) {
this.isFinished = isFinished;
}
protected void setOutputBuffer(ArrayList<String> outputBuffer) {
this.outputBuffer = outputBuffer;
}
public ArrayList<String> getOutputBuffer() {
return this.outputBuffer;
}
}

173
src/main/java/Game/TicTacToe/Board.java

@ -0,0 +1,173 @@
package Game.TicTacToe;
import java.util.ArrayList;
import java.util.Arrays;
public class Board {
enum State {
CIRCLE,
CROSS,
EMPTY
}
public enum CurrentState {
DRAW,
CIRCLEWIN,
CROSSWIN,
NOTFINISHED
}
private ArrayList<int[]> winPatterns;
private State[] states;
public Board() {
states = new State[9];
for (int i = 0; i < states.length; i++) {
states[i] = State.EMPTY;
}
winPatterns = new ArrayList<>();
winPatterns.add(new int[]{1,1,1,0,0,0,0,0,0});
winPatterns.add(new int[]{0,0,0,1,1,1,0,0,0});
winPatterns.add(new int[]{0,0,0,0,0,0,1,1,1});
winPatterns.add(new int[]{1,0,0,1,0,0,1,0,0});
winPatterns.add(new int[]{0,1,0,0,1,0,0,1,0});
winPatterns.add(new int[]{0,0,1,0,0,1,0,0,1});
winPatterns.add(new int[]{0,0,1,0,1,0,1,0,0});
winPatterns.add(new int[]{1,0,0,0,1,0,0,0,1});
}
public static char getStatedChar(State state) {
switch (state) {
case CIRCLE:
return 'O';
case CROSS:
return 'X';
case EMPTY:
return ' ';
default:
return '-';
}
}
public boolean setCellState(int cell, boolean cross) {
if (cell <= 9 && cell >= 1) {
if (this.states[cell-1] != State.EMPTY) {
return false;
}
if (cross) {
this.states[cell-1] = State.CROSS;
} else {
this.states[cell-1] = State.CIRCLE;
}
}else {
return false;
}
return true;
}
/*
1 2 3
o x o
4 5 6
o x o
7 8 9
o x o
*/
public ArrayList<String> getOutputBoard() {
ArrayList<String> outputBoard = new ArrayList<>();
outputBoard.add("1 ║2 ║3");
outputBoard.add(" " + getStatedChar(states[0]) + " ║ " + getStatedChar(states[1]) + " ║ " + getStatedChar(states[2]) +" ");
outputBoard.add("═════╬═════╬═════");
outputBoard.add("4 ║5 ║6");
outputBoard.add(" " + getStatedChar(states[3]) + " ║ " + getStatedChar(states[4]) + " ║ " + getStatedChar(states[5]) +" ");
outputBoard.add("═════╬═════╬═════");
outputBoard.add("7 ║8 ║9");
outputBoard.add(" " + getStatedChar(states[6]) + " ║ " + getStatedChar(states[7]) + " ║ " + getStatedChar(states[8]) +" ");
return outputBoard;
}
public State[] getStates() {
return this.states;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Board)) {
return false;
}
Board x = (Board)o;
for (int i = 0; i < x.getStates().length; i++) {
if (this.getStates()[i] != x.getStates()[i]) {
return false;
}
}
return true;
}
//Checkfull(draw), Checkwinner clear,neue Runde und Scoreboard
public CurrentState getCurrentState() {
int counterCross;
int counterCircle;
for (int[] pattern : winPatterns) {
counterCircle = 0;
counterCross = 0;
for (int i = 0; i < pattern.length; i++) {
if (pattern[i] == 1) {
if (getStates()[i] == State.CIRCLE)
counterCircle++;
if (getStates()[i] == State.CROSS)
counterCross++;
}
}
if (counterCircle >= 3)
return CurrentState.CIRCLEWIN;
if (counterCross >= 3)
return CurrentState.CROSSWIN;
}
//Not finished
for (int i = 0; i < getStates().length; i++) {
if (getStates()[i] == State.EMPTY) {
return CurrentState.NOTFINISHED;
}
}
//Draw
return CurrentState.DRAW;
}
public static State[] convertSimpleToState(int[] temp) {
if (temp.length != 9)
return null;
State[] stateArray = new State[9];
for (int i = 0; i < temp.length; i++) {
switch(temp[i]) {
case 1:
stateArray[i] = State.CIRCLE;
break;
case 2:
stateArray[i] = State.CROSS;
break;
default:
stateArray[i] = State.EMPTY;
}
}
return stateArray;
}
}

81
src/main/java/Game/Tictactoe.java

@ -0,0 +1,81 @@
package Game;
import Game.TicTacToe.Board;
public class Tictactoe extends Game {
private String input;
private Board currentBoard;
private boolean crossTurn;
public Tictactoe() {
init();
}
private void init() {
crossTurn = true;
currentBoard = new Board();
outputBuffer.add("Welcome to Tic Tac Toe. \nCross start the game");
outputBuffer.addAll(currentBoard.getOutputBoard());
outputBuffer.add((crossTurn ? "Cross" : "Circle") + " it´s your Turn, please choose a Cell:");
}
@Override
public void update(String input) {
outputBuffer.clear();
if (isFinished()) {
resetBoard();
return;
}
boolean validTurn = false;
try {
validTurn = currentBoard.setCellState(Integer.parseInt(input), crossTurn);
} catch (NumberFormatException e) {
}
outputBuffer.addAll(currentBoard.getOutputBoard());
if (validTurn)
switchTurn();
else
outputBuffer.add("Invalid Turn!");
switch (currentBoard.getCurrentState()) {
case CIRCLEWIN:
outputBuffer.add("Circle won the game gg");
setFinished(true);
break;
case CROSSWIN:
outputBuffer.add("Cross won the game gg");
setFinished(true);
break;
case DRAW:
outputBuffer.add("l2p");
setFinished(true);
break;
case NOTFINISHED:
outputBuffer.add((crossTurn ? "Cross" : "Circle") + " it´s your Turn, please choose a Cell:");
break;
default:
throw new IllegalStateException("Unexpected value: " + currentBoard.getCurrentState());
}
if (isFinished()) {
outputBuffer.add("Please enter any key to start the game!");
}
}
public void resetBoard() {
setFinished(false);
currentBoard = new Board();
crossTurn = true;
outputBuffer.add("Starting a new Game... Prepare for the fight");
outputBuffer.addAll(currentBoard.getOutputBoard());
outputBuffer.add((crossTurn ? "Cross" : "Circle") + " it´s your Turn, please choose a Cell:");
}
public void switchTurn() {
crossTurn = !crossTurn;
}
}

11
src/main/java/Main.java

@ -1,6 +1,17 @@
import Game.Tictactoe;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
System.out.println("Hello world!");
Tictactoe ttt = new Tictactoe();
Scanner scan = new Scanner(System.in);
ttt.print();
while (scan.hasNext()) {
ttt.update(scan.next());
ttt.print();
}
}
}

43
src/test/java/Game/GameTest.java

@ -0,0 +1,43 @@
package Game;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
class GameTest {
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final PrintStream originalOut = System.out;
Game game;
@BeforeEach
void setUp() {
System.setOut(new PrintStream(outContent));
game = mock(Game.class, Mockito.CALLS_REAL_METHODS);
}
@AfterEach
void tearDown() {
System.setOut(originalOut);
}
@Test
public void print() {
ArrayList<String> testOB = new ArrayList<>();
testOB.add("Hello");
testOB.add("World");
testOB.add("!!!");
game.setOutputBuffer(testOB);
game.print();
assertEquals("Hello\nWorld\n!!!\n", outContent.toString().replaceAll("\r", ""));
}
}

128
src/test/java/Game/TicTacToe/BoardTest.java

@ -0,0 +1,128 @@
package Game.TicTacToe;
import Game.Tictactoe;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.internal.util.reflection.FieldSetter;
import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
class BoardTest {
Board board;
@BeforeEach
void setUp() {
board = new Board();
}
@AfterEach
void tearDown() {
}
@Test
void getStatedChar() {
assertEquals(Board.getStatedChar(Board.State.CIRCLE), 'O');
assertEquals(Board.getStatedChar(Board.State.CROSS), 'X');
assertEquals(Board.getStatedChar(Board.State.EMPTY), ' ');
}
@Test
void testForEmptyBoardOnInitialization() {
for (int i = 0; i < 9; i++) {
assertEquals(board.getStates()[i], Board.State.EMPTY);
}
}
@Test
void setCellState() {
Board.State[] lastBoard = Arrays.copyOf(board.getStates(), board.getStates().length);
board.setCellState(1, true);
assertFalse(Arrays.equals(lastBoard, board.getStates()));
assertEquals(board.getStates()[0], Board.State.CROSS);
board.setCellState(1, false);
assertEquals(board.getStates()[0], Board.State.CROSS);
board.setCellState(2, false);
assertEquals(board.getStates()[1], Board.State.CIRCLE);
}
@SuppressWarnings("AssertBetweenInconvertibleTypes")
@Test
void testEquals() {
assertNotEquals(board, "Test");
Board secondBoard = new Board();
assertEquals(board, secondBoard);
secondBoard.getStates()[0] = Board.State.CROSS;
assertNotEquals(board, secondBoard);
board.getStates()[0] = Board.State.CROSS;
assertEquals(board, secondBoard);
}
@Test
void convertSimpleToState() {
int[] test = {1, 1, 1, 2, 0, 2, 2, 0, 0};
Board.State[] expected = {Board.State.CIRCLE, Board.State.CIRCLE, Board.State.CIRCLE, Board.State.CROSS, Board.State.EMPTY, Board.State.CROSS, Board.State.CROSS, Board.State.EMPTY, Board.State.EMPTY};
int[] test2 = {1, 0, 0, 1, 0, 0, 1, 0, 0};
Board.State[] expected2 = {Board.State.CIRCLE, Board.State.EMPTY, Board.State.EMPTY, Board.State.CIRCLE, Board.State.EMPTY, Board.State.EMPTY, Board.State.CIRCLE, Board.State.EMPTY, Board.State.EMPTY};
int[] test3 = {69, 0, 0, 0, 1, 0, 0, 0, 1};
Board.State[] expected3 = {Board.State.CIRCLE, Board.State.EMPTY, Board.State.EMPTY, Board.State.EMPTY, Board.State.CIRCLE, Board.State.EMPTY, Board.State.EMPTY, Board.State.EMPTY, Board.State.CIRCLE};
int[] test4 = {3, 0, 0, 0, 1, 0, 0, 0, 1};
Board.State[] expected4 = {Board.State.EMPTY, Board.State.EMPTY, Board.State.EMPTY, Board.State.EMPTY, Board.State.CIRCLE, Board.State.EMPTY, Board.State.EMPTY, Board.State.EMPTY, Board.State.CIRCLE};
int[] test5 = {3, 0, 0, 0, 1, 0, 0, 0};
assertTrue(Arrays.deepEquals(expected, Board.convertSimpleToState(test)));
assertTrue(Arrays.deepEquals(expected2, Board.convertSimpleToState(test2)));
assertFalse(Arrays.deepEquals(expected3, Board.convertSimpleToState(test3)));
assertTrue(Arrays.deepEquals(expected4, Board.convertSimpleToState(test4)));
assertNull(Board.convertSimpleToState(test5));
}
@Test
void getCurrentState() {
Board.State[] testArray = Board.convertSimpleToState(new int[]{2, 2, 2, 1, 0, 1, 1, 0, 0});
Board.State[] testArray2 = Board.convertSimpleToState(new int[]{1, 0, 2, 1, 2, 0, 1, 0, 2});
Board.State[] testArray3 = Board.convertSimpleToState(new int[]{1, 0, 2, 0, 1, 2, 0, 2, 1});
Board.State[] testArray4 = Board.convertSimpleToState(new int[]{0, 1, 2, 2, 1, 0, 0, 1, 2});
Board.State[] testArray5 = Board.convertSimpleToState(new int[]{1, 0, 0, 2, 2, 2, 1, 0, 1});
Board.State[] testArray6 = Board.convertSimpleToState(new int[]{2, 0, 1, 2, 1, 0, 1, 2, 0});
Board.State[] testArray7 = Board.convertSimpleToState(new int[]{0, 0, 1, 0, 2, 1, 2, 2, 1});
Board.State[] testArray8 = Board.convertSimpleToState(new int[]{1, 0, 0, 1, 1, 0, 2, 2, 2});
Board.State[] drawArray = Board.convertSimpleToState(new int[]{2, 1, 2, 1, 2, 1, 1, 2, 1});
Board.State[] drawArray2 = Board.convertSimpleToState(new int[]{2, 2, 1, 1, 1, 2, 2, 2, 1});
Board.State[] notFinishedArray = Board.convertSimpleToState(new int[]{2, 2, 1, 2, 0, 1, 0, 0, 0});
try {
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), testArray);
assertEquals(board.getCurrentState(), Board.CurrentState.CROSSWIN);
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), testArray2);
assertEquals(board.getCurrentState(), Board.CurrentState.CIRCLEWIN);
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), testArray3);
assertEquals(board.getCurrentState(), Board.CurrentState.CIRCLEWIN);
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), testArray4);
assertEquals(board.getCurrentState(), Board.CurrentState.CIRCLEWIN);
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), testArray5);
assertEquals(board.getCurrentState(), Board.CurrentState.CROSSWIN);
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), testArray6);
assertEquals(board.getCurrentState(), Board.CurrentState.CIRCLEWIN);
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), testArray7);
assertEquals(board.getCurrentState(), Board.CurrentState.CIRCLEWIN);
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), testArray8);
assertEquals(board.getCurrentState(), Board.CurrentState.CROSSWIN);
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), drawArray);
assertEquals(board.getCurrentState(), Board.CurrentState.DRAW);
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), drawArray2);
assertEquals(board.getCurrentState(), Board.CurrentState.DRAW);
FieldSetter.setField(board, board.getClass().getDeclaredField("states"), notFinishedArray);
assertEquals(board.getCurrentState(), Board.CurrentState.NOTFINISHED);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}

27
src/test/java/Game/TictactoeTest.java

@ -0,0 +1,27 @@
package Game;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.*;
class TictactoeTest {
Tictactoe ttt;
@BeforeEach
void setUp() {
ttt = new Tictactoe();
}
@AfterEach
void tearDown() {
}
}
Loading…
Cancel
Save