public static String MakeMove() { HiPerfTimer timer = new HiPerfTimer(); timer.Start(); int x = Map.MyLocation.X; int y = Map.MyLocation.Y; GameState g = new GameState(readMap(), Map.MyLocation, Map.OpponentLocation); MapAnalyzer ma = new MapAnalyzer(g); if (g.getSuccessorStates(Player).Count == 0) { return randomMove(); } bool separated = !ma.sameField(g.Player, g.Opponent); EvaluatorCollection ec = new EvaluatorCollection(); Search s; if (!separated) { ec.add(new CutOffEvaluator()); ec.add(new VoronoiEvaluator()); s = new MiniMaxSearch(); } else { ec.add(new FloodFillEvaluator()); s = new MiniMaxSearch(); } MultiplyEvaluators finalEval = new MultiplyEvaluators(new GameWinEvaluator(), ec); timer.Stop(); int depth = 4; double time = timer.Duration * 1000; GameState best = new GameState(); while (time < 500) { depth++; timer.Start(); best = new GameState(s.doSearch(g, finalEval, depth, time)); timer.Stop(); time += timer.Duration * 1000; } //Console.Error.WriteLine(separated + " " + time + " " + depth); //ma.printMap(); if (best.previousPlayerMove == null) return "N"; else return intDirectionToString(best.previousPlayerMove.Direction); }
public int evaluation(GameState g, int player) { int direction = g.previousPlayerMove.Direction; int[,] map = g.Map; //int[,] newMap = MapManipulator.straightLineFromPosition(map, player == 1 ? g.Opponent : g.Player, direction); //int distance = MapManipulator.distanceStraightLine(map, player == 1 ? g.Opponent : g.Player, direction); MapAnalyzer m = new MapAnalyzer(map); //m.printMap(); //since MapAnalyzer actually clones the arrays and so player reports the wrong size if being part of the wall, manipulate the array directly //and fill opponent first, then check the player field size. this will report correct size int opponentFieldSize = m.fieldSize(player == 0 ? g.Opponent : g.Player); int playerFieldSize = m.fieldSize(player == 1 ? g.Opponent : g.Player); bool seperated = m.sameField(g.Player, g.Opponent); int score = 0; if (seperated && playerFieldSize > opponentFieldSize) return 100; if (seperated && opponentFieldSize > playerFieldSize) return -100; if (seperated && opponentFieldSize == playerFieldSize) return 5; if (g.Player.X + 1 == g.Opponent.X && g.Player.Y == g.Opponent.Y) score -= -50; if (g.Player.X - 1 == g.Opponent.X && g.Player.Y == g.Opponent.Y) score -= -50; if (g.Player.X == g.Opponent.X && g.Player.Y + 1 == g.Opponent.Y) score -= -50; if (g.Player.X == g.Opponent.X && g.Player.Y - 1 == g.Opponent.Y) score -= -50; if (g.Player.X +1== g.Opponent.X && g.Player.Y - 1 == g.Opponent.Y) score -= -50; if (g.Player.X-1 == g.Opponent.X && g.Player.Y - 1 == g.Opponent.Y) score -= -50; if (g.Player.X+1 == g.Opponent.X && g.Player.Y + 1 == g.Opponent.Y) score -= -50; if (g.Player.X-1 == g.Opponent.X && g.Player.Y + 1 == g.Opponent.Y) score -= -50; //Console.Error.WriteLine(MyTronBot.intDirectionToString(direction)); //Console.Error.WriteLine("OpponentFieldSize: " + opponentFieldSize + " PlayerFieldSize: " + playerFieldSize); //Console.Error.WriteLine("Utility cutoff: " + (playerFieldSize - opponentFieldSize) + "\n"); //Console.Error.WriteLine("Distance Eval: " + distanceEvaluation + "\nEval: " + evaluation); //if (opponentFieldSize < playerFieldSize) finalEval = playerFieldSize + distanceEvaluation; //Console.Error.WriteLine("FinalEval: " + finalEval); return score; }