I am making a Tic Tac Toe game to be played in the console either against another human or a simple AI. It is a little rough but it works. What concerns me is how well it adheres to SOLID and other design principles as this is my first time using them in practice. I would appreciate a review of how my classes are structured and any advice. I am sharing a link from GitHub because there is too much code to post everything here.
These are some of the largest classes and give me an uneasy feeling.
GameBoard.class - has the game board and holds players' markers
package board;
import java.util.ArrayList;
public class GameBoard {
private Cell[] board;
private ArrayList<Integer> availableSpots;
public GameBoard(int n) {
availableSpots = new ArrayList<Integer>();
//the game board
board = new Cell[n];
for (int i = 0; i < n; i++) {
board[i] = new Cell();
}
//list of initial open cells
for (int i = 0; i < 9; i++) {
availableSpots.add(i);
}
}
public Cell[] getBoard() {
return board;
}
public void addMarker(int n, String s) {
if (availableSpots.contains(n)) {
board[n].setMarker(s);
removeSpotFromList(n);
//System.out.println(availableSpots.size());
}
else {
System.out.println("Cell not available");
}
}
public String getCellValue(int n) {
return board[n].getMarker();
}
public ArrayList<Integer> getAvailableSpots() {
return availableSpots;
}
//remove number from arraylist
public void removeSpotFromList(int n) {
availableSpots.set(n, null);
availableSpots.trimToSize();
for (int i=0; i<availableSpots.size(); i++) {
//System.out.println(availableSpots.get(i) + ", ");
}
}
}
Game.class - switches between players and calls each turn
import board.GameBoard;
import board.PrintBoard;
import consuleInput.InputReader;
import import players.Playable;
import players.PlayerGroup;
public class Game {
public static void play() {
Modes modes = new Modes();
InputReader ir = new InputReader();
GameBoard bg = new GameBoard(9);
PrintBoard pb = new PrintBoard();
PlayerGroup pg = new PlayerGroup();
GameStateChecker gsc = new GameStateChecker();
System.out.println("choose a mode:");
System.out.println("1. Player vs player");
System.out.println("2. player v computer");
System.out.println("3. computer vs computer");
int mode = ir.toIntegerReader("type below");
modes.chooseMode(mode, pg);
pb.print(bg);
int counter = 9;
Playable currentPlayer;
boolean hasWinner = false;
int player = 0;
//int choice;
do{
currentPlayer = pg.getPlayer(player);
//int choice = ir.toIntegerReader("pick a square (0-8):");
bg.addMarker(currentPlayer.playerMove(bg.getAvailableSpots()), currentPlayer.getMarker());
pb.print(bg);
hasWinner = gsc.checkPatterns(bg, currentPlayer);
//System.out.println("is there a winner " + hasWinner);
counter--;
if (player == 0) {
player = 1;
}
else {
player = 0;
}
/*
currentPlayer = pg.getPlayer(1);
choice = ir.toIntegerReader("pick a square (0-8):");
bg.addMarker(choice, currentPlayer.getMarker());
pb.print(bg);
hasWinner = gsc.checkPatterns(bg, currentPlayer);
counter--;
*/
}
while (!hasWinner);
}
}
board
. \$\endgroup\$