Ejemplo n.º 1
0
        private Result getMax(int curDepth, int agentIdx, ClientGameState curState, double alpha, double beta)
        {
            List<ActionSet> legalActions;
            double max = Double.MinValue;
            ActionSet bestActions = new ActionSet(curState.Me.units.Count);
            if (curDepth < this.searchDepth)
            {
                legalActions = curState.GetLegalActions(curState.myPlayerIdx);
            }
            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.Me.units.Count; unitIdx++)
                {
                    successor.Me.units[unitIdx].action = action[unitIdx];
                }
                int nextAgentIdx = (agentIdx + 1) % 2;

                moveStack.Push(action);
                Result result = this.getNode(curDepth, nextAgentIdx, successor, alpha, beta);
                if (curDepth == 0)
                {
                    debugWindow.AddLog(action.ToString() + " : " + result.Score);
                }
                if (result.Score > max)
                {
                    max = result.Score;
                    //Program.abDebug.WriteLine("Max at " + curDepth + " : " + max);
                    action.CopyTo(bestActions);
                    alpha = max;
                    if (curDepth == 0)
                    {
                        for( int idx=0; idx<curState.Me.units.Count; idx++)
                        {
                            Program.MainForm.SetAction(curState.myPlayerIdx, curState.Me.units[idx].id, bestActions[idx]);
                        }
                    }
                }
                moveStack.Pop();
                if (max > beta)
                {
                    //Program.abDebug.WriteLine("Beta Cutoff");
                    this.cutoffs++;
                    break;
                }
            }

            return new Result(max, bestActions);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        public ActionSet GetAction(ClientGameState myState)
        {
            Stopwatch searchDuration = new Stopwatch();

            this.nodesSearched = 0;
            searchDuration.Start();
            Result best = this.getNode(-1, 0, myState);
            searchDuration.Stop();
            this.debugWindow.AddLog("Depth " + this.searchDepth + " searched " + this.nodesSearched + " nodes in " + searchDuration.ElapsedMilliseconds + "ms");
            return best.Actions;
        }
Ejemplo n.º 4
0
 public ActionSet GetAction(ClientGameState myState)
 {
     this.nodesSearched = 0;
     this.cutoffs = 0;
     this.moveStack.Clear();
     this.searchDuration.Restart();
     double alpha = double.MinValue;
     double beta = double.MaxValue;
     Result best = this.getNode(-1, 0, myState, alpha, beta);
     searchDuration.Stop();
     this.debugWindow.AddLog("Depth " + this.searchDepth + " searched " + this.nodesSearched + " nodes(" + this.cutoffs + " cutoffs) in " + searchDuration.ElapsedMilliseconds + "ms");
     return best.Actions;
 }
Ejemplo n.º 5
0
 public ClientGameState(ClientGameState source)
     : base(source)
 {
     this.myPlayerIdx = source.myPlayerIdx;
 }
Ejemplo n.º 6
0
 public void UpdateState(ClientGameState newState)
 {
     this.state = newState;
     canvas.Invalidate();
 }
Ejemplo n.º 7
0
        private Result getNode(int curDepth, int agentIdx, ClientGameState curState)
        {
            Player me = curState.Me;
            Player opponent = curState.Opponent;

            this.nodesSearched++;
            if (agentIdx == 0) {
                curDepth++;
                if (nodesSearched % 1000 == 0)
                {
                    this.debugWindow.AddLog("Searched " + this.nodesSearched + " nodes...");
                }
            } else {
                me = curState.Opponent;
                opponent = curState.Me;
            }

            if ((curDepth == this.searchDepth) || (curState.Won == true) || (curState.Lost == true))
            {
                double score = curState.Evaluate();
                ActionSet actions = new ActionSet(me.units.Count);
                for (int idx = 0; idx < me.units.Count; idx++)
                {
                    actions[idx] = Action.NONE;
                }

                return new Result(score, actions);
            }

            Result result;
            if (agentIdx == 0)
            {
                result = this.getMax(curDepth, agentIdx, curState);
            }
            else
            {
                result = this.getMin(curDepth, agentIdx, curState);
            }

            return result;
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        private Result getNode(int curDepth, int agentIdx, ClientGameState curState, double alpha, double beta)
        {
            Player me = curState.Me;
            Player opponent = curState.Opponent;

            this.nodesSearched++;
            if (agentIdx == 0) {
                curDepth++;
                if (nodesSearched % 1000 == 0)
                {
                    this.debugWindow.AddLog("Searched " + this.nodesSearched + " nodes...");
                }
            } else {
                me = curState.Opponent;
                opponent = curState.Me;
            }

            if (me.bullets.Count < 1 || curDepth > 15)
            {
            #if DEBUG
                if ((curDepth >= this.searchDepth) || (curState.Won == true) || (curState.Lost == true))
            #else
            if ((curDepth == this.searchDepth) || (curState.Won == true) || (curState.Lost == true) || (searchDuration.ElapsedMilliseconds > 2800))
            #endif
                {
                    double score = curState.Evaluate();
                    //Program.abDebug.WriteLine(String.Join(",", moveStack) + " - " + curDepth.ToString() + ":" + score.ToString());
                    ActionSet actions = new ActionSet(me.units.Count);
                    for (int idx = 0; idx < me.units.Count; idx++)
                    {
                        actions[idx] = Action.NONE;
                    }

                    return new Result(score, actions);
                }
            }

            Result result;
            if (agentIdx == 0)
            {
                result = this.getMax(curDepth, agentIdx, curState, alpha, beta);
            }
            else
            {
                result = this.getMin(curDepth, agentIdx, curState, alpha, beta);
            }

            return result;
        }
Ejemplo n.º 10
0
        private void player2Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Random rnd = new Random();
            State[,] layout = Program.MainForm.Login("Player 2");
            GameState initialState = Program.MainForm.GetStatus(1);
            IAgent agent = new AlphaBetaAgent(p2Debug);

            ClientGameState myState = new ClientGameState(layout, initialState, 1);
            myState.currentTick = -1;
            #if DEBUG
            p2Debug.UpdateState(myState);
            Application.DoEvents();
            #endif

            while (player2Worker.CancellationPending == false)
            {
                GameState curState = Program.MainForm.GetStatus(1);
                if (curState.events.blockEvents.Count > 0)
                {
                    p2Debug.AddLog("Player 2 received " + curState.events.blockEvents.Count + " unseen block events");
                    myState.ProcessEvents(curState.events);
                }
                if (curState.currentTick > myState.currentTick)
                {
                    myState = new ClientGameState(myState.blocks, curState, 1);
                    myState.ProcessEvents(curState.events);
            #if DEBUG
                    p2Debug.UpdateState(myState);
                    Application.DoEvents();
            #endif
                    RandomAgent(rnd, myState, p2Debug);
                }

                Thread.Sleep(100);
            }
        }
