Esempio n. 1
0
 public IEnumerable<Point> PossibleMoves(int x, int y, bool ignoreWalls)
 {
     Point move = new Point();
     for(int i=0; i<Map.MOVES.Length; i++) {
     move.X = x; move.Y = y;
     move.MoveInDirection(Map.MOVES[i]);
     if (!ignoreWalls && !IsWall(move.X, move.Y)) {
         yield return move;
     } else if (ignoreWalls) {
         yield return move;
     }
     }
 }
Esempio n. 2
0
    // Determine which direction has the most available spaces and fill
    // as efficiently as possible
    private static string PerformSurvivalMove()
    {
        float score = 0;
        float bestScore = 0;
        int depth = 0;

        GameState gs = new GameState();
        Point p = new Point();
        string bestMove = Map.MOVES[0];

        List<string> ties = new List<string>();

        for(int i=0; i<Map.MOVES.Length; i++) {
        p.X = Map.MyX(); p.Y = Map.MyY();
        p.MoveInDirection(Map.MOVES[i]);
        if (!Map.IsWall(p.X, p.Y)) {
            //score = FloodFill(gs.ApplyMoveToMeAndCreate(Map.MOVES[i]), p.X, p.Y);
            score = FloodFillDepthFirst(gs.ApplyMoveToMeAndCreate(Map.MOVES[i]));
        } else {
            score = 0;
        }
        //Console.Error.WriteLine("Far:" + Map.MOVES[i] + ":" + score);
        if (score > bestScore) {
            bestMove = Map.MOVES[i];
            bestScore = score;
            ties.Clear();
            ties.Add(bestMove);
        } else if (score == bestScore) {
            ties.Add(Map.MOVES[i]);
        }
        }

        // break ties
        // hug closest wall
        if (ties.Count > 0) {
        bestScore = int.MaxValue;
        foreach(string move in ties) {
            p.X = Map.MyX(); p.Y = Map.MyY();
            p.MoveInDirection(move);
            // use shortest distance to closest wall
            score = int.MaxValue;
            int tmp;
            foreach (string direction in Map.MOVES) {
                Point q = new Point(p.X, p.Y);
                q.MoveInDirection(direction);
                if (q.X == Map.MyX() && q.Y == Map.MyY()) {
                    continue;
                }
                q.X = p.X;
                q.Y = p.Y;
                tmp = ScoreStraightPath(direction, q);
                if (tmp < score) {
                    score = tmp;
                }
            }
            //Console.Error.WriteLine("Far tie break:" + move + ":" + score);
            if (score < bestScore) {
                bestScore = score;
                bestMove = move;
            }
        }
        }

        return bestMove;
    }
Esempio n. 3
0
    private static int ScoreStraightPath(string direction, Point p)
    {
        int score = 0;
        p.MoveInDirection(direction);

        while(!Map.IsWall(p.X, p.Y)) {
        score++;
        p.MoveInDirection(direction);
        }

        return score;
    }
