Example #1
0
        private Result getMin(int curDepth, int agentIdx, ClientGameState curState)
        {
            double min = Double.MaxValue;
            ActionSet bestActions = new ActionSet(curState.Me.units.Count);
            int opponentIdx = (curState.myPlayerIdx + 1) % 2;
            List<ActionSet> legalActions = curState.GetLegalActions(opponentIdx);

            foreach (ActionSet action in legalActions)
            {
                ClientGameState successor = new ClientGameState(curState);
                for (int unitIdx = 0; unitIdx < successor.Opponent.units.Count; unitIdx++)
                {
                    successor.Opponent.units[unitIdx].action = action[unitIdx];
                }
                successor.UpdateGameState();
                int nextAgentIdx = (agentIdx + 1) % 2;

                Result result = this.getNode(curDepth, nextAgentIdx, successor);
                if (result.Score < min)
                {
                    min = result.Score;
                    action.CopyTo(bestActions);
                }
            }

            return new Result(min, bestActions);
        }
        private Result getMin(int curDepth, int agentIdx, ClientGameState curState, double alpha, double beta)
        {
            List<ActionSet> legalActions;
            double min = Double.MaxValue;
            ActionSet bestActions = new ActionSet(curState.Opponent.units.Count);
            int opponentIdx = (curState.myPlayerIdx + 1) % 2;
            if (curDepth < this.searchDepth)
            {
                legalActions = curState.GetLegalActions(opponentIdx);
            }
            else
            {
                legalActions = new List<ActionSet>();
                legalActions.Add(bestActions);
            }
            if (legalActions.Count < 1)
            {
                return new Result(1000, bestActions);
            }

            foreach (ActionSet action in legalActions)
            {
                //Program.abDebug.Write("[" + action.ToString() + "]");
                ClientGameState successor = new ClientGameState(curState);
                for (int unitIdx = 0; unitIdx < successor.Opponent.units.Count; unitIdx++)
                {
                    successor.Opponent.units[unitIdx].action = action[unitIdx];
                }
                successor.UpdateGameState();
                int nextAgentIdx = (agentIdx + 1) % 2;
                moveStack.Push(action);
                Result result = this.getNode(curDepth, nextAgentIdx, successor, alpha, beta);
                if (result.Score < min)
                {
                    min = result.Score;
                    //Program.abDebug.WriteLine("Min at " + curDepth + " : " + min);
                    action.CopyTo(bestActions);
                    beta = min;
                }
                moveStack.Pop();
                if (min < alpha)
                {
                    //Program.abDebug.WriteLine("Alpha Cutoff");
                    this.cutoffs++;
                    break;
                }
            }

            return new Result(min, bestActions);
        }
