コード例 #1
0
        public static List <PositionNode> GetNextSteps(this Ship ship, PositionNode current)
        {
            PositionNode shipNode = new PositionNode(ship.pos, ship.rotation, ship.speed);

            List <PositionNode> path = new List <PositionNode>();

            int count = 0;

            while (current != null && !current.Equals(shipNode) && current.parent != null && count < 30)
            {
                path.Add(current);
                current = current.parent;
                count++;
            }

            if (count >= 30)
            {
                Console.Error.WriteLine("Can't find shipNode");
                return(null);
            }

            if (current != null && current.Equals(shipNode))
            {
                path.Reverse();
                return(path);
            }

            return(null);
        }
コード例 #2
0
ファイル: Pathfinding.cs プロジェクト: SleepyJune/Codingames
        public static void InitializeNeighbours()
        {
            List <MoveType> validMoves = new List <MoveType>
            {
                MoveType.Wait,
                MoveType.Left,
                MoveType.Right,
                MoveType.Faster,
                MoveType.Slower,
            };

            foreach (var current in nodeTable.Values)
            {
                foreach (MoveType move in validMoves)
                {
                    int speed    = current.speed;
                    int rotation = current.rotation;

                    switch (move)
                    {
                    case MoveType.Faster:
                        speed += 1;
                        break;

                    case MoveType.Slower:
                        speed -= 1;
                        break;

                    case MoveType.Right:
                        rotation = (current.rotation + 5) % 6;
                        break;

                    case MoveType.Left:
                        rotation = (current.rotation + 1) % 6;
                        break;

                    default:
                        break;
                    }

                    if (speed > 2 || speed < 0 ||
                        (speed == 0 && move == MoveType.Wait))
                    {
                        continue;
                    }

                    Vector       pos     = current.pos + Vector.directions[current.rotation] * speed;
                    PositionNode newNode = new PositionNode(pos, rotation, speed);

                    if (pos.isInBound())
                    {
                        current.neighbours.Add(nodeTable[newNode], move);
                    }
                }
            }
        }
コード例 #3
0
        public ShipPositionInfo(Vector pos, int rotation, int speed)
        {
            this.pos      = pos;
            this.rotation = rotation;
            this.speed    = speed;

            this.shipFront = this.pos + Vector.directions[this.rotation];
            this.shipRight = this.pos + Vector.directions[(this.rotation + 5) % 6];
            this.shipLeft  = this.pos + Vector.directions[(this.rotation + 1) % 6];

            this.shipBack = this.pos - Vector.directions[this.rotation];
            this.minePos  = this.pos - Vector.directions[this.rotation] * 2;

            this.positionNode = PositionNode.GetPositionNode(pos, rotation, speed);
        }
コード例 #4
0
ファイル: Pathfinding.cs プロジェクト: SleepyJune/Codingames
        public static void InitializeNodes()
        {
            for (int x = 0; x <= 22; x++)
            {
                for (int y = 0; y <= 20; y++)
                {
                    for (int speed = 0; speed <= 2; speed++)
                    {
                        for (int rotation = 0; rotation < Vector.directions.Count; rotation++)
                        {
                            Hex    hexPos = new Hex(x, y);
                            Vector pos    = hexPos.ConvertCube();

                            PositionNode newNode = new PositionNode(pos, rotation, speed);
                            nodeTable.Add(newNode, newNode);
                        }
                    }
                }
            }
        }
