private void CalculateDistances(Queue <PlayerModel> bfsQueue) { while (bfsQueue.Count != 0) { var curNode = bfsQueue.Dequeue(); if (_distancesToFinish[curNode.CurPosition.Y][curNode.CurPosition.X] != -1) { continue; } // Ищем минимальное значение расстояния до финиша среди соседей int minDistance = MaxPathLength; for (int i = -1; i <= 1; ++i) { for (int j = -1; j <= 1; ++j) { if (!_worldModel.IsEmptyPosition(curNode.CurPosition.X + j, curNode.CurPosition.Y + i)) { continue; } // Если на клетку можно встать, её еще не посетили // и она не находится с другой стороны от финиша - идем в неё var movementLine = new Line(new Coordinates(curNode.CurPosition.X, curNode.CurPosition.Y), new Coordinates(curNode.CurPosition.X + j, curNode.CurPosition.Y + i)); var wayPoints = _worldModel.FindIntersectedWayPoints(movementLine); int nextWayPoint = GetNextWayPoint(curNode); if (_distancesToFinish[curNode.CurPosition.Y + i][curNode.CurPosition.X + j] == -1) { if (wayPoints.Count == 0 || wayPoints.Contains(curNode.LastWayPoint) || wayPoints.Contains(nextWayPoint)) { // Если пересекаем следующий вэйпоинт PlayerModel nextState = (PlayerModel)curNode.Clone(); nextState.CurPosition.X += j; nextState.CurPosition.Y += i; if (wayPoints.Contains(nextWayPoint)) { nextState.LastWayPoint = nextWayPoint; } bfsQueue.Enqueue(nextState); } } else { // Уже посещенная или стартовая вершина if (curNode.LastWayPoint != 0 || !wayPoints.Contains(_worldModel.WayPointsCount() - 1)) { minDistance = Math.Min(_distancesToFinish[curNode.CurPosition.Y + i][curNode.CurPosition.X + j], minDistance); } } } } // Мин. расстояние до текущей вершины выражается через мин. расстояние до соседей _distancesToFinish[curNode.CurPosition.Y][curNode.CurPosition.X] = minDistance + 1; } }
private void CheckWayPointsIntersections(PlayerModel player, string playerId, IGameUpdatesHandler handler) { var intersectedWayPoint = _world.FindIntersectedWayPoints(player.GetLastMovement()); foreach (var pointNumber in intersectedWayPoint) { if (pointNumber == player.LastWayPoint + 1) { player.LastWayPoint = pointNumber; } } // Конец игры == игрок пересек последний вэйпоинт if (player.LastWayPoint == _world.WayPointsCount() - 1) { _players[playerId].IsWinner = true; handler?.OnEndOfGame(playerId, true); } }