Exemplo n.º 1
0
    public GamePoint find_point(int x, int y, int this_virus_level, int desired_virus_level)
    {
        if (x >= width() || y >= height() || y < 0 || x < 0)
        {
            return(null);
        }

        // BEGIN: First find a path to the desired position to influence our movement
        var grid  = get_pathnode_map(x, y, this_virus_level, !goingAfterEnemy);
        var aStar = new SettlersEngine.SpatialAStar <GamePathNode, Object>(grid);
        var path  = aStar.Search(new Point(x, y), new Point(desiredX, desiredY), null);
        //LinkedList<GamePathNode> path = null;
        // END: First find a path to the desired position to influence our movement


        var points           = new List <GamePoint>();
        var returnablePoints = new List <GamePoint>();

        //var startingPoint = new GamePoint(x, y);
        points.Add(new GamePoint(x + 1, y));
        points.Add(new GamePoint(x - 1, y));
        points.Add(new GamePoint(x, y + 1));
        points.Add(new GamePoint(x, y - 1));

        int loopCount   = 0;
        int returnDepth = 0;

        while (points.Count > 0 && loopCount < 1000)
        {
            //Console.WriteLine("FloodFill: " + loopCount);
            var pt = points[0];
            loopCount++;

            // make sure the point is not out of range of the game board
            if (pt.X >= width() || pt.X < 0 || pt.Y >= height() || pt.Y < 0)
            {
                points.Remove(pt);
                continue;
            }


            // check to make sure this tile is not dangerous (eg >= enemy virus adjacent to it), if it is remove it
            if (pt.X + 1 < width())
            {
                if (map[pt.X + 1, pt.Y].Type == NodeType.EnemyVirus && map[pt.X + 1, pt.Y].VirusLevel >= this_virus_level)
                {
                    points.Remove(pt);
                    continue;
                }
            }
            if (pt.X - 1 >= 0)
            {
                if (map[pt.X - 1, pt.Y].Type == NodeType.EnemyVirus && map[pt.X - 1, pt.Y].VirusLevel >= this_virus_level)
                {
                    points.Remove(pt);
                    continue;
                }
            }
            if (pt.Y + 1 < height())
            {
                if (map[pt.X, pt.Y + 1].Type == NodeType.EnemyVirus && map[pt.X, pt.Y + 1].VirusLevel >= this_virus_level)
                {
                    points.Remove(pt);
                    continue;
                }
            }
            if (pt.Y - 1 >= 0)
            {
                if (map[pt.X, pt.Y - 1].Type == NodeType.EnemyVirus && map[pt.X, pt.Y - 1].VirusLevel >= this_virus_level)
                {
                    points.Remove(pt);
                    continue;
                }
            }

            // at this point we willa ctually look at this node
            var node = map[pt.X, pt.Y];

            // if it is interesting let's go to it
            if (node.Type == NodeType.EnemyTile ||
                node.Type == NodeType.NeutralTile ||
                (node.Type == NodeType.EnemyVirus && node.VirusLevel < this_virus_level) ||
                (node.Type == NodeType.MyVirus && node.VirusLevel == this_virus_level && this_virus_level < desired_virus_level && pt.Depth == 1))
            {
                returnablePoints.Add(pt);
                points.Remove(pt);

                if (returnDepth == 0)
                {
                    returnDepth = pt.Depth;
                }
            }
            // else if the pt is not interesting remove it
            else if (node.Type == NodeType.Wall ||
                     node.Type == NodeType.MyBase ||
                     node.Type == NodeType.EnemyBase ||
                     (node.Type == NodeType.MyVirus && node.VirusLevel != this_virus_level) ||
                     (node.Type == NodeType.EnemyVirus && node.VirusLevel >= this_virus_level) ||
                     (node.Type == NodeType.MyVirus && pt.Depth == 1))
            {
                points.Remove(pt);
            }
            // else if it is my tile or my far away virus look for something else
            else if (node.Type == NodeType.MyTile || (node.Type == NodeType.MyVirus && pt.Depth > 1))
            {
                // if we can add the point then do so
                if (returnDepth == 0 || pt.Depth < returnDepth)
                {
                    // for each direction made a seed point in that direction and add it to the points if that point is not already in points
                    foreach (Direction dir in Enum.GetValues(typeof(Direction)))
                    {
                        var seedPoint = new GamePoint(pt, dir);

                        bool alreadyInPoints = false;

                        foreach (var point in points)
                        {
                            if (point.X == seedPoint.X && point.Y == seedPoint.Y)
                            {
                                alreadyInPoints = true;
                                break;
                            }
                        }

                        if (!alreadyInPoints)
                        {
                            points.Add(seedPoint);
                        }
                    }
                }
                points.Remove(pt);
            }
            else
            {
                Console.WriteLine("PROBLEM: I don't know what to do for this node of type: " + node.Type);
                return(null);
            }
        }


        if (loopCount >= 999)
        {
            Console.WriteLine("ALERT: Preventing Infinite Loop at Flood Fill.");
        }

        if (returnablePoints.Count > 0)
        {
            // Check points for Priority in this order:
            //   1. Enemy Viruses
            //   2. Enemy Tiles
            //   3. Neutral Tiles
            //   4. My Viruses to join with

            var inOrder = new List <GamePoint>();

            foreach (var returnablePoint in returnablePoints)
            {
                if (map[returnablePoint.X, returnablePoint.Y].Type == NodeType.EnemyVirus)
                {
                    inOrder.Add(returnablePoint);
                }
            }

            foreach (var returnablePoint in returnablePoints)
            {
                if (map[returnablePoint.X, returnablePoint.Y].Type == NodeType.EnemyTile)
                {
                    inOrder.Add(returnablePoint);
                }
            }

            foreach (var returnablePoint in returnablePoints)
            {
                if (map[returnablePoint.X, returnablePoint.Y].Type == NodeType.NeutralTile)
                {
                    inOrder.Add(returnablePoint);
                }
            }

            foreach (var returnablePoint in returnablePoints)
            {
                if (map[returnablePoint.X, returnablePoint.Y].Type == NodeType.MyVirus)
                {
                    inOrder.Add(returnablePoint);
                }
            }

            // go through the points we want in order and if there is a path return the point that is in that path
            //   this basically says, "oh you have a many options? well take the one that mvoes you closer to the desired point".
            if (path != null && path.Count > 2)
            {
                path.RemoveFirst();
                GamePathNode firstStep = null;

                //because path.First won't compile :(
                foreach (var node in path)
                {
                    firstStep = node;
                    break;
                }

                foreach (var returnablePoint in inOrder)
                {
                    if (returnablePoint.X == firstStep.X && returnablePoint.Y == firstStep.Y)
                    {
                        return(returnablePoint);
                    }
                }
            }

            //only should happen if there was no path
            return(inOrder[0]);
        }
        else
        {
            // just go where ever that path we found the the desired point is
            if (path != null && path.Count > 2)
            {
                path.RemoveFirst();
                GamePathNode firstStep = null;

                //because path.First won't compile :(
                foreach (var node in path)
                {
                    firstStep = node;
                    break;
                }

                return(new GamePoint(firstStep.X, firstStep.Y));
            }
        }

        Console.WriteLine("PROBLEM: No point was found to return...\n");
        return(null);
    }
