コード例 #1
0
        public Beam(TankOperation operation, Grid grid, SignalWeights weights)
        {
            StartAction = operation.GetAction();
            EvalState startingState = new EvalState(operation.GetAction(), grid);

            bestStates[0] = operation.GetScore(startingState, weights);
        }
コード例 #2
0
 public bool Back(int pixels)
 {
     this.amount = pixels;
     this.action = TankAction.Back;
     this.autoReset.WaitOne();
     return lastActionSuccess;
 }
コード例 #3
0
ファイル: TankClient.cs プロジェクト: leesjensen/TurboTank
        public TestTankClient(DynObject startResponse, TankAction expectedAction, DynObject takeActionResponse = null)
        {
            this.expectedAction = expectedAction;
            this.startResponse = startResponse;

            if (takeActionResponse == null)
            {
                takeActionResponse = DynObject.Parse(@"{
                    'status': 'won',
                    'health': 200,
                    'energy': 10,
                    'orientation': 'north',
                    'grid': '________________________
            ___W_____WWWWWWWW_______
            ___W_W__________________
            ___W_W_______B__________
            ___W_W__________________
            ___W_W__________________
            _WWWWWWWWW___L____O_____
            _____W__________________
            _____W_WWWWW____________
            _________WWWWWWWW_______
            ________________________
            ___________WWWW_________
            __X_____________________
            ________________________
            ____WWW_________________
            ________________________'
                }");
            }

            this.takeActionResponse = takeActionResponse;
        }
