예제 #1
0
    static MovementScore FindMovementScoreExplore(MapStates[,] map, int startx, int starty, Bot[] bots, int endx, int endy)
    {
        int[] directionX = new int[] { 0, -1, 0, 1, 0 };
        int[] directionY = new int[] { 0, 0, -1, 0, 1 };
        int   width      = map.GetLength(0);
        int   height     = map.GetLength(1);

        int[,] distances = new int[width, height];
        MovementScore score = new MovementScore();

        score.certainDeath  = 0;
        score.closestPoints = int.MaxValue;
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                distances[x, y] = -1;
            }
        }

        Queue <Point> queue    = new Queue <Point>();
        Queue <Point> newQueue = new Queue <Point>();

        if (map[startx, starty] != MapStates.Wall)
        {
            queue.Enqueue(new Point {
                X = startx, Y = starty
            });
        }
        for (int step = 1; queue.Count > 0; step++)
        {
            score.certainDeath = step;
            while (queue.Count > 0)
            {
                Point p = queue.Dequeue();

                if (distances[p.X, p.Y] < 0)
                {
                    bool death = false;

                    foreach (Bot bot in bots)
                    {
                        if (bot.Nostradamus.IsThere(p.X, p.Y, step))
                        {
                            death = true;
                            break;
                        }
                    }
                    if (!death)
                    {
                        if (map[p.X, p.Y] != MapStates.Visited && score.closestPoints > step)
                        {
                            score.closestPoints = step;
                        }
                        distances[p.X, p.Y] = step;
                        for (int i = 0; i < directionX.Length; i++)
                        {
                            int newx = p.X + directionX[i];
                            int newy = p.Y + directionY[i];

                            if (newx < 0)
                            {
                                newx += width;
                            }
                            if (newx >= width)
                            {
                                newx -= width;
                            }
                            if (newy < 0)
                            {
                                newy += height;
                            }
                            if (newy >= height)
                            {
                                newy -= height;
                            }
                            if (distances[newx, newy] == -1 && map[newx, newy] != MapStates.Wall)
                            {
                                newQueue.Enqueue(new Point {
                                    X = newx, Y = newy
                                });
                                distances[newx, newy] = -2;
                            }
                        }
                    }
                }
            }

            var q = queue;
            queue    = newQueue;
            newQueue = q;
        }

        if (score.certainDeath > 0)
        {
            int[,] d            = FindDistancesMap(map, startx, starty);
            score.closestPoints = d[endx, endy];
        }

        return(score);
    }
