+1 (315) 557-6473 

Program To Build a Nim and Tic Tac Toe Game Using Java Programming Language Assignment Solution.


Instructions

Objective
Write a program to build a Nim and tic tac toe game using Java programming language.

Requirements and Specifications

Create a game build based on tic tac toe and Nim game
Use methods, classes and functions for this program
The game should work on a single run basis
Source Code
TIC TAC TOE
package game;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
class TicTacToe5 implements Game {
 private static final int EMPTY = 4;
 private static final String COMPUTER_SYMBOL = "O";
 private static final String HUMAN_SYMBOL = "X";
 private int[][] board = new int[3][3];
 private Map<Position, Integer> store = new HashMap<>();
 private int nextPlayer;
 private Scanner scanner;
 /**
  * Construct an instance of the TicTacToe Game
  */
 public TicTacToe5(Scanner scanner) {
  if (scanner == null) {
   throw new IllegalArgumentException("Scanner must not be null");
  }
  this.scanner = scanner;
 }
 @Override
 public void init() {
  clearBoard();
  nextPlayer = COMPUTER;
 }
 @Override
 public int winner() {
  return positionValue();
 }
 @Override
 public int nextPlayer() {
  return nextPlayer;
 }
 @Override
 public String[] askHumanMove() {
  String[] params = new String[2];
  System.out.println("row: ");
  params[0] = scanner.nextLine();
  System.out.println("col: ");
  params[1] = scanner.nextLine();
  return params;
 }
 // Find optimal move
 @Override
 public Best chooseMove(int side) {
  return chooseMove(side, -4);
 }
 // Play move, including checking legality
 @Override
 public boolean makeMove(int side, int row, int column) {
  if (row < 0 || row >= 3 || column < 0 || column >= 3 || board[row][column] != EMPTY)
   return false;
  board[row][column] = side;
  nextPlayer = 2 - nextPlayer;
  return true;
 }
 @Override
 public String position() {
  StringBuilder boardStr = new StringBuilder();
  for (int row = 0; row < 3; row++) {
   for (int col = 0; col < 3; col++) {
    String spot;
    switch (board[row][col]) {
     case HUMAN:
      spot = " " + HUMAN_SYMBOL + " ";
      break;
     case COMPUTER:
      spot = " " + COMPUTER_SYMBOL + " ";
      break;
     case EMPTY:
      spot = " ";
      break;
     default:
      throw new IllegalArgumentException();
    }
    boardStr.append(spot);
    if (col < 2)
     boardStr.append("|");
   }
   if (row < 2)
    boardStr.append("\n-----------\n");
  }
  return boardStr.toString();
 }
 private Best chooseMove(int side, int depth) {
  int opp; // The other side
  Best reply; // Opponent's best reply
  int simpleEval; // Result of an immediate evaluation
  int bestRow = -1; // Initialize running value with out-of-range value
  int bestColumn = -1;
  int value;
  Position thisPosition = new Position(board);
  if ((simpleEval = positionValue()) != UNCLEAR)
   return new Best(simpleEval);
  // Don't look up top-level value: can't use it (already used for last move)
  if (depth > 0) {
   Integer lookupVal = store.get(thisPosition);
   if (lookupVal != null)
    return new Best(lookupVal);
  }
  // Initialize running values with out-of-range values (good software practice)
  // Here also to ensure that *some* move is chosen, even if a hopeless case
  if (side == COMPUTER) {
   opp = HUMAN;
   value = HUMAN - 1; // impossibly low value
  } else {
   opp = COMPUTER;
   value = COMPUTER + 1; // impossibly high value
  }
  for (int row = 0; row < 3; row++)
   for (int column = 0; column < 3; column++)
    if (squareIsEmpty(row, column)) {
     place(row, column, side);
     reply = chooseMove(opp, depth+1);
     place(row, column, EMPTY);
     // Update if side gets better position
     if (side == COMPUTER && reply.val > value || side == HUMAN && reply.val < value) {
      value = reply.val;
      bestRow = row;
      bestColumn = column;
     }
    }
  store.put(thisPosition, value);
  return new Best(value, bestRow, bestColumn);
 }
 // Simple supporting routines
 private void clearBoard() {
  for (int i = 0; i < 3; i++)
   for (int j = 0; j < 3; j++)
    board[i][j] = EMPTY;
 }
 private boolean boardIsFull() {
  for (int row = 0; row < 3; row++)
   for (int column = 0; column < 3; column++)
    if (board[row][column] == EMPTY)
     return false;
  return true;
 }
 private boolean isAWin(int side) {
  int row, column;
  /* Look for all in a row */
  for (row = 0; row < 3; row++) {
   for (column = 0; column < 3; column++)
    if (board[row][column] != side)
     break;
   if (column >= 3)
    return true;
  }
  /* Look for all in a column */
  for (column = 0; column < 3; column++) {
   for (row = 0; row < 3; row++)
    if (board[row][column] != side)
     break;
   if (row >= 3)
    return true;
  }
  /* Look on diagonals */
  if (board[1][1] == side && board[2][2] == side && board[0][0] == side)
   return true;
  return board[0][2] == side && board[1][1] == side && board[2][0] == side;
 }
 // Play a move, possibly clearing a square
 private void place(int row, int column, int piece) {
  board[row][column] = piece;
 }
 private boolean squareIsEmpty(int row, int column) {
  return board[row][column] == EMPTY;
 }
 // Compute static value of current position (win, draw, etc.)
 private int positionValue() {
  return isAWin(COMPUTER) ? COMPUTER : isAWin(HUMAN) ? HUMAN : boardIsFull() ? DRAW : UNCLEAR;
 }
 final static class Position {
  private int[][] board;
  public Position(int[][] theBoard) {
   board = new int[3][3];
   for (int i = 0; i < 3; i++)
    System.arraycopy(theBoard[i], 0, board[i], 0, 3);
  }
  public boolean equals(Object rhs) {
   if (!(rhs instanceof Position))
    return false;
   for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
     if (board[i][j] != ((Position) rhs).board[i][j])
      return false;
   return true;
  }
  public int hashCode() {
   int hashVal = 0;
   for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
     hashVal = hashVal * 4 + board[i][j];
   return hashVal;
  }
 }
}
NIM
package game;
import java.util.Scanner;
public class Nim5 implements Game{
    private final static int NUM_ROWS = 3;
    private final static int SZ_ROW0 = 5;
    private final static int SZ_ROW1 = 3;
    private final static int SZ_ROW2 = 1;
    // These fields represent the actual position at any time.
    private int[] heap = new int[NUM_ROWS];
    private int nextPlayer;
    private Scanner scanner;
    /**
     * Construct an instance of the Nim Game
     */
    public Nim5(Scanner scanner) {
        if (scanner == null) {
            throw new IllegalArgumentException("Scanner must not be null");
        }
        this.scanner = scanner;
    }
    /**
     * Set up the position ready to play.
     */
    @Override
    public void init() {
        heap[0] = SZ_ROW0;
        heap[1] = SZ_ROW1;
        heap[2] = SZ_ROW2;
        nextPlayer = COMPUTER;
    }
    /**
     * Who has won the game? Returns one of HUMAN, COMPUTER, UNCLEAR
     *
     * @return the winner.
     */
    @Override
    public int winner() {
        if (nextPlayer == HUMAN && getStarsLeft() == 0) {
            return COMPUTER;
        }
        if (nextPlayer == COMPUTER && getStarsLeft() == 0) {
            return HUMAN;
        }
        return UNCLEAR;
    }
    @Override
    public int nextPlayer() {
        return nextPlayer;
    }
    @Override
    public String[] askHumanMove() {
        String[] params = new String[2];
        System.out.println("row: ");
        params[0] = scanner.nextLine();
        System.out.println("stars: ");
        params[1] = scanner.nextLine();
        return params;
    }
    /**
     * Make a move
     *
     * @param side of player making move
     * @param row to take stars from
     * @param number of stars taken.
     * @return false if move is illegal.
     */
    @Override
    public boolean makeMove(int side, int row, int number) {
        if (side != nextPlayer) {
            return false; // wrong player played
        }
        if (!isLegal(row, number)) {
            return false;
        } else {
            nextPlayer = 2 - nextPlayer;
            heap[row] = heap[row] - number;
        }
        return true;
    }
    @Override
    public Best chooseMove(int side) {
        Best best = null;
        for (int i = 0; i < NUM_ROWS; i++) {
            for (int j = 1; j <= heap[i]; j++) {
                heap[i] -= j;
                nextPlayer = 2 - side;
    int winner = winner();
                if (winner != UNCLEAR) {
                    heap[i] += j;
                    nextPlayer = side;
                    if (best == null) {
                        best = new Best(winner, i, j);
                    }
                    if (winner == side) {
                        return new Best(winner, i, j);
                    }
                } else {
                    Best stepBest = chooseMove(2 - side);
                    heap[i] += j;
                    nextPlayer = side;
                    if (side == stepBest.val) {
                        return new Best(side, i, j);
                    }
                    best = stepBest;
                }
            }
        }
        return best;
    }
    /**
     * This method displays current position
     */
    @Override
    public String position() {
        StringBuilder board = new StringBuilder();
        for (int i = 0; i < NUM_ROWS; i++) {
            char c = (char) ((int) 'A' + i);
            board.append(c).append(": ");
            for (int j = heap[i]; j > 0; j--) {
                board.append("* ");
            }
            board.append('\n');
        }
        return board.toString();
    }
    /**
     * Compute the total number of stars left.
     */
    private int getStarsLeft() {
        return (heap[0] + heap[1] + heap[2]);
    }
    private boolean isLegal(int row, int stars) {
        return 0 <= row && row <= 2 && stars >= 1 && stars <= heap[row];
    }
}