// Executes a move to the board private void ExecuteMove(Move move) { if (move.isjump) board[move.xfrom, move.yfrom] = 0; board[move.xto, move.yto] = aicode; board.Convert(move.xto, move.yto, aicode, othercode); }
// Makes the AI choose and execute a move public override void MakeMove() { Move bestMove; // Find a list of moves that make the most conversions List<Move> bestOffensiveMoves = FindBestOffensiveMoves(aicode); if (bestOffensiveMoves.Count == 0) return; // If there are more than one best moves, find the most defensive one if (bestOffensiveMoves.Count > 1) { List<Move> bestDefensiveMoves = FindBestDefensiveMoves(bestOffensiveMoves); // Take a random move from final list bestMove = bestDefensiveMoves[(new Random()).Next(bestDefensiveMoves.Count)]; } else bestMove = bestOffensiveMoves[0]; // If no great gain is made, block enemy's best move if (bestMove.gain == 1 && !bestMove.isjump) { List<Move> bestEnemyMoves = FindBestOffensiveMoves(othercode); foreach (Move m in bestEnemyMoves) { if (m.gain >= 1 && m.isjump) bestMove = new Move(0, 0, m.xto, m.yto, false, 1); } } ExecuteMove(bestMove); }
private void BuildTree(int level, Node current, int code) { // If looked enough into the future or hit a terminal state, calculate value // and return if (level == MAXDEPTH || current.state.GameOver) { int thisCount = current.state.Count(thiscode); int otherCount = current.state.Count(othercode); if (current.state.GameOver) if (thisCount > otherCount) current.value = int.MaxValue; else current.value = int.MinValue; return; } // Find all possible moves for code on the working board var ownedPieces = from GamePiece g in current.state where g.Code == code select g; int gain = 0; foreach (GamePiece gp in ownedPieces) { for (int i = 0; i < 16; i++) { // Make sure move is valid if (gp.x + positioncheck[i][0] < Board.SIZE_X && gp.x + positioncheck[i][0] >= 0 && gp.y + positioncheck[i][1] < Board.SIZE_Y && gp.y + positioncheck[i][1] >= 0) { if (current.state[gp.x + positioncheck[i][0], gp.y + positioncheck[i][1]] != 0) continue; } else continue; // Execute move on working board and save move and state Move move = new Move(gp.x, gp.y, gp.x + positioncheck[i][0], gp.y + positioncheck[i][1], i >= 8); Board transform = (Board)current.state.Clone(); gain = Tad_MiniMaxAI.ExecuteMove(transform, code, move) * code == thiscode ? 1 : -1; // Calculate gain / loss made by move Node newnode = new Node(transform); newnode.move = move; current.children[move] = newnode; } } // Increase level and add children level++; foreach (Node n in current.children.Values) BuildTree(level, n, code == 1 ? 2 : 1); int max = int.MinValue; foreach (Node n in current.children.Values) if (n.value > max) max = n.value; current.value = gain + max; }
public void MakeMove() { Move bestMove; List<Move> bestOffensiveMoves = FindBestOffensiveMoves(thiscode); if (bestOffensiveMoves.Count == 0) return; if (bestOffensiveMoves.Count > 1) { List<Move> bestDefensiveMoves = new List<Move>(); int lost = 0; int worstloss = 9; foreach (Move m in bestOffensiveMoves) { if (m.isjump) { for (int i = 0; i < 16; i++) { if (!(m.xfrom + positioncheck[i, 0] <= maxX && m.xfrom + positioncheck[i, 0] >= 0 && m.yfrom + positioncheck[i, 1] <= maxX && m.yfrom + positioncheck[i, 1] >= 0)) continue; if (board[m.xfrom + positioncheck[i, 0], m.yfrom + positioncheck[i, 1]].code == othercode) { lost = board.Convert(m.xfrom, m.yfrom, thiscode, thiscode); break; } } if (lost <= worstloss) { if (lost < worstloss) bestDefensiveMoves.RemoveRange(0, bestDefensiveMoves.Count); bestDefensiveMoves.Add(m); worstloss = lost; } } else bestDefensiveMoves.Add(m); } bestMove = bestDefensiveMoves[(new Random()).Next(bestDefensiveMoves.Count)]; } else bestMove = bestOffensiveMoves[0]; if (bestMove.gain == 1) { List<Move> bestEnemyMoves = FindBestOffensiveMoves(othercode); foreach (Move m in bestEnemyMoves) { if (m.gain >= 1 && m.isjump) bestMove = new Move(0, 0, m.xto, m.yto, false, 1); } } ExecuteMove(bestMove); }
public override void MakeMove() { tree = new GameTree(board, aicode); int max = int.MinValue; Move bestMove = new Move(0, 0, 0, 0, false); foreach (GameTree.Node n in tree.root.children.Values) if (n.value > max) { max = n.value; bestMove = n.move; } ExecuteMove(board, aicode, bestMove); }
// Executes a move to the board public static int ExecuteMove(Board b, int c, Move move) { if (move.isjump) b[move.xfrom, move.yfrom] = 0; b[move.xto, move.yto] = c; return b.Convert(move.xto, move.yto, c, c == 1 ? 2 : 1) + (move.isjump ? 0 : 1); }