예제 #2
0
    public Movement Step(Point[] playerPositions, bool wallLeft, bool wallUp, bool wallRight, bool wallDown)
    {
        Point me = playerPositions[playerPositions.Length - 1];

        for (int i = 0; i < playerPositions.Length; i++)
        {
            if (i < bots.Length)
            {
                int x = playerPositions[i].X, y = playerPositions[i].Y;

                bots[i].AddPoint(map, x, y);
                if (map[x, y] == MapStates.Unknown)
                {
                    map[x, y] = i + MapStates.Visited2;
                }
            }
        }
        map[me.X, me.Y] = MapStates.Visited;
        frame++;

        if (wallUp)
        {
            map[me.X, me.Y - 1] = MapStates.Wall;
        }
        if (wallDown)
        {
            map[me.X, me.Y + 1] = MapStates.Wall;
        }
        if (wallLeft)
        {
            map[me.X - 1, me.Y] = MapStates.Wall;
        }
        if (wallRight)
        {
            map[me.X + 1, me.Y] = MapStates.Wall;
        }

        // Dump some stats
        int width   = map.GetLength(0);
        int height  = map.GetLength(1);
        int visited = 0;

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                if (map[x, y] == MapStates.Visited)
                {
                    visited++;
                }
            }
        }
        DumpLine("Position: ({0}, {1})", me.X, me.Y);
        DumpLine("Visited: {0}", visited);

        // Decide where to go
        int[]         directionX     = new int[] { 0, -1, 0, 1, 0 };
        int[]         directionY     = new int[] { 0, 0, -1, 0, 1 };
        Movement[]    direction      = new Movement[] { Movement.Stand, Movement.Left, Movement.Up, Movement.Right, Movement.Down };
        Movement      movement       = Movement.Stand;
        MovementScore bestMoveScore  = new MovementScore();
        bool          testCloseDeath = !IsOnlyUnknownConnected(map, me.X, me.Y);

        DumpLine("TCD: {0}", testCloseDeath);
        bestMoveScore.certainDeath  = 0;
        bestMoveScore.closestPoints = int.MaxValue;
        for (int i = 0; i < directionX.Length; i++)
        {
            int newX = directionX[i] + me.X;
            int newY = directionY[i] + me.Y;

            if (newX < 0)
            {
                newX += width;
            }
            if (newX >= width)
            {
                newX -= width;
            }
            if (newY < 0)
            {
                newY += height;
            }
            if (newY >= height)
            {
                newY -= height;
            }

            MovementScore score;

            if (!explore)
            {
                score = FindMovementScore(map, newX, newY, bots);
            }
            else
            {
                score = FindMovementScoreExplore(map, newX, newY, bots, explorex, explorey);
                if (direction[i] == Movement.Stand)
                {
                    continue;
                }
            }

            Dump("{0}: {1} [{2}, {3}]", direction[i], map[newX, newY], score.certainDeath, score.closestPoints);

            bool s1e = score.certainDeath < 13 && testCloseDeath;
            bool s2e = bestMoveScore.certainDeath < 13 && testCloseDeath;

            if (s1e && !s2e)
            {
                DumpLine();
                continue;
            }

            bool betterScore = !s1e && s2e;

            if (!betterScore && s1e && s2e)
            {
                betterScore = score.certainDeath > bestMoveScore.certainDeath;
            }

            if (betterScore || (score.closestPoints < bestMoveScore.closestPoints ||
                                (score.closestPoints == bestMoveScore.closestPoints && score.certainDeath > bestMoveScore.certainDeath)))
            {
                movement      = direction[i];
                bestMoveScore = score;
                Dump(" *");
            }
            DumpLine();
        }

        foreach (Bot bot in bots)
        {
            DumpLine("{0} {1} {2} {3}", bot.IsRepeating, bot.RepeatStart, bot.PointPosition, bot.Points.Count);
        }

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                if (x == me.X && y == me.Y)
                {
                    Dump("X ");
                }
                else
                {
                    int foundIndex = -1;

                    for (int i = 0; i < bots.Length; i++)
                    {
                        if (bots[i].Position.X == x && bots[i].Position.Y == y)
                        {
                            foundIndex = i;
                            break;
                        }
                    }
                    if (foundIndex != -1)
                    {
                        Dump("{0} ", (char)('A' + foundIndex));
                    }
                    else if (map[x, y] == MapStates.Wall)
                    {
                        Dump("# ");
                    }
                    else if (map[x, y] == MapStates.Unknown)
                    {
                        Dump("  ");
                    }
                    else
                    {
                        Dump("{0} ", (int)map[x, y]);
                    }
                }
            }
            DumpLine();
        }

        if (fullDumpEnabled && frame == fullDumpFrame)
        {
            Console.Error.WriteLine("width: {0}, height = {1}", width, height);
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    if (map[x, y] == MapStates.Wall)
                    {
                        Console.Error.Write("#");
                    }
                    else if (map[x, y] == MapStates.Unknown)
                    {
                        Console.Error.Write(" ");
                    }
                    else
                    {
                        Console.Error.Write(".");
                    }
                }
                Console.Error.WriteLine();
            }
            foreach (Bot bot in bots)
            {
                foreach (Point p in bot.Path)
                {
                    Console.Error.Write("{0}{1}", (char)('A' + p.X), (char)('A' + p.Y));
                }
                Console.Error.WriteLine();
            }
        }

        return(movement);
    }
예제 #3
0
        static void Test1()
        {
            const string mapInput = @"                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                        B A C D                         
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                          #                             
                        X 1                             
                        # #                             
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        ";

            Bot[] bots;
            Point me;

            MapStates[,] map = ParseMap(mapInput, out me, out bots);
            int width  = map.GetLength(0);
            int height = map.GetLength(1);

            PrintMap(map, me.X, me.Y, bots);

            for (int i = 0; i < bots.Length; i++)
            {
                if (bots[i].Nostradamus is PesimisticNostradamus)
                {
                    Console.WriteLine((char)(i + 'A'));
                    PesimisticNostradamus pn = bots[i].Nostradamus as PesimisticNostradamus;
                    int[,] distances = pn.Distances;

                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++)
                        {
                            if (distances[x, y] == -1)
                            {
                                Console.Write(" # ");
                            }
                            else
                            {
                                Console.Write("{0,2} ", distances[x, y]);
                            }
                        }
                        Console.WriteLine();
                    }
                    Console.WriteLine();
                }
            }

            MovementScore score = Game.FindMovementScore(map, me.X + 1, me.Y, bots);
        }