Example #3
0
        private static void GoalAgent(Random rnd, ClientGameState myState, AIDebugWindow debugWin)
        {
            int avoidedLosing = 0;
            List<ActionSet> legalActions = myState.GetLegalActions(myState.myPlayerIdx);
            if (legalActions.Count < 1)
            {
                return;
            }

            List<ActionSet> validActions = new List<ActionSet>();
            foreach(ActionSet action in legalActions)
            {
                ClientGameState afterState = new ClientGameState(myState);
                for (int unitIdx = 0; unitIdx < afterState.Me.units.Count; unitIdx++)
                {
                    afterState.Me.units[unitIdx].action = action[unitIdx];
                }
                for (int unitIdx = 0; unitIdx < afterState.Opponent.units.Count; unitIdx++)
                {
                    afterState.Opponent.units[unitIdx].action = Action.NONE;
                }

                afterState.UpdateGameState();
                if (afterState.Lost == false)
                {
                    validActions.Add(action);
                }
                else
                {
                    avoidedLosing++;
                }
            }
            if (validActions.Count < 1)
            {
                return;
            }

            int closestTankIdx = -1;
            Size closestTankDist = new Size(myState.BoardWidth, myState.BoardHeight);

            Player me = myState.Me;
            Player enemy = myState.Opponent;

            for (int idx = 0; idx < me.units.Count; idx++)
            {
                Unit tank = me.units[idx];
                Size distToEnemyBase = Utils.DistanceBetween(tank, enemy.playerBase);
                if (distToEnemyBase.Width + distToEnemyBase.Height < closestTankDist.Width + closestTankDist.Height)
                {
                    closestTankDist = distToEnemyBase;
                    closestTankIdx = idx;
                }
            }

            Unit closestTank = me.units[closestTankIdx];
            Action desiredAction = Action.NONE;
            if (closestTankDist.Height == 0)
            {
                //Vertically aligned with enemy base, so check if we are facing the right direction
                if (closestTankDist.Width < 0 && closestTank.direction != Direction.RIGHT)
                {
                    desiredAction = Action.RIGHT;
                }
                else if (closestTankDist.Width > 0 && closestTank.direction != Direction.LEFT)
                {
                    desiredAction = Action.LEFT;
                }
                else
                {
                    // We are aligned and facing the right direction, so start shooting
                    desiredAction = Action.FIRE;
                }
            }
            else if (closestTankDist.Width == 0)
            {
                //Horizontally aligned with enemy base, so check if we are facing the right direction
                if (closestTankDist.Height < 0 && closestTank.direction != Direction.DOWN)
                {
                    desiredAction = Action.DOWN;
                }
                else if (closestTankDist.Height > 0 && closestTank.direction != Direction.UP)
                {
                    desiredAction = Action.UP;
                }
                else
                {
                    // We are aligned and facing the right direction, so start shooting
                    desiredAction = Action.FIRE;
                }
            }
            else
            {
                // We still need to get in position... let's see if we can
                if (Math.Abs(closestTankDist.Width) <= Math.Abs(closestTankDist.Height))
                {
                    if (closestTankDist.Width < 0)
                    {
                        desiredAction = Action.RIGHT;
                    }
                    else
                    {
                        desiredAction = Action.LEFT;
                    }
                }
                else
                {
                    if (closestTankDist.Height < 0)
                    {
                        desiredAction = Action.DOWN;
                    }
                    else
                    {
                        desiredAction = Action.UP;
                    }
                }
            }

            foreach (ActionSet actionSet in validActions)
            {
                if (actionSet[closestTankIdx] == desiredAction)
                {
                    for (int idx = 0; idx < myState.Me.units.Count; idx++)
                    {
                        debugWin.AddLog("Unit " + idx + " : Action=" + actionSet[idx]);
                        Program.MainForm.SetAction(myState.myPlayerIdx, myState.Me.units[idx].id, actionSet[idx]);
                    }
                    return;
                }
            }

            switch(desiredAction)
            {
                case Action.RIGHT:
                    if ((closestTank.direction == Direction.RIGHT) && (myState.blocks[closestTank.x + 3, closestTank.y] == State.FULL)) desiredAction = Action.FIRE;
                    break;
                case Action.LEFT:
                    if ((closestTank.direction == Direction.LEFT) && (myState.blocks[closestTank.x - 3, closestTank.y] == State.FULL)) desiredAction = Action.FIRE;
                    break;
                case Action.UP:
                    if ((closestTank.direction == Direction.UP) && (myState.blocks[closestTank.x, closestTank.y - 3] == State.FULL)) desiredAction = Action.FIRE;
                    break;
                case Action.DOWN:
                    if ((closestTank.direction == Direction.DOWN) && (myState.blocks[closestTank.x, closestTank.y + 3] == State.FULL)) desiredAction = Action.FIRE;
                    break;
            }
            foreach (ActionSet actionSet in validActions)
            {
                if (actionSet[closestTankIdx] == desiredAction)
                {
                    for (int idx = 0; idx < myState.Me.units.Count; idx++)
                    {
                        debugWin.AddLog("Unit " + idx + " : Action=" + actionSet[idx]);
                        Program.MainForm.SetAction(myState.myPlayerIdx, myState.Me.units[idx].id, actionSet[idx]);
                    }
                    return;
                }
            }

            int pickActions = rnd.Next(validActions.Count);
            ActionSet picked = validActions[pickActions];
            for (int idx = 0; idx < myState.Me.units.Count; idx++)
            {
                debugWin.AddLog("Unit " + idx + " : Action=" + picked[idx]);
                Program.MainForm.SetAction(myState.myPlayerIdx, myState.players[myState.myPlayerIdx].units[idx].id, picked[idx]);
            }
        }