/// <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); }
/// <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()); } } }