Example #1
0
    private char selectNextDirection(Point[] players, int myPlayerIndex, bool debugMode)
    {
        //  2
        //  .
        // 0.....1
        //   .  .
        //   .  .

        //start timer
        var me = players[myPlayerIndex];
        var opponents = players.Except(new[] { me }).ToArray();
        if (debugMode) Player.Debug("I'm at {0}", Point.From(me.Index, map.Width, map.Height));

        MaxiMinState bestPath = null;
        var queue = new Queue<MaxiMinState>();
        var nodes = nodesFrom(map);

        // push all my exits to queue bundled with opponents current positions
        queue.Enqueue(new MaxiMinState { Steps = new[] { me.Index }, Me = me.Index, Opponents = opponents.Select(x => x.Index).ToArray(), Score = 0 });
        var counter = 0;

        // foreach position in queue
        while (queue.Any() && timer.ElapsedMilliseconds < MAX_AI_TIME_MS)
        {
            //	position me at new position
            counter++;
            var state = queue.Dequeue();

            var myPath = string.Join("-", state.Steps);

            //  push all new exits to queue (with path) bundled with opponents new positions
            foreach (var exit in nodes[state.Me].Neighbours.ToArray())//.Where(x => x.Cost == 1.0)
            {
                if (timer.ElapsedMilliseconds >= MAX_AI_TIME_MS)
                {
                    Console.Error.WriteLine("Looping through exits when time is up.");
                    break; //Time is up
                }

                //if (debugMode) Console.Error.Write("{0}: Eval {1}->{2} [{3}]: ", counter, myPath, exit.Node.Id, string.Join(", ", state.Opponents));
                if (state.Opponents.Any(x => x == exit.Node.Id))
                {
                    //if (debugMode) Console.Error.WriteLine("Walked into opponent");
                    continue;
                }

                //	move opponents towards my new position
                var opponentNewPositions = new int[state.Opponents.Length];
                for (int i = 0; i < state.Opponents.Length; i++)
                {
                    if (timer.ElapsedMilliseconds >= MAX_AI_TIME_MS)
                    {
                        Console.Error.WriteLine("Looping through opponents when time is up.");
                        break; //Time is up
                    }

                    var opponentPath = new Dijkstra(nodes, state.Opponents[i]);
                    var newPosition = opponentPath.GetPathTo(exit.Node.Id).Skip(1).First();
                    if (newPosition == exit.Node.Id)
                    {
                        //if (debugMode) Console.Error.WriteLine("Killed by opponent");
                        break;
                    }
                    opponentNewPositions[i] = newPosition;
                }
                if (opponentNewPositions.Last() == 0)
                    continue; //We were killed by opponent in inner loop or time is up

                var score = state.Score + valueOf(map[exit.Node.Id]);
                var newState = new MaxiMinState { Steps = state.Steps.Concat(new[] { exit.Node.Id }).ToArray(), Me = exit.Node.Id, Opponents = opponentNewPositions, Score = score };
                if (bestPath == null || bestPath.Score < newState.Score)
                {
                    bestPath = newState;
                    if (debugMode) Console.Error.Write("{0}: Eval {1}->{2} [{3}]: ", counter, myPath, exit.Node.Id, string.Join(", ", state.Opponents));
                    if (debugMode) Console.Error.WriteLine("Score {0}", newState.Score);
                }
                //else
                //{
                //	if (debugMode) Console.Error.WriteLine("----- {0}", newState.Score);
                //}

                queue.Enqueue(newState);
            }

            //	if queue empty or time is up, break
        }

        //walk towards the best path
        Player.Debug("Calculated {0} iterations. Best path is {1} steps.", counter, bestPath == null ? 0 : bestPath.Steps.Length);
        var nextTile = bestPath == null || bestPath.Steps.Length < 2 ? me.Index : bestPath.Steps.Skip(1).First();
        //if (debugMode) Player.Debug("Moving to {0} through {1}", bestPath == null ? nextTile : bestPath.Me, nextTile);
        return map.DirectionTo(me, nextTile);
    }