bool isGameOver() { bool moveFound = true; for (int j = 0; j <= BOARD_SIZE; j++) { for (int i = 0; i <= BOARD_SIZE; i++) { DirectionalPieces dPiece = isValidMove(i, j, PieceColor.Black, board); if (dPiece.down || dPiece.left || dPiece.up || dPiece.right || dPiece.leftDown || dPiece.leftUp || dPiece.rightDown || dPiece.rightUp) { moveFound = false; Instantiate(dummyPiece, new Vector3(i, 1, j), Quaternion.identity); } } } return(moveFound); }
void getClick(float x, float y) { int newX = Mathf.RoundToInt(x); int newY = Mathf.RoundToInt(y); DirectionalPieces dPiece = isValidMove(newX, newY, PieceColor.Black, board); if (dPiece.down || dPiece.left || dPiece.up || dPiece.right || dPiece.leftDown || dPiece.leftUp || dPiece.rightDown || dPiece.rightUp) { currentTurn = turn.AI; Vector3 spawnPos = new Vector3(newX, 1, newY); boardObjects[newX, newY] = (GameObject)Instantiate(blackPiece, spawnPos, Quaternion.identity); board[newX, newY] = PieceColor.Black; blackScore++; doFlips(newX, newY, PieceColor.Black, dPiece); currentTurnText.text = "Current Turn: AI Turn (White)"; //print(AIDiff); //if (AIDiff <= 4) { StartCoroutine("enemyMove"); //} //doEnemyMove(); } }
public move miniMaxBetter(PieceColor [,] currentBoard, int depth, bool maximizingPlayer, int alpha, int beta, int i2, int j2) { //bool breaking = false; //print(depth); if (depth == 0 && maximizingPlayer) { move endMove; //endMove.value = boardPoints[i2, j2]; endMove.value = 0; endMove.i = i2; endMove.j = j2; endMove.points = 0; return(endMove); } if (depth == 0 && !maximizingPlayer) { move endMove; //endMove.value = boardPoints[i2, j2]; endMove.value = 0; endMove.i = i2; endMove.j = j2; endMove.points = 0; return(endMove); } //White Player if (maximizingPlayer) { move bestMove; bestMove.value = -99999; bestMove.i = -1; bestMove.j = -1; bestMove.points = -1; for (int j = 0; j <= BOARD_SIZE; j++) { for (int i = 0; i <= BOARD_SIZE; i++) { DirectionalPieces dPiece = gmScript.isValidMove(i, j, PieceColor.White, currentBoard); if (dPiece.down || dPiece.left || dPiece.up || dPiece.right || dPiece.leftDown || dPiece.leftUp || dPiece.rightDown || dPiece.rightUp) { currentBoard[i, j] = PieceColor.White; move currentMove = miniMaxBetter(currentBoard, depth - 1, false, alpha, beta, i, j); currentMove.value += boardPoints[i, j]; currentMove.points += dPiece.points; if (currentMove.value > bestMove.value) { bestMove.value = currentMove.value; bestMove.i = i; bestMove.j = j; bestMove.points = currentMove.points; } else if (currentMove.value == bestMove.value) { if (currentMove.points > bestMove.points) { bestMove.value = currentMove.value; bestMove.i = i; bestMove.j = j; bestMove.points = currentMove.points; } } else { //currentMove.value -= boardPoints[i, j]; } //undo our moves as we get out of them currentBoard[i, j] = PieceColor.Null; //alpha beta pruning alpha = Mathf.Max(alpha, bestMove.value); if (beta <= alpha) { return(bestMove); //breaking = true; //for double for loop //break; } } } //if (breaking) break; //double for loop } return(bestMove); } //end of if statement //player's turn else { move bestMove; bestMove.value = 99999; bestMove.i = -1; bestMove.j = -1; bestMove.points = -1; for (int j = 0; j <= BOARD_SIZE; j++) { for (int i = 0; i <= BOARD_SIZE; i++) { DirectionalPieces dPiece = gmScript.isValidMove(i, j, PieceColor.Black, currentBoard); if (dPiece.down || dPiece.left || dPiece.up || dPiece.right || dPiece.leftDown || dPiece.leftUp || dPiece.rightDown || dPiece.rightUp) { currentBoard[i, j] = PieceColor.Black; move currentMove = miniMaxBetter(currentBoard, depth - 1, true, alpha, beta, i, j); currentMove.value -= boardPoints[i, j]; currentMove.points -= dPiece.points; if (currentMove.value < bestMove.value) { bestMove.value = currentMove.value; bestMove.i = i; bestMove.j = j; bestMove.points = currentMove.points; } else if (currentMove.value == bestMove.value) { if (currentMove.points < bestMove.points) { bestMove.value = currentMove.value; bestMove.i = i; bestMove.j = j; bestMove.points = currentMove.points; } } else { //currentMove.value += boardPoints[i, j]; } currentBoard[i, j] = PieceColor.Null; //alpha beta pruning beta = Mathf.Min(beta, bestMove.value); if (beta <= alpha) { return(bestMove); //breaking = true; //for double for loop //break; } } } //if (breaking) break; } return(bestMove); } //end of else } //end of minimaxbetter
void doFlips(int x, int y, PieceColor thisColor, DirectionalPieces dPieces) { PieceColor otherColor = PieceColor.Null; if (thisColor == PieceColor.Black) { otherColor = PieceColor.White; } if (thisColor == PieceColor.White) { otherColor = PieceColor.Black; } if (otherColor == PieceColor.Null) { print("ERROR"); } if (dPieces.up) { for (int i = x - 1; i >= 0; i--) { if (board[i, y] == thisColor || board[i, y] == PieceColor.Null) { break; } else { board[i, y] = boardObjects[i, y].GetComponentInChildren <PieceScript>().Flip(); } } } if (dPieces.down) { for (int i = x + 1; i <= BOARD_SIZE; i++) { if (board[i, y] == thisColor || board[i, y] == PieceColor.Null) { break; } else { board[i, y] = boardObjects[i, y].GetComponentInChildren <PieceScript>().Flip(); } } } if (dPieces.left) { for (int i = y - 1; i > 0; i--) { if (board[x, i] == thisColor || board[x, i] == PieceColor.Null) { break; } else { board[x, i] = boardObjects[x, i].GetComponentInChildren <PieceScript>().Flip(); } } } if (dPieces.right) { for (int i = y + 1; i <= BOARD_SIZE; i++) { if (board[x, i] == thisColor || board[x, i] == PieceColor.Null) { break; } else { board[x, i] = boardObjects[x, i].GetComponentInChildren <PieceScript>().Flip(); } } } if (dPieces.leftUp) { int i = x - 1; int j = y - 1; while (i >= 0 && j >= 0) { if (board[i, j] == thisColor || board[i, j] == PieceColor.Null) { break; } else { board[i, j] = boardObjects[i, j].GetComponentInChildren <PieceScript>().Flip(); } i--; j--; } } if (dPieces.rightDown) { int i = x + 1; int j = y + 1; while (i != BOARD_SIZE && j != BOARD_SIZE) { if (board[i, j] == thisColor || board[i, j] == PieceColor.Null) { break; } else { board[i, j] = boardObjects[i, j].GetComponentInChildren <PieceScript>().Flip(); } i++; j++; } } if (dPieces.rightUp) { int i = x - 1; int j = y + 1; while (i >= 0 && j != BOARD_SIZE) { if (board[i, j] == thisColor || board[i, j] == PieceColor.Null) { break; } else { board[i, j] = boardObjects[i, j].GetComponentInChildren <PieceScript>().Flip(); } i--; j++; } } if (dPieces.leftDown) { int i = x + 1; int j = y - 1; while (i != BOARD_SIZE && j >= 0) { if (board[i, j] == thisColor || board[i, j] == PieceColor.Null) { break; } else { board[i, j] = boardObjects[i, j].GetComponentInChildren <PieceScript>().Flip(); } i++; j--; } } }
void doEnemyMove() { //completely random /*for (int j = 0; j <= BOARD_SIZE; j++) { * for (int i = 0; i <= BOARD_SIZE; i++) { * DirectionalPieces dPiece = isValidMove(i, j, PieceColor.White, board); * if (dPiece.down || dPiece.left || dPiece.up || dPiece.right || dPiece.leftDown || dPiece.leftUp || dPiece.rightDown || dPiece.rightUp) { * boardObjects[i, j] = (GameObject) Instantiate(whitePiece, new Vector3(i, 1, j), Quaternion.identity); * board[i,j] = PieceColor.White; * whiteScore ++; * doFlips(i, j, PieceColor.White, dPiece); * foundMove = true; * break; * } * } * if (foundMove) break; * }*/ //move bestMove = AIscript.miniMax(board, 1, true, -99999, 99999, 0, 0); //1 means 1 level of depth, no smarts //2 means 1 level of depth, smarts //10 is 5 level of depth, smarts move bestMove; if (AIDiff % 2 == 0) { bestMove = AIscript.miniMaxBetter(board, Mathf.CeilToInt(AIDiff / 2.0F), true, -99999, 99999, 0, 0); } else { bestMove = AIscript.miniMax(board, Mathf.CeilToInt(AIDiff / 2.0F), true, -99999, 99999, 0, 0); } //first move: //6 takes 7 seconds //7 takes 22 seconds //8 takes 58 seconds //9 takes 2 minute 58 seconds if (bestMove.i != -1 && bestMove.j != -1) { //I know it's valid, but I need to know which way to flip... sorry. print(bestMove.value); DirectionalPieces dPiece = isValidMove(bestMove.i, bestMove.j, PieceColor.White, board); boardObjects[bestMove.i, bestMove.j] = (GameObject)Instantiate(whitePiece, new Vector3(bestMove.i, 1, bestMove.j), Quaternion.identity); board[bestMove.i, bestMove.j] = PieceColor.White; whiteScore++; doFlips(bestMove.i, bestMove.j, PieceColor.White, dPiece); currentTurn = turn.player; currentTurnText.text = "Current Turn: Your Turn (Black)"; if (isGameOver()) { print("PLAYER CAN'T MOVE!"); endGame(); } } else { print(bestMove.value + ", " + bestMove.i + ", " + bestMove.j); print("GAME OVER I CAN'T MOVE"); endGame(); } }