Skip to content

Commit d3ff165

Browse files
committed
Finish Section 3
1 parent e5ecaf8 commit d3ff165

17 files changed

+476
-27
lines changed

src/exercises/ConstructorClass.java

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import java.lang.reflect.Constructor;
44
import java.lang.reflect.InvocationTargetException;
55
import java.util.*;
6-
import java.util.stream.Collectors;
76

87
public class ConstructorClass {
98

src/exercises/Main.java

-26
This file was deleted.

src/game/Game.java

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package game;
2+
3+
public interface Game {
4+
5+
void startGame();
6+
}

src/game/internal/Board.java

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package game.internal;
2+
3+
class Board {
4+
private Cell[][] cells;
5+
private BoardDimensions dimensions;
6+
7+
public Board(BoardDimensions boardDimensions) {
8+
this.dimensions = boardDimensions;
9+
this.cells = new Cell[boardDimensions.getNumberOfColumns()][boardDimensions.getNumberOfRows()];
10+
initAllCells();
11+
}
12+
13+
private void initAllCells() {
14+
for (int r = 0; r < dimensions.getNumberOfRows(); r++) {
15+
for (int c = 0; c < dimensions.getNumberOfColumns(); c++) {
16+
this.cells[c][r] = new Cell();
17+
}
18+
}
19+
}
20+
21+
public void updateCell(int row, int column, Sign sign) {
22+
this.cells[column][row].setSign(sign);
23+
}
24+
25+
public Sign checkWinner() {
26+
// Check rows
27+
for (int r = 0; r < dimensions.getNumberOfRows(); r++) {
28+
Sign sign = getRowWinner(r);
29+
if (sign != Sign.EMPTY) {
30+
return sign;
31+
}
32+
}
33+
34+
// Check columns
35+
for (int c = 0; c < dimensions.getNumberOfColumns(); c++) {
36+
Sign sign = getColumnWinner(c);
37+
if (sign != Sign.EMPTY) {
38+
return sign;
39+
}
40+
}
41+
42+
// Check diagonal
43+
Sign sign = getDiagonalWinner(0, 0, 1, 1);
44+
if (sign != Sign.EMPTY) {
45+
return sign;
46+
}
47+
48+
// Check diagonal
49+
return getDiagonalWinner(0, dimensions.getNumberOfColumns() - 1, -1, 1);
50+
}
51+
52+
public boolean isCellEmpty(int row, int column) {
53+
return this.cells[column][row].isEmpty();
54+
}
55+
56+
public char getPrintableCellSign(int row, int column) {
57+
return this.cells[column][row].getSign().getValue();
58+
}
59+
60+
public boolean isBoardFull() {
61+
for (int r = 0; r < dimensions.getNumberOfRows(); r++) {
62+
for (int c = 0; c < dimensions.getNumberOfColumns(); c++) {
63+
if (this.cells[c][r].isEmpty()) {
64+
return false;
65+
}
66+
}
67+
}
68+
return true;
69+
}
70+
71+
private Sign getColumnWinner(int currentColumn) {
72+
Sign initialSign = this.cells[currentColumn][0].getSign();
73+
74+
if (initialSign == Sign.EMPTY) {
75+
return initialSign;
76+
}
77+
78+
for (int r = 1; r < dimensions.getNumberOfRows(); r++) {
79+
if (this.cells[currentColumn][r].getSign() != initialSign) {
80+
return Sign.EMPTY;
81+
}
82+
}
83+
return initialSign;
84+
}
85+
86+
private Sign getRowWinner(int currentRow) {
87+
Sign initialSign = this.cells[0][currentRow].getSign();
88+
89+
if (initialSign == Sign.EMPTY) {
90+
return initialSign;
91+
}
92+
93+
for (int c = 1; c < dimensions.getNumberOfColumns(); c++) {
94+
if (this.cells[c][currentRow].getSign() != initialSign) {
95+
return Sign.EMPTY;
96+
}
97+
}
98+
return initialSign;
99+
}
100+
101+
102+
private Sign getDiagonalWinner(int startRow, int startColumn, int horizontalStep, int verticalStep) {
103+
Sign initialSign = this.cells[startColumn][startRow].getSign();
104+
if (initialSign == Sign.EMPTY) {
105+
return Sign.EMPTY;
106+
}
107+
108+
int r = startRow + verticalStep;
109+
int c = startColumn + horizontalStep;
110+
111+
while (r < dimensions.getNumberOfRows() && c < dimensions.getNumberOfColumns()) {
112+
if (this.cells[c][r].getSign() != initialSign) {
113+
return Sign.EMPTY;
114+
}
115+
r += verticalStep;
116+
c += horizontalStep;
117+
}
118+
119+
return initialSign;
120+
}
121+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package game.internal;
2+
3+
class BoardDimensions {
4+
private static final int NUM_OF_ROWS = 3;
5+
private static final int NUM_OF_COLUMNS = 3;
6+
7+
8+
public int getNumberOfRows() {
9+
return NUM_OF_ROWS;
10+
}
11+
12+
public int getNumberOfColumns() {
13+
return NUM_OF_COLUMNS;
14+
}
15+
}

src/game/internal/BoardLocation.java

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package game.internal;
2+
3+
class BoardLocation {
4+
private int row;
5+
private int column;
6+
7+
public BoardLocation(int row, int column) {
8+
this.row = row;
9+
this.column = column;
10+
}
11+
12+
public int getRow() {
13+
return row;
14+
}
15+
16+
public int getColumn() {
17+
return column;
18+
}
19+
}

src/game/internal/BoardPrinter.java

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2020 Michael Pogrebinsky - Java Reflection - Master Class
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package game.internal;
26+
27+
class BoardPrinter {
28+
private final BoardDimensions dimensions;
29+
30+
public BoardPrinter(BoardDimensions dimensions) {
31+
this.dimensions = dimensions;
32+
}
33+
34+
public void print(Board board) {
35+
printHorizontalBorder();
36+
37+
printBoard(board);
38+
39+
printHorizontalBorder();
40+
}
41+
42+
private void printBoard(Board board) {
43+
for (int r = 0; r < dimensions.getNumberOfRows(); r++) {
44+
System.out.print("|");
45+
for (int c = 0; c < dimensions.getNumberOfColumns(); c++) {
46+
System.out.printf(" %s |", board.getPrintableCellSign(r, c));
47+
}
48+
System.out.println();
49+
}
50+
}
51+
52+
private void printHorizontalBorder() {
53+
for (int c = 0; c < dimensions.getNumberOfColumns() * 4 + 1; c++) {
54+
System.out.print("-");
55+
}
56+
System.out.println();
57+
}
58+
}

src/game/internal/Cell.java

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package game.internal;
2+
3+
class Cell {
4+
private Sign sign;
5+
6+
public Cell() {
7+
sign = Sign.EMPTY;
8+
}
9+
10+
public boolean isEmpty() {
11+
return sign == Sign.EMPTY;
12+
}
13+
14+
public Sign getSign() {
15+
return sign;
16+
}
17+
18+
public void setSign(Sign sign) {
19+
this.sign = sign;
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package game.internal;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Random;
6+
7+
class ComputerInputProvider implements InputProvider {
8+
public final BoardDimensions dimensions;
9+
private final Random random = new Random();
10+
11+
public ComputerInputProvider(BoardDimensions dimensions) {
12+
this.dimensions = dimensions;
13+
}
14+
15+
@Override
16+
public BoardLocation provideNextMove(Board board) {
17+
List<BoardLocation> availableCells = new ArrayList<>();
18+
19+
for (int r = 0; r < dimensions.getNumberOfRows(); r++) {
20+
for (int c = 0; c < dimensions.getNumberOfColumns(); c++) {
21+
if (board.isCellEmpty(r, c)) {
22+
availableCells.add(new BoardLocation(r, c));
23+
}
24+
}
25+
}
26+
27+
int chosenCell = random.nextInt(availableCells.size());
28+
29+
return availableCells.get(chosenCell);
30+
}
31+
}

src/game/internal/ComputerPlayer.java

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package game.internal;
2+
3+
class ComputerPlayer implements Player {
4+
private static final String NAME = "Computer";
5+
private final ComputerInputProvider locationProvider;
6+
7+
public ComputerPlayer(ComputerInputProvider locationProvider) {
8+
this.locationProvider = locationProvider;
9+
}
10+
11+
@Override
12+
public void play(Board board, Sign sign) {
13+
BoardLocation location = locationProvider.provideNextMove(board);
14+
board.updateCell(location.getRow(), location.getColumn(), sign);
15+
}
16+
17+
@Override
18+
public String getPlayerName() {
19+
return NAME;
20+
}
21+
}

src/game/internal/HumanPlayer.java

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package game.internal;
2+
3+
class HumanPlayer implements Player {
4+
private static final String NAME = "You";
5+
private final KeyboardInputProvider inputProvider;
6+
7+
public HumanPlayer(KeyboardInputProvider inputProvider) {
8+
this.inputProvider = inputProvider;
9+
}
10+
11+
@Override
12+
public void play(Board board, Sign sign) {
13+
BoardLocation nextMoveLocation = inputProvider.provideNextMove(board);
14+
board.updateCell(nextMoveLocation.getRow(), nextMoveLocation.getColumn(), sign);
15+
}
16+
17+
@Override
18+
public String getPlayerName() {
19+
return NAME;
20+
}
21+
}

src/game/internal/InputProvider.java

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package game.internal;
2+
3+
interface InputProvider {
4+
BoardLocation provideNextMove(Board board);
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package game.internal;
2+
3+
import java.util.Scanner;
4+
5+
class KeyboardInputProvider implements InputProvider {
6+
private final Scanner scanner = new Scanner(System.in);
7+
private final BoardDimensions boardDimensions;
8+
9+
public KeyboardInputProvider(BoardDimensions boardDimensions) {
10+
this.boardDimensions = boardDimensions;
11+
}
12+
13+
@Override
14+
public BoardLocation provideNextMove(Board board) {
15+
int row;
16+
int column;
17+
do {
18+
System.out.print("Please choose row: ");
19+
row = scanner.nextInt();
20+
System.out.print("Please choose column: ");
21+
column = scanner.nextInt();
22+
} while (row < 0
23+
|| row >= boardDimensions.getNumberOfRows()
24+
|| column < 0
25+
|| column >= boardDimensions.getNumberOfColumns()
26+
|| !board.isCellEmpty(row, column));
27+
return new BoardLocation(row, column);
28+
}
29+
}

0 commit comments

Comments
 (0)