public int MiniMax(GameState gs, int depth, Boolean maxPlayer) { //base case if (depth == 0 || gs.GetState().Equals(GameState.State.terminal)) { return FindHeuristicValue(gs); } if(maxPlayer) { int bestValue = MIN_VALUE; foreach(GameState child in gs.GetChildren()) { int value = MiniMax(child, depth - 1, false); if (value.CompareTo(bestValue) > 0) { gs.SetHeuristicValue(value); bestValue = value; } } return bestValue; } else { int bestValue = MAX_VALUE; foreach (GameState child in gs.GetChildren()) { int value = MiniMax(child, depth - 1, true); if(value.CompareTo(bestValue) < 0) { gs.SetHeuristicValue(value); bestValue = value; } } return bestValue; } }
public int FindHeuristicValue(GameState gs) { int value = 0; //The count of connectCells a cell contains int bestCount = 0; int connectR = Board.GetConnectR(); if(gs.GetState().Equals(GameState.State.terminal)) { return gs.GetHeuristicValue(); } //if true it is maxPlayers turn and the board needs to be evaluate to minimize min's score if(gs.isMaxPlayer()) { //check if max can make a killer move foreach(Cell cell in gs.GetBoard().getPlayerCells(gs.GetPlayer())) { if(cell.isTerminal() > 0) { value = MAX_VALUE; return value; } } //check if it is impossible to prevent min from winning if(gs.GetCell().isTerminal() > 1) { value = MIN_VALUE; return value; } //check if min can make a killer move foreach (Cell cell in gs.GetBoard().getPlayerCells(gs.GetPlayer().getOpponent())) { if (cell.isTerminal() == 1) { value = MIN_VALUE / 2; return value; } } //last resort - find the move that gives the most possibilites for connect 4 foreach(Cell cell in gs.GetBoard().getPlayerCells(gs.GetPlayer())) { int count = 0; foreach(KeyValuePair<int, HashSet<Cell>> c in cell.GetObservers()) { count = count + c.Value.Count; } foreach(KeyValuePair<int, List<Cell>> k in cell.GetConnectedCells()) { count = count + k.Value.Count; } if(count > bestCount) { bestCount = count; } } value = bestCount; return value; } //It is not max's turn else { //check if min can make a killer move foreach (Cell cell in gs.GetBoard().getPlayerCells(gs.GetPlayer().getOpponent())) { if (cell.isTerminal() > 0) { value = MIN_VALUE; return value; } } //check if it is impossible to prevent max from winning if (gs.GetCell().isTerminal() > 1) { value = MAX_VALUE; return value; } //check if max can make a killer move foreach (Cell cell in gs.GetBoard().getPlayerCells(gs.GetPlayer())) { if (cell.isTerminal() == 1) { value = MAX_VALUE / 2; return value; } } } //last resort - find the move that gives the most possibilites for connect 4 foreach (Cell cell in gs.GetBoard().getPlayerCells(gs.GetPlayer().getOpponent())) { int count = 0; foreach (KeyValuePair<int, HashSet<Cell>> c in cell.GetObservers()) { count = count + c.Value.Count; } foreach (KeyValuePair<int, List<Cell>> k in cell.GetConnectedCells()) { count = count + k.Value.Count; } if (count > bestCount) { bestCount = count; } } value = bestCount; return value; }
public void GenerateStates(GameState gs, int depth, Boolean maxPlayer) { if(depth == 0 || gs.GetState().Equals(GameState.State.terminal)) { return; } gs.FindChildrenStates(maxPlayer); foreach(GameState child in gs.GetChildren()) { if (maxPlayer) { GenerateStates(child, depth - 1, false); } else GenerateStates(child, depth - 1, true); } }