コード例 #5
0
ファイル: Pathfinding.cs プロジェクト: SleepyJune/Codingames
        public static bool isPositionSafe(PositionNode node, Ship ship, int step)
        {
            foreach (var cannon in ship.dodgeableCannons)
            {
                foreach (var check in node.checkList)
                {
                    if (cannon.turns == step && cannon.hexPos == check)
                    {
                        return(false);
                    }
                }
            }

            foreach (var check in node.checkList)
            {
                if (Mine.minePos.Contains(check))
                {
                    return(false);
                }

                if (ship.enemyShipCollisionCheck.Contains(check))
                {
                    return(false);
                }
            }

            if (node.rotation != node.prevRotation)
            {
                if (Mine.minePos.Contains(node.extraCheckList[node.prevRotation]))
                {
                    return(false);
                }

                if (ship.enemyShipCollisionCheck.Contains(node.extraCheckList[node.prevRotation]))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #6
0
ファイル: Strategy.cs プロジェクト: SleepyJune/Codingames
        public static void ShipMakeMove(Ship ship)
        {
            bool waitMove = false;

            if (ship.isShipStuck())
            {
                waitMove = true;

                if (ship.firedLastRound == false)
                {
                    foreach (var enemy in Ship.ships.Values.OrderBy(s => s.pos.Distance(ship.pos)))
                    {
                        if (enemy.team == Team.Enemy && enemy.isAlive)
                        {
                            //Console.Error.WriteLine("ATK " + enemy.id + ":" + enemy.pos.toStr());

                            var predictedPos = ship.GetPredictedFirePos(enemy);

                            if (predictedPos.Distance(ship.currentPositionInfo.shipFront) <= 11)
                            {
                                var action = new Action(MoveType.Fire, ship, predictedPos);
                                Action.AddAction(action);
                                return;
                            }
                        }
                    }
                }
            }

            foreach (var cannon in Cannon.cannons)
            {
                //var shipPredictedPos = ship.GetPredictedPos(cannon.turns);

                if (cannon.turns <= 3 && ship.WillCannonHitShip(cannon))
                {
                    if (false)//(ship.speed == 0 && ship.lastMoveCommand.Distance(ship.pos) > 4)
                    {
                        var action = new Action(MoveType.Faster, ship);
                        Action.AddAction(action);
                        return;
                    }
                    else
                    {
                        int randX = random.Next(0, 22);
                        int randY = random.Next(0, 20);

                        Hex hex = new Hex(randX, randY);

                        Vector randomPos = hex.ConvertCube();
                        Console.Error.WriteLine("Dodging");

                        Action action = ship.Dodge(cannon);

                        if (action != null)
                        {
                            Action.AddAction(action);
                            return;
                        }
                    }
                }
            }

            if (ship.speed == 2) //check ramming into mines
            {
                var forwardPos = ship.pos + 3 * Vector.directions[ship.rotation];
                if (Mine.minePos.Contains(forwardPos.ConvertHex()))
                {
                    ship.targetPosition = Vector.Undefined;
                }
            }

            if (Game.gameTurn >= ship.nextMineTurn)
            {
                foreach (var enemy in Ship.ships.Values)
                {
                    if (enemy.isAlive && enemy.team == Team.Enemy)
                    {
                        if (enemy.nextPositionInfo.pos == ship.currentPositionInfo.minePos ||
                            enemy.nextPositionInfo.shipFront == ship.currentPositionInfo.minePos ||
                            enemy.nextPositionInfo.shipBack == ship.currentPositionInfo.minePos)
                        {
                            var action = new Action(MoveType.Mine, ship);
                            Action.AddAction(action);
                            return;
                        }
                    }
                }
            }

            foreach (var barrel in Barrel.barrels.OrderBy(b => ship.nextPositionInfo.pos.Distance(b.pos)
                                                          - Convert.ToInt32(ship.targetPosition == b.pos) * 100))
            {
                bool sameTarget = false;
                foreach (var ally in Ship.ships.Values)
                {
                    if (ally.team == Team.Ally && ally.isAlive && ally != ship &&
                        ally.nextPositionInfo.pos.Distance(barrel.pos) < ship.nextPositionInfo.pos.Distance(barrel.pos))
                    {
                        sameTarget = true;
                        break;
                    }
                }

                if (sameTarget)
                {
                    continue;
                }

                if (ship.nextPositionInfo.shipFront == barrel.pos ||
                    ship.nextPositionInfo.pos == barrel.pos)
                {
                    continue;
                }


                if (Ship.ships.Values.Any(enemy => enemy.isAlive && enemy.team == Team.Enemy &&
                                          enemy.nextPositionInfo.pos.Distance(barrel.pos) <= 5 &&
                                          enemy.nextPositionInfo.pos.Distance(barrel.pos) < ship.nextPositionInfo.pos.Distance(barrel.pos)))
                {
                    continue;
                }

                Console.Error.WriteLine("Target: " + barrel.pos.ConvertHex().toStr());

                Action action = ship.MoveShip(barrel.pos);

                if (action != null)
                {
                    if (action.move != MoveType.Wait)
                    {
                        Action.AddAction(action);
                        return;
                    }
                    else
                    {
                        waitMove = true;
                        break;
                    }
                }
                else
                {
                    waitMove = true;
                    break;
                }
            }

            if (waitMove)//ship.speed >= 1 && ship.lastMoveCommand != Vector.Undefined)
            {
            }
            else
            {
                Console.Error.WriteLine("Searching Random Position...");

                PositionNode target = null;
                target = Pathfinding.GetLongestPath(ship, 6);

                /*var shipWithMostRum = Ship.ships.Values.OrderByDescending(s => s.rum).FirstOrDefault();
                 * if (ship == shipWithMostRum)
                 * {
                 *  target = Pathfinding.GetLongestPath(ship, 6, true);
                 * }
                 * else
                 * {
                 *  target = Pathfinding.GetLongestPath(ship, 6);
                 * }*/

                var path = ship.GetNextSteps(target);
                if (path != null && path.Count > 1)
                {
                    var next = path[0];

                    foreach (var node in path)
                    {
                        Console.Error.WriteLine(node.step + ": S: " + node.speed + " R: " + node.rotation
                                                + " " + node.moveType + " " + node.pos.toStr());
                    }

                    Action action = new Action(next.moveType, ship);

                    if (action.move != MoveType.Wait)
                    {
                        Action.AddAction(action);
                        return;
                    }
                    else
                    {
                        waitMove = true;
                    }
                }
            }

            /*else
             * {
             *  foreach (var enemy in Ship.ships.Values.OrderBy(s => s.pos.Distance(ship.pos)))
             *  {
             *      if (enemy.team == Team.Enemy && enemy.isAlive)
             *      {
             *
             *          Vector pos = ship.RandomPosition(enemy.nextPositionInfo.shipFront, 3, 7);
             *          Console.Error.WriteLine("Random enemy: " + pos.toStr());
             *
             *          if (pos == Vector.Undefined)
             *          {
             *              continue;
             *          }
             *
             *
             *          Action action = ship.MoveShip(pos);
             *          if (action != null)
             *          {
             *              if (action.move != MoveType.Wait)
             *              {
             *                  Action.AddAction(action);
             *                  return;
             *              }
             *              else
             *              {
             *                  waitMove = true;
             *                  break;
             *              }
             *          }
             *          else
             *          {
             *              break;
             *          }
             *      }
             *  }
             * }*/

            if (ship.firedLastRound == false)
            {
                foreach (var enemy in Ship.ships.Values.OrderBy(s => s.pos.Distance(ship.pos)))
                {
                    if (enemy.team == Team.Enemy && enemy.isAlive)
                    {
                        //Console.Error.WriteLine("ATK " + enemy.id + ":" + enemy.pos.toStr());

                        var predictedPos = ship.GetPredictedFirePos(enemy);

                        if (predictedPos != Vector.Undefined &&
                            predictedPos.Distance(ship.currentPositionInfo.shipFront) <= 10)
                        {
                            var action = new Action(MoveType.Fire, ship, predictedPos);
                            Action.AddAction(action);
                            return;
                        }
                    }
                }
            }

            if (Game.gameTurn >= ship.nextMineTurn)
            {
                /*foreach (var enemy in Ship.ships.Values)
                 * {
                 *  if (enemy.isAlive && enemy.team == Team.Enemy)
                 *  {
                 *      if (ship.currentPositionInfo.minePos.Distance(enemy.nextPositionInfo.shipFront) <= 2)
                 *      {
                 *          var action = new Action(MoveType.Mine, ship);
                 *          Action.AddAction(action);
                 *          return;
                 *      }
                 *  }
                 * }*/

                /*foreach (var ally in Ship.ships.Values)
                 * {
                 *  if (ally.isAlive && ally.team == Team.Ally && ally != ship)
                 *  {
                 *      if (ship.currentPositionInfo.minePos.Distance(ally.nextPositionInfo.shipFront) > 3)
                 *      {
                 *          var action = new Action(MoveType.Mine, ship);
                 *          Action.AddAction(action);
                 *          return;
                 *      }
                 *  }
                 * }*/
            }

            Action.AddAction(new Action(ship));
        }
コード例 #7
0
ファイル: Pathfinding.cs プロジェクト: SleepyJune/Codingames
        public static PositionNode GetLongestPath(Ship ship, int radius, bool fleeing = false)
        {
            HashSet <PositionNode> set        = new HashSet <PositionNode>();
            Queue <PositionNode>   q          = new Queue <PositionNode>();
            List <PositionNode>    nextExpand = new List <PositionNode>();

            PositionNode shipNode = PositionNode.GetPositionNode(ship.pos, ship.rotation, ship.speed);

            //shipNode.distance = 0;
            shipNode.step   = 0;
            shipNode.parent = null;

            set.Add(shipNode);
            q.Enqueue(shipNode);

            int step  = 0;
            int loops = 0;

            PositionNode current = null;

            // bfs loop
            while (q.Count != 0)
            {
                current = q.Dequeue();

                foreach (var pair in current.neighbours)
                {
                    var neighbour = pair.Key;
                    var move      = pair.Value;

                    int neighbourStep = step + 1;//current.step + 1;

                    neighbour.prevRotation = current.rotation;

                    if (!set.Contains(neighbour) && isPositionSafe(neighbour, ship, neighbourStep))
                    {
                        set.Add(neighbour);

                        neighbour.parent   = current;
                        neighbour.moveType = move;
                        neighbour.step     = neighbourStep;

                        nextExpand.Add(neighbour);
                    }
                }

                if (q.Count == 0 && nextExpand.Count > 0) //if bfs is done expanding current step and next expand has items
                {
                    if (step >= radius)
                    {
                        break;
                    }

                    nextExpand.ForEach(n => q.Enqueue(n)); //put all list items into queue
                    nextExpand.Clear();

                    step++; //add 1 more step to count the distance
                }

                loops++;
            }

            if (step >= radius && nextExpand.Count > 0)
            {
                PositionNode first = null;
                if (fleeing)
                {
                    first = nextExpand.OrderByDescending(n => CombinedDistanceFromEnemy(n.pos)).FirstOrDefault();
                }
                else
                {
                    first = nextExpand.OrderByDescending(n => n.pos.Distance(ship.pos)).FirstOrDefault();
                }

                return(first);
            }

            return(null);
        }
コード例 #8
0
ファイル: Pathfinding.cs プロジェクト: SleepyJune/Codingames
        public static PositionNode CalculateShortestPaths(Ship ship, Vector targetPosition)
        {
            float loopStartTime = Timer.TickCount;

            HashSet <PositionNode> closedSet = new HashSet <PositionNode>();
            HashSet <PositionNode> openSet   = new HashSet <PositionNode>();

            foreach (var node in Pathfinding.nodeTable.Values)
            {
                node.gScore = 9999;
                node.fScore = 9999;
                node.parent = null;
                //prev.Add(stop, null);
            }

            List <PositionNode> nextExpand = new List <PositionNode>();

            PositionNode shipNode = PositionNode.GetPositionNode(ship.pos, ship.rotation, ship.speed);

            shipNode.gScore = 0;
            shipNode.fScore = shipNode.pos.Distance(targetPosition);
            shipNode.step   = 0;
            shipNode.parent = null;

            openSet.Add(shipNode);

            PositionNode current = null;
            int          step    = 0;
            int          loops   = 0;

            while (openSet.Count > 0)
            {
                current = openSet.OrderBy(n => n.fScore).FirstOrDefault();

                if (current.pos == targetPosition)
                {
                    break;
                }

                openSet.Remove(current);
                closedSet.Add(current);

                foreach (var pair in current.neighbours)
                {
                    var neighbour = pair.Key;
                    var move      = pair.Value;
                    var distance  = move == 0 ? 0 : 1;

                    distance += neighbour.speed;

                    var neighbourStep = current.step + 1;

                    if (closedSet.Contains(neighbour) || !isPositionSafe(neighbour, ship, neighbourStep))
                    {
                        continue;
                    }

                    var alternativeDistance = current.gScore + distance;
                    if (!openSet.Contains(neighbour))
                    {
                        //nextExpand.Add(neighbour);
                        openSet.Add(neighbour);
                    }
                    else if (alternativeDistance >= neighbour.gScore)
                    {
                        continue;
                    }

                    neighbour.parent   = current;
                    neighbour.gScore   = alternativeDistance;
                    neighbour.fScore   = alternativeDistance + neighbour.pos.Distance(targetPosition);
                    neighbour.moveType = move;
                    neighbour.step     = neighbourStep;
                }

                /*if (openSet.Count == 0 && nextExpand.Count > 0)
                 * {
                 *  nextExpand.ForEach(n => openSet.Add(n)); //put all list items into queue
                 *  nextExpand.Clear();
                 *
                 *  step++; //add 1 more step to count the distance
                 *  Console.Error.WriteLine("Loops: " + loops + " Steps: " + step);
                 * }*/

                loops++;
            }

            //float loopTime = Timer.TickCount - loopStartTime;
            //Console.Error.WriteLine("LoopTime: " + loopTime);
            Console.Error.WriteLine("Loops: " + loops + " Steps: " + step);

            return(current);
        }
コード例 #9
0
        public static List <PositionNode> GetNextSteps(this Ship ship, Vector targetPosition)
        {
            PositionNode result = Pathfinding.CalculateShortestPaths(ship, targetPosition);

            return(GetNextSteps(ship, result));
        }