public override PlayerAction Play(Tank tank) { if (TankHelper.EnemyInFront(tank, Opponent.Tank1, Opponent.Tank2, map)) { return(PlayerActionHelper.GetAttackAction(tank)); } MyWanderingTank myTank = MyWanderingTank.GetMyTank(tank); PlayerAction pAction = new PlayerAction(); Block currentBlock = map.Blocks[tank.X, tank.Y]; BlockNeighbours neighbours = map.GetNeighbours(currentBlock); Block frontBlock = neighbours.GetNeighbour(tank.Direction); if (myTank.Turned) { pAction.PlayerActionType = PlayerActionType.Forward; pAction.Direction = tank.Direction; myTank.Turned = false; return(pAction); } if (MathHelper.GetRandomNumber(0, 3) != 0 && frontBlock != null && frontBlock.Pattern == Pattern.Clear) { pAction.PlayerActionType = PlayerActionType.Forward; pAction.Direction = tank.Direction; myTank.Turned = false; return(pAction); } //Turn int randomNumber = MathHelper.GetRandomNumber(0, 100) + myTank.Number;// % 4; var myNeighbours = map.GetNeighbours(currentBlock); var passableBlocks = myNeighbours.Neighbours.Where(c => c.Passable && c != frontBlock).ToList(); myTank.Turned = true; var passableBlocksCount = passableBlocks.Count(); if (passableBlocksCount == 0) { pAction.PlayerActionType = PlayerActionType.Forward; pAction.Direction = tank.Direction; myTank.Turned = false; return(pAction); } var index = randomNumber % passableBlocksCount; var nextBlock = passableBlocks[index]; pAction.Direction = DirectionHelper.GetDirection(currentBlock.X, currentBlock.Y, nextBlock.X, nextBlock.Y); pAction.PlayerActionType = PlayerActionType.Turn; return(pAction); }
public override PlayerAction Play(Tank tank) { if (TankHelper.EnemyInFront(tank, Opponent.Tank1, Opponent.Tank2, map)) { return(PlayerActionHelper.GetAttackAction(tank)); } PlayerAction pAction = new PlayerAction(); Block currentBlock = map.Blocks[tank.X, tank.Y]; BlockNeighbours neighbours = map.GetNeighbours(currentBlock); Block frontBlock = neighbours.GetNeighbour(tank.Direction); Block[] nextDistinations = Opponent.Flag.GetCloser(tank.X, tank.Y); //If moving forward makes the tank closer to enemy flag, move forward. if (frontBlock != null && frontBlock.Pattern == Pattern.Clear) { foreach (Block b in nextDistinations) { if (b == frontBlock) { pAction.PlayerActionType = PlayerActionType.Forward; pAction.Direction = tank.Direction; return(pAction); } } } if (Opponent.Flag.Captured) { pAction.PlayerActionType = PlayerActionType.Turn; return(pAction); } //Turn toward one of the next distinations. pAction.Direction = currentBlock.GetDirection(nextDistinations[0]); pAction.PlayerActionType = PlayerActionType.Turn; return(pAction); }
public override PlayerAction Play(Tank tank) { this.tank = tank; //if there is an enemy, fire.; if (TankHelper.EnemyInFront(tank, Opponent.Tank1, Opponent.Tank2, map)) { return(PlayerActionHelper.GetAttackAction(tank)); } var neighbourhood = map.GetNeighbours(tank.X, tank.Y); Tank[] enemiesInSight = TankHelper.GetEnemyTanksInSight(tank, Opponent.Tank1, Opponent.Tank2, map); bool isUnderFire = false; if (enemiesInSight.Length > 0) { foreach (Tank t in enemiesInSight) { if (TankHelper.GetIsUnderFire(tank, t)) { isUnderFire = true; if (TankHelper.GetIsPointedBy(tank, t)) { return(PlayerActionHelper.GetTurnToAction(tank, t)); } } } //it is under fire but the enemy is not at back //then, go forward anyway, even if going forward leads to danger. if (isUnderFire) { return(PlayerActionHelper.GetForwardAction(tank)); } //if enemy is in sight but not pointing at me, //I turn and point at the enemy PlayerActionHelper.GetTurnToAction(tank, enemiesInSight.First()); } //Get the neighbouring blocks leading to enemy headquarter //Make the distance = distance - 1 var neighbours = neighbourhood.Neighbours; Block frontBlock = neighbourhood.GetNeighbour(tank.Direction); //distance = distance - 1 List <Block> nextDistinations = Opponent.Flag.GetCloser(tank.X, tank.Y).ToList(); //Go forward if frontblock makes the distance=distance-1 if (nextDistinations.Contains(frontBlock)) { var frontInsightTanks = TankHelper.GetEnemyTanksInSight(frontBlock.X, frontBlock.Y, Opponent.Tank1, Opponent.Tank2, map); if (frontInsightTanks.Length == 0) { return(PlayerActionHelper.GetForwardAction(tank)); } //if the next block is insight //and the next next block is clear and is not insight. //the tank can still get away from the enemy if (!TankHelper.GetIsUnderFire(frontBlock.X, frontBlock.Y, frontInsightTanks)) { var frontNeighbourhood = map.GetNeighbours(frontBlock); var frontFrontBlock = frontNeighbourhood.GetNeighbour(tank.Direction); if (frontFrontBlock != null && frontFrontBlock.Passable) { var frontFrontInsightTanks = TankHelper.GetEnemyTanksInSight(frontFrontBlock.X, frontFrontBlock.Y, Opponent.Tank1, Opponent.Tank2, map); if (frontFrontInsightTanks.Length == 0) { return(PlayerActionHelper.GetForwardAction(tank)); } } } nextDistinations.Remove(frontBlock); } //long randomNumber = DateTime.Now.Ticks; if (nextDistinations.Count != 0) { Block selectedBlock = nextDistinations[0]; return(PlayerActionHelper.GetTurnToAction(tank, selectedBlock)); } //if nextDistinations.Count==0 Block selectedBlock2 = neighbourhood.Neighbours[0]; return(PlayerActionHelper.GetTurnToAction(tank, selectedBlock2)); }
public static double[] CollectFeatures(Tank tank, Map map, IPlayer opponent) { double[] x = new double[FeatureCount]; int i = 0; //Enemy in front x[i++] = TankHelper.EnemyInFront(tank, opponent.Tank1, opponent.Tank2, map).ToInt(); //If a tank face one direction, it never turns to that direction. //Direction of the tank //A tank cannot turn to its direction. x[i++] = (tank.Direction == Direction.Up).ToInt(); x[i++] = (tank.Direction == Direction.Right).ToInt(); x[i++] = (tank.Direction == Direction.Down).ToInt(); x[i++] = (tank.Direction == Direction.Left).ToInt(); //Danger from and underfire { Tuple <bool, bool> dangerousAndUnderFire_up = TankHelper.GetIsInDangerAndUnderFire(tank.X, tank.Y, Common.Direction.Up, map, opponent.Tank1, opponent.Tank2); x[i++] = dangerousAndUnderFire_up.Item1.ToInt(); x[i++] = dangerousAndUnderFire_up.Item2.ToInt(); } { Tuple <bool, bool> dangerousAndUnderFire_right = TankHelper.GetIsInDangerAndUnderFire(tank.X, tank.Y, Common.Direction.Right, map, opponent.Tank1, opponent.Tank2); x[i++] = dangerousAndUnderFire_right.Item1.ToInt(); x[i++] = dangerousAndUnderFire_right.Item2.ToInt(); } { Tuple <bool, bool> dangerousAndUnderFire_down = TankHelper.GetIsInDangerAndUnderFire(tank.X, tank.Y, Common.Direction.Down, map, opponent.Tank1, opponent.Tank2); x[i++] = dangerousAndUnderFire_down.Item1.ToInt(); x[i++] = dangerousAndUnderFire_down.Item2.ToInt(); } { Tuple <bool, bool> dangerousAndUnderFire_left = TankHelper.GetIsInDangerAndUnderFire(tank.X, tank.Y, Common.Direction.Left, map, opponent.Tank1, opponent.Tank2); x[i++] = dangerousAndUnderFire_left.Item1.ToInt(); x[i++] = dangerousAndUnderFire_left.Item2.ToInt(); } //Neighbouring blocks properties //For turning var neighbourhood = map.GetNeighbours(tank.X, tank.Y); BlockProperties up_properties = GetProperties(tank, neighbourhood.Up, opponent, map); BlockProperties right_properties = GetProperties(tank, neighbourhood.Right, opponent, map); BlockProperties down_properties = GetProperties(tank, neighbourhood.Down, opponent, map); BlockProperties left_properties = GetProperties(tank, neighbourhood.Left, opponent, map); up_properties.Assign(ref x, ref i); right_properties.Assign(ref x, ref i); down_properties.Assign(ref x, ref i); left_properties.Assign(ref x, ref i); //Get Forward Block Properties //It is important, Indicates going forward or not. BlockProperties front_properties;// = GetNeighbourProperties(tank, neighbourhood.GetNeighbour(tank.Direction), opponent, map); switch (tank.Direction) { case Direction.Up: front_properties = up_properties; break; case Direction.Right: front_properties = right_properties; break; case Direction.Down: front_properties = down_properties; break; case Direction.Left: default: front_properties = left_properties; break; } front_properties.Assign(ref x, ref i); Block frontBlock = neighbourhood.GetNeighbour(tank.Direction); var frontNeighbourhood = map.GetNeighbours(frontBlock); BlockProperties front_front_properties = GetProperties(tank, neighbourhood.GetNeighbour(tank.Direction), opponent, map); front_front_properties.Assign(ref x, ref i); bool rush = front_properties.Passable && front_properties.InDanger && !front_properties.UnderFire && front_front_properties.Passable && !front_front_properties.InDanger; x[i++] = rush.ToInt(); return(x); }