Esempio n. 1
0
    private IEnumerator GetEngineMove()
    {
        // This prevents the player from making a move during the calculation.
        isReady = false;

        ChangeText("Thinking...", "");

        // This checks if it is stalemate for the engine.
        if (position.IsStalemate(color.Flip()))
        {
            StartCoroutine(HandleStrike("You lose!", "Stalemate!"));
            yield break;
        }

        // This checks if there are only kings on the board, which is always a draw.
        if (position.All(c => c == '_' || c.ToLower() == 'k'))
        {
            StartCoroutine(HandleStrike("You lose!", "Kings only!"));
            yield break;
        }

        yield return(_bestMove.Start(position, (MovesLeft * 2) + 1, color == PieceColor.Black));

        // This looks convoluted, but it's only asking if the player has made a blunder, to the point of an unwinnable position.
        if (isWinning &&
            ((color == PieceColor.White && _bestMove.Result.Evaluation != sbyte.MaxValue - (MovesLeft * 2)) ||
             (color == PieceColor.Black && _bestMove.Result.Evaluation != (MovesLeft * 2) + sbyte.MinValue)))
        {
            isWinning = false;
            Log("Rustmate has evaluated that this position is now unwinnable for you. Congratulations.");
        }

        ChangeText("Mate in", "", MovesLeft.ToString());

        PlaySound(Sounds._1dch.Opponent);

        // This indicates if the game has ended.
        if (_bestMove.Result.IsEqual(Position.finishedGame))
        {
            isReady = false;

            PlaySound(Sounds._1dch.Check);

            // Stalemate.
            if (_bestMove.Result.Evaluation == 0)
            {
                StartCoroutine(HandleStrike("You lose!", "Stalemate!"));
            }

            // Checkmate against the player.
            else if (color == PieceColor.White ^ _bestMove.Result.Evaluation > 0)
            {
                StartCoroutine(HandleStrike("You lose!", "Checkmate!"));
            }

            // Checkmate for the player.
            else
            {
                PlaySound(Sounds._1dch.GameEnd, Sounds._1dch.Solve);

                string message = new[] { "Good game!", "Well played!" }.PickRandom();
                Solve(message);
                ChangeText("Solved!", message);
            }
        }
        else
        {
            // This allows the player to make a move again.
            isReady = true;

            position = _bestMove
                       .Result
                       .Move(position, this);

            Log("Rustmate plays {0}, the position is now {1}.", ToLog(_bestMove.Result), position);

            souvenirPositions.Add(ToLog(_bestMove.Result));

            // Having the game end after an engine move always means a loss for the player.
            if (position.IsGameEnd(color))
            {
                StartCoroutine(HandleStrike("You lose!", position.IsStalemate(color) ? "Stalemate!" : "Checkmate!"));
            }

            // This checks if there are only kings on the board, which is always a draw.
            else if (position.All(c => c == '_' || c.ToLower() == 'k'))
            {
                StartCoroutine(HandleStrike("You lose!", "Kings only!"));
            }

            else if (MovesLeft == 0)
            {
                StartCoroutine(HandleStrike("You lose!", "Out of moves!"));
            }
        }

        RenderPosition(position);
    }