public void UpdateTankActionSituation(TankSituation tankSituation, TankAction tankAction, GameState newGameState)
        {
            TankAction[] tankActions = new TankAction[] { TankAction.NONE, TankAction.NONE, TankAction.NONE, TankAction.NONE };
            tankActions[tankSituation.Tank.Index] = tankAction;
            List <Point> wallsRemoved = new List <Point>();

            MutableGameStateEngine.ApplyAllActions(newGameState as MutableGameState, tankActions, wallsRemoved);
            bool isAdjacentWallRemoved = false;

            if (!tankSituation.TankState.IsActive)
            {
                IsValid = (TankAction == TankAction.NONE);
                return;
            }
            else
            {
                IsValid = true;
            }

            if (tankAction == TankAction.FIRE)
            {
                Direction    movementDir = tankSituation.TankState.Dir;
                TankLocation tankLoc
                    = Game.Current.Turns[newGameState.Tick].CalculationCache.TankLocationMatrix[tankSituation.TankState.Pos];
                Point adjacentWallPoint = tankLoc.OutsideEdgesByDirection[(int)movementDir].CentreCell.Position;
                isAdjacentWallRemoved = wallsRemoved.Any(
                    wallPoint => wallPoint == adjacentWallPoint
                    );
            }

            NewGameState          = newGameState;
            WallsRemoved          = wallsRemoved.ToArray();
            IsAdjacentWallRemoved = isAdjacentWallRemoved;
            NewTankState          = NewGameState.GetMobileState(TankSituation.Tank.Index);
        }
Ejemplo n.º 2
0
 public override void ApplyActions(TankAction[] tankActions)
 {
     MutableGameStateEngine.ApplyAllActions(this, tankActions);
 }
Ejemplo n.º 3
0
        private void CheckGameState()
        {
            GameState calculatedGameState = PrevGameState.Clone();

            calculatedGameState.Tick = Game.Current.CurrentTurn.Tick;
            if (calculatedGameState is MutableGameState)
            {
                MutableGameStateEngine.ApplyAllActions((MutableGameState)calculatedGameState, TankActionsTaken);
            }
            else
            if (calculatedGameState is ImmutableGameState)
            {
                ImmutableGameStateEngine.ApplyActions((ImmutableGameState)calculatedGameState, TankActionsTaken);
            }
            else
            {
                throw new InvalidOperationException(
                          String.Format(
                              "The calculated game state on turn {0} can't be cast to a known game state type",
                              Game.Current.CurrentTurn.Tick
                              )
                          );
            }

            calculatedGameState.Outcome |= Outcome.InProgress;
            Game.Current.CurrentTurn.GameStateCalculatedByGameStateEngine = calculatedGameState;

            string reasonDifferent;

            if (!GameState.AreGameStatesEquivalent(NewGameState, calculatedGameState, out reasonDifferent))
            {
                LogDebugMessage(
                    "ERROR! The calculated game state does not match the new harness game state. \r\nReason: {0}",
                    reasonDifferent);

#if THROW_HARNESS_ERRORS
                throw new ApplicationException(
                          String.Format(
                              "The calculated game state does not match the new harness game state. \r\nReason: {0}",
                              reasonDifferent
                              )
                          );
#endif

                // Workaround for a bug in the Entelect test harness on tick 1.
                // Copy calculated game state into retrieved game state:
                if (NewGameState.Tick == 1)
                {
                    BitMatrix destWalls = NewGameState.Walls;
                    BitMatrix srcWalls  = calculatedGameState.Walls;

                    // Copy walls from calculated game state:
                    for (int x = destWalls.TopLeft.X; x <= destWalls.BottomRight.X; x++)
                    {
                        for (int y = destWalls.TopLeft.Y; y <= destWalls.BottomRight.Y; y++)
                        {
                            destWalls[x, y] = srcWalls[x, y];
                        }
                    }

                    // Copy mobile states:
                    for (int i = 0; i < Constants.MOBILE_ELEMENT_COUNT; i++)
                    {
                        MobileState calculatedMobileState = calculatedGameState.GetMobileState(i);
                        NewGameState.SetMobileState(i, ref calculatedMobileState);
                    }
                }
            }
        }
Ejemplo n.º 4
0
        protected override void ChooseMoves()
        {
            GameState currGameState = Game.Current.CurrentTurn.GameState;

            TankAction[] tankActionsForLiveTank = new TankAction[]
            {
                TankAction.UP,
                TankAction.DOWN,
                TankAction.FIRE,
                TankAction.LEFT,
                TankAction.RIGHT,
                TankAction.NONE
            };
            TankAction[] tankActionsForDeadTank = new TankAction[]
            {
                TankAction.NONE
            };

            TankAction[][] tankActionsPerTank = new TankAction[Constants.TANK_COUNT][];

            foreach (Tank tank in You.Tanks)
            {
                MobileState mobileState = currGameState.GetMobileState(tank.Index);
                if (mobileState.IsActive)
                {
                    // Check if needing to avoid a bullet or shoot a bullet on the path to the base or the tank itself
                    // If so, limit the actions to only those that allow avoiding the bullet

                    tankActionsPerTank[tank.Number] = tankActionsForLiveTank;
                }
                else
                {
                    tankActionsPerTank[tank.Number] = tankActionsForDeadTank;
                }
            }

            double[,] valueEstimates = new double[tankActionsPerTank[0].Length, tankActionsPerTank[1].Length];
            GameStateValueEstimator valueEstimator = new GameStateValueEstimator();

            valueEstimator.Player = You;

            Tank   tank0     = You.Tanks[0];
            Tank   tank1     = You.Tanks[1];
            double bestValue = double.NegativeInfinity;

            TankAction[] bestTankActions = null;

            for (int ta0 = 0; ta0 < tankActionsPerTank[0].Length; ta0++)
            {
                TankAction tankAction0 = tankActionsPerTank[0][ta0];

                for (int ta1 = 0; ta1 < Constants.TANK_COUNT; ta1++)
                {
                    TankAction tankAction1 = tankActionsPerTank[1][ta1];

                    GameState gameStateClone = currGameState.Clone();
                    gameStateClone.Tick++;

                    TankAction[] tankActions = new TankAction[Constants.TANK_COUNT];
                    tankActions[tank0.Index] = tankAction0;
                    tankActions[tank1.Index] = tankAction1;
                    MutableGameStateEngine.ApplyAllActions(gameStateClone as MutableGameState, tankActions);
                    valueEstimator.GameState = gameStateClone;
                    double value = valueEstimator.Evaluate();
                    if (value > bestValue)
                    {
                        bestValue       = value;
                        bestTankActions = tankActions;
                    }
                }
            }
            TankActionSet actionSet = new TankActionSet(YourPlayerIndex, currGameState.Tick);

            if (bestTankActions != null)
            {
                actionSet.Actions[tank0.Number] = bestTankActions[tank0.Number];
                actionSet.Actions[tank1.Number] = bestTankActions[tank1.Number];
            }

            Coordinator.SetBestMoveSoFar(actionSet);
        }