I'm trying to learn some OOP programming using Java, so I've created TicTacToe. Could you give me some advice on how I can improve this code?
Player.java:
package com.kamil.dude.tactoe;
import java.util.Random;
import java.util.Scanner;
public class Player {
public char currentPlayer;
public Player() {
Random generator = new Random();
currentPlayer = (generator.nextBoolean()) == true ? 'O' : 'X';
}
public void setPlayer() {
currentPlayer = (currentPlayer == 'O') ? 'X' : 'O';
}
public int getInput(int size) {
Scanner in = new Scanner(System.in);
int fieldNumber = in.nextInt();
while (fieldNumber < 1 || fieldNumber > size) {
fieldNumber = in.nextInt();
}
return fieldNumber;
}
}
GameBoard.java:
package com.kamil.dude.tactoe;
public class GameBoard {
private Player player;
private char gameBoard[]; // I want to represent gameBoard as an array of buttons
private int fieldNumber;
private int filledFieldsNumber;
private final int lengthOfGameBoardSide;
private final int bottomLeftCornerIndex; // helps to check slash lines
private int size;
public GameBoard(int size) {
this.lengthOfGameBoardSide = (int) Math.sqrt(size);
this.bottomLeftCornerIndex = size - ((int) Math.sqrt(size) - 1);
this.size = size;
player = new Player();
gameBoard = new char[size];
for (int i = 0; i < size; ++i) {
gameBoard[i] = '0';
}
}
public void draw() {
for (int i = 0, charsInRow = 0; i < size; ++i, ++charsInRow) {
if (charsInRow == lengthOfGameBoardSide) {
charsInRow = 0;
System.out.println();
}
if (gameBoard[i] == '0') {
if (i < 9)
System.out.print(i + 1 + " ");
else
System.out.print(i + 1 + " ");
}
else if (gameBoard[i] == 'O')
System.out.print("O ");
else
System.out.print("X ");
}
System.out.println();
}
public void checkInput() {
fieldNumber = player.getInput(size);
if (player.currentPlayer == 'O' && isFieldFree(fieldNumber)) {
gameBoard[fieldNumber - 1] = 'O';
++filledFieldsNumber;
player.setPlayer();
}
else if (player.currentPlayer == 'X' && isFieldFree(fieldNumber)) {
gameBoard[fieldNumber - 1] = 'X';
++filledFieldsNumber;
player.setPlayer();
}
}
private boolean isFieldFree(int fieldNumber) {
return (gameBoard[fieldNumber - 1] == '0') ? true : false;
}
public boolean isGameEnded() {
if (checkIfWin() || checkIfDraw())
return true;
return false;
}
private boolean checkIfWin() {
if (checkVerticalLines() || checkHorizontalLines() || checkSlashLines())
return true;
return false;
}
private boolean checkVerticalLines() {
int repeatNumber = 0;
for (int i = 0; i < lengthOfGameBoardSide; ++i) {
for (int j = i; j < size && repeatNumber != lengthOfGameBoardSide - 1; j += lengthOfGameBoardSide) {
if (gameBoard[j] != '0' && gameBoard[j + lengthOfGameBoardSide] == gameBoard[j]) {
++repeatNumber;
} else {
repeatNumber = 0;
break;
}
}
if (checkRepeatedSignsNumber(repeatNumber))
return true;
}
return false;
}
private boolean checkHorizontalLines() {
int repeatNumber = 0;
for (int i = 0; i < bottomLeftCornerIndex; i += lengthOfGameBoardSide) {
for (int j = i; j < size && repeatNumber != lengthOfGameBoardSide - 1; ++j) {
if (gameBoard[j] != '0' && gameBoard[j + 1] == gameBoard[j]) {
++repeatNumber;
} else {
repeatNumber = 0;
break;
}
}
if (checkRepeatedSignsNumber(repeatNumber))
return true;
}
return false;
}
private boolean checkSlashLines() {
if (checkBackSlash() || checkSlash())
return true;
return false;
}
private boolean checkBackSlash() {
int repeatNumber = 0;
for (int i = 0; i < size && repeatNumber != lengthOfGameBoardSide - 1; i += lengthOfGameBoardSide + 1) {
if (gameBoard[i] != '0' && gameBoard[i + (lengthOfGameBoardSide + 1)] == gameBoard[i]) {
++repeatNumber;
} else {
repeatNumber = 0;
break;
}
if (checkRepeatedSignsNumber(repeatNumber))
return true;
}
return false;
}
private boolean checkSlash() {
int repeatNumber = 0;
for (int i = 2; i < bottomLeftCornerIndex && repeatNumber != lengthOfGameBoardSide - 1; i += size - bottomLeftCornerIndex) {
if (gameBoard[i] != '0' && gameBoard[i + (size - bottomLeftCornerIndex)] == gameBoard[i]) {
++repeatNumber;
} else {
repeatNumber = 0;
break;
}
if (checkRepeatedSignsNumber(repeatNumber))
return true;
}
return false;
}
private boolean checkRepeatedSignsNumber(int repeatNumber) {
if (repeatNumber == lengthOfGameBoardSide - 1) {
draw();
player.setPlayer();
System.out.println("Player " + player.currentPlayer + " wins");
return true;
}
return false;
}
private boolean checkIfDraw() {
if (filledFieldsNumber == size) {
draw();
System.out.println("Draw!");
return true;
}
return false;
}
}
Main.java:
package com.kamil.dude.tactoe;
public class Main {
public static void main(String[] args) {
GameBoard board = new GameBoard(9); // You can change game board size by giving number of fields
for(;;) {
board.draw();
board.checkInput();
if(board.isGameEnded() == true)
break;
}
}
}