public BitState Clone() { var clone = new BitState { bots = bots.ConvertAll(e => e.Clone()), bombs = bombs.ConvertAll(b => b.Clone()) }; for (int i = 0; i < Constants.BoxTypes; i++) { clone.boxes[i] = new BitArray(boxes[i]); } for (int i = 0; i < Constants.ItemTypes; i++) { clone.items[i] = new BitArray(items[i]); } for (int i = 0; i < Constants.MaxPlayers; i++) { //clone.playerMaps[i] = new BitArray(this.playerMaps[i]); clone.bombMap[i] = new BitArray(bombMap[i]); } clone.turnNumber = turnNumber; clone.lastComputedScore = lastComputedScore; clone.lastScoreComputation = lastScoreComputation; return(clone); }
public static BitSolution generateBestRandomSolution(BitState g, int playerId, int depth, int timeToRun) { BitSolution best = null; double maxScore = double.NegativeInfinity; int count = 0; var timer = new Stopwatch(); timer.Start(); while (timer.ElapsedMilliseconds <= timeToRun) { //var time = timer.ElapsedMilliseconds; //Console.Error.WriteLine("Time elapsed: {0} ms", time); var solution = randomSolution(g.Clone(), playerId, depth); if (solution.score > maxScore) { maxScore = solution.score; best = solution; } count++; //time = timer.ElapsedMilliseconds; //Console.Error.WriteLine("Time elapsed: {0} ms", time); } timer.Stop(); Console.Error.WriteLine("{0} solutions considered", count); return(best); }
public static void GenerateMoves() { moveRight = new BitArray[Constants.PlayableSquares]; moveLeft = new BitArray[Constants.PlayableSquares]; moveUp = new BitArray[Constants.PlayableSquares]; moveDown = new BitArray[Constants.PlayableSquares]; for (int p = 0; p < Constants.PlayableSquares; p++) { var mapPos = BitState.GetMapIndex(p); // right var bits = new BitArray(Constants.PlayableSquares); bits[p] = true; if (mapPos.Item1 + 1 < Constants.BoardWidth && mapPos.Item2 % 2 == 0) { bits[p + 1] = true; } moveRight[p] = bits; // left bits = new BitArray(Constants.PlayableSquares); bits[p] = true; if (mapPos.Item1 - 1 >= 0 && mapPos.Item2 % 2 == 0) { bits[p - 1] = true; } moveLeft[p] = bits; // up bits = new BitArray(Constants.PlayableSquares); bits[p] = true; if (mapPos.Item2 - 1 >= 0 && mapPos.Item1 % 2 == 0) { bits[BitState.GetBitIndex(mapPos.Item1, mapPos.Item2 - 1)] = true; } moveUp[p] = bits; // down bits = new BitArray(Constants.PlayableSquares); bits[p] = true; if (mapPos.Item2 + 1 < Constants.BoardHeight && mapPos.Item1 % 2 == 0) { bits[BitState.GetBitIndex(mapPos.Item1, mapPos.Item2 + 1)] = true; } moveDown[p] = bits; } }
public static void GenerateBombs() { bombRight = new BitArray[Constants.BoardWidth, Constants.PlayableSquares]; bombLeft = new BitArray[Constants.BoardWidth, Constants.PlayableSquares]; bombUp = new BitArray[Constants.BoardWidth, Constants.PlayableSquares]; bombDown = new BitArray[Constants.BoardWidth, Constants.PlayableSquares]; for (int i = 1; i <= Constants.BoardWidth; i++) { for (int p = 0; p < Constants.PlayableSquares; p++) { var mapPos = BitState.GetMapIndex(p); // right var bits = new BitArray(Constants.PlayableSquares); if (mapPos.Item1 + i < Constants.BoardWidth && mapPos.Item2 % 2 == 0) { bits[p + i] = true; } bombRight[i - 1, p] = bits; // left bits = new BitArray(Constants.PlayableSquares); if (mapPos.Item1 - i >= 0 && mapPos.Item2 % 2 == 0) { bits[p - i] = true; } bombLeft[i - 1, p] = bits; // up bits = new BitArray(Constants.PlayableSquares); if (mapPos.Item2 - i >= 0 && mapPos.Item1 % 2 == 0) { bits[BitState.GetBitIndex(mapPos.Item1, mapPos.Item2 - i)] = true; } bombUp[i - 1, p] = bits; // down bits = new BitArray(Constants.PlayableSquares); if (mapPos.Item2 + i < Constants.BoardHeight && mapPos.Item1 % 2 == 0) { bits[BitState.GetBitIndex(mapPos.Item1, mapPos.Item2 + i)] = true; } bombDown[i - 1, p] = bits; } } }
public static BitSolution bfs(BitState g, int playerId, int timeToRun) { var timer = new Stopwatch(); timer.Start(); var open = new List <Node>(); var closed = new List <BitSolution>(); open.Add(new Node(new BitSolution(), null, g.Clone())); while (timer.ElapsedMilliseconds <= timeToRun && open.Count > 0) { var sol = open[0].solution; var gs = open[0].gameState; if (open[0].parent != null) { closed.Remove(open[0].parent); } open.RemoveAt(0); foreach (Move m in gs.getMoves(playerId)) { var solClone = sol.Clone(); var gsClone = gs.Clone(); solClone.moves.Add(m); gsClone.play(m, playerId); if (gsClone.getBot(playerId).isAlive) { open.Add(new Node(solClone, sol, gsClone)); } } closed.Add(sol); } timer.Stop(); BitSolution best = null; double maxScore = double.NegativeInfinity; foreach (var s in closed) { if (s.score > maxScore) { maxScore = s.score; best = s; } } return(best); }
private static BitSolution randomSolution(BitState g, int playerId, int depth) { var movesTimer = new Stopwatch(); //var playTimer = new Stopwatch(); //var scoreTimer = new Stopwatch(); movesTimer.Start(); var s = new BitSolution(); movesTimer.Stop(); //Console.Error.WriteLine("Time to construct BitSolution: {0}", movesTimer.ElapsedMilliseconds); for (int d = 0; d < depth; d++) { //movesTimer.Start(); var moves = g.getMoves(playerId); //movesTimer.Stop(); var move = moves[rnd.Next(moves.Count)]; //playTimer.Start(); g.play(move, playerId); //playTimer.Stop(); s.moves.Add(move); if (!g.getBot(playerId).isAlive) { break; } } //scoreTimer.Start(); s.score = g.score(playerId); //scoreTimer.Stop(); //Console.Error.WriteLine("Moves: {0} ms", movesTimer.ElapsedMilliseconds); //Console.Error.WriteLine("Play: {0} ms", playTimer.ElapsedMilliseconds); //Console.Error.WriteLine("Score: {0} ms", scoreTimer.ElapsedMilliseconds); //Console.Error.WriteLine(); return(s); }
public Node(BitSolution solution, BitSolution parent, BitState gameState) { this.solution = solution; this.parent = parent; this.gameState = gameState; }
static void Main() { int turnNumber = 0; string[] inputs; inputs = Console.ReadLine().Split(' '); int width = int.Parse(inputs[0]); int height = int.Parse(inputs[1]); int myId = int.Parse(inputs[2]); BitMaps.GenerateMoves(); BitMaps.GenerateBombs(); // game loop while (true) { turnNumber++; char[,] map = new char[width, height]; List <Robot> bots = new List <Robot>(); List <Bomb> bombs = new List <Bomb>(); for (int i = 0; i < height; i++) { var row = Console.ReadLine().ToCharArray(); for (int j = 0; j < width; j++) { map[j, i] = row[j]; } } int entities = int.Parse(Console.ReadLine()); for (int i = 0; i < entities; i++) { inputs = Console.ReadLine().Split(' '); var entityType = int.Parse(inputs[0]); if (entityType == Constants.ENTITY_ROBOT) { var r = new Robot { owner = int.Parse(inputs[1]) }; var x = int.Parse(inputs[2]); var y = int.Parse(inputs[3]); r.position = BitState.GetBitIndex(x, y); r.param1 = int.Parse(inputs[4]); r.param2 = int.Parse(inputs[5]); bots.Add(r); } else if (entityType == Constants.ENTITY_ITEM) { if (int.Parse(inputs[4]) == Constants.ITEM_RANGE) { map[int.Parse(inputs[2]), int.Parse(inputs[3])] = Constants.MAP_ITEM_RANGE; } else { map[int.Parse(inputs[2]), int.Parse(inputs[3])] = Constants.MAP_ITEM_BOMB; } } else { var r = new Bomb { owner = int.Parse(inputs[1]) }; var x = int.Parse(inputs[2]); var y = int.Parse(inputs[3]); r.position = BitState.GetBitIndex(x, y); r.param1 = int.Parse(inputs[4]); r.param2 = int.Parse(inputs[5]); bombs.Add(r); map[x, y] = Constants.MAP_BOMB; } } var bgs = new BitState(map, bots, bombs, turnNumber); var best = BitSolution.generateBestRandomSolution(bgs, myId, 20, 80); Console.WriteLine(bgs.getBot(myId).getCommand(best.moves[0]) + " " + best.score); bgs.play(best.moves[0], myId); Console.Error.WriteLine(bgs.score(myId)); } }