public override IState CalculateNextState(GameState state, TestBot bot) { // Done Healing or no Cash if (state.myHero.life > 85 || state.myHero.gold == 0) { // Check if there is a good enemy to steal var maxMines = 0; foreach (var hero in state.heroes) { if (maxMines < hero.mineCount) maxMines = hero.mineCount; } // Go steal if he has more mine than you if (state.myHero.mineCount + 3 <= maxMines) { return new AttackWinner(); } // No worthy opponent, go capture mines return new CaptureMine(); } // Go Heal return this; }
public override IState CalculateNextState(GameState state, TestBot bot) { // Target Enemy ? // if (costToMine + 25 >= life) // Heal // else // mine // if capturing a mine will kill you if(state.myHero.life < 26) return new GoHeal(); // Max mine of hero var maxMines = 0; foreach (var hero in state.heroes) { if (maxMines < hero.mineCount) maxMines = hero.mineCount; } if (state.myHero.mineCount + 3 <= maxMines) { if(state.myHero.life >= 75) return new AttackWinner(); else return new GoHeal(); } return this; }
public override IState CalculateNextState(GameState state, TestBot bot) { var enemy = GetEnemy(state); if (enemy.mineCount <= state.myHero.mineCount) { if(state.myHero.life > 25) return new CaptureMine(); return new GoHeal(); } else if(enemy.life > state.myHero.life) return new GoHeal(); return this; }
private string OneBestMove(GameState gameState, IPathfinder pathfinder) { string murderDirection = murderAlgo(gameState); if (!string.IsNullOrEmpty(murderDirection)) { Console.Out.WriteLine("WARWARWAR"); return murderDirection; } // If we suddenly lost a lot of life, maybe we should reconsider. if (heroLife.HasValue && heroLife.Value >= (gameState.myHero.life + 20)) { Console.WriteLine("EvenBestChoice: LOW ON LIFE! Maybe we were attacked?"); target = null; } heroLife = gameState.myHero.life; // If we suddenly moved a lot, maybe we should reconsider. if (heroPos != null && Pos.DistanceBetween(heroPos, gameState.myHero.pos) >= 2) { Console.WriteLine("EvenBestChoice: TELEPORTED! Maybe we were killed?"); target = null; } heroPos = gameState.myHero.pos; Tuple<PathData, TargetInfo> pathDataAndTarget = null; if (target != null) { Console.WriteLine("EvenBestChoice: Current target: ({0},{1}) [tile {2}]", target.pos.x, target.pos.y, target.tile); pathDataAndTarget = Tuple.Create(pathfinder.pathTo(target.pos, gameState.myHero.pos, gameState.board, SPIKE_COST), target); } else { // Seek mine if possible, otherwise seek a tavern if (gameState.myHero.life >= 35) { pathDataAndTarget = SeekMine(gameState, pathfinder); } if (pathDataAndTarget == null || pathDataAndTarget.Item1.lostHealth >= gameState.myHero.life) { pathDataAndTarget = SeekTavern(gameState, pathfinder); } } // If this is the last move, release target unless it's a tavern and we're < 90 life if (target != null && pathDataAndTarget != null && pathDataAndTarget.Item1.nextDirection != Direction.Stay && Pos.DistanceBetween(target.pos, gameState.myHero.pos) <= 1 && (target.tile != Tile.TAVERN || gameState.myHero.life >= 90)) { Console.WriteLine("EvenBestChoice: Reached destination ({0},{1}) [{2}], releasing target", target.pos.x, target.pos.y, target.tile); target = null; } string nextDirection = pathDataAndTarget != null ? pathDataAndTarget.Item1.nextDirection : null; return !String.IsNullOrEmpty(nextDirection) ? nextDirection : Direction.Stay; }
public Pathfinder(GameState _gameInfo) { gameInfo = _gameInfo; int sizeX = gameInfo.board.GetLength(0); int sizeY = gameInfo.board.GetLength(0); globalMap = new PathfinderTile[sizeX, sizeY]; //Initialise pathfinding board for (int i = 0; i < gameInfo.board.GetLength(0); ++i) { for (int j = 0; j < gameInfo.board.GetLength(0); ++j) { globalMap[i, j] = new PathfinderTile(i, j, gameInfo.board[i][j]); } } }
public string WhatShouldIDo(GameState state) { gState = state; Dictionary<Pos, Tile> POI = new Dictionary<Pos, Tile>(); numberOfMinePlayer1 = 0; numberOfMinePlayer2 = 0; numberOfMinePlayer3 = 0; numberOfMinePlayer4 = 0; for (int i = 0; i < state.board.Length; i++) { for (int j = 0; j < state.board[i].Length; j++) { if (state.board[i][j] != Tile.FREE && state.board[i][j] != Tile.IMPASSABLE_WOOD) { POI.Add(new Pos() { x = i, y = j }, state.board[i][j]); } if (state.board[i][j] == Tile.GOLD_MINE_1) numberOfMinePlayer1++; else if (state.board[i][j] == Tile.GOLD_MINE_2) numberOfMinePlayer2++; else if (state.board[i][j] == Tile.GOLD_MINE_3) numberOfMinePlayer3++; else if (state.board[i][j] == Tile.GOLD_MINE_4) numberOfMinePlayer4++; } } Pos bestPoiPos = new Pos(); int bestScore = Int32.MaxValue; Pathfinder pathfinder = new Pathfinder(state); foreach (var poi in POI) { int cost = WhatsMyScore(pathfinder.GetDestinationCost(poi.Key), poi.Value); if (cost < bestScore) { bestPoiPos = poi.Key; bestScore = cost; } } return pathfinder.GetNextMoveToGetToDestination(bestPoiPos.x, bestPoiPos.y); }
public Hero GetEnemy(GameState state) { var EnemyPlayer = new Hero(); var MaxMine = 0; foreach (var hero in state.heroes) { if (hero.mineCount > MaxMine) { if (hero.pos != state.myHero.pos) { MaxMine = hero.mineCount; EnemyPlayer = hero; } } } return EnemyPlayer; }
public override Pos GetGoal(GameState state, TestBot bot) { var enemy = GetEnemy(state); return enemy.pos; }
public override Pos GetGoal(GameState state, TestBot bot) { throw new System.NotImplementedException(); }
public override Pos GetGoal(GameState state, TestBot bot) { Console.WriteLine("Capturing mine"); return bot.GetClosestMine(state.myHero.pos, state.board); }
public string BestMove(GameState gameState, IPathfinder pathfinder) { return OneBestMove(gameState, pathfinder); }
private Tuple<PathData, TargetInfo> SeekTiles(GameState gameState, IPathfinder pathfinder, int tileCost, params Tile[] soughtTiles) { // Scan game board and find path data to all matching tiles List<Tuple<Pos, Tile, PathData>> moves = new List<Tuple<Pos, Tile, PathData>>(); SortedSet<Tile> tiles = new SortedSet<Tile>(soughtTiles); for (int x = 0; x < gameState.board.Length; ++x) { for (int y = 0; y < gameState.board[x].Length; ++y) { Tile tile = gameState.board[x][y]; if (tiles.Contains(tile)) { Pos pos = new Pos(x, y); PathData curPathData = pathfinder.pathTo(pos, gameState.myHero.pos, gameState.board, SPIKE_COST); // Fix health if we don't have one if (curPathData.lostHealth == 0) { curPathData.lostHealth = curPathData.distance; } // Add tile cost to health cost curPathData.lostHealth += tileCost; // Add potential target. moves.Add(Tuple.Create(pos, tile, curPathData)); } } } // Seek to minimize lost health. moves.Sort((a, b) => a.Item3.lostHealth - b.Item3.lostHealth); // Find a move that will take us to the target. Tuple<PathData, TargetInfo> res = null; if (moves.Count != 0 && moves[0].Item3.distance < 1000) { res = Tuple.Create(moves[0].Item3, new TargetInfo(moves[0].Item1, moves[0].Item3.distance, moves[0].Item2)); if (res.Item1.lostHealth >= gameState.myHero.life) { Console.WriteLine("EvenBestChoice: WARNING: current choice will kill us: costs {0}, remaining life {1}", res.Item1.lostHealth, gameState.myHero.life); } } if (res != null && res.Item1 == null) { res = null; } return res; }
private Tuple<PathData, TargetInfo> SeekTavern(GameState gameState, IPathfinder pathfinder) { return SeekTiles(gameState, pathfinder, TAVERN_COST, Tile.TAVERN); }
private Tuple<PathData, TargetInfo> SeekMine(GameState gameState, IPathfinder pathfinder) { List<Tile> mineTiles = new List<Tile>(new[] { Tile.GOLD_MINE_NEUTRAL, Tile.GOLD_MINE_1, Tile.GOLD_MINE_2, Tile.GOLD_MINE_3, Tile.GOLD_MINE_4, }); if (gameState.myHero.id == 1) { mineTiles.Remove(Tile.GOLD_MINE_1); } else if (gameState.myHero.id == 2) { mineTiles.Remove(Tile.GOLD_MINE_2); } else if (gameState.myHero.id == 3) { mineTiles.Remove(Tile.GOLD_MINE_3); } else if (gameState.myHero.id == 4) { mineTiles.Remove(Tile.GOLD_MINE_4); } return SeekTiles(gameState, pathfinder, MINE_COST, mineTiles.ToArray()); }
public virtual IState CalculateNextState(GameState state, TestBot bot) { return this; }
public abstract Pos GetGoal(GameState state, TestBot bot);
private String murderAlgo(GameState gameState) { int size = gameState.board.Length -1 ; Pos myPos = gameState.myHero.pos; foreach(Hero hero in gameState.heroes) { if (hero.pos.x < size && gameState.board[hero.pos.x + 1][hero.pos.y] == Tile.TAVERN) { continue; } if (hero.pos.y < size && gameState.board[hero.pos.x][hero.pos.y + 1] == Tile.TAVERN) { continue; } if (hero.pos.x > 0 && gameState.board[hero.pos.x - 1][hero.pos.y] == Tile.TAVERN) { continue; } if (hero.pos.y > 0 && gameState.board[hero.pos.x][hero.pos.y - 1] == Tile.TAVERN) { continue; } if (Pos.DistanceBetween(hero.pos, hero.spawnPos) == 0) { continue; } if (hero.life < gameState.myHero.life) { if (Math.Abs(myPos.x - hero.pos.x) + Math.Abs(myPos.y - hero.pos.y) == 2) { if (myPos.x > hero.pos.x) { return Direction.North; } else if (myPos.x < hero.pos.x) { return Direction.South; } else if (myPos.y > hero.pos.y) { return Direction.West; } else { return Direction.East; } } else if (Math.Abs(myPos.x - hero.pos.x) + Math.Abs(myPos.y - hero.pos.y) == 1) { //Maybe there's a tavern if (myPos.x < size && gameState.board[myPos.x + 1][myPos.y] == Tile.TAVERN) { return Direction.South; } if (myPos.y < size && gameState.board[myPos.x][myPos.y + 1] == Tile.TAVERN) { return Direction.East; } if (myPos.x > 0 && gameState.board[myPos.x - 1][myPos.y] == Tile.TAVERN) { return Direction.North; } if (myPos.y > 0 && gameState.board[myPos.x][myPos.y - 1] == Tile.TAVERN) { return Direction.West; } return Direction.Stay; } } } return ""; }
public override Pos GetGoal(GameState state, TestBot bot) { // Go to tavern return bot.GetClosestTavern(state.myHero.pos); }