Beispiel #1
0
    // Sets a Token on a Field from the given Move on the GameField
    // (The Validation is handled via button enabling.
    //  There the placement is allowed!)
    // Return the winner or null
    public Player?SetTokenOnField(Move move)
    {
        Player?winner = null;

        // Only do something when token is not covered
        if (!TokenIsCovered(move.Token))
        {
            // Remove the Token if it's on an upper Field
            RemoveTokenFromField(move.Token);

            // Check if the Field is empty
            if (GameField.ContainsKey(move.Field))
            {
                // Compare with the upper Token on the Field
                if (System.Convert.ToInt32(move.Token.tag) > System.Convert.ToInt32(GameField[move.Field].Peek().tag))
                {
                    // Place the Token on the highest position of the Field
                    GameField[move.Field].Push(move.Token);
                }
            }
            else
            {
                Stack <GameObject> tokenStack = new Stack <GameObject>();
                tokenStack.Push(move.Token);
                // Place the Token on the Field
                GameField.Add(move.Field, tokenStack);
            }

            // Check if game is won with the converted state of string tokens
            winner = WinDetection.CheckWinner(TypeConverter.ConvertState(GameField));
        }

        return(winner);
    }
Beispiel #2
0
        // The recursive alpha beta function
        // Checks every possible move for every recursion step (depth)
        // Stops the search by the alpha and beta cap value
        // Optimization: Checks for win or loose when depth is not reached yet
        // Returns the value for the root move, calculated by the evaluation function
        private static int AlphaBeta(int depth, StringState state, Player player, int alpha, int beta)
        {
            // Optimization: Checks for win or loose when depth is not reached yet
            // It is not necessary to look any further if win or loose
            // The earlier the detection the higher the value
            if (depth > 0)
            {
                // Check for the winner (may be empty)
                Player?winner = WinDetection.CheckWinner(state);

                // Has the ai won the game?
                if (winner == Constants.AI_PLAYER)
                {
                    // Return high value (like 1000)
                    // The higher the left recursion count the better the value
                    return(1000 * Constants.AI_DEPTH);
                }

                // Has the ai lost the game?
                if (winner == TypeConverter.GetOpponent(Constants.AI_PLAYER))
                {
                    // Return low value (like -1000)
                    // The higher the left recursion count the lower the value
                    return(-1000 * Constants.AI_DEPTH);
                }
            }
            // Otherwise the depth is reached (last recursion step)
            else
            {
                // Evaluate the leaf
                return(EvaluateState(state, player));
            }

            // Switch player after win detection
            // After evaluation this won't be necessary anymore
            // But eval has to be calculated for the player for which the current recursion call was made
            player = TypeConverter.GetOpponent(player);

            // Get all possible moves for the current state and player
            List <MoveString> possibleMoves = GetPossibleMoves(state, player);

            // If the Player is the ai the vale will be maxed
            if (player == Constants.AI_PLAYER)
            {
                // Start with lowest possible value
                int bestValue = int.MinValue;

                // Iterate through each possible move
                foreach (MoveString move in possibleMoves)
                {
                    // Generate a new reference state with the move on the previous state
                    StringState moveState = GetStateWithMove(state, move);

                    // Check for the highest value in the recursion
                    bestValue = Math.Max(bestValue, AlphaBeta(depth - 1, moveState, player, alpha, beta));

                    // Alpha beta Pruning
                    alpha = Math.Max(alpha, bestValue);
                    if (beta <= alpha)
                    {
                        return(bestValue);
                    }
                }

                return(bestValue);
            }
            // Otherwise the value will be minned for the opponent
            else
            {
                // Start with highest possible value
                int bestValue = int.MaxValue;

                // Iterate through each possible move
                foreach (MoveString move in possibleMoves)
                {
                    // Generate a new reference state with the move on the previous state
                    StringState moveState = GetStateWithMove(state, move);

                    // Check for the lowest value in the recursion
                    bestValue = Math.Min(bestValue, AlphaBeta(depth - 1, moveState, player, alpha, beta));

                    // Alpha beta Pruning
                    beta = Math.Min(beta, bestValue);
                    if (beta <= alpha)
                    {
                        return(bestValue);
                    }
                }

                return(bestValue);
            }
        }