Exemplo n.º 1
0
    /// <summary>
    /// Завершаем шаг и проверяем выиграла ли одна из команд
    /// Команда выигрывает если все ее фигуры, которые могут двигаться
    /// достигли лагеря противоположенной команды
    /// </summary>
    public bool CompleteStep(PieceStrategy strategy)
    {
        bool hasAllPlayerPiecesReachedEnemyCamp = true;
        bool hasAllEnemyPiecesReachedPlayerCamp = true;

        bool playerIsBlocked = true;
        bool enemyIsBlocked  = true;

        foreach (Piece piece in pieces)
        {
            // Проверям может ли двигаться фигура
            List <Cell> availableCells = strategy.GetAvailableCells(piece.cellRef);

            if (piece.IsPlayer)
            {
                bool isInEnemyCamp = IsInEnemyCamp(piece.cellRef);
                if (!isInEnemyCamp)
                {
                    hasAllPlayerPiecesReachedEnemyCamp = false;
                }

                if (!isInEnemyCamp && availableCells.Count > 0)
                {
                    playerIsBlocked = false;
                }
            }
            else
            {
                bool isInPlayerCamp = IsInPlayerCamp(piece.cellRef);
                if (!isInPlayerCamp)
                {
                    hasAllEnemyPiecesReachedPlayerCamp = false;
                }

                if (availableCells.Count > 0)
                {
                    enemyIsBlocked = false;
                }
            }
        }

        bool hasPlayerWon = hasAllPlayerPiecesReachedEnemyCamp || playerIsBlocked;
        bool hasEnemyWon  = hasAllEnemyPiecesReachedPlayerCamp || enemyIsBlocked;

        // Все фишки игрока достигли вражеского лагеря либо заблокированы противником
        if (hasPlayerWon)
        {
            OnWin?.Invoke(true);
        }

        // Все фишки противника достигли лагеря игрока либо заблокированы игроком
        if (hasEnemyWon)
        {
            OnWin?.Invoke(false);
        }

        IsPlayerTurn = !IsPlayerTurn;

        return(hasPlayerWon || hasEnemyWon);
    }
    public void MakeDecision()
    {
        List <Piece> movablePieces = new List <Piece>();
        List <Piece> piecesInCamp  = new List <Piece>();
        List <Piece> aiPieces      = new List <Piece>();

        List <Piece> allPieces = board.GetPieces();

        foreach (Piece piece in allPieces)
        {
            if (!piece.IsPlayer)
            {
                aiPieces.Add(piece);

                if (!board.IsInPlayerCamp(piece.cellRef))
                {
                    movablePieces.Add(piece);
                }
                else
                {
                    piecesInCamp.Add(piece);
                }
            }
        }

        Piece targetPiece = null;
        Cell  destination = null;

        float targetDistance = int.MaxValue;

        // Ищем среди фишек не в лагере игрока
        for (int i = 0; i < movablePieces.Count; i++)
        {
            Cell originCell = movablePieces[i].cellRef;

            float       originDistance = Math.Abs(originCell.X - board.Cols) + Math.Abs(originCell.Y - board.Rows);
            List <Cell> cells          = strategy.GetAvailableCells(movablePieces[i].cellRef);
            for (int j = 0; j < cells.Count; j++)
            {
                // попали в лагерь игрока. Ход удачный
                if (board.IsInPlayerCamp(cells[j]))
                {
                    targetPiece    = movablePieces[i];
                    destination    = cells[j];
                    targetDistance = 0f;
                    break;
                }

                // Пытаемся приблизиться
                float distance = Math.Abs(cells[j].X - board.Cols) + Math.Abs(cells[j].Y - board.Rows);
                if (distance > originDistance)
                {
                    continue;
                }

                if (distance < targetDistance)
                {
                    targetDistance = distance;
                    targetPiece    = movablePieces[i];
                    destination    = cells[j];
                }
            }

            // Можем попасть в лагерь. Прекращаем поиск
            if (targetDistance == 0)
            {
                break;
            }
        }

        // Не нашли фишку мне лагеря игрока, ходим фишкой которая уже в лагере
        if (targetPiece == lastPiece || targetDistance > int.MaxValue / 2)
        {
            List <Cell> cells = null;
            for (int i = 0; i < piecesInCamp.Count; i++)
            {
                Cell originCell = piecesInCamp[i].cellRef;

                float originDistance = Math.Abs(originCell.X - board.Cols) + Math.Abs(originCell.Y - board.Rows);

                cells = strategy.GetAvailableCells(piecesInCamp[i].cellRef);

                for (int j = 0; j < cells.Count; j++)
                {
                    // Пытаемся приблизиться
                    float distance = Math.Abs(cells[j].X - board.Cols) + Math.Abs(cells[j].Y - board.Rows);
                    if (distance > originDistance)
                    {
                        continue;
                    }

                    if (distance < targetDistance)
                    {
                        targetDistance = distance;
                        targetPiece    = piecesInCamp[i];
                        destination    = cells[j];
                    }
                }
            }

            // Делаем рандомный ход
            if (targetDistance > int.MaxValue / 2)
            {
                do
                {
                    targetPiece = aiPieces[random.Next() % aiPieces.Count];
                    cells       = strategy.GetAvailableCells(targetPiece.cellRef);
                }while (cells.Count == 0);

                destination = cells[random.Next() % cells.Count];
            }
        }

        lastPiece = targetPiece;

        List <Cell> path = strategy.ComputePath(targetPiece.cellRef, destination);

        OnDecisionMade?.Invoke(targetPiece, path);
    }
Exemplo n.º 3
0
    /// <summary>
    /// Перемещаем фигуру игрока
    /// </summary>
    private IEnumerator MovePiece(Piece piece, Cell origin)
    {
        activePiece = piece;

        foreach (var cell in cellFrames)
        {
            cell.Select(cell.Data == origin);
        }

        List <Cell> availableCells = strategy.GetAvailableCells(origin);

        if (availableCells.Count == 0)
        {
            foreach (var cell in cellFrames)
            {
                cell.Select(false);
            }

            destination = null;
            activePiece = null;

            yield break;
        }

        foreach (Cell cell in availableCells)
        {
            cell.Highlight(true);
        }

        // Ждем указания конечной точки
        while (destination == null)
        {
            yield return(null);
        }

        foreach (Cell cell in availableCells)
        {
            cell.Highlight(false);
        }

        foreach (var cell in cellFrames)
        {
            cell.Select(false);
        }

        if (!availableCells.Contains(destination))
        {
            destination = null;
            activePiece = null;

            yield break;
        }
        else
        {
            List <Cell> path = strategy.ComputePath(origin, destination);

            SmoothMoveStrategy moveStrategy = new SmoothMoveStrategy(piece, board, path);
            foreach (Vector2 pos in moveStrategy.Move())
            {
                Vector2 realPos = ConvertToBoard(pos.x, pos.y);
                piece.SetPosition(realPos.x, realPos.y);

                if (moveStrategy.IsCompleted)
                {
                    bool isGameFinished = board.CompleteStep(strategy);
                    UpdateTurn();

                    destination = null;
                    activePiece = null;

                    if (!isGameFinished && !board.IsPlayerTurn)
                    {
                        ai.MakeDecision();
                    }

                    yield break;
                }

                yield return(moveStrategy.Delay());
            }
        }
    }