/** * Check if the game is over or not * * @param tempBoard * @return true if game over */ public boolean isGameOver(int[] tempBoard) { // Check for player1 int pitSize = mancalaBoard.getPitSize(); int totSize = mancalaBoard.getBoardSize(); boolean flag = true; for (int i = 0; i < pitSize; i++) { if (tempBoard[i] > 0) { flag = false; break; } } // Check for player2 if (!flag) { flag = true; for (int j = pitSize + 1; j < totSize - 1; j++) { if (tempBoard[j] > 0) { flag = false; break; } } } if (!flag) return false; else return true; }
/** * Makes the move temporarily for seeing the moves ahead * * @param move * @param currPlayer * @return the board */ public int[] makeTempMove(Move move, Player currPlayer) { int moveIndex = move.getMoveIndex(); mancalaBoard.displayBoard(); int boardSize = mancalaBoard.getBoardSize(); int[] tempBoard = new int[boardSize]; int[] srcBoard = mancalaBoard.getBoard(); System.arraycopy(srcBoard, 0, tempBoard, 0, boardSize); int numOfStones = tempBoard[moveIndex]; tempBoard[moveIndex] = 0; moveIndex++; while (numOfStones > 0) { if ((moveIndex % boardSize) == mancalaBoard.getOpponentsMancala(currPlayer.playerNum)) { moveIndex++; continue; } tempBoard[(moveIndex) % boardSize]++; moveIndex++; numOfStones--; } // Just to check if we get a free turn int indexToCompare = (moveIndex - 1) % boardSize; int myMancala = mancalaBoard.getMancala(currPlayer.playerNum); if (!(indexToCompare == myMancala)) { if (tempBoard[indexToCompare] == 1) { if ((currPlayer.playerNum == 1 && indexToCompare < mancalaBoard.getPitSize()) || (currPlayer.playerNum == 2 && indexToCompare > mancalaBoard.getPitSize())) { // check opponents opp pit - 2*p - index int oppPit = (mancalaBoard.getPitSize() * 2) - indexToCompare; if (tempBoard[oppPit] > 0) { tempBoard[myMancala] += tempBoard[oppPit] + tempBoard[indexToCompare]; tempBoard[oppPit] = 0; tempBoard[indexToCompare] = 0; } } } } return tempBoard; }
/** * Make the selected move * * @param move : the move the player wants to take * @param currPlayer * @return true if after making a turn we get a free turn */ public boolean makeMove(Move move, Player currPlayer) { boolean freeTurn = false; int moveIndex = move.getMoveIndex(); int[] tempBoard = mancalaBoard.getBoard(); int boardSize = mancalaBoard.getBoardSize(); int numOfStones = tempBoard[moveIndex]; tempBoard[moveIndex] = 0; moveIndex++; while (numOfStones > 0) { if ((moveIndex % boardSize) == mancalaBoard.getOpponentsMancala(currPlayer.playerNum)) { moveIndex++; continue; } tempBoard[(moveIndex) % boardSize]++; moveIndex++; numOfStones--; } int indexToCompare = (moveIndex - 1) % boardSize; int myMancala = mancalaBoard.getMancala(currPlayer.playerNum); // Check if you get a free turn if (indexToCompare == myMancala) { freeTurn = true; System.out.println("You got a free turn with this move"); } else { // Check if you can steal the stones if (tempBoard[indexToCompare] == 1) { if ((currPlayer.playerNum == 1 && indexToCompare < mancalaBoard.getPitSize()) || (currPlayer.playerNum == 2 && indexToCompare > mancalaBoard.getPitSize())) { int oppPit = (mancalaBoard.getPitSize() * 2) - indexToCompare; if (tempBoard[oppPit] > 0) { tempBoard[myMancala] += tempBoard[oppPit] + tempBoard[indexToCompare]; tempBoard[oppPit] = 0; tempBoard[indexToCompare] = 0; } } } } mancalaBoard.setBoard(tempBoard); return freeTurn; }
/** * Generate nextMove according to greedy algorithm * * @param currPlayer * @return the move according to the greedy algorithm */ public Move getGreedyMove(Player currPlayer) { TreeMap<Integer, ArrayList<Integer>> scoreMoveMap = new TreeMap<>(); int mancalaIndex = mancalaBoard.getMancala(currPlayer.playerNum); int oppMancalaIndex = mancalaBoard.getOpponentsMancala(currPlayer.playerNum); int startIndex = 0; int endIndex = mancalaBoard.getPitSize(); if (currPlayer.playerNum == 2) { startIndex = mancalaBoard.getPitSize() + 1; endIndex = mancalaBoard.getBoardSize() - 1; } for (int i = startIndex; i < endIndex; i++) { Move currMove = new Move(i); int[] tempBoard = new int[mancalaBoard.getBoardSize()]; tempBoard = makeTempMove(currMove, currPlayer); int numToInc = tempBoard[mancalaIndex]; ArrayList<Integer> possibleMoves = new ArrayList<Integer>(); if (scoreMoveMap.containsKey(numToInc)) { possibleMoves = (ArrayList<Integer>) scoreMoveMap.get(numToInc); } possibleMoves.add(i); scoreMoveMap.put(numToInc, possibleMoves); } int highestEvalVal = scoreMoveMap.lastKey(); List<Integer> highestMoves = scoreMoveMap.get(highestEvalVal); Move finalMove = new Move(highestMoves.remove(0)); while (isIllegalMove(finalMove)) { finalMove = new Move(highestMoves.remove(0)); } return finalMove; }
/** * Convert the index entered to a move * * @param pitNum - The pit number * @param currPlayer * @return the move */ public Move convertIndexToMove(int pitNum, Player currPlayer) { Move move; int sizeOfBoard = mancalaBoard.getPitSize(); if (currPlayer.playerNum == 1) { // Move according to player1 move = new Move(pitNum - 1); } else { // Move according to player2 move = new Move(sizeOfBoard + pitNum); } return move; }
/** * Steal all the stones * * @param tempBoard * @return the board after stealing */ public int[] getAllStones(int[] tempBoard) { int pitSize = mancalaBoard.getPitSize(); int totSize = mancalaBoard.getBoardSize(); for (int i = 0; i < pitSize; i++) { tempBoard[pitSize] += tempBoard[i]; tempBoard[i] = 0; } for (int j = pitSize + 1; j < totSize - 1; j++) { tempBoard[totSize - 1] += tempBoard[j]; tempBoard[j] = 0; } return tempBoard; }
/** * Gives the number of mancala stones for a move * * @param currMove * @param mancalaIndex * @return the number of stones */ public int checkMove(Move currMove, int mancalaIndex) { int moveIndex = currMove.getMoveIndex(); int distFromMancala = mancalaIndex - moveIndex; System.out.println("mancala is at: " + mancalaIndex); System.out.println("dis from mancala: " + distFromMancala); int[] tempBoard = mancalaBoard.getBoard(); int numOfStones = tempBoard[moveIndex]; System.out.println("num of stones: " + numOfStones + " for move: " + moveIndex); if (numOfStones < distFromMancala) { return 0; } else { return (1 + ((numOfStones - distFromMancala) / (2 * mancalaBoard.getPitSize() + 1))); } }
/** Playing the game */ public void playGame() { Player currPlayer = player1; int numOfTotalMoveplayer1 = 0; int numOfTotalMoveplayer2 = 0; while (true) { // System.out.println(); /*System.out.println(); System.out.println("##################################"); System.out.println("Current Player is player " + currPlayer.playerNum); System.out.println(); System.out.println(); System.out.println("################################"); System.out.println(" TURN CHANGED"); System.out.println("################################"); */ // Find the nextMove Move nextMove; if (!currPlayer.isHuman) { nextMove = getCompMove(mancalaBoard.getPitSize(), searchType, currPlayer); } else { nextMove = getHumanMove(mancalaBoard.getPitSize(), currPlayer); } // Play the move boolean gotFreeTurn = makeMove(nextMove, currPlayer); if (currPlayer.equals(player1)) { numOfTotalMoveplayer1++; } else { numOfTotalMoveplayer2++; } // Check for game over if (isGameOver(mancalaBoard.getBoard())) { mancalaBoard.setBoard(getAllStones(mancalaBoard.getBoard())); if (isGameDrawn()) { System.out.println("No winner : Game draw"); } else { int winner = findWinner(); System.out.println("Game over. Player " + winner + " won."); System.out.println("Scores are"); System.out.println("Player 1: " + getScore(player1)); System.out.println("Player 2: " + getScore(player2)); } System.out.println("Player1 took : " + numOfTotalMoveplayer1 + "moves"); System.out.println("Player2 took : " + numOfTotalMoveplayer2 + "moves"); break; } // Toggle the turn if no free turn if (!gotFreeTurn) { if (currPlayer.equals(player1)) { currPlayer = player2; } else { currPlayer = player1; } } } }
public BoardFTCheck makeTempMiniMaxMove(Move move, Player currPlayer, int[] srcBoard) { int moveIndex = move.getMoveIndex(); int boardSize = mancalaBoard.getBoardSize(); int[] tempBoard = new int[boardSize]; System.arraycopy(srcBoard, 0, tempBoard, 0, boardSize); int numOfStones = tempBoard[moveIndex]; tempBoard[moveIndex] = 0; moveIndex++; while (numOfStones > 0) { if ((moveIndex % boardSize) == mancalaBoard.getOpponentsMancala(currPlayer.playerNum)) { moveIndex++; continue; } tempBoard[(moveIndex) % boardSize]++; moveIndex++; numOfStones--; } // if just to check if we get a free turn int indexToCompare = (moveIndex - 1) % boardSize; // System.out.println("indexTocomp : " + indexToCompare); int myMancala = mancalaBoard.getMancala(currPlayer.playerNum); boolean freeTurn = false; // if just to check if we get a free turn if (indexToCompare == myMancala) { freeTurn = true; System.out.println("Yayyyyii , I got a free turn"); } else { if (tempBoard[indexToCompare] == 1) { if ((currPlayer.playerNum == 1 && indexToCompare < mancalaBoard.getPitSize()) || (currPlayer.playerNum == 2 && indexToCompare > mancalaBoard.getPitSize())) { // check opponents opp pit - 2*p - index int oppPit = (mancalaBoard.getPitSize() * 2) - indexToCompare; if (tempBoard[oppPit] > 0) { tempBoard[myMancala] += tempBoard[oppPit] + tempBoard[indexToCompare]; tempBoard[oppPit] = 0; tempBoard[indexToCompare] = 0; } } } } // System.out.println("tempBoard in make temp move: " + tempBoard.toString()); // if the game is over we need to evaluate the function boolean gameOver = false; if (isGameOver(tempBoard)) { tempBoard = getAllStones(tempBoard); gameOver = true; } System.out.println(); BoardFTCheck bft = new BoardFTCheck(tempBoard, freeTurn, gameOver); return bft; }
public MiniMaxTree miniMaxHelperWithGO2( MiniMaxTree gameTree, MiniMaxNode rootNode, Player currPlayer, int[] tempBoard, int tempDepth, int globalDepth, boolean checkParentsFt) { System.out.println(); // System.out.println("In miniMaxHelperWithGO2 "); // TODO : CHECK THE DEPTH if (tempDepth >= globalDepth && !checkParentsFt) { return gameTree; } MiniMaxNode currParent = rootNode; if (!checkParentsFt) { if (currPlayer.equals(player1)) { currPlayer = player2; } else { currPlayer = player1; } } int startIndex = 0; int endIndex = mancalaBoard.getPitSize(); if (currPlayer.playerNum == 2) { startIndex = mancalaBoard.getPitSize() + 1; endIndex = mancalaBoard.getBoardSize() - 1; } // boolean checkParentsFt = false; int i = startIndex; for (i = startIndex; i < endIndex; i++) { Move currMove = new Move(i); if (isIllegalMove(currMove, tempBoard)) { continue; } else { BoardFTCheck bft = makeTempMiniMaxMoveWithGO2(currMove, currPlayer, tempBoard); int mydepth = currParent.depth; if (mydepth == 0) { mydepth++; } if (!checkParentsFt) { mydepth++; } int evalFunc; // Odds are minimizers if (mydepth % 2 == 1) { evalFunc = Integer.MAX_VALUE; } else { evalFunc = Integer.MIN_VALUE; } // if we reached the leaf find the evaluation right away if (mydepth == globalDepth || bft.leadsToGameOver) { displayHelper(bft.tempBoard); // If I dont get a free turn at last level then only evaluate if (!bft.freeTurn) { evalFunc = getEvalFunc(currPlayer, bft.tempBoard); } else { // last level is already toggled if (evalFunc == Integer.MAX_VALUE) { evalFunc = Integer.MIN_VALUE; } else { evalFunc = Integer.MAX_VALUE; } } } MiniMaxNode newNode = new MiniMaxNode( bft.tempBoard, currPlayer.playerNum, mydepth, evalFunc, currParent, currMove, bft.freeTurn); // displayHelper(bft.tempBoard); /*System.out.println("Node to insert is "); displayHelper(newNode.nodeBoard); System.out.println("£££££££££££££££££££££££££££"); System.out.println("In insert tree"); System.out.println("£££££££££££££££££££££££££££");*/ gameTree.insert(newNode, currParent); // gameTree.displayTree(); /*System.out.println("return from insert tree"); System.out.println();*/ if (bft.freeTurn) { miniMaxHelperWithGO2( gameTree, newNode, currPlayer, bft.tempBoard, mydepth, globalDepth, true); } else { miniMaxHelperWithGO2( gameTree, newNode, currPlayer, bft.tempBoard, mydepth, globalDepth, false); } } } return gameTree; }