Ejemplo n.º 11
0
        private void player1Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Random rnd = new Random();
            State[,] layout = Program.MainForm.Login("Player 1");
            GameState initialState = Program.MainForm.GetStatus(0);
            IAgent agent = new AlphaBetaAgent(p1Debug);

            ClientGameState myState = new ClientGameState(layout, initialState, 0);
            myState.currentTick = -1;
            #if DEBUG
            p1Debug.UpdateState(myState);
            Application.DoEvents();
            #endif

            while (player1Worker.CancellationPending == false)
            {
                GameState curState = Program.MainForm.GetStatus(0);
                if (curState.events.blockEvents.Count > 0)
                {
                    p1Debug.AddLog("Player 1 received " + curState.events.blockEvents.Count + " unseen block events");
                    myState.ProcessEvents(curState.events);
                }
                if (curState.currentTick > myState.currentTick)
                {
                    myState = new ClientGameState(myState.blocks, curState, 0);
                    myState.ProcessEvents(curState.events);
            #if DEBUG
                    p1Debug.UpdateState(myState);
                    Application.DoEvents();
            #endif
                    ActionSet actions = agent.GetAction(myState);
                    for (int idx = 0; idx < myState.Me.units.Count; idx++)
                    {
                        p1Debug.AddLog("Unit " + idx + " : Action=" + actions[idx]);
                        Program.MainForm.SetAction(myState.myPlayerIdx, myState.players[myState.myPlayerIdx].units[idx].id, actions[idx]);
                    }
                }

                Thread.Sleep(100);
            }
        }
Ejemplo n.º 12
0
        private static void RandomAgent(Random rnd, ClientGameState myState, AIDebugWindow debugWin)
        {
            List<ActionSet> legalActions = myState.GetLegalActions(myState.myPlayerIdx);
            if (legalActions.Count < 1)
            {
                return;
            }

            int pickActions = rnd.Next(legalActions.Count);
            ActionSet picked = legalActions[pickActions];
            for (int idx = 0; idx < myState.players[myState.myPlayerIdx].units.Count; idx++)
            {
                debugWin.AddLog("Unit " + idx + " : Action=" + picked[idx]);
                Program.MainForm.SetAction(myState.myPlayerIdx, myState.players[myState.myPlayerIdx].units[idx].id, picked[idx]);
            }
        }
Ejemplo n.º 13
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]);
            }
        }
Ejemplo n.º 14
0
        private static void BruteForceAgent(Random rnd, ClientGameState myState, AIDebugWindow debugWin)
        {
            int closestTankIdx = -1;
            Size closestTankDist = new Size(myState.BoardWidth,myState.BoardHeight);

            List<ActionSet> legalActions = myState.GetLegalActions(myState.myPlayerIdx);
            if (legalActions.Count < 1)
            {
                return;
            }

            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 legalActions)
            {
                if (actionSet[closestTankIdx] == desiredAction)
                {
                    for (int idx = 0; idx < myState.players[myState.myPlayerIdx].units.Count; idx++)
                    {
                        debugWin.AddLog("Unit " + idx + " : Action=" + actionSet[idx]);
                        Program.MainForm.SetAction(myState.myPlayerIdx, myState.players[myState.myPlayerIdx].units[idx].id, actionSet[idx]);
                    }
                    return;
                }
            }

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