Skip to content

Instantly share code, notes, and snippets.

@luyao795
Created August 25, 2017 03:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luyao795/6ca43b5334a4307717040d1f219d76a0 to your computer and use it in GitHub Desktop.
Save luyao795/6ca43b5334a4307717040d1f219d76a0 to your computer and use it in GitHub Desktop.
This class defines variable depth AI behavior by using MiniMax with Alpha-Beta Pruning.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class MoveStatus {
public int row, col;
public int score;
public MoveStatus(int Row, int Col, int Score)
{
row = Row;
col = Col;
score = Score;
}
}
public class AIReversi {
public GameController gameController = new GameController ();
public int[,] evalFun = {
{ 30, -25, 10, 5, 5, 10, -25, 30 },
{ -25, -25, 1, 1, 1, 1, -25, -25 },
{ 10, 1, 5, 2, 2, 5, 1, 10 },
{ 5, 1, 2, 1, 1, 2, 1, 5 },
{ 5, 1, 2, 1, 1, 2, 1, 5 },
{ 10, 1, 5, 2, 2, 5, 1, 10 },
{ -25, -25, 1, 1, 1, 1, -25, -25 },
{ 30, -25, 10, 5, 5, 10, -25, 30 }
};
// evaluate the board
public int EvaluateBoard(int[,] board, int color)
{
List<Vector2> playerMoves = gameController.MoveList (board, 1);
List<Vector2> AIMoves = gameController.MoveList (board, 2);
int playerScore = 0;
int AIScore = 0;
foreach (Vector2 move in playerMoves) {
playerScore += evalFun [(int)move.x, (int)move.y];
}
foreach (Vector2 move in AIMoves) {
AIScore += evalFun [(int)move.x, (int)move.y];
}
//int playerPieces = gameController.CountPieces (board, 1);
//int AIPieces = gameController.CountPieces (board, 2);
int result = 0;
if (color == 1) {
result = playerScore - AIScore;
}
if (color == 2) {
result = AIScore - playerScore;
}
return result;
}
// Minimax algorithm without alpha-beta pruning
public MoveStatus MiniMax(int[,] board, int color, int maxDepth, int currentDepth)
{
if (gameController.IsGameOver () || currentDepth == maxDepth) {
return new MoveStatus (-1, -1, EvaluateBoard (board, color));
}
MoveStatus ms = new MoveStatus (-1, -1, 0);
if (color == 2) {
ms.score = int.MinValue;
} else
ms.score = int.MaxValue;
List<Vector2> allNextMoves;
// this is the AI turn right now
if (color == 2) {
allNextMoves = gameController.MoveList (board, 2);
foreach (Vector2 move in allNextMoves) {
int[,] newBoard = gameController.GetNextBoard (board, 2, (int)move.x, (int)move.y);
int score = MiniMax (newBoard, 1, maxDepth, currentDepth + 1).score;
if (score > ms.score) {
ms.row = (int)move.x;
ms.col = (int)move.y;
ms.score = score;
}
}
// this is the human turn right now
} else {
allNextMoves = gameController.MoveList (board, 1);
foreach (Vector2 move in allNextMoves) {
int[,] newBoard = gameController.GetNextBoard (board, 1, (int)move.x, (int)move.y);
int score = MiniMax (newBoard, 2, maxDepth, currentDepth + 1).score;
if (score < ms.score) {
ms.row = (int)move.x;
ms.col = (int)move.y;
ms.score = score;
}
}
}
return ms;
}
// Minimax algorithm with alpha-beta pruning
public MoveStatus MiniMaxAlphaBeta(int[,] board, int color, int maxDepth, int currentDepth, int alpha, int beta)
{
if (gameController.IsGameOver () || currentDepth == maxDepth) {
return new MoveStatus (-1, -1, EvaluateBoard (board, color));
}
MoveStatus ms = new MoveStatus (-1, -1, 0);
if (color == 2) {
ms.score = int.MinValue;
} else
ms.score = int.MaxValue;
List<Vector2> allNextMoves;
// this is the AI turn right now
if (color == 2) {
allNextMoves = gameController.MoveList (board, 2);
foreach (Vector2 move in allNextMoves) {
int[,] newBoard = gameController.GetNextBoard (board, 2, (int)move.x, (int)move.y);
int score = MiniMaxAlphaBeta (newBoard, 1, maxDepth, currentDepth + 1, alpha, beta).score;
if (score > ms.score) {
ms.row = (int)move.x;
ms.col = (int)move.y;
ms.score = score;
if (ms.score > alpha)
alpha = ms.score;
if (alpha >= beta)
break;
}
}
// this is the human turn right now
} else {
allNextMoves = gameController.MoveList (board, 1);
foreach (Vector2 move in allNextMoves) {
int[,] newBoard = gameController.GetNextBoard (board, 1, (int)move.x, (int)move.y);
int score = MiniMaxAlphaBeta (newBoard, 2, maxDepth, currentDepth + 1, alpha, beta).score;
if (score < ms.score) {
ms.row = (int)move.x;
ms.col = (int)move.y;
ms.score = score;
if (ms.score < beta)
beta = ms.score;
if (beta <= alpha)
break;
}
}
}
return ms;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment