java programming

profilebishnu
TicTacToeBoard.docx

/**

* Bishnu karki

* 3127350

* fall 2020

* Class: COSC 1436

* EL Centro College

* Professor Keith Smelser

*

*

*/

/**

* The TicTacToe board is a 2 dimensional array

* This is very similar to an Excel Spreadsheet - using rows and columns

*

* col 012

* row 0 xxx (0,0) | (0,1) | (0,2)

* row 1 xxx (1,0) | (1,1) | (1,2)

* row 2 xxx (2,0) | (2,1) | (2,2)

*

* The array is loaded with the Boolean Class.

* Boolean allows for true and false and also null.

* This program treats null as not loaded, true as X and false as O

*/

import java.util.concurrent.ThreadLocalRandom;

public class TicTacToeBoard {

public static final byte MAX_ROWS = 3;

public static final byte MAX_COLS = 3;

public static final char NOT_PLAYED = ' ';

public static final char PLAYER_1 = 'X';

public static final char PLAYER_2 = 'O';

private static final char NO_WINNER = '?';

private GuiBoard theGUIBoard;

private boolean smartPlay = false;

// This enum is used as an indicator to know to process

// rows or columns

private enum ROW_OR_COLUMN {

ROW, COLUMN

};

private Character[][] ticTacToeBoard = new Character[MAX_ROWS][MAX_COLS];

private char computerPlayer = NOT_PLAYED;

/**

* Constructor - Set the computer player X/O + security code

*/

public TicTacToeBoard(char myComputerPlayer, boolean smartPlay) {

if (myComputerPlayer == PLAYER_1 || myComputerPlayer == PLAYER_2) {

computerPlayer = myComputerPlayer;

} else {

exit("Invalid TicTacToe Player - must be " + PLAYER_1 + " or " + PLAYER_2);

}

this.smartPlay = smartPlay; // set method level variable

System.out.println("Computer Player is " + computerPlayer + ", Smart Computer is " + smartPlay);

theGUIBoard = new GuiBoard();

}

/**

* Show a message and force the program to exit

*/

private void exit(String msg) {

System.err.println(msg);

System.err.println("Program will exit now.");

System.exit(1);

}

/**

* Check for a Rows or Columns for all same valid values If found - set the

* theWinnerIs value

*/

private Character checkRowOrColumnForWinner(ROW_OR_COLUMN rowOrColumn) {

Character locatedWinner = null;

// Since MAX_ROWS and MAX_COLS is 3 - will set MAX to 3 for all situations

final int MAX = MAX_ROWS;

for (byte idxDirection_1 = 0; idxDirection_1 < MAX; ++idxDirection_1) {

if (locatedWinner != null) {

// owner was set - No need to work on other rows or columns

break;

}

for (byte idxDirection_2 = 0; idxDirection_2 < MAX; ++idxDirection_2) {

Character entry = null;

if (rowOrColumn.equals(ROW_OR_COLUMN.ROW)) {

entry = ticTacToeBoard[idxDirection_1][idxDirection_2];

} else { // must be column

entry = ticTacToeBoard[idxDirection_2][idxDirection_1];

}

if (entry == null) { // Unused location - No Winner here

locatedWinner = null; // reset back to Null for next row/col

break;

}

if (locatedWinner == null) {

locatedWinner = entry;

} else if (!locatedWinner.equals(entry)) {

// Multiple entries in Row or Column - No Winner here

locatedWinner = null; // reset back to Null

break;

}

}

}

return locatedWinner;

}

/**

* Report true if a winner is found

* or false if no winner detected

*/

public boolean hasWinner() {

return (theWinnerIs() != NO_WINNER);

}

/**

* Returns X or O or ? if no winner found

*/

public char theWinnerIs() {

Character theWinner = checkRowOrColumnForWinner(ROW_OR_COLUMN.ROW);

if (theWinner == null) { // If not Row Winner - try Column Winner

theWinner = checkRowOrColumnForWinner(ROW_OR_COLUMN.COLUMN);

}

// Final result

if (theWinner == null) {

theWinner = NO_WINNER;

}

return theWinner;

}

/**

* Return true if no items have been played. Return false if game has started

*/

private boolean checkFirstPlay() {

for (byte idxRow = 0; idxRow < MAX_ROWS; ++idxRow) {

for (byte idxCol = 0; idxCol < MAX_COLS; ++idxCol) {

if (ticTacToeBoard[idxRow][idxCol] != null) {

return false;

}

}

}

return true;

}

/**

* Set the entry value only if it has the default null value.

*/

private boolean setValue(int row, int column, char player) {

if (player == PLAYER_2) {

if (checkFirstPlay()) {

System.err.println(PLAYER_1 + " must start the game");

return false;

}

}

if (ticTacToeBoard[row][column] == null) {

ticTacToeBoard[row][column] = player;

theGUIBoard.setSquare(row, column, player);

return true;

}

return false;

}

/**

* Public setValue method for the human player (Overloaded)

*/

public boolean setValue(int row, int column) {

char thePlayer = PLAYER_1;

if (computerPlayer == PLAYER_1) {

thePlayer = PLAYER_2;

}

return setValue(row, column, thePlayer);

}

/**

* Private setValue for the Computer player

*/

private boolean setValueComputer(int row, int column) {

return setValue(row, column, computerPlayer);

}

/**

* Determines the best offensive or defensive move

* @param player

* @return

* Returns -1 for no options or 0-8 for spot.

*/

private int bestComputerPlacement() {

//Grab center square if available

if (ticTacToeBoard[1][1] == null) {

return 4;

}

// Init counter

WinOptions[] computerOptions = new WinOptions[8];

WinOptions[] humanOptions = new WinOptions[8];

int idx = 0;

char humanPlayer = PLAYER_1;

if (computerPlayer == PLAYER_1) {

humanPlayer = PLAYER_2;

}

idx = -1;

computerOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.ROW1, computerPlayer);

computerOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.ROW2, computerPlayer);

computerOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.ROW3, computerPlayer);

computerOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.COL1, computerPlayer);

computerOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.COL2, computerPlayer);

computerOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.COL3, computerPlayer);

computerOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.DIAG_DOWN, computerPlayer);

computerOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.DIAG_UP, computerPlayer);

idx = -1;

humanOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.ROW1, humanPlayer);

humanOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.ROW2, humanPlayer);

humanOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.ROW3, humanPlayer);

humanOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.COL1, humanPlayer);

humanOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.COL2, humanPlayer);

humanOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.COL3, humanPlayer);

humanOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.DIAG_DOWN, humanPlayer);

humanOptions[++idx] = new WinOptions(ticTacToeBoard, WinOptions.WIN_WAY.DIAG_UP, humanPlayer);

//System.out.println("PC HIGH");

for (idx = 0; idx < 8; ++idx) {

//System.out.println(idx + ":" + computerOptions[idx].getWinState() + ":" + computerOptions[idx].getPosition());

if (computerOptions[idx].getWinState().equals(WinOptions.STATE.PREFERRED)) {

return computerOptions[idx].getPosition();

}

}

//System.out.println("HUMAN HIGH");

for (idx = 0; idx < 8; ++idx) {

//System.out.println(idx + ":" + humanOptions[idx].getWinState() + ":" + computerOptions[idx].getPosition());

if (humanOptions[idx].getWinState().equals(WinOptions.STATE.PREFERRED)) {

return humanOptions[idx].getPosition();

}

}

//System.out.println("PC AVAIL");

for (idx = 0; idx < 8; ++idx) {

//System.out.println(idx + ":" + computerOptions[idx].getWinState());

if (computerOptions[idx].getWinState().equals(WinOptions.STATE.AVAILABLE)) {

return computerOptions[idx].getPosition();

}

}

//System.out.println("HUMAN AVAIL");

for (idx = 0; idx < 8; ++idx) {

//System.out.println(idx + ":" + humanOptions[idx].getWinState());

if (humanOptions[idx].getWinState().equals(WinOptions.STATE.AVAILABLE)) {

return humanOptions[idx].getPosition();

}

}

return -1;

}

/**

* Place the computer position

* @param position

* @return

*/

private boolean placement(int position) {

// determine the row and column

int row = position / MAX_ROWS;

int col = position % MAX_COLS;

if (setValueComputer(row, col)) {

System.out.println("Computer played at row " + row + " column " + col);

return true; // found and loaded

}

return false; // default

}

/**

* The computer will play now.

* It will set its mark (X or O) at an empty location.

* Based on Random results - smartPlay flag plays with intelligent mode

*

*/

public boolean theComputersTurn() {

if (smartPlay) {

int answer = bestComputerPlacement();

if (answer != -1) {

if (placement(answer)) {

return true;

} // otherwise continue and issue a random choice

}

}

final int MIN_RANGE = 0;

final int MAX_RANGE = 8;

final int RETRY_LIMIT = 15;

short count = 0;

int boxNumber = 0;

do {

++count;

// Get a Random Number - 0-8 (9 values)

boxNumber = ThreadLocalRandom.current().nextInt(MIN_RANGE, MAX_RANGE + 1);

if (placement(boxNumber)) {

return true; // found and loaded

}

} while (count < RETRY_LIMIT);

return false; // Exiting - Could not find an open spot by random process

}

}