예제 #1
0
 // 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);
 }
예제 #2
0
        // 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);
        }
예제 #3
0
        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;
        }
예제 #4
0
        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);
        }
예제 #5
0
 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);
 }
예제 #6
0
 // 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);
 }