예제 #1
0
        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;
            }
        }
예제 #2
0
        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);
            }
        }