From 9a6e8f1af4da1ca296056c1d37b7b56c59b3f1e7 Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Wed, 19 Jan 2022 10:42:44 +0100 Subject: [PATCH 01/11] Added Gameinterface with TTT class and printTest --- src/main/java/Game/Game.java | 8 +++++ src/main/java/Game/Tictactoe.java | 18 +++++++++++ src/test/java/Game/TictactoeTest.java | 44 +++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/main/java/Game/Game.java create mode 100644 src/main/java/Game/Tictactoe.java create mode 100644 src/test/java/Game/TictactoeTest.java diff --git a/src/main/java/Game/Game.java b/src/main/java/Game/Game.java new file mode 100644 index 0000000..9ddc0d2 --- /dev/null +++ b/src/main/java/Game/Game.java @@ -0,0 +1,8 @@ +package Game; + +public interface Game { + public abstract void print(); + + + +} diff --git a/src/main/java/Game/Tictactoe.java b/src/main/java/Game/Tictactoe.java new file mode 100644 index 0000000..87da6c4 --- /dev/null +++ b/src/main/java/Game/Tictactoe.java @@ -0,0 +1,18 @@ +package Game; + +import java.util.ArrayList; + +public class Tictactoe implements Game { + private ArrayList outputBuffer = new ArrayList(); + + @Override + public void print() { + for (int i = 0; i < outputBuffer.size(); i++) { + System.out.println(outputBuffer.get(i)); + } + } + + void setOutputBuffer(ArrayList outputBuffer){ + this.outputBuffer = outputBuffer; + } +} diff --git a/src/test/java/Game/TictactoeTest.java b/src/test/java/Game/TictactoeTest.java new file mode 100644 index 0000000..55d7874 --- /dev/null +++ b/src/test/java/Game/TictactoeTest.java @@ -0,0 +1,44 @@ +package Game; + +import org.junit.Rule; +import org.junit.contrib.java.lang.system.SystemOutRule; +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 { + + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + + Tictactoe ttt; + + + @BeforeEach + void setUp() { + ttt = new Tictactoe(); + System.setOut(new PrintStream(outContent)); + } + + @AfterEach + void tearDown() { + System.setOut(originalOut); + } + + @Test + public void testPrint() { + ArrayList testOB = new ArrayList(); + testOB.add("Hello"); + testOB.add("World"); + testOB.add("!!!"); + ttt.setOutputBuffer(testOB); + ttt.print(); + assertEquals("Hello\nWorld\n!!!\n", outContent.toString().replaceAll("\r", "")); + } +} \ No newline at end of file From f58cbf0a2efcaedab5ae977a6489a18f128f720e Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Wed, 19 Jan 2022 11:18:53 +0100 Subject: [PATCH 02/11] Game Interface TTT getStatedChar Method --- src/main/java/Game/Tictactoe.java | 22 +++++++++++++++++++++- src/test/java/Game/TictactoeTest.java | 10 ++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/Game/Tictactoe.java b/src/main/java/Game/Tictactoe.java index 87da6c4..5be7517 100644 --- a/src/main/java/Game/Tictactoe.java +++ b/src/main/java/Game/Tictactoe.java @@ -3,15 +3,35 @@ package Game; import java.util.ArrayList; public class Tictactoe implements Game { + enum State { + CIRCLE, + CROSS, + EMPTY + } private ArrayList outputBuffer = new ArrayList(); + private String input; @Override public void print() { for (int i = 0; i < outputBuffer.size(); i++) { - System.out.println(outputBuffer.get(i)); + System.out.println(outputBuffer.get(i)); } } + public char getStatedChar(State state) { + switch (state) { + case CIRCLE: + return 'O'; + case CROSS: + return 'X'; + case EMPTY: + return ' '; + default: + return '-'; + } + } + + void setOutputBuffer(ArrayList outputBuffer){ this.outputBuffer = outputBuffer; } diff --git a/src/test/java/Game/TictactoeTest.java b/src/test/java/Game/TictactoeTest.java index 55d7874..39a6f3e 100644 --- a/src/test/java/Game/TictactoeTest.java +++ b/src/test/java/Game/TictactoeTest.java @@ -1,7 +1,5 @@ package Game; -import org.junit.Rule; -import org.junit.contrib.java.lang.system.SystemOutRule; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -41,4 +39,12 @@ class TictactoeTest { ttt.print(); assertEquals("Hello\nWorld\n!!!\n", outContent.toString().replaceAll("\r", "")); } + + + @Test + void getStatedChar() { + assertEquals(ttt.getStatedChar(Tictactoe.State.CIRCLE), 'O'); + assertEquals(ttt.getStatedChar(Tictactoe.State.CROSS), 'X'); + assertEquals(ttt.getStatedChar(Tictactoe.State.EMPTY), ' '); + } } \ No newline at end of file From 03628a0e1fedc084e1b055efe9c2eab5738e51d1 Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Wed, 19 Jan 2022 11:39:32 +0100 Subject: [PATCH 03/11] Game TTT added Board creation --- src/main/java/Game/Tictactoe.java | 22 ++++++++++++++++++++++ src/test/java/Game/TictactoeTest.java | 8 ++++++++ 2 files changed, 30 insertions(+) diff --git a/src/main/java/Game/Tictactoe.java b/src/main/java/Game/Tictactoe.java index 5be7517..0988a12 100644 --- a/src/main/java/Game/Tictactoe.java +++ b/src/main/java/Game/Tictactoe.java @@ -3,6 +3,8 @@ package Game; import java.util.ArrayList; public class Tictactoe implements Game { + + enum State { CIRCLE, CROSS, @@ -10,6 +12,15 @@ public class Tictactoe implements Game { } private ArrayList outputBuffer = new ArrayList(); private String input; + private State[] currentBoard; + + public Tictactoe() { + init(); + } + + private void init() { + currentBoard = newBoard(); + } @Override public void print() { @@ -31,8 +42,19 @@ public class Tictactoe implements Game { } } + private State[] newBoard() { + State[] board = new State[9]; + for (int i = 0; i < board.length; i++) { + board[i] = State.EMPTY; + } + return board; + } void setOutputBuffer(ArrayList outputBuffer){ this.outputBuffer = outputBuffer; } + + public State[] getCurrentBoard() { + return currentBoard; + } } diff --git a/src/test/java/Game/TictactoeTest.java b/src/test/java/Game/TictactoeTest.java index 39a6f3e..998accf 100644 --- a/src/test/java/Game/TictactoeTest.java +++ b/src/test/java/Game/TictactoeTest.java @@ -47,4 +47,12 @@ class TictactoeTest { assertEquals(ttt.getStatedChar(Tictactoe.State.CROSS), 'X'); assertEquals(ttt.getStatedChar(Tictactoe.State.EMPTY), ' '); } + + @Test + void testForEmptyBoardOnInitialization() { + Tictactoe.State[] board = ttt.getCurrentBoard(); + for (int i = 0; i < board.length; i++) { + assertEquals(board[i], Tictactoe.State.EMPTY); + } + } } \ No newline at end of file From 9c7bedcd7cd3e7ff34e00f8bc76434d0533646dc Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Sat, 22 Jan 2022 17:03:02 +0100 Subject: [PATCH 04/11] changed interface Game to abstract class for better object orientation --- src/main/java/Game/Game.java | 21 +++++++++++-- src/main/java/Game/Tictactoe.java | 14 ++------- src/test/java/Game/GameTest.java | 43 +++++++++++++++++++++++++++ src/test/java/Game/TictactoeTest.java | 17 ----------- 4 files changed, 64 insertions(+), 31 deletions(-) create mode 100644 src/test/java/Game/GameTest.java diff --git a/src/main/java/Game/Game.java b/src/main/java/Game/Game.java index 9ddc0d2..540a3d3 100644 --- a/src/main/java/Game/Game.java +++ b/src/main/java/Game/Game.java @@ -1,7 +1,24 @@ package Game; -public interface Game { - public abstract void print(); +import java.util.ArrayList; + +public abstract class Game { + + protected ArrayList outputBuffer = new ArrayList<>(); + + public void print() { + for (String s : outputBuffer) { + System.out.println(s); + } + } + + protected void setOutputBuffer(ArrayList outputBuffer) { + this.outputBuffer = outputBuffer; + } + + public ArrayList getOutputBuffer() { + return this.outputBuffer; + } diff --git a/src/main/java/Game/Tictactoe.java b/src/main/java/Game/Tictactoe.java index 0988a12..371c54a 100644 --- a/src/main/java/Game/Tictactoe.java +++ b/src/main/java/Game/Tictactoe.java @@ -2,7 +2,7 @@ package Game; import java.util.ArrayList; -public class Tictactoe implements Game { +public class Tictactoe extends Game { enum State { @@ -10,7 +10,6 @@ public class Tictactoe implements Game { CROSS, EMPTY } - private ArrayList outputBuffer = new ArrayList(); private String input; private State[] currentBoard; @@ -22,12 +21,7 @@ public class Tictactoe implements Game { currentBoard = newBoard(); } - @Override - public void print() { - for (int i = 0; i < outputBuffer.size(); i++) { - System.out.println(outputBuffer.get(i)); - } - } + public char getStatedChar(State state) { switch (state) { @@ -50,10 +44,6 @@ public class Tictactoe implements Game { return board; } - void setOutputBuffer(ArrayList outputBuffer){ - this.outputBuffer = outputBuffer; - } - public State[] getCurrentBoard() { return currentBoard; } diff --git a/src/test/java/Game/GameTest.java b/src/test/java/Game/GameTest.java new file mode 100644 index 0000000..57c399e --- /dev/null +++ b/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 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", "")); + } +} \ No newline at end of file diff --git a/src/test/java/Game/TictactoeTest.java b/src/test/java/Game/TictactoeTest.java index 998accf..08e51ef 100644 --- a/src/test/java/Game/TictactoeTest.java +++ b/src/test/java/Game/TictactoeTest.java @@ -12,35 +12,18 @@ import static org.junit.jupiter.api.Assertions.*; class TictactoeTest { - private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); - private final PrintStream originalOut = System.out; - Tictactoe ttt; - @BeforeEach void setUp() { ttt = new Tictactoe(); - System.setOut(new PrintStream(outContent)); } @AfterEach void tearDown() { - System.setOut(originalOut); - } - @Test - public void testPrint() { - ArrayList testOB = new ArrayList(); - testOB.add("Hello"); - testOB.add("World"); - testOB.add("!!!"); - ttt.setOutputBuffer(testOB); - ttt.print(); - assertEquals("Hello\nWorld\n!!!\n", outContent.toString().replaceAll("\r", "")); } - @Test void getStatedChar() { assertEquals(ttt.getStatedChar(Tictactoe.State.CIRCLE), 'O'); From 711f610c542b1f58c4462fd27b2d2019c5439524 Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Sat, 22 Jan 2022 17:40:28 +0100 Subject: [PATCH 05/11] added write board function for TicTacToe --- src/main/java/Game/Game.java | 2 ++ src/main/java/Game/Tictactoe.java | 29 +++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/main/java/Game/Game.java b/src/main/java/Game/Game.java index 540a3d3..fd0e0ff 100644 --- a/src/main/java/Game/Game.java +++ b/src/main/java/Game/Game.java @@ -6,6 +6,8 @@ public abstract class Game { protected ArrayList outputBuffer = new ArrayList<>(); + public abstract void update(String string); + public void print() { for (String s : outputBuffer) { System.out.println(s); diff --git a/src/main/java/Game/Tictactoe.java b/src/main/java/Game/Tictactoe.java index 371c54a..c936bb2 100644 --- a/src/main/java/Game/Tictactoe.java +++ b/src/main/java/Game/Tictactoe.java @@ -4,7 +4,6 @@ import java.util.ArrayList; public class Tictactoe extends Game { - enum State { CIRCLE, CROSS, @@ -21,7 +20,10 @@ public class Tictactoe extends Game { currentBoard = newBoard(); } - + @Override + public void update(String string) { + writeBoard(currentBoard); + } public char getStatedChar(State state) { switch (state) { @@ -47,4 +49,27 @@ public class Tictactoe extends Game { public State[] getCurrentBoard() { return currentBoard; } + /* + 1 ║2 ║3 + o ║ x ║ o + ═════╬═════╬═════ + 4 ║5 ║6 + o ║ x ║ o + ═════╬═════╬═════ + 7 ║8 ║9 + o ║ x ║ o + */ + private void writeBoard(State[] state) { + this.outputBuffer.clear(); + outputBuffer.add("1 ║2 ║3"); + outputBuffer.add(" " + getStatedChar(state[0]) + " ║ " + getStatedChar(state[1]) + " ║ " + getStatedChar(state[2]) +" "); + outputBuffer.add("═════╬═════╬═════"); + + outputBuffer.add("4 ║5 ║6"); + outputBuffer.add(" " + getStatedChar(state[3]) + " ║ " + getStatedChar(state[4]) + " ║ " + getStatedChar(state[5]) +" "); + outputBuffer.add("═════╬═════╬═════"); + + outputBuffer.add("7 ║8 ║9"); + outputBuffer.add(" " + getStatedChar(state[6]) + " ║ " + getStatedChar(state[7]) + " ║ " + getStatedChar(state[8]) +" "); + } } From 289a1f90a15e1a2f30113da3f798c817f0dddb3f Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Sat, 22 Jan 2022 18:31:14 +0100 Subject: [PATCH 06/11] refactoring: created Board class for better object orientation and extracted functionality from Tictactoe to board with tests --- src/main/java/Game/TicTacToe/Board.java | 66 +++++++++++++++++++++ src/main/java/Game/Tictactoe.java | 64 +++----------------- src/test/java/Game/TicTacToe/BoardTest.java | 39 ++++++++++++ src/test/java/Game/TictactoeTest.java | 14 ----- 4 files changed, 112 insertions(+), 71 deletions(-) create mode 100644 src/main/java/Game/TicTacToe/Board.java create mode 100644 src/test/java/Game/TicTacToe/BoardTest.java diff --git a/src/main/java/Game/TicTacToe/Board.java b/src/main/java/Game/TicTacToe/Board.java new file mode 100644 index 0000000..92ac33e --- /dev/null +++ b/src/main/java/Game/TicTacToe/Board.java @@ -0,0 +1,66 @@ +package Game.TicTacToe; + +import java.util.ArrayList; + +public class Board { + + enum State { + CIRCLE, + CROSS, + EMPTY + } + private State[] states; + + + public Board() { + states = new State[9]; + for (int i = 0; i < states.length; i++) { + states[i] = State.EMPTY; + } + } + + + + public static char getStatedChar(State state) { + switch (state) { + case CIRCLE: + return 'O'; + case CROSS: + return 'X'; + case EMPTY: + return ' '; + default: + return '-'; + } + } + + /* + 1 ║2 ║3 + o ║ x ║ o + ═════╬═════╬═════ + 4 ║5 ║6 + o ║ x ║ o + ═════╬═════╬═════ + 7 ║8 ║9 + o ║ x ║ o + */ + public ArrayList getOutputBoard() { + ArrayList 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; + } +} diff --git a/src/main/java/Game/Tictactoe.java b/src/main/java/Game/Tictactoe.java index c936bb2..b8c09eb 100644 --- a/src/main/java/Game/Tictactoe.java +++ b/src/main/java/Game/Tictactoe.java @@ -1,75 +1,25 @@ package Game; -import java.util.ArrayList; +import Game.TicTacToe.Board; public class Tictactoe extends Game { - enum State { - CIRCLE, - CROSS, - EMPTY - } private String input; - private State[] currentBoard; + private Board currentBoard; + private boolean crossTurn; public Tictactoe() { init(); } private void init() { - currentBoard = newBoard(); + crossTurn = true; + currentBoard = new Board(); } @Override - public void update(String string) { - writeBoard(currentBoard); - } - - public char getStatedChar(State state) { - switch (state) { - case CIRCLE: - return 'O'; - case CROSS: - return 'X'; - case EMPTY: - return ' '; - default: - return '-'; - } - } - - private State[] newBoard() { - State[] board = new State[9]; - for (int i = 0; i < board.length; i++) { - board[i] = State.EMPTY; - } - return board; + public void update(String input) { + outputBuffer.addAll(currentBoard.getOutputBoard()); } - public State[] getCurrentBoard() { - return currentBoard; - } - /* - 1 ║2 ║3 - o ║ x ║ o - ═════╬═════╬═════ - 4 ║5 ║6 - o ║ x ║ o - ═════╬═════╬═════ - 7 ║8 ║9 - o ║ x ║ o - */ - private void writeBoard(State[] state) { - this.outputBuffer.clear(); - outputBuffer.add("1 ║2 ║3"); - outputBuffer.add(" " + getStatedChar(state[0]) + " ║ " + getStatedChar(state[1]) + " ║ " + getStatedChar(state[2]) +" "); - outputBuffer.add("═════╬═════╬═════"); - - outputBuffer.add("4 ║5 ║6"); - outputBuffer.add(" " + getStatedChar(state[3]) + " ║ " + getStatedChar(state[4]) + " ║ " + getStatedChar(state[5]) +" "); - outputBuffer.add("═════╬═════╬═════"); - - outputBuffer.add("7 ║8 ║9"); - outputBuffer.add(" " + getStatedChar(state[6]) + " ║ " + getStatedChar(state[7]) + " ║ " + getStatedChar(state[8]) +" "); - } } diff --git a/src/test/java/Game/TicTacToe/BoardTest.java b/src/test/java/Game/TicTacToe/BoardTest.java new file mode 100644 index 0000000..e75cbdb --- /dev/null +++ b/src/test/java/Game/TicTacToe/BoardTest.java @@ -0,0 +1,39 @@ +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 static org.junit.jupiter.api.Assertions.*; + +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); + } + } + + + +} \ No newline at end of file diff --git a/src/test/java/Game/TictactoeTest.java b/src/test/java/Game/TictactoeTest.java index 08e51ef..5eb08d8 100644 --- a/src/test/java/Game/TictactoeTest.java +++ b/src/test/java/Game/TictactoeTest.java @@ -24,18 +24,4 @@ class TictactoeTest { } - @Test - void getStatedChar() { - assertEquals(ttt.getStatedChar(Tictactoe.State.CIRCLE), 'O'); - assertEquals(ttt.getStatedChar(Tictactoe.State.CROSS), 'X'); - assertEquals(ttt.getStatedChar(Tictactoe.State.EMPTY), ' '); - } - - @Test - void testForEmptyBoardOnInitialization() { - Tictactoe.State[] board = ttt.getCurrentBoard(); - for (int i = 0; i < board.length; i++) { - assertEquals(board[i], Tictactoe.State.EMPTY); - } - } } \ No newline at end of file From 08468123300cd283e5777b5415f1e13c7c84e688 Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Sat, 22 Jan 2022 18:48:56 +0100 Subject: [PATCH 07/11] added equals method for Board with test --- src/main/java/Game/TicTacToe/Board.java | 16 ++++++++++++++++ src/test/java/Game/TicTacToe/BoardTest.java | 12 +++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/Game/TicTacToe/Board.java b/src/main/java/Game/TicTacToe/Board.java index 92ac33e..1930ba9 100644 --- a/src/main/java/Game/TicTacToe/Board.java +++ b/src/main/java/Game/TicTacToe/Board.java @@ -34,6 +34,8 @@ public class Board { } } + + /* 1 ║2 ║3 o ║ x ║ o @@ -63,4 +65,18 @@ public class Board { 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; + } } diff --git a/src/test/java/Game/TicTacToe/BoardTest.java b/src/test/java/Game/TicTacToe/BoardTest.java index e75cbdb..ae9f366 100644 --- a/src/test/java/Game/TicTacToe/BoardTest.java +++ b/src/test/java/Game/TicTacToe/BoardTest.java @@ -35,5 +35,15 @@ class BoardTest { } - + @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); + } } \ No newline at end of file From 9560dfb17875b708b122595971e33a1fdd704a45 Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Sat, 22 Jan 2022 19:00:31 +0100 Subject: [PATCH 08/11] Added setCellState to class Board with test --- src/main/java/Game/TicTacToe/Board.java | 12 ++++++++++++ src/test/java/Game/TicTacToe/BoardTest.java | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/main/java/Game/TicTacToe/Board.java b/src/main/java/Game/TicTacToe/Board.java index 1930ba9..0f82d3d 100644 --- a/src/main/java/Game/TicTacToe/Board.java +++ b/src/main/java/Game/TicTacToe/Board.java @@ -34,6 +34,18 @@ public class Board { } } + public void setCellState(int cell, boolean cross) { + if (cell <= 9 && cell >= 1) { + if (this.states[cell-1] != State.EMPTY) { + return; + } + if (cross) { + this.states[cell-1] = State.CROSS; + } else { + this.states[cell-1] = State.CIRCLE; + } + } + } /* diff --git a/src/test/java/Game/TicTacToe/BoardTest.java b/src/test/java/Game/TicTacToe/BoardTest.java index ae9f366..bda9727 100644 --- a/src/test/java/Game/TicTacToe/BoardTest.java +++ b/src/test/java/Game/TicTacToe/BoardTest.java @@ -5,6 +5,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Arrays; + import static org.junit.jupiter.api.Assertions.*; class BoardTest { @@ -34,6 +36,17 @@ class BoardTest { } } + @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 From c6f77554bb7d30288258a60e2869f73e086cbcc2 Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Wed, 26 Jan 2022 09:08:57 +0100 Subject: [PATCH 09/11] added static method convertSimpleToState to Board class with test --- src/main/java/Game/Game.java | 5 +-- src/main/java/Game/TicTacToe/Board.java | 41 ++++++++++++++++++++- src/main/java/Game/Tictactoe.java | 12 ++++++ src/test/java/Game/TicTacToe/BoardTest.java | 21 +++++++++++ 4 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/main/java/Game/Game.java b/src/main/java/Game/Game.java index fd0e0ff..f927c82 100644 --- a/src/main/java/Game/Game.java +++ b/src/main/java/Game/Game.java @@ -6,7 +6,7 @@ public abstract class Game { protected ArrayList outputBuffer = new ArrayList<>(); - public abstract void update(String string); + public abstract void update(String input); public void print() { for (String s : outputBuffer) { @@ -21,7 +21,4 @@ public abstract class Game { public ArrayList getOutputBuffer() { return this.outputBuffer; } - - - } diff --git a/src/main/java/Game/TicTacToe/Board.java b/src/main/java/Game/TicTacToe/Board.java index 0f82d3d..66c00c1 100644 --- a/src/main/java/Game/TicTacToe/Board.java +++ b/src/main/java/Game/TicTacToe/Board.java @@ -9,6 +9,14 @@ public class Board { CROSS, EMPTY } + + enum CurrentState { + DRAW, + CIRCLEWIN, + CROSSWIN, + NOTFINÌSHED + } + private State[] states; @@ -34,17 +42,20 @@ public class Board { } } - public void setCellState(int cell, boolean cross) { + public boolean setCellState(int cell, boolean cross) { if (cell <= 9 && cell >= 1) { if (this.states[cell-1] != State.EMPTY) { - return; + return false; } if (cross) { this.states[cell-1] = State.CROSS; } else { this.states[cell-1] = State.CIRCLE; } + }else { + return false; } + return true; } @@ -91,4 +102,30 @@ public class Board { } return true; } + + + //Checkfull(draw), Checkwinner clear,neue Runde und Scoreboard + + + + 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; + } + } diff --git a/src/main/java/Game/Tictactoe.java b/src/main/java/Game/Tictactoe.java index b8c09eb..035b7b7 100644 --- a/src/main/java/Game/Tictactoe.java +++ b/src/main/java/Game/Tictactoe.java @@ -19,7 +19,19 @@ public class Tictactoe extends Game { @Override public void update(String input) { + outputBuffer.clear(); + boolean validTurn = currentBoard.setCellState(Integer.parseInt(input), crossTurn); outputBuffer.addAll(currentBoard.getOutputBoard()); + if(validTurn) { + switchTurn(); + } else { + outputBuffer.add("Invalid Turn!"); + } + outputBuffer.add((crossTurn?"Cross":"Circle") + " it´s your Turn, please choose a Cell:"); + } + + public void switchTurn() { + crossTurn = !crossTurn; } } diff --git a/src/test/java/Game/TicTacToe/BoardTest.java b/src/test/java/Game/TicTacToe/BoardTest.java index bda9727..6a297fe 100644 --- a/src/test/java/Game/TicTacToe/BoardTest.java +++ b/src/test/java/Game/TicTacToe/BoardTest.java @@ -4,10 +4,12 @@ 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 { @@ -59,4 +61,23 @@ class BoardTest { 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)); + } } \ No newline at end of file From b704539e86fb3ffcb6eb834437eb142a5778bc63 Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Wed, 26 Jan 2022 10:32:33 +0100 Subject: [PATCH 10/11] added getCurrentState method for Board class with tests for detecting winner, draw or not finished game --- src/main/java/Game/TicTacToe/Board.java | 44 +++++++++++++++++++- src/test/java/Game/TicTacToe/BoardTest.java | 45 +++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/main/java/Game/TicTacToe/Board.java b/src/main/java/Game/TicTacToe/Board.java index 66c00c1..c3a9e87 100644 --- a/src/main/java/Game/TicTacToe/Board.java +++ b/src/main/java/Game/TicTacToe/Board.java @@ -1,6 +1,7 @@ package Game.TicTacToe; import java.util.ArrayList; +import java.util.Arrays; public class Board { @@ -14,9 +15,10 @@ public class Board { DRAW, CIRCLEWIN, CROSSWIN, - NOTFINÌSHED + NOTFINISHED } + private ArrayList winPatterns; private State[] states; @@ -25,6 +27,15 @@ public class Board { 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}); } @@ -106,7 +117,38 @@ public class Board { //Checkfull(draw), Checkwinner clear,neue Runde und Scoreboard + public CurrentState getCurrentState() { + + int counterCross = 0; + int counterCircle = 0; + + 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) diff --git a/src/test/java/Game/TicTacToe/BoardTest.java b/src/test/java/Game/TicTacToe/BoardTest.java index 6a297fe..40218e4 100644 --- a/src/test/java/Game/TicTacToe/BoardTest.java +++ b/src/test/java/Game/TicTacToe/BoardTest.java @@ -80,4 +80,49 @@ class BoardTest { 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(); + } + } } \ No newline at end of file From 657953f1902ae23210b899360605e7cdeb83f6e0 Mon Sep 17 00:00:00 2001 From: Dion Aliu Date: Wed, 26 Jan 2022 11:25:53 +0100 Subject: [PATCH 11/11] added Tic Tac Toe game loop and finished attribute to Game --- src/main/java/Game/Game.java | 9 +++++ src/main/java/Game/TicTacToe/Board.java | 6 +-- src/main/java/Game/Tictactoe.java | 52 +++++++++++++++++++++++-- src/main/java/Main.java | 11 ++++++ 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/main/java/Game/Game.java b/src/main/java/Game/Game.java index f927c82..39bc4f8 100644 --- a/src/main/java/Game/Game.java +++ b/src/main/java/Game/Game.java @@ -5,6 +5,7 @@ import java.util.ArrayList; public abstract class Game { protected ArrayList outputBuffer = new ArrayList<>(); + private boolean isFinished = false; public abstract void update(String input); @@ -14,6 +15,14 @@ public abstract class Game { } } + public boolean isFinished() { + return isFinished; + } + + protected void setFinished(boolean isFinished) { + this.isFinished = isFinished; + } + protected void setOutputBuffer(ArrayList outputBuffer) { this.outputBuffer = outputBuffer; } diff --git a/src/main/java/Game/TicTacToe/Board.java b/src/main/java/Game/TicTacToe/Board.java index c3a9e87..daaea57 100644 --- a/src/main/java/Game/TicTacToe/Board.java +++ b/src/main/java/Game/TicTacToe/Board.java @@ -11,7 +11,7 @@ public class Board { EMPTY } - enum CurrentState { + public enum CurrentState { DRAW, CIRCLEWIN, CROSSWIN, @@ -119,8 +119,8 @@ public class Board { public CurrentState getCurrentState() { - int counterCross = 0; - int counterCircle = 0; + int counterCross; + int counterCircle; for (int[] pattern : winPatterns) { counterCircle = 0; diff --git a/src/main/java/Game/Tictactoe.java b/src/main/java/Game/Tictactoe.java index 035b7b7..22ef89a 100644 --- a/src/main/java/Game/Tictactoe.java +++ b/src/main/java/Game/Tictactoe.java @@ -15,19 +15,63 @@ public class Tictactoe extends Game { 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(); - boolean validTurn = currentBoard.setCellState(Integer.parseInt(input), crossTurn); + if (isFinished()) { + resetBoard(); + return; + } + boolean validTurn = false; + try { + validTurn = currentBoard.setCellState(Integer.parseInt(input), crossTurn); + + } catch (NumberFormatException e) { + + } + outputBuffer.addAll(currentBoard.getOutputBoard()); - if(validTurn) { + if (validTurn) switchTurn(); - } else { + 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()); } - outputBuffer.add((crossTurn?"Cross":"Circle") + " it´s your Turn, please choose a Cell:"); + 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() { diff --git a/src/main/java/Main.java b/src/main/java/Main.java index af6d878..89b9c35 100644 --- a/src/main/java/Main.java +++ b/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(); + } } }