コード例 #4
0
        public void DoBeforeUpdatingTheState(
            int currentTick,
            DateTime nextTickTimeOnServer,
            TimeSpan timeUntilNextTick,
            DateTime localTimeBeforeGetStatusCall,
            DateTime localTimeAfterGetStatusCall)
        {
            AllMobileStatesAccountedFor = new bool[Constants.MOBILE_ELEMENT_COUNT];

            TankActionsTaken = new TankAction[Constants.TANK_COUNT];
            for (int i = 0; i < TankActionsTaken.Length; i++)
            {
                TankActionsTaken[i] = TankAction.NONE;
            }

            PrevGameState        = Game.Current.CurrentTurn.GameState;
            NewGameState         = PrevGameState.Clone();
            NewGameState.Tick    = currentTick;
            NewGameState.Outcome = Outcome.InProgress;

            // TODO: Ideally the current turn should be updated as the very last step,
            // to prevent race conditions in scenarios where CurrentTurn is accessed
            // from another thread before the game state is fully updated:
            UpdateCurrentTurn(currentTick, nextTickTimeOnServer, timeUntilNextTick, localTimeBeforeGetStatusCall, localTimeAfterGetStatusCall);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        public override void ChooseMovesAsP(MoveResult moveResult)
        {
            Move move = moveResult.Move;

            LogDebugMessage("*** PROTAGONIST (P = {0}) ***", move.p);
            LogDebugMessage("Slack: {0}", moveResult.Slack);

            double valueOfMove = ScenarioValueFunctions.ClearRunAtBaseScenarioValueFunction.Evaluate(moveResult.Slack);

            LogDebugMessage("Value of move: {0}", valueOfMove);

            // Attack the enemy base:
            LogDebugMessage("Tank number: {0}", move.i);
            TankActionRecommendation recommendation
                = moveResult.GetRecommendedTankActionsByPlayerAndTankNumber(move.p, move.i);

            if (recommendation.IsAMoveRecommended)
            {
                TankSituation tankSituation         = GameSituation.GetTankSituationByPlayerAndTankNumber(move.p, move.i);
                TankAction    recommendedTankAction = recommendation.RecommendedTankAction;
                LogDebugMessage("Recommended tank action: {0}", recommendedTankAction);

                tankSituation.AdjustTankActionValue(recommendedTankAction, valueOfMove);
            }
            else
            {
                LogDebugMessage("No moves recommended");
            }
        }
コード例 #7
0
        public TestTankClient(DynObject startResponse, TankAction expectedAction, DynObject takeActionResponse = null)
        {
            this.expectedAction = expectedAction;
            this.startResponse  = startResponse;

            if (takeActionResponse == null)
            {
                takeActionResponse = DynObject.Parse(@"{
                    'status': 'won',
                    'health': 200,
                    'energy': 10,
                    'orientation': 'north',
                    'grid': '________________________
___W_____WWWWWWWW_______
___W_W__________________
___W_W_______B__________
___W_W__________________
___W_W__________________
_WWWWWWWWW___L____O_____
_____W__________________
_____W_WWWWW____________
_________WWWWWWWW_______
________________________
___________WWWW_________
__X_____________________
________________________
____WWW_________________
________________________'
                }");
            }

            this.takeActionResponse = takeActionResponse;
        }
コード例 #8
0
ファイル: TankClient.cs プロジェクト: leesjensen/TurboTank
        public dynamic TakeAction(TankAction move)
        {
            Dictionary<string, string> headers = new Dictionary<string, string>();
            headers.Add("X-Sm-Playerid", PlayerId);

            return client.GetJsonResponse("/game/" + GameId + "/" + move.ToString().ToLower(), "POST", "", headers);
        }
コード例 #9
0
        public override MoveResult EvaluateLeafNodeMove(Move move)
        {
            MobileState tankState_i = GetTankState_i(move);
            MobileState tankState_j = GetTankState_j(move);

            // Both tanks must be alive:
            if (!(tankState_i.IsActive && tankState_j.IsActive))
            {
                return(new MoveResult(move)
                {
                    EvaluationOutcome = ScenarioEvaluationOutcome.Invalid
                });
            }

            TankSituation tankSit_i = GetTankSituation(move.p, move.i);
            TankSituation tankSit_j = GetTankSituation(move.pBar, move.j);
            int           ticksUntilFriendlyTankCanFireAgain = tankSit_i.ExpectedNextTickWhenTankCanFireAgain - GameState.Tick;
            int           ticksUntilEnemyTankCanFireAgain    = tankSit_j.ExpectedNextTickWhenTankCanFireAgain - GameState.Tick;

            if (ticksUntilEnemyTankCanFireAgain <= 0 || ticksUntilFriendlyTankCanFireAgain > 0)
            {
                return(new MoveResult(move)
                {
                    EvaluationOutcome = ScenarioEvaluationOutcome.Invalid
                });
            }

            int attackDistance = GetAttackDistanceFromTankToTank(move.p, move.i, move.j);

            if (attackDistance - ticksUntilEnemyTankCanFireAgain > 5)
            {
                return(new MoveResult(move)
                {
                    EvaluationOutcome = ScenarioEvaluationOutcome.Invalid
                });
            }

            foreach (TankActionSituation tankActSit in tankSit_i.TankActionSituationsPerTankAction)
            {
                int A_p_i = GetAttackDistanceFromHypotheticalTankStateToTank(
                    tankActSit.NewTankState, move.pBar, move.j, TankHelper.EdgeOffsets);
                int    slack       = A_p_i - ticksUntilEnemyTankCanFireAgain;
                double attackValue = ScenarioValueFunctions.AttackDisarmedEnemyTankSlackUntilRearmedFunction.Evaluate(slack);
                tankActSit.Value += attackValue;
            }

            // Convert a good attacking position into killing the enemy tank, by weighting the attacking action more highly:
            TankAction[] attackActions = GetTankActionsFromTankToAttackTank(move.p, move.i, move.j);
            if (attackActions.Length > 0)
            {
                TankAction attackAction      = attackActions[0];
                double     attackActionValue = ScenarioValueFunctions.AttackDisarmedEnemyTankAttackActionFunction.Evaluate(attackDistance);
                tankSit_i.TankActionSituationsPerTankAction[(int)attackAction].Value += attackActionValue;
            }

            return(new MoveResult(move)
            {
                EvaluationOutcome = ScenarioEvaluationOutcome.Possible
            });
        }
コード例 #10
0
        public TankAction GetBestTankAction()
        {
            TankAction bestAction = TankAction.NONE;

            if (IsTankActionDetermined)
            {
                bestAction = ChosenTankAction;
            }
            else
            {
                double bestValue = double.NegativeInfinity;

                foreach (TankAction tankAction in TankHelper.TankActions)
                {
                    TankActionSituation tankActSit = TankActionSituationsPerTankAction[(int)tankAction];
                    if (tankActSit.IsValid)
                    {
                        double actionValue = tankActSit.Value;
                        if (actionValue > bestValue)
                        {
                            bestValue  = actionValue;
                            bestAction = tankAction;
                        }
                    }
                }
            }
            return(bestAction);
        }
コード例 #11
0
        public static TankAction[] GetTankActionsOnShortestPath(
            DirectionalMatrix <DistanceCalculation> distances, Direction dir, int x, int y)
        {
            DistanceCalculation distanceCalc = distances[dir, x, y];

            if (distanceCalc.Distance == Constants.UNREACHABLE_DISTANCE)
            {
                return(new TankAction[0]);
            }

            TankAction[] tankActions = new TankAction[distanceCalc.Distance];
            int          index       = distanceCalc.Distance;
            Node         node        = new Node(ActionType.Moving, dir, x, y);

            while (index != 0)
            {
                index--;
                tankActions[index] = node.Dir.ToTankAction();
                node = distanceCalc.AdjacentNode;
                if (node.ActionType == ActionType.Firing)
                {
                    index--;
                    tankActions[index] = TankAction.FIRE;
                    node = new Node(ActionType.Moving, node.Dir, node.X, node.Y);
                }
                distanceCalc = distances[node.Dir, node.X, node.Y];
            }
            return(tankActions);
        }
コード例 #12
0
        public override void ChooseMovesAsPBar(MoveResult moveResult)
        {
            Move move = moveResult.Move;

            LogDebugMessage("*** ANTAGONIST (PBar = {0}) ***", move.pBar);
            LogDebugMessage("Slack: {0}", moveResult.Slack);

            double valueOfMove = ScenarioValueFunctions.ClearRunAtBaseScenarioValueFunction.Evaluate(moveResult.Slack);

            LogDebugMessage("Value of move: {0}", valueOfMove);

            // Defend against an enemy attack on your base:
            for (int tankNumber = 0; tankNumber < Constants.TANKS_PER_PLAYER; tankNumber++)
            {
                LogDebugMessage("Tank number: {0}", tankNumber);
                TankActionRecommendation recommendation = moveResult.GetRecommendedTankActionsByPlayerAndTankNumber(move.pBar, tankNumber);
                if (recommendation.IsAMoveRecommended)
                {
                    TankSituation tankSituation
                        = GameSituation.GetTankSituationByPlayerAndTankNumber(move.pBar, tankNumber);
                    TankAction recommendedTankAction = recommendation.RecommendedTankAction;
                    LogDebugMessage("Recommended tank action: {0}", recommendedTankAction);

                    tankSituation.AdjustTankActionValue(recommendedTankAction, valueOfMove);
                }
                else
                {
                    LogDebugMessage("No moves recommended");
                }
            }
        }
コード例 #13
0
        public dynamic TakeAction(TankAction move)
        {
            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add("X-Sm-Playerid", PlayerId);

            return(client.GetJsonResponse("/game/" + GameId + "/" + move.ToString().ToLower(), "POST", "", headers));
        }
コード例 #14
0
 protected TankActionSet()
 {
     Actions = new TankAction[Constants.TANKS_PER_PLAYER];
     for (int i = 0; i < Constants.TANKS_PER_PLAYER; i++)
     {
         Actions[i] = TankAction.NONE;
     }
 }
コード例 #15
0
        public dynamic TakeAction(TankAction move)
        {
            if ((move & expectedAction) == 0)
            {
                throw new Exception("Got: " + move + ", expected: " + expectedAction);
            }

            return(takeActionResponse);
        }
コード例 #16
0
ファイル: EvalState.cs プロジェクト: leesjensen/TurboTank
        public EvalState(TankAction action, EvalState previousState, int score, Grid grid)
            : this(action, grid)
        {
            if (previousState.Evaluated)
            {
                this.previousState = previousState;
            }

            this.Score = previousState.Score + score;
        }
コード例 #17
0
ファイル: EvalState.cs プロジェクト: leesjensen/TurboTank
        public EvalState(TankAction action, EvalState previousState, int score, Grid grid)
            : this(action, grid)
        {
            if (previousState.Evaluated)
            {
                this.previousState = previousState;
            }

            this.Score = previousState.Score + score;
        }
コード例 #18
0
        // TODO: honour the timeoutInMilliseconds setting
        public bool TrySetActions(int playerIndex, TankAction tankAction1, TankAction tankAction2,
                                  ICommunicatorCallback callback, int timeoutInMilliseconds)
        {
            ChallengeClient client = new ChallengeClient(EndPointConfigurationName, Url);

            client.Open();
            try
            {
                try
                {
                    client.setActions(tankAction1.Convert(), tankAction2.Convert());
                    return(true);
                }
                catch (FaultException <EndOfGameException> endOfGameFault)
                {
                    LogDebugError(endOfGameFault, endOfGameFault.Message);
                    callback.UpdateGameOutcomeToLoseDueToError(playerIndex, endOfGameFault.Message);
                    return(false);
                }
                catch (FaultException <NoBlameException> noBlameFault)
                {
                    LogDebugError(noBlameFault, noBlameFault.Message);
                    callback.UpdateGameOutcomeDueToNoBlameCrash(noBlameFault.Message);
#if THROW_HARNESS_ERRORS
                    throw;
#else
                    return(false);
#endif
                }
                catch (EndpointNotFoundException endpointException)
                {
                    LogDebugError(endpointException, endpointException.Message);
                    callback.UpdateGameOutcomeDueToServerUnavailable(endpointException.Message);
#if THROW_HARNESS_ERRORS
                    throw;
#else
                    return(false);
#endif
                }
                catch (CommunicationException commsException)
                {
                    LogDebugError(commsException, commsException.Message);
                    callback.UpdateGameOutcomeDueToServerUnavailable(commsException.Message);
#if THROW_HARNESS_ERRORS
                    throw;
#else
                    return(false);
#endif
                }
            }
            finally
            {
                client.Close();
            }
        }
コード例 #19
0
 public static TankAction[] ConvertNodesToTankActions(Node[] nodes)
 {
     TankAction[] tankActions = new TankAction[nodes.Length];
     for (int i = 0; i < nodes.Length; i++)
     {
         Node       node       = nodes[i];
         TankAction tankAction = node.ActionType == ActionType.Firing ? TankAction.FIRE : node.Dir.ToTankAction();
         tankActions[i] = tankAction;
     }
     return(tankActions);
 }
コード例 #20
0
        public bool TrySetTankActions(TankActionSet actionSet, int timeoutInMilliseconds)
        {
            if (actionSet == null)
            {
                return(true);
            }

            if (actionSet.Tick != Game.Current.CurrentTurn.Tick)
            {
                LogDebugMessage("Tank actions not submitted as tick {0} is in the past", actionSet.Tick);
                return(false);
            }

            int        playerIndex      = actionSet.PlayerIndex;
            GameState  currentGameState = Game.Current.CurrentTurn.GameState;
            int        numberAlive      = 0;
            int        tankId           = -1;
            TankAction tankAction       = TankAction.NONE;
            int        tankNumber       = -1;

            for (int t = 0; t < Constants.TANKS_PER_PLAYER; t++)
            {
                Tank        tank      = Game.Current.Players[actionSet.PlayerIndex].Tanks[t];
                MobileState tankState = currentGameState.GetMobileState(tank.Index);
                if (tankState.IsActive)
                {
                    numberAlive++;
                    tankId     = tank.Id;
                    tankAction = actionSet.Actions[t];
                    tankNumber = tank.Number;
                }
            }

            LogDebugMessage("Sending tank actions for player {0}", Solver.YourPlayerIndex);

            if (numberAlive == 1)
            {
                LogDebugMessage("    Tank {0} action {1} (tank id: {2})", tankNumber, tankAction, tankId);
                return(Communicator.TrySetAction(playerIndex, tankId, tankAction, CommunicatorCallback, timeoutInMilliseconds));
            }
            else
            if (numberAlive == 2)
            {
                TankAction tankAction1 = actionSet.Actions[0];
                TankAction tankAction2 = actionSet.Actions[1];
                LogDebugMessage("    Tank 0 action {0}", tankAction1);
                LogDebugMessage("    Tank 1 action {0}", tankAction2);
                return(Communicator.TrySetActions(playerIndex, tankAction1, tankAction2, CommunicatorCallback, timeoutInMilliseconds));
            }
            else
            {
                return(true);
            }
        }
コード例 #21
0
    public TankAction GetNextAction(TankAction? previousAction)
    {
        if (TankAPI.CurrentState.TargetInSight)
            return TankAction.FireCannon;

        if (TankAPI.CurrentState[Direction.Front] > 1) {
            return TankAction.MoveForward;
        }

        return AvoidDeadEnd();
    }
コード例 #22
0
        public TankActionSet GenerateTankActions(int yourPlayerIndex, int tick)
        {
            TankActionSet tankActionSet = new TankActionSet(yourPlayerIndex, tick);

            foreach (Tank tank in Game.Current.Players[yourPlayerIndex].Tanks)
            {
                TankSituation tankSituation = TankSituationsByTankIndex[tank.Index];
                TankAction    bestAction    = tankSituation.GetBestTankAction();
                tankActionSet.Actions[tank.Number] = bestAction;
            }

            return(tankActionSet);
        }
コード例 #23
0
ファイル: Brain.cs プロジェクト: dliaskos/TankChallenge
    private Direction?DetectCloseIn(TankAction previousAction, TankState previousState, TankState currentState)
    {
        if (previousAction == TankAction.TurnLeft ||
            previousAction == TankAction.TurnRight)
        {
            return(null);
        }

        var closeIn = default(Direction?);

        var right_closeIn = false;
        var left_closeIn  = false;

        if (currentState[Direction.Left] < previousState[Direction.Left])
        {
            left_closeIn = true;
        }

        if (currentState[Direction.Right] < previousState[Direction.Right])
        {
            right_closeIn = true;
        }

        if (right_closeIn && left_closeIn)
        {
            if (currentState[Direction.Left] - previousState[Direction.Left] <=
                currentState[Direction.Right] - previousState[Direction.Right])
            {
                closeIn = Direction.Left;
            }
            else
            {
                closeIn = Direction.Right;
            }
        }
        else if (left_closeIn)
        {
            closeIn = Direction.Left;
        }
        else if (right_closeIn)
        {
            closeIn = Direction.Right;
        }

        if (closeIn.HasValue && currentState[closeIn.Value] == 1)
        {
            closeIn = null;
        }

        return(closeIn);
    }
コード例 #24
0
 private void LogActionsTaken()
 {
     for (int t = 0; t < Constants.TANK_COUNT; t++)
     {
         MobileState tankState = NewGameState.GetMobileState(t);
         if (tankState.IsActive)
         {
             Tank       tank        = Game.Current.Elements[t] as Tank;
             TankAction actionTaken = TankActionsTaken[t];
             LogDebugMessage("Player {0} tank {1} took action {2} and is now at {3}",
                             tank.PlayerNumber, tank.Number, actionTaken, tankState.Pos);
         }
     }
     DebugHelper.WriteLine();
 }
コード例 #25
0
        public static Direction ToDirection(this TankAction action, Direction currentDirection = Direction.NONE)
        {
            switch (action)
            {
            case TankAction.DOWN:
            case TankAction.LEFT:
            case TankAction.RIGHT:
            case TankAction.UP:
                return((Direction)action);

            default:
                // case TankAction.NONE:
                // case TankAction.FIRE:
                return(currentDirection);
            }
        }
コード例 #26
0
 public void ChooseTankAction(TankAction tankAction)
 {
     if (IsTankActionDetermined)
     {
         if (tankAction != ChosenTankAction)
         {
             throw new InvalidOperationException(
                       string.Format(
                           "The tank with index {0}) already has a chosen action of {1}. This can't be changed to {2}.",
                           Tank.Index, ChosenTankAction, tankAction));
         }
         return;
     }
     ChosenTankAction       = tankAction;
     IsTankActionDetermined = true;
 }
コード例 #27
0
        public override MoveResult EvaluateLeafNodeMove(Move move)
        {
            MobileState   tankState_i = GetTankState_i(move);
            TankSituation tankSit_i   = GetTankSituation(move.p, move.i);

            if (tankSit_i.IsLockedDown || !tankState_i.IsActive)
            {
                return(new MoveResult(move)
                {
                    EvaluationOutcome = ScenarioEvaluationOutcome.Invalid
                });
            }

            foreach (TankActionSituation tankActSit in tankSit_i.TankActionSituationsPerTankAction)
            {
                MobileState newTankState          = tankActSit.NewTankState;
                int         attackDistToEnemyBase = GetAttackDistanceToEnemyBaseFromTankState(YourPlayerIndex, ref newTankState);
                if (tankActSit.TankAction == TankAction.FIRE && tankActSit.IsAdjacentWallRemoved)
                {
                    Point       adjacentPos            = tankActSit.NewTankState.Pos + tankActSit.NewTankState.Dir.GetOffset();
                    MobileState adjacentState          = new MobileState(adjacentPos, tankActSit.NewTankState.Dir, isActive: true);
                    int         attackDistToEnemyBase2 = GetAttackDistanceToEnemyBaseFromTankState(YourPlayerIndex, ref adjacentState) + 1;
                    if (attackDistToEnemyBase2 < attackDistToEnemyBase)
                    {
                        attackDistToEnemyBase = attackDistToEnemyBase2;
                    }
                }
                double value = ScenarioValueFunctions.AttackEnemyBaseFunction.Evaluate(attackDistToEnemyBase);
                tankActSit.Value += value;
            }

            // Convert a good position into killing the enemy base, by weighting the attacking action more highly:
            int attackDistance = GetAttackDistanceToEnemyBaseFromTankState(move.i, ref tankState_i);

            TankAction[] attackActions = GetActionsToAttackEnemyBase(move.p, move.i);
            if (attackActions.Length > 0)
            {
                TankAction attackAction      = attackActions[0];
                double     attackActionValue = ScenarioValueFunctions.AttackEnemyBaseAttackActionFunction.Evaluate(attackDistance);
                tankSit_i.TankActionSituationsPerTankAction[(int)attackAction].Value += attackActionValue;
            }

            return(new MoveResult(move)
            {
                EvaluationOutcome = ScenarioEvaluationOutcome.Possible
            });
        }
コード例 #28
0
        public override MoveResult EvaluateLeafNodeMove(Move move)
        {
            TankSituation tankSituation = GetTankSituation(move.p, move.i);
            int           ticksUntil_p_i_CanFireAgain = tankSituation.ExpectedNextTickWhenTankCanFireAgain - GameState.Tick;
            int           worstSlack = -Constants.UNREACHABLE_DISTANCE;
            TankAction    tankActionToAddressWorstSlack = TankAction.NONE;
            bool          isScenarioApplicable          = false;

            foreach (BulletSituation bulletSituation in GameSituation.BulletSituationsByTankIndex)
            {
                if (bulletSituation == null)
                {
                    continue;
                }

                EvaluateBulletSituation(move, tankSituation, bulletSituation,
                                        ticksUntil_p_i_CanFireAgain, ref worstSlack, ref tankActionToAddressWorstSlack, ref isScenarioApplicable);
            }

            if (isScenarioApplicable)
            {
                MoveResult moveResult = new MoveResult(move)
                {
                    Slack = worstSlack,
                    EvaluationOutcome
                        = worstSlack < -10
                        ? ScenarioEvaluationOutcome.Possible
                        : (worstSlack <= 0
                          ? ScenarioEvaluationOutcome.Close
                          : ScenarioEvaluationOutcome.Current
                           )
                };
                moveResult.RecommendedTankActionsByTankIndex[tankSituation.Tank.Index]
                    = new TankActionRecommendation {
                    IsAMoveRecommended = true, RecommendedTankAction = tankActionToAddressWorstSlack
                    };
                return(moveResult);
            }
            else
            {
                return(new MoveResult(move)
                {
                    EvaluationOutcome = ScenarioEvaluationOutcome.Invalid
                });
            }
        }
        public override MoveResult EvaluateLeafNodeMove(Move move)
        {
            MobileState tankState_i = GetTankState_i(move);
            MobileState tankState_j = GetTankState_j(move);

            // Both tanks must be alive:
            if (!(tankState_i.IsActive && tankState_j.IsActive))
            {
                return(new MoveResult(move)
                {
                    EvaluationOutcome = ScenarioEvaluationOutcome.Invalid
                });
            }

            TankSituation tankSit_i = GetTankSituation(move.p, move.i);

            // Weight for distance to attack enemy over the long haul versus having the upper hand in the encounter in the short term:
            foreach (TankActionSituation tankActSit in tankSit_i.TankActionSituationsPerTankAction)
            {
                int A_p_i = GetAttackDistanceFromHypotheticalTankStateToTank(
                    tankActSit.NewTankState, move.pBar, move.j, TankHelper.EdgeOffsets);
                int A_pBar_j = GetAttackDistanceFromTankToHypotheticalTankAtPoint(
                    move.pBar, move.j, tankActSit.NewTankState.Pos, TankHelper.EdgeOffsets);
                int    attackDiffSlack = A_p_i - A_pBar_j;
                double attackValue     = ScenarioValueFunctions.GrappleWithEnemyTankAttackFunction.Evaluate(A_p_i);
                double grappleValue    = ScenarioValueFunctions.GrappleWithEnemyTankAttackDiffFunction.Evaluate(attackDiffSlack);
                tankActSit.Value += attackValue + grappleValue;
            }

            // Convert a good attacking position into killing the enemy tank, by weighting the attacking action more highly:
            int attackDistance = GetAttackDistanceFromTankToTank(move.p, move.i, move.j);

            TankAction[] attackActions = GetTankActionsFromTankToAttackTank(move.p, move.i, move.j);
            if (attackActions.Length > 0)
            {
                TankAction attackAction      = attackActions[0];
                double     attackActionValue = ScenarioValueFunctions.GrappleWithEnemyTankAttackActionFunction.Evaluate(attackDistance);
                tankSit_i.TankActionSituationsPerTankAction[(int)attackAction].Value += attackActionValue;
            }

            return(new MoveResult(move)
            {
                EvaluationOutcome = ScenarioEvaluationOutcome.Possible
            });
        }
コード例 #30
0
ファイル: Game.cs プロジェクト: leesjensen/TurboTank
        public void Run(SignalWeights weights)
        {
            dynamic joinResponse = client.Start();

            turnTimeout = (joinResponse.config.turn_timeout / 1000) - 5000;
            Grid grid = new Grid();

            Status status = ParseStatus(joinResponse, grid);

            while (status == Status.Running)
            {
                numberOfTurns++;

                TankAction action       = GetBestAction(grid, weights);
                dynamic    moveResponse = client.TakeAction(action);
                status = ParseStatus(moveResponse, grid);
            }
        }
        public override void ChooseMovesAsP(MoveResult moveResult)
        {
            Move        move        = moveResult.Move;
            MobileState tankState_j = GetTankState_j(move);

            TankAction[] attackActions = GetTankActionsFromTankToAttackTankAtPointAlongDirectionOfMovement(
                move.p, move.i, tankState_j.Pos, move.dir1, TankHelper.EdgeOffsets,
                keepMovingCloserOnFiringLastBullet: false);
            if (attackActions.Length > 0)
            {
                int attackDistance = GetAttackDistanceFromTankToTankAtPointAlongDirectionOfMovement(
                    move.p, move.i, tankState_j.Pos, move.dir1, TankHelper.EdgeOffsets);
                TankAction    attackAction      = attackActions[0];
                double        attackActionValue = ScenarioValueFunctions.AttackLockedDownEnemyTankFunction.Evaluate(attackDistance);
                TankSituation tankSit_i         = GetTankSituation(move.p, move.i);
                tankSit_i.TankActionSituationsPerTankAction[(int)attackAction].Value += attackActionValue;
            }
        }
コード例 #32
0
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public TankAction GetNextAction(TankAction? previousAction)
    {
        var nextAction = default(TankAction);

        if (previousAction.HasValue &&
            previousAction.Value == TankAction.TryToShoot &&
            TankAPI.CurrentState.TargetInSight) {

            nextAction = TankAction.TryToShoot;
            Console.WriteLine("--DEBUG: ShootTurnShoot TryShoot AGAIN!");

        } else {
            nextAction = _queue.Dequeue();
        }

        Console.WriteLine("--DEBUG: ShootTurnShoot Action: {0}", nextAction);

        return nextAction;
    }
コード例 #33
0
ファイル: Brain.cs プロジェクト: JimLiaskos/TankChallenge
    private Direction? DetectCloseIn(TankAction previousAction, TankState previousState, TankState currentState)
    {
        if (previousAction == TankAction.TurnLeft ||
            previousAction == TankAction.TurnRight) {

            return null;
        }

        var closeIn = default(Direction?);

        var right_closeIn = false;
        var left_closeIn = false;

        if (currentState[Direction.Left] < previousState[Direction.Left])
            left_closeIn = true;

        if (currentState[Direction.Right] < previousState[Direction.Right])
            right_closeIn = true;

        if (right_closeIn && left_closeIn) {

            if (currentState[Direction.Left] - previousState[Direction.Left] <=
                currentState[Direction.Right] - previousState[Direction.Right]) {

                closeIn = Direction.Left;
            } else {

                closeIn = Direction.Right;
            }

        } else if (left_closeIn) {
            closeIn = Direction.Left;
        } else if (right_closeIn) {
            closeIn = Direction.Right;
        }

        if (closeIn.HasValue && currentState[closeIn.Value] == 1)
            closeIn = null;

        return closeIn;
    }
コード例 #34
0
        public void UpdateTankState(int unitId, TankAction tankAction,
                                    Point newPos, Direction newDir, bool isActive)
        {
            bool tankFound = false;

            for (int t = 0; t < Constants.TANK_COUNT; t++)
            {
                Tank tank = Game.Current.Elements[t] as Tank;
                if (tank.Id == unitId)
                {
                    MobileState newMobileState = new MobileState(newPos, newDir, isActive);
                    NewGameState.SetMobileState(t, ref newMobileState);
                    TankActionsTaken[tank.Index] = tankAction;
                    tankFound = true;
                    AllMobileStatesAccountedFor[tank.Index] = true;
                    break;
                }
            }

            /* TODO: Else find a likely matching tank in the previous game state based on position and direction: */

#if DEBUG
            if (!tankFound)
            {
                LogDebugMessage("ERROR! No existing tank could be found with id {0} at position ({1}, {2})",
                                unitId, newPos.X, newPos.Y);

#if THROW_HARNESS_ERRORS
                throw new InvalidOperationException(
                          String.Format(
                              "No existing tank could be found with id {0} at position ({1}, {2})",
                              unitId, newPos.X, newPos.Y)
                          );
#endif
            }
#endif
        }
コード例 #35
0
        private static int InitializePlayersAndUnitsAndGetYourPlayerIndex(game wsGame, ICommunicatorCallback callback)
        {
            int yourPlayerIndex = -1;  // To keep the compiler happy

            for (int playerIndex = 0; playerIndex < wsGame.players.Length; playerIndex++)
            {
                player wsPlayer   = wsGame.players[playerIndex];
                string playerName = wsPlayer.name;
                bool   isYou      = false;
                if (playerName == wsGame.playerName)
                {
                    yourPlayerIndex = playerIndex;
                    isYou           = true;
                }
                Point basePos = new Point((short)[email protected], (short)[email protected]);
                callback.InitializePlayer(playerIndex, playerName, basePos, isYou);

                // Set up the tanks:
                for (int tankNumber = 0; tankNumber < wsPlayer.units.Length; tankNumber++)
                {
                    unit      tankUnit            = wsPlayer.units[tankNumber];
                    int       unitId              = tankUnit.id;
                    Point     initialTankPosition = new Point((short)tankUnit.x, (short)tankUnit.y);
                    Direction initialTankDirection
                        = tankUnit.directionSpecified
                        ? tankUnit.direction.Convert()
                        : Direction.NONE;
                    TankAction initialTankAction
                        = tankUnit.actionSpecified
                        ? tankUnit.action.Convert()
                        : TankAction.NONE;

                    callback.InitializeTank(playerIndex, tankNumber, unitId, ref initialTankPosition, initialTankDirection, initialTankAction);
                }
            }
            return(yourPlayerIndex);
        }
コード例 #36
0
        public static action Convert(this TankAction tankAction)
        {
            switch (tankAction)
            {
            case TankAction.DOWN:
                return(global::action.DOWN);

            case TankAction.FIRE:
                return(global::action.FIRE);

            case TankAction.LEFT:
                return(global::action.LEFT);

            case TankAction.RIGHT:
                return(global::action.RIGHT);

            case TankAction.UP:
                return(global::action.UP);

            default:
                // case TankAction.NONE
                return(global::action.NONE);
            }
        }
コード例 #37
0
 public TankController(Tank tank)
 {
     this.action = TankAction.None;
     this.Tank = tank;
     this.autoReset = new AutoResetEvent(false);
 }
コード例 #38
0
 public void TurnRight(int degrees)
 {
     this.amount = degrees;
     this.action = TankAction.Right;
     this.autoReset.WaitOne();
 }
コード例 #39
0
 public void TurnGunLeft(int degrees)
 {
     this.amount = degrees;
     this.action = TankAction.TurretLeft;
     this.autoReset.WaitOne();
 }
コード例 #40
0
ファイル: TankAPI.cs プロジェクト: JimLiaskos/TankChallenge
    public static void PerformAction(TankAction action)
    {
        var apiAction = default(System.Action);

        switch (action) {
            case TankAction.FireCannon:
                apiAction = API.FireCannon;
                break;

            case TankAction.MoveForward:
                apiAction = API.MoveForward;

                _currentPosition = _currentPosition +
                    CompassMapping.GetDirectionSign(_currentDirection) *
                    CompassMapping.GetDirectionOffset(_currentDirection, (uint) 1);

                break;

            case TankAction.MoveBackward:
                apiAction = API.MoveBackward;

                var oppsiteDirection = CompassMapping.GetOppositeDirection(_currentDirection);

                _currentPosition = _currentPosition +
                    CompassMapping.GetDirectionSign(oppsiteDirection) *
                    CompassMapping.GetDirectionOffset(oppsiteDirection, (uint) 1);

                break;

            case TankAction.TurnLeft:
                apiAction = API.TurnLeft;

                _currentDirection = CompassMapping.GetNewDirection(
                    _currentDirection, Compass.West);

                break;

            case TankAction.TurnRight:
                apiAction = API.TurnRight;

                _currentDirection = CompassMapping.GetNewDirection(
                    _currentDirection, Compass.East);

                break;

            case TankAction.TryToShoot:
                apiAction = () => {
                    if (CurrentState.TargetInSight)
                        API.FireCannon();
                };
                break;

            default:
                apiAction = null;
                break;
        }

        if (apiAction == null) {
            throw new ApplicationException(string.Format("Unknown TankAction: {0}", (int) action));
        }

        TankAPI.ConsumeTurn(apiAction);
    }
コード例 #41
0
        private void EvaluateBulletSituation(Move move, TankSituation tankSituation, BulletSituation bulletSituation,
                                             int ticksUntil_p_i_CanFireAgain, ref int worstSlack, ref TankAction tankActionToAddressWorstSlack,
                                             ref bool isScenarioApplicable)
        {
            bool       isScenarioApplicableForThisBulletSituation = false;
            int        bestSlackForThisBulletSituation            = Constants.UNREACHABLE_DISTANCE;
            TankAction bestTankActionForThisBulletSituation       = TankAction.NONE;

            foreach (BulletCalculationByTick bulletCalc in bulletSituation.BulletCalculationsByTick)
            {
                if (!bulletCalc.AreTanksAtRisk)
                {
                    continue;
                }
                int ticksToEscape = bulletCalc.Tick - GameState.Tick;
                if (ticksToEscape < 0)
                {
                    continue;
                }

                // Are you in the firing line:
                if (bulletCalc.TankCentrePointsThatDie.ContainsPoint(tankSituation.TankState.Pos))
                {
                    List <BulletSurvivalTactic> bulletTactics = new List <BulletSurvivalTactic>();
                    isScenarioApplicableForThisBulletSituation = true;

                    // Suppose the bullet just misses the tank on turn n, with t ticks to escape...
                    int closestEscapeTick  = ticksToEscape * 2 / 3;  // 2t - n + 1 = 2n + 1 so 3n = 2t
                    int furthestEscapeTick = 2 * ticksToEscape + 1;  // 2t + n + 1 = 2n so n = 2t + 1

                    for (int tk = closestEscapeTick; tk <= furthestEscapeTick; tk++)
                    {
                        if (tk >= bulletSituation.BulletCalculationsByTick.Length)
                        {
                            break;
                        }
                        BulletCalculationByTick bulletCalc_tk = bulletSituation.BulletCalculationsByTick[tk];
                        if (!bulletCalc_tk.AreTanksAtRisk)
                        {
                            break;
                        }
                        ticksToEscape = bulletCalc_tk.Tick - GameState.Tick;

                        // Fire at the bullet:
                        foreach (MobileState headOnState in bulletCalc_tk.ClosestTankStatesThatCanShootBulletHeadOn)
                        {
                            // Move into position to confront the bullet:
                            AddBulletSurvivalTactic(move, ticksUntil_p_i_CanFireAgain, ticksToEscape,
                                                    bulletTactics, headOnState, bulletSituation.TickOffsetWhenTankCanFireAgain,
                                                    isConfrontingBullet: true);
                        }

                        // Other moves to dodge the bullet:
                        foreach (Point survivalPoint in bulletCalc_tk.ClosestTankCentrePointsThatSurviveClockwise)
                        {
                            Direction dir = bulletSituation.BulletMovementDir.Clockwise();
                            AddBulletSurvivalTactic(move, ticksUntil_p_i_CanFireAgain, ticksToEscape,
                                                    bulletTactics, survivalPoint, dir, bulletSituation.TickOffsetWhenTankCanFireAgain,
                                                    isConfrontingBullet: false);
                        }

                        foreach (Point survivalPoint in bulletCalc_tk.ClosestTankCentrePointsThatSurviveAntiClockwise)
                        {
                            Direction dir = bulletSituation.BulletMovementDir.AntiClockwise();
                            AddBulletSurvivalTactic(move, ticksUntil_p_i_CanFireAgain, ticksToEscape,
                                                    bulletTactics, survivalPoint, dir, bulletSituation.TickOffsetWhenTankCanFireAgain,
                                                    isConfrontingBullet: false);
                        }
                    }

                    var bulletTacticsByTankAction = bulletTactics.GroupBy(tactic => tactic.InitialTankAction);
                    foreach (var grouping in bulletTacticsByTankAction)
                    {
                        TankAction           tankAction = grouping.Key;
                        BulletSurvivalTactic bestTacticForTankAction = grouping.OrderBy(tactic => tactic.Value).First();
                        tankSituation.TankActionSituationsPerTankAction[(int)tankAction].Value
                            += bestTacticForTankAction.Value;
                        // Note that this is a combination of the slack value and the disarmament value
                        if (bestTacticForTankAction.Slack < bestSlackForThisBulletSituation)
                        {
                            bestSlackForThisBulletSituation      = bestTacticForTankAction.Slack;
                            bestTankActionForThisBulletSituation = tankAction;
                        }
                    }

                    // We've made our escape plans. Don't continue iterating through bullet calculations...
                    break;
                }

                // If any of the danger points are adjacent to your current point,
                // prevent moving into the bullet by add a large negative value to the move,
                // with the size of the value depending on the slack...
                foreach (TankActionSituation tankActionSituation in tankSituation.TankActionSituationsPerTankAction)
                {
                    if (bulletCalc.TankCentrePointsThatDie.ContainsPoint(tankActionSituation.NewTankState.Pos))
                    {
                        // Calculate the slack values and tank action value adjustment...
                        double value = ScenarioValueFunctions.AvoidWalkingIntoABulletFunction.Evaluate(ticksToEscape);
                        tankActionSituation.Value += value;
                    }
                }
            }

            if (isScenarioApplicableForThisBulletSituation)
            {
                if (bestSlackForThisBulletSituation > worstSlack)
                {
                    worstSlack = bestSlackForThisBulletSituation;
                    tankActionToAddressWorstSlack = bestTankActionForThisBulletSituation;
                }
                isScenarioApplicable = true;
            }
        }
コード例 #42
0
ファイル: TankClient.cs プロジェクト: leesjensen/TurboTank
        public dynamic TakeAction(TankAction move)
        {
            if ((move & expectedAction) == 0) throw new Exception("Got: " + move + ", expected: " + expectedAction);

            return takeActionResponse;
        }
コード例 #43
0
ファイル: Beam.cs プロジェクト: leesjensen/TurboTank
 public Beam(TankOperation operation, Grid grid, SignalWeights weights)
 {
     StartAction = operation.GetAction();
     EvalState startingState = new EvalState(operation.GetAction(), grid);
     bestStates[0] = operation.GetScore(startingState, weights);
 }
コード例 #44
0
        public void Tick(TimeSpan elapsedTime)
        {
            lastActionSuccess = true;

            switch (this.action)
            {
                case TankAction.Ahead:
                case TankAction.Back:
                    var pixelPerMillesecond = TankConfig.PixelPerSecondMovementSpeed / 1000;
                    var pixelMovement = Math.Min(elapsedTime.TotalMilliseconds * pixelPerMillesecond, this.amount);
                    var tankMovementAngle = this.action == TankAction.Ahead ? this.Tank.Angle : this.Tank.Angle - (float)Math.PI;

                    var newAngle = this.Tank.Position.Move(tankMovementAngle, pixelMovement);
                    if (this.Tank.Position.X < TankConfig.ArenaEndX && this.Tank.Position.X > TankConfig.ArenaStartX
                        && this.Tank.Position.Y < TankConfig.ArenaEndY && this.Tank.Position.Y > TankConfig.ArenaStartY)
                    {
                        this.Tank.Position = newAngle;
                        this.amount -= pixelMovement;
                    }
                    else
                    {
                        this.lastActionSuccess = false;
                        this.amount = 0;
                    }
                    break;
                case TankAction.Right:
                case TankAction.Left:
                    var turnMillisecondRate = (2 * (float)Math.PI) / TankConfig.TankFullTurnTime.TotalMilliseconds;
                    var totalTurnRadian = Math.Min(elapsedTime.TotalMilliseconds * turnMillisecondRate, StaticHelpers.DegreeToRadian(this.amount));
                    if (this.action == TankAction.Right)
                    {
                        this.Tank.Angle += (float)totalTurnRadian;
                    }
                    else
                    {
                        this.Tank.Angle -= (float)totalTurnRadian;
                    }
                    var totalTurnDegrees = StaticHelpers.RadianToDegree(totalTurnRadian);
                    this.amount -= totalTurnDegrees;
                    break;
                case TankAction.TurretLeft:
                case TankAction.TurretRight:
                    var turretTurnturnMillisecondRate = (2 * (float)Math.PI) / TankConfig.TankFullTurnTime.TotalMilliseconds;
                    var totalturretTurnRadian = Math.Min(elapsedTime.TotalMilliseconds * turretTurnturnMillisecondRate, StaticHelpers.DegreeToRadian(this.amount));
                    if (this.action == TankAction.Right)
                    {
                        this.Tank.TurretAngle += (float)totalturretTurnRadian;
                    }
                    else
                    {
                        this.Tank.TurretAngle -= (float)totalturretTurnRadian;
                    }
                    var totalTurretTurnDegrees = StaticHelpers.RadianToDegree(totalturretTurnRadian);
                    this.amount -= totalTurretTurnDegrees;
                    break;
                default:
                    this.amount = 0;
                    return;
            }

            if (this.amount <= 0)
            {
                this.action = TankAction.None;
                this.autoReset.Set();
            }
        }
コード例 #45
0
ファイル: EvalState.cs プロジェクト: leesjensen/TurboTank
 public EvalState(TankAction action, Grid grid)
 {
     this.Action = action;
     this.Grid = grid;
 }