Exemplo n.º 1
0
        public override bool Equals(object obj)
        {
            if (!base.Equals(obj))
            {
                return(false);
            }
            ResolveEvent other = (ResolveEvent)obj;

            return(other.robotIdToSpawn.Equals(robotIdToSpawn) &&
                   other.robotIdToMove.Equals(robotIdToMove) &&
                   other.robotIdToHealth.Equals(robotIdToHealth) &&
                   other.myBatteryHit.Equals(myBatteryHit) &&
                   other.opponentBatteryHit.Equals(opponentBatteryHit) &&
                   other.missedAttacks.Equals(missedAttacks) &&
                   other.robotIdsBlocked.Equals(robotIdsBlocked));
        }
Exemplo n.º 2
0
        public List <GameEvent> CommandsToEvents()
        {
            List <Command> commands = new List <Command>();

            commands.AddRange(primary.FetchCommands());
            commands.AddRange(secondary.FetchCommands());
            Dictionary <short, RobotTurnObject> robotIdToTurnObject = new Dictionary <short, RobotTurnObject>(primary.team.Count + secondary.team.Count);
            List <Robot> allRobots = primary.team.Concat(secondary.team).ToList();

            allRobots.ForEach(r => {
                RobotTurnObject rto = new RobotTurnObject(r.id, r.priority);
                rto.isActive        = !r.position.Equals(Map.NULL_VEC);
                robotIdToTurnObject.Add(r.id, rto);
            });
            List <GameEvent> events = new List <GameEvent>();

            for (int p = GameConstants.MAX_PRIORITY; p >= 0; p--)
            {
                HashSet <Command> currentCmds = robotIdToTurnObject.Values.ToList().FindAll(rto => rto.priority == p && commands.Any(c => c.robotId == rto.robotId)).ConvertAll(rto =>
                {
                    rto.priority--;
                    Command cmd = commands.Find(c => c.robotId == rto.robotId);
                    commands.Remove(cmd);
                    return(cmd);
                }).ToHashSet();
                List <GameEvent> priorityEvents = new List <GameEvent>();

                currentCmds.ToList().ForEach((Command c) =>
                {
                    Robot primaryRobot = GetRobot(c.robotId);
                    if (!robotIdToTurnObject.GetValueOrDefault(c.robotId).isActive&& !(c is Command.Spawn))
                    {
                        currentCmds.Remove(c);
                    }
                });
                currentCmds.ToList().ForEach((Command c) =>
                {
                    Robot primaryRobot = GetRobot(c.robotId);
                    bool isPrimary     = c.owner.Equals(primary.name);
                    if (c is Command.Spawn)
                    {
                        priorityEvents.AddRange(primaryRobot.Spawn(board.GetQueuePosition(c.direction, isPrimary), isPrimary));
                    }
                    else if (c is Command.Move)
                    {
                        priorityEvents.AddRange(primaryRobot.Move(c.direction, isPrimary));
                    }
                    else if (c is Command.Attack)
                    {
                        priorityEvents.AddRange(primaryRobot.Attack(c.direction, isPrimary));
                    }
                });

                if (priorityEvents.Count > 0)
                {
                    ResolveEvent resolveEvent = new ResolveEvent();
                    resolveEvent.robotIdToSpawn = priorityEvents.FindAll(e => e is SpawnEvent)
                                                  .ConvertAll(e => (SpawnEvent)e)
                                                  .ConvertAll(e => new Tuple <short, Tuple <int, int> >(e.robotId, e.destinationPos));
                    resolveEvent.robotIdToMove = priorityEvents.FindAll(e => e is MoveEvent)
                                                 .ConvertAll(e => (MoveEvent)e)
                                                 .ConvertAll(e => new Tuple <short, Tuple <int, int> >(e.robotId, e.destinationPos));
                    resolveEvent.robotIdToHealth = new List <Tuple <short, short> >();
                    resolveEvent.missedAttacks   = new List <Tuple <int, int> >();
                    priorityEvents.FindAll(e => e is AttackEvent)
                    .ConvertAll(e => (AttackEvent)e)
                    .ForEach(e => {
                        Robot attacker = GetRobot(e.robotId);
                        allRobots.FindAll(robot => e.locs.Contains(robot.position))
                        .ForEach(r =>
                        {
                            short damage = attacker.Damage(r);
                            Tuple <short, short> robotAndHealth = resolveEvent.robotIdToHealth.Find(t => t.Item1 == r.id);
                            if (robotAndHealth == null)
                            {
                                resolveEvent.robotIdToHealth.Add(new Tuple <short, short>(r.id, (short)(r.health - damage)));
                            }
                            else
                            {
                                resolveEvent.robotIdToHealth.Remove(robotAndHealth);
                                robotAndHealth = new Tuple <short, short>(robotAndHealth.Item1, (short)(robotAndHealth.Item2 - damage));
                                resolveEvent.robotIdToHealth.Add(robotAndHealth);
                            }
                        });
                        e.locs.FindAll(board.IsBattery).ForEach(v => {
                            bool isPrimaryBase = board.IsPrimary(v);
                            short drain        = (short)(GameConstants.DEFAULT_BATTERY_MULTIPLIER * attacker.attack);
                            resolveEvent.primaryBatteryCost   += isPrimaryBase ? drain : (short)0;
                            resolveEvent.secondaryBatteryCost += isPrimaryBase ? (short)0: drain;
                            resolveEvent.myBatteryHit          = resolveEvent.myBatteryHit || isPrimaryBase;
                            resolveEvent.opponentBatteryHit    = resolveEvent.opponentBatteryHit || !isPrimaryBase;
                        });
                        e.locs.FindAll(v => !board.IsBattery(v) && !allRobots.Any(r => r.position.Equals(v)) && !board.IsVoid(v))
                        .ForEach(v => {
                            if (!resolveEvent.missedAttacks.Contains(v))
                            {
                                resolveEvent.missedAttacks.Add(v);
                            }
                        });
                        if (e.locs.Any(board.IsVoid))
                        {
                            resolveEvent.robotIdsBlocked.Add(attacker.id);
                        }
                    });

                    bool valid = false;
                    while (!valid)
                    {
                        valid = true;

                        // Move x Move
                        List <Tuple <Tuple <int, int>, List <Tuple <short, bool> > > > spacesToRobotIds = new List <Tuple <Tuple <int, int>, List <Tuple <short, bool> > > >();
                        resolveEvent.robotIdToSpawn.ForEach(t => {
                            Tuple <Tuple <int, int>, List <Tuple <short, bool> > > pair = spacesToRobotIds.Find(s => s.Item1.Equals(t.Item2));
                            if (pair == null)
                            {
                                spacesToRobotIds.Add(new Tuple <Tuple <int, int>, List <Tuple <short, bool> > >(t.Item2, new List <Tuple <short, bool> >()
                                {
                                    new Tuple <short, bool>(t.Item1, true)
                                }));
                            }
                            else
                            {
                                pair.Item2.Add(new Tuple <short, bool>(t.Item1, true));
                            }
                        });
                        resolveEvent.robotIdToMove.ForEach(t => {
                            Tuple <Tuple <int, int>, List <Tuple <short, bool> > > pair = spacesToRobotIds.Find(s => s.Item1.Equals(t.Item2));
                            if (pair == null)
                            {
                                spacesToRobotIds.Add(new Tuple <Tuple <int, int>, List <Tuple <short, bool> > >(t.Item2, new List <Tuple <short, bool> >()
                                {
                                    new Tuple <short, bool>(t.Item1, false)
                                }));
                            }
                            else
                            {
                                pair.Item2.Add(new Tuple <short, bool>(t.Item1, false));
                            }
                        });
                        spacesToRobotIds.FindAll(t => t.Item2.Count > 1).ForEach(t =>
                                                                                 t.Item2.ForEach(r => {
                            Tuple <short, Tuple <int, int> > pairToRemove = new Tuple <short, Tuple <int, int> >(r.Item1, t.Item1);
                            if (r.Item2)
                            {
                                resolveEvent.robotIdToSpawn.Remove(pairToRemove);
                            }
                            else
                            {
                                resolveEvent.robotIdToMove.Remove(pairToRemove);
                            }
                            resolveEvent.robotIdsBlocked.Add(r.Item1);
                            valid = false;
                        })
                                                                                 );

                        // Spawn x Still
                        List <Tuple <short, Tuple <int, int> > > spawnsToBlock = resolveEvent.robotIdToSpawn.FindAll(t => {
                            Robot other = allRobots.Find(r => r.position.Equals(t.Item2));
                            if (other == null)
                            {
                                return(false);
                            }
                            return(!resolveEvent.robotIdToMove.Any(m => other.id.Equals(m.Item1)));
                        });
                        spawnsToBlock.ForEach(t => {
                            resolveEvent.robotIdToSpawn.Remove(t);
                            resolveEvent.robotIdsBlocked.Add(t.Item1);
                            valid = false;
                        });

                        // Move x Still/Swap
                        List <Tuple <short, Tuple <int, int> > > movesToBlock = resolveEvent.robotIdToMove.FindAll(t => {
                            if (board.IsVoid(t.Item2) || board.IsBattery(t.Item2))
                            {
                                return(true);
                            }
                            Robot self  = allRobots.Find(r => r.id.Equals(t.Item1));
                            Robot other = allRobots.Find(r => r.position.Equals(t.Item2));
                            if (other == null)
                            {
                                return(false);
                            }
                            return(!resolveEvent.robotIdToMove.Any(m => other.id.Equals(m.Item1) && !self.position.Equals(m.Item2)));
                        });
                        movesToBlock.ForEach(t => {
                            resolveEvent.robotIdToMove.Remove(t);
                            resolveEvent.robotIdsBlocked.Add(t.Item1);
                            valid = false;
                        });
                    }
                    priorityEvents.Add(resolveEvent);

                    List <Tuple <short, short> > delayResolved = resolveEvent.robotIdToHealth.FindAll(h =>
                                                                                                      resolveEvent.robotIdToMove.Any(m => m.Item1.Equals(h.Item1)) ||
                                                                                                      resolveEvent.robotIdsBlocked.Any(b => b.Equals(h.Item1))
                                                                                                      );
                    if (delayResolved.Count > 0)
                    {
                        delayResolved.ForEach(t => resolveEvent.robotIdToHealth.Remove(t));
                        ResolveEvent delayResolveEvent = new ResolveEvent();
                        delayResolveEvent.robotIdToHealth = delayResolved;
                        priorityEvents.Add(delayResolveEvent);
                    }


                    resolveEvent.robotIdToSpawn.ForEach(t => {
                        GetRobot(t.Item1).position = t.Item2;
                    });
                    resolveEvent.robotIdToMove.ForEach(t => {
                        GetRobot(t.Item1).position = t.Item2;
                    });
                    resolveEvent.robotIdToHealth.ForEach(t => {
                        Robot r  = GetRobot(t.Item1);
                        r.health = t.Item2;
                    });
                }

                robotIdToTurnObject.Keys.ToList().ForEach((k) => robotIdToTurnObject.GetValueOrDefault(k).isActive = !GetRobot(k).position.Equals(Map.NULL_VEC));

                priorityEvents.AddRange(processPriorityFinish(primary.team, true));
                priorityEvents.AddRange(processPriorityFinish(secondary.team, false));

                priorityEvents.ForEach(e =>
                {
                    e.priority         = (byte)p;
                    primary.battery   -= e.primaryBatteryCost;
                    secondary.battery -= e.secondaryBatteryCost;
                });
                events.AddRange(priorityEvents);
                if (primary.battery <= 0 || secondary.battery <= 0)
                {
                    EndEvent e = new EndEvent();
                    e.primaryLost          = primary.battery <= 0;
                    e.secondaryLost        = secondary.battery <= 0;
                    e.primaryBatteryCost   = Math.Max(primary.battery, (short)0);
                    e.secondaryBatteryCost = Math.Max(secondary.battery, (short)0);
                    e.turnCount            = turn;
                    events.Add(e);
                    break;
                }
            }
            return(events);
        }