Esempio n. 4
0
    // alpha beta with iterative deepening
    private static string PerformNearMove(Path shortestPath)
    {
        int depth = 0;
        float time = 0;
        float score, bestScore;
        GameState gs = new GameState();
        Point p = new Point();
        // default to something that won't kill us - server sometimes
        // runs out of time WAY early resulting in no time to perform alpha beta
        // iterations
        string bestMove = Map.MOVES[0]; //PerformFoolishRandomMove();
        DateTime lastAlphaBeta;

        List<string> ties = new List<string>();

        string[] moves = new string[4];
        float[] scores = new float[4];	// 0 north, 1 south, 2 east, 3 west
        scores[0]=3;
        scores[1]=2;
        scores[2]=1;
        scores[3]=0;

        // used to adjust time estimate for next depth so we don't go over time limit
        float timebase = ((float)Map.Width() * (float)Map.Height()) / (15f * 15f);

        while(Duration() + time < (TIME_LIMIT - TIME_THRESHOLD) && depth <= 12) {
        score = int.MinValue;
        bestScore = int.MinValue;
        depth++;

        // order moves by previous iterations scores
        // TODO this really does nothing. Cache of game states is needed
        // for quick eval retrival and move ordering
        int length = scores.Length;
        bool swapped = true;

        moves[0] = "North";
        moves[1] = "South";
        moves[2] = "East";
        moves[3] = "West";

        while(swapped) {
            swapped = false;
            for(int b=0; b<length - 1; b++) {
                if (scores[b] < scores[b+1]) {
                    string tmp = moves[b];
                    float ftmp = scores[b];

                    moves[b] = moves[b+1];
                    scores[b] = scores[b+1];

                    moves[b+1] = tmp;
                    scores[b+1] = ftmp;

                    swapped = true;
                }
            }
            length -= 1;

            //Console.Error.WriteLine("best:" + best + " score:" + scores[best]);
        }

        for(int i=0; i<moves.Length; i++) {
            string move = moves[i];
            p.X = Map.MyX(); p.Y = Map.MyY();
            p.MoveInDirection(move);
            if (!Map.IsWall(p.X, p.Y)) {
                // negate since starting with opponents moves
                lastAlphaBeta = DateTime.Now;
                score = -AlphaBeta(gs.ApplyMoveToMeAndCreate(move), depth, -int.MaxValue, -(-int.MaxValue), false);

                // estimate time for next depth
                TimeSpan ts = DateTime.Now - lastAlphaBeta;
                time = (float)ts.Milliseconds * (depth * timebase);
            } else {
                score = int.MinValue;
            }
            //Console.Error.WriteLine("alphabeta:" + move + ":" + score + " depth:" + depth);
            if (score > bestScore) {
                bestMove = move;
                bestScore = score;
                ties.Clear();
                ties.Add(bestMove);
            } else if (score == bestScore) {
                ties.Add(move);
            }

            // track score
            string temp = move.Substring(0, 1).ToUpper();
            int firstChar = (int)temp[0];
            switch(firstChar) {
            case 'N':
                scores[0] = score;
                break;
            case 'S':
                scores[1] = score;
                break;
            case 'E':
                scores[2] = score;
                break;
            case 'W':
                scores[3] = score;
                break;
            }
        }
        depth++;
        }

        List<string> secondaryTies = new List<string>();
        // break ties
        if (ties.Count > 1) {
        bestScore = int.MinValue;
        foreach(string move in ties) {
            //Console.Error.WriteLine("alpha tie break:" + move);
            p.X = Map.MyX(); p.Y = Map.MyY();
            p.MoveInDirection(move);
            if (Map.IsWall(p.X, p.Y)) {
                continue;
            }

            Territory room = new Territory(gs.ApplyMoveToMeAndCreate(move));
            room.DetermineTerritories();
            score = (float)room.GetMySize() - (float)room.GetOpponentSize();

            //Console.Error.WriteLine("alpha tie break:" + move + ":" + score);
            if (score > bestScore) {
                bestScore = score;
                bestMove = move;
                secondaryTies.Clear();
                secondaryTies.Add(move);
            } else if (score == bestScore) {
                secondaryTies.Add(move);
            }
        }
        }

        // kinda lame, but need another tie breaker...quick and dirty
        if (secondaryTies.Count > 1) {
        bestScore = int.MinValue;
        foreach(string move in ties) {
            if (shortestPath != null) {
                if (move.Equals(shortestPath.direction)) {
                    bestMove = shortestPath.direction;
                    break;
                }
            }
            p.X = Map.MyX(); p.Y = Map.MyY();
            p.MoveInDirection(move);
            if (Map.IsWall(p.X, p.Y)) {
                continue;
            }
            score = -GetEuclideanOpponentDistance(p.X, p.Y);
            //Console.Error.WriteLine("alpha tie break:" + move + ":" + score);
            if (score > bestScore) {
                bestScore = score;
                bestMove = move;
            }
        }
        }

        return bestMove;
    }