Ejemplo n.º 1
0
Archivo: AI.cs Proyecto: jncronin/nmm
        public static int Heuristic(ulong board, List <ulong> possible_moves = null)
        {
            if (Board.CurrentPlayerHasLessThanThree(board))
            {
                return(-1000);       // this is a losing position
            }
            if (possible_moves == null)
            {
                possible_moves = Board.GetMoves(board);
            }

            if (possible_moves.Count == 0)
            {
                return(-1000);       // this is a losing position
            }
            /* We score +1 for a move, +2 if it forms a mill */
            int score    = 0;
            var old_runs = Board.GetRunPieces(board);

            foreach (var move in possible_moves)
            {
                var new_runs = Board.GetRunPieces(move);
                if (new_runs != old_runs && Board.CountBits(new_runs) >= Board.CountBits(old_runs))
                {
                    score += 5;
                }
                else
                {
                    score++;
                }
            }

            return(score);
        }
Ejemplo n.º 2
0
Archivo: AI.cs Proyecto: jncronin/nmm
        int minimax(ulong board, int depth, bool maximizingPlayer, out ulong move)
        {
            if (cache_v[depth].TryGetValue(board, out var cached))
            {
                move = cache_move[depth][board]; return(cached);
            }

            var children = Board.GetMoves(board);

            if (depth == 0 || Board.CurrentPlayerHasLessThanThree(board) || children.Count == 0)
            {
                move = 0UL;
                return(Heuristic(board, IsWhite, children));
            }

            if (maximizingPlayer)
            {
                var   bestValue = int.MinValue;
                ulong best_move = 0UL;
                foreach (var child in children)
                {
                    var v = minimax(child, depth - 1, false, out var unused);
                    if (v > bestValue)
                    {
                        bestValue = v;
                        best_move = child;
                    }
                }
                move = best_move;
                cache_v[depth][board]    = bestValue;
                cache_move[depth][board] = move;
                return(bestValue);
            }
            else
            {
                // minimizing player
                var   bestValue = int.MaxValue;
                ulong best_move = 0UL;
                foreach (var child in children)
                {
                    var v = minimax(child, depth - 1, true, out var unused);
                    if (v < bestValue)
                    {
                        bestValue = v;
                        best_move = child;
                    }
                }
                move = best_move;
                cache_v[depth][board]    = bestValue;
                cache_move[depth][board] = move;
                return(bestValue);
            }
        }
Ejemplo n.º 3
0
        public bool MakeTurn()
        {
            if (next_player)
            {
                Console.WriteLine("Turn: " + (turn++).ToString());
            }

            Board.PrintBoard(board);

            List <ulong> AllowedMoves = null;

            if (Board.CurrentPlayerHasLessThanThree(board) || (AllowedMoves = Board.GetMoves(board)).Count == 0)
            {
                // Current player has lost
                if (next_player)
                {
                    Console.Write("Black");
                }
                else
                {
                    Console.Write("White");
                }
                Console.WriteLine(" Wins!");
                return(false);
            }


            while (true)
            {
                ulong move;
                if (next_player)
                {
                    move = White.GetMove(board);
                }
                else
                {
                    move = Black.GetMove(board);
                }

                // ensure move is valid
                foreach (var allowed_move in AllowedMoves)
                {
                    if (allowed_move == move)
                    {
                        next_player = !next_player;
                        DumpMove(board, move);
                        board = move;
                        return(true);
                    }
                }

                // move is invalid
                if (next_player)
                {
                    White.IllegalMove(move);
                }
                else
                {
                    Black.IllegalMove(move);
                }

                // request again
            }
        }