Exemplo n.º 2
0
    public override bool run()
    {
        update_map();

        int desired_virus_level = 0;
        int enemy_virus_count   = 0;

        // see if we need to find a new

        // find the desired level for our viruses
        foreach (var virus in viruses)
        {
            if (virus.getOwner() == enemyID())
            {
                desired_virus_level += virus.getLevel();
                enemy_virus_count++;
            }
        }
        if (enemy_virus_count > 0)
        {
            desired_virus_level = (int)Math.Ceiling((double)desired_virus_level / (double)enemy_virus_count) + 1;
        }

        // for each of my bases try to spawn a virus
        var my_bases = new Dictionary <Base, int>();

        foreach (var my_base in bases)
        {
            if (
                my_base.getOwner() == playerID() &&
                map[my_base.getX(), my_base.getY()].VirusLevel == -1 &&
                players[playerID()].getCycles() >= 10
                )
            {
                var grid  = get_pathnode_map(my_base.getX(), my_base.getY(), -1, false);
                var aStar = new SettlersEngine.SpatialAStar <GamePathNode, Object>(grid);
                var path  = aStar.Search(new Point(my_base.getX(), my_base.getY()), new Point(desiredX, desiredY), null);

                //Console.WriteLine("Base at: " + my_base.getX() + "," + my_base.getY() + " has a path of length " + (path != null ? Convert.ToString(path.Count) : "NULL") );

                my_bases.Add(my_base, path != null ? path.Count : int.MaxValue);
            }
        }

        var sortedBases = from key in my_bases.Keys
                          orderby my_bases[key] ascending
                          select key;

        foreach (var my_base in sortedBases)
        {
            my_base.spawn(0);
        }

        // check to see if we will loose soon
        if (players[enemyID()].getByteDollars() >= 118)
        {
            players[playerID()].talk("I curse Wooly Willy on you, " + players[enemyID()].getPlayerName());
        }

        // for each of my viruses find a point to go to, then go there!
        foreach (var virus in viruses)
        {
            if (virus.getOwner() == playerID())
            {
                update_map();

                var pt = find_point(virus.getX(), virus.getY(), virus.getLevel(), desired_virus_level);

                var points    = new List <GamePoint>();
                int loopCount = 0;
                while (pt != null && loopCount < 1000)
                {
                    loopCount++;
                    points.Insert(0, pt);
                    pt = pt.Parent;
                }

                if (loopCount >= 999)
                {
                    Console.WriteLine("ALERT: Preventing Infinite Loop at UNPACKING POINTS.");
                }

                loopCount = 0;
                while (virus.getMovesLeft() > 0 && points.Count > 0 && loopCount < 1000)
                {
                    //switch(rand.Next(5)) { case 0: virus.move(virus.getX() + 1, virus.getY()); break;  case 1: virus.move(virus.getX(), virus.getY() + 1); break;  case 2: virus.move(virus.getX(), virus.getY() - 1); break;  case 3: virus.move(virus.getX() - 1, virus.getY()); break; }
                    loopCount++;
                    virus.move(points[0].X, points[0].Y);
                    //if we just move to the desired point
                    if (goingAfterEnemy && points[0].X == desiredX && points[0].Y == desiredY)
                    {
                        find_new_desired_point(points[0].X, points[0].Y);
                    }
                    points.RemoveAt(0);
                }

                if (loopCount >= 999)
                {
                    Console.WriteLine("ALERT: Preventing Infinite Loop at DOING MOVE.");
                }
            }
        }

        return(true);
    }