private List <Point> GetPerkAims() { var aims = FullBoard.GetPerks() .Where(x => !FullBoard.IsInDanger(x, PrevFullBoard) && !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT) && FullBoard.GetPathFromHero(x, PrevFullBoard)?.Length < 4) .ToList(); return(aims); }
private List <Point> GetZombieAims() { var target = FullBoard.GetZombies().Where(x => x.GetLengthTo(FullBoard.GetMe()) <= 5).ToList(); var aims = new List <Point>(); aims.AddRange(target.Select(x => x.ShiftLeft().ShiftLeft()).Where(x => !FullBoard.IsHeroBarrierAt(x) && !FullBoard.IsInDanger(x, PrevFullBoard) && !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT))); aims.AddRange(target.Select(x => x.ShiftRight().ShiftRight()).Where(x => !FullBoard.IsHeroBarrierAt(x) && !FullBoard.IsInDanger(x, PrevFullBoard) && !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT))); aims.AddRange(target.Select(x => x.ShiftLeft().ShiftLeft()).Where(x => !FullBoard.IsHeroBarrierAt(x) && !FullBoard.IsInDanger(x, PrevFullBoard) && !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT))); aims.AddRange(target.Select(x => x.ShiftRight().ShiftRight()).Where(x => !FullBoard.IsHeroBarrierAt(x) && !FullBoard.IsInDanger(x, PrevFullBoard) && !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT))); return(aims); }
private List <Point> GetGoldAims() { var notAfk = FullBoard.GetOtherHeroes().Where(x => !PrevFullBoard.GetOtherHeroes().Contains(x)).ToList(); var aims = FullBoard.GetGold() .Where(x => x.GetLengthTo(FullBoard.GetMe()) < Constants.GoldRadius * 2 && !FullBoard.IsInDanger(x, PrevFullBoard) && !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT) && FullBoard.GetPathFromHero(x, PrevFullBoard)?.Length < Constants.GoldRadius && notAfk.All(othetHero => FullBoard.GetPath(othetHero, x, PrevFullBoard)?.Length >= FullBoard.GetPathFromHero(x, PrevFullBoard)?.Length)) .ToList(); return(aims); }
// GET: GameBoard public ActionResult Index() { FullBoard board = new FullBoard() { GameBoard = sudoku.buildBoard() }; int puzzleNumber; load.LoadNewPuzzle(board.GameBoard, out puzzleNumber); board.BoardNumber = puzzleNumber; return(View("GameBoard", board)); }
public ActionResult LoadGame() { FullBoard board = new FullBoard() { GameBoard = sudoku.buildBoard() }; int puzzleNumber; load.LoadSavedPuzzle(board.GameBoard, out puzzleNumber); board.Status = sudoku.GetPuzzleStatus(board.GameBoard); board.BoardNumber = puzzleNumber; return(View("GameBoard", board)); }
private List <Point> GetFarmAims() { var target = new List <Point>(); target.AddRange(FullBoard.GetOtherHeroes().Where(x => FullBoard.GetStarts().Any(start => start.GetLengthTo(x) < 2)).ToList()); target.AddRange(FullBoard.GetStarts()); var aims = new List <Point>(); aims.AddRange(target.Select(x => x.ShiftLeft()).Where(x => !FullBoard.IsHeroBarrierAt(x) && !FullBoard.IsInDanger(x, PrevFullBoard) && !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT))); aims.AddRange(target.Select(x => x.ShiftRight()).Where(x => !FullBoard.IsHeroBarrierAt(x) && !FullBoard.IsInDanger(x, PrevFullBoard) && !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT))); aims.AddRange(target.Select(x => x.ShiftTop()).Where(x => !FullBoard.IsHeroBarrierAt(x) && !FullBoard.IsInDanger(x, PrevFullBoard) && !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT))); aims.AddRange(target.Select(x => x.ShiftBottom()).Where(x => !FullBoard.IsHeroBarrierAt(x) && !FullBoard.IsInDanger(x, PrevFullBoard) && !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT))); return(aims); }
private List <Point> GetTheNearestToHero(IEnumerable <Point> aims) { AimPath bestPath = null; foreach (var aim in aims) { var path = FullBoard.GetPathFromHero(aim, PrevFullBoard); if (path != null && path.Path.Count > 1) { if (bestPath == null || path.Length < bestPath.Length) { bestPath = path; } } } return(bestPath?.Path); }
private (List <Point>, Direction)? GetTheNearestToExit(IEnumerable <Point> aims) { var aimPathes = new Dictionary <Point, AimPath>(); foreach (var point in aims) { var path = FullBoard.GetPathFromHero(point, PrevFullBoard); if (path != null && path.Path.Count > 1) { aimPathes[point] = path; } } foreach (var item in aimPathes.OrderBy(x => GetLenghtToExit(FullBoard, x.Key) * 2 + x.Value.Length)) { var aim = item.Key; var path = item.Value; if (!FullBoard.IsHeroBarrierAt(aim.ShiftLeft()) && !FullBoard.IsAt(aim.ShiftLeft(), Element.START) && !FullBoard.IsInDanger(aim.ShiftLeft(), PrevFullBoard) && GetLenghtToExit(FullBoard, aim.ShiftLeft()) > GetLenghtToExit(FullBoard, aim) && !FullBoard.IsHeroBarrierAt(aim.ShiftLeft().ShiftLeft()) && FullBoard.GetPathFromHero(aim.ShiftLeft().ShiftLeft(), PrevFullBoard) != null) { path = FullBoard.GetPathFromHero(aim.ShiftLeft(), PrevFullBoard); if (path != null) { return(path.Path, Direction.Left); } } if (!FullBoard.IsHeroBarrierAt(aim.ShiftRight()) && !FullBoard.IsAt(aim.ShiftRight(), Element.START) && !FullBoard.IsInDanger(aim.ShiftRight(), PrevFullBoard) && GetLenghtToExit(FullBoard, aim.ShiftRight()) > GetLenghtToExit(FullBoard, aim) && !FullBoard.IsHeroBarrierAt(aim.ShiftRight().ShiftRight()) && FullBoard.GetPathFromHero(aim.ShiftRight().ShiftRight(), PrevFullBoard) != null) { path = FullBoard.GetPathFromHero(aim.ShiftRight(), PrevFullBoard); if (path != null) { return(path.Path, Direction.Right); } } if (!FullBoard.IsHeroBarrierAt(aim.ShiftTop()) && !FullBoard.IsAt(aim.ShiftTop(), Element.START) && !FullBoard.IsInDanger(aim.ShiftTop(), PrevFullBoard) && GetLenghtToExit(FullBoard, aim.ShiftTop()) > GetLenghtToExit(FullBoard, aim) && !FullBoard.IsHeroBarrierAt(aim.ShiftTop().ShiftTop()) && FullBoard.GetPathFromHero(aim.ShiftTop().ShiftTop(), PrevFullBoard) != null) { path = FullBoard.GetPathFromHero(aim.ShiftTop(), PrevFullBoard); if (path != null) { return(path.Path, Direction.Up); } } if (!FullBoard.IsHeroBarrierAt(aim.ShiftBottom()) && !FullBoard.IsAt(aim.ShiftBottom(), Element.START) && !FullBoard.IsInDanger(aim.ShiftBottom(), PrevFullBoard) && GetLenghtToExit(FullBoard, aim.ShiftBottom()) > GetLenghtToExit(FullBoard, aim) && !FullBoard.IsHeroBarrierAt(aim.ShiftBottom().ShiftBottom()) && FullBoard.GetPathFromHero(aim.ShiftBottom().ShiftBottom(), PrevFullBoard) != null) { path = FullBoard.GetPathFromHero(aim.ShiftBottom(), PrevFullBoard); if (path != null) { return(path.Path, Direction.Down); } } } return(null); }
private List <Point> GetBoxAims() { var boxesAims = FullBoard.GetBoxes(); return(boxesAims); }
private List <Point> GetExitAims() { var exitAims = FullBoard.GetExits().Where(x => !FullBoard.IsAt(x, Element.LASER_DOWN, Element.LASER_LEFT, Element.LASER_UP, Element.LASER_RIGHT)).ToList(); return(exitAims); }
/// <summary> /// Calls each move to make decision what to do (next move) /// </summary> public override Command WhatToDo(Board board) { var me = board.GetMe(); if (Static.TurnsWithoutAim == Constants.MaxTurnCountWithoutAim) { Static.TurnsWithoutAim = 0; return(Command.Reset()); } if (board.GetExits().Contains(me)) { return(Command.DoNothing()); } if (!board.IsMeAlive()) { HandleDie(); return(Command.DoNothing()); } if (Static.PerkCooldownDeathRay > 0) { Static.PerkCooldownDeathRay--; } if (Static.PerkCooldownUnlimitedFire > 0) { Static.PerkCooldownUnlimitedFire--; } if (Static.PerkCooldownUnstopableLaser > 0) { Static.PerkCooldownUnstopableLaser--; } foreach (var point in board.GetStepBarriers(PrevBoard)) { board.AddOnLayer4(point.X, point.Y, 's'); } foreach (var point in board.GetJumpBarriers(PrevBoard)) { board.AddOnLayer5(point.X, point.Y, 'j'); } if (board.IsAt(me, Element.ROBO_FLYING)) { if (prevBestPath != null) { foreach (var pathPoint in prevBestPath) { board.AddOnLayer4(pathPoint.X, pathPoint.Y, 't'); } board.AddOnLayer4(prevBestPath.Last().X, prevBestPath.Last().Y, 'a'); } return(Command.DoNothing()); } //Check that fire is not danger and gun is ready if (CanFire(board, me)) { //Try to use Death Ray perk if (Static.PerkCooldownDeathRay > 0) { if (board.GetOtherHeroes().Any(hero => hero.Y == me.Y && hero.X > me.X && hero.GetLengthTo(me) < Constants.DeathRayLength) || board.GetZombies().Any(hero => hero.Y == me.Y && hero.X > me.X && hero.GetLengthTo(me) < Constants.DeathRayLength)) { board.AddOnLayer2(me.X, me.Y, '~'); return(Command.Fire(Direction.Right)); } if (board.GetOtherHeroes().Any(hero => hero.Y == me.Y && hero.X < me.X && hero.GetLengthTo(me) < Constants.DeathRayLength) || board.GetZombies().Any(hero => hero.Y == me.Y && hero.X < me.X && hero.GetLengthTo(me) < Constants.DeathRayLength)) { board.AddOnLayer2(me.X, me.Y, '~'); return(Command.Fire(Direction.Left)); } if (board.GetOtherHeroes().Any(hero => hero.X == me.X && hero.Y < me.Y && hero.GetLengthTo(me) < Constants.DeathRayLength) || board.GetZombies().Any(hero => hero.X == me.X && hero.Y < me.Y && hero.GetLengthTo(me) < Constants.DeathRayLength)) { board.AddOnLayer2(me.X, me.Y, '~'); return(Command.Fire(Direction.Up)); } if (board.GetOtherHeroes().Any(hero => hero.X == me.X && hero.Y > me.Y && hero.GetLengthTo(me) < Constants.DeathRayLength) || board.GetZombies().Any(hero => hero.X == me.X && hero.Y > me.Y && hero.GetLengthTo(me) < Constants.DeathRayLength)) { board.AddOnLayer2(me.X, me.Y, '~'); return(Command.Fire(Direction.Down)); } } if (ShouldFireToLeft()) { board.AddOnLayer2(me.X, me.Y, '~'); return(Command.Fire(Direction.Left)); } if (ShouldFireToRight()) { board.AddOnLayer2(me.X, me.Y, '~'); return(Command.Fire(Direction.Right)); } if (ShouldFireToTop()) { board.AddOnLayer2(me.X, me.Y, '~'); return(Command.Fire(Direction.Up)); } if (ShouldFireToBottom()) { board.AddOnLayer2(me.X, me.Y, '~'); return(Command.Fire(Direction.Down)); } } Static.CanExit = false; //Priority 1 aims: Corners of the full map (map new areas discovering) List <Point> bestPath = GetTheNearestToHero(GetCornersAims()); //Not discover new arias if level is not final (22) and exist already visible if (board.CurrentLevel < 22 && GetTheNearestToHero(GetExitAims()) != null) { bestPath = null; } //Strategy choice: Farm on the start or collect gold and go to exit if (GetTheNearestToHero(GetGoldAims()) != null || goldCollected > 0) { Static.Farm = 0; } else if (board.GetOtherHeroes().Any()) { Static.Farm = 1; } //Kill other heroes on the start if no gold nearly if (Static.Farm == 1) { bestPath = GetTheNearestToHero(GetFarmAims()); } //Go to nearest gold or perk if (bestPath == null) { var stuffAims = new List <Point>(); stuffAims.AddRange(GetGoldAims()); stuffAims.AddRange(GetPerkAims()); bestPath = GetTheNearestToHero(stuffAims); } //Try to find exit if (bestPath == null) { Static.CanExit = true; //Exit is allowed there are no other aims bestPath = GetTheNearestToHero(GetExitAims()); if (bestPath != null) { Static.IsExitOpen = true; boxesMoved = 0; } } if (bestPath == null) { Static.IsExitOpen = false; } //If all map is discovered and no path to exit - try to move boxes that is nearest to exit if (bestPath == null && boxesMoved <= 5) { var boxToPull = GetTheNearestToExit(GetBoxAims()); if (boxToPull != null) { bestPath = boxToPull.Value.Item1; if (bestPath.Count == 1) { boxesMoved++; return(Command.Pull(boxToPull.Value.Item2)); } } } //If still no exist after boxes move - kill everything if (bestPath == null) { var heroAims = new List <Point>(); heroAims.AddRange(GetAfkAims()); heroAims.AddRange(GetHeroesAims()); heroAims.AddRange(GetZombieAims()); bestPath = GetTheNearestToHero(heroAims); } if (bestPath == null) { Static.TurnsWithoutAim++; return(Command.DoNothing()); } else { Static.TurnsWithoutAim = 0; } bestPath = bestPath.Select(x => x.AbsoluteToRelative(board.Size, board.Offset)).ToList(); prevBestPath = bestPath; //Show best path on the board foreach (var pathPoint in bestPath) { board.AddOnLayer4(pathPoint.X, pathPoint.Y, 't'); var absolute = pathPoint.RelativeToAbsolute(board.Size, board.Offset); FullBoard.AddOnLayer4(absolute.X, absolute.Y, 't'); } board.AddOnLayer4(bestPath.Last().X, bestPath.Last().Y, 'a'); var a = bestPath.Last().RelativeToAbsolute(board.Size, board.Offset); FullBoard.AddOnLayer4(a.X, a.Y, 'a'); var nextPosition = bestPath[1]; if (board.IsAt(nextPosition, Element.GOLD)) { goldCollected++; } if (board.IsAt(nextPosition, Element.EXIT)) { goldCollected = 0; } if (board.IsAt(nextPosition, Element.DEATH_RAY_PERK)) { Static.PerkCooldownDeathRay = 10; } if (board.IsAt(nextPosition, Element.UNLIMITED_FIRE_PERK)) { Static.PerkCooldownUnlimitedFire = 10; } if (board.IsAt(nextPosition, Element.UNSTOPPABLE_LASER_PERK)) { Static.PerkCooldownUnstopableLaser = 10; } if (me.GetLengthTo(nextPosition) == 1) { return(Command.Go(GetDirection(me, nextPosition))); } return(Command.Jump(GetDirection(me, nextPosition))); }
public ActionResult SaveGame(FullBoard board) { save.SaveGame(board.GameBoard, board.BoardNumber); board.Status = sudoku.GetPuzzleStatus(board.GameBoard); return(View("GameBoard", board)); }
public ActionResult UpdateGame(FullBoard board) { board.Status = sudoku.GetPuzzleStatus(board.GameBoard); return(View("GameBoard", board)); }
private void Socket_OnMessage(object sender, MessageEventArgs e) { if (!ShouldExit) { var watch = System.Diagnostics.Stopwatch.StartNew(); var response = e.Data; if (!response.StartsWith(ResponsePrefix)) { Console.WriteLine("Something strange is happening on the server... Response:\n{0}", response); ShouldExit = true; } else { var boardString = response.Substring(ResponsePrefix.Length); var board = new Board(boardString); Board = board; if (FullBoard.CurrentLevel == 0) { FullBoard.CurrentLevel = board.CurrentLevel; } if (FullBoard.CurrentLevel != board.CurrentLevel) { FullBoard = new Board(Constants.FullBoardSize); if (Directory.Exists(Constants.CacheFolder)) { var levelCacheFile = $"{Constants.CacheFolder}/{board.CurrentLevel}.dat"; if (File.Exists(levelCacheFile)) { using (FileStream fs = new FileStream(levelCacheFile, FileMode.OpenOrCreate)) { FullBoard = (Board)formatter.Deserialize(fs); } } } FullBoard.CurrentLevel = board.CurrentLevel; } for (int layer = 0; layer < FullBoard.Field.GetLength(0); layer++) { for (int x = 0; x < FullBoard.Size; x++) { for (int y = 0; y < FullBoard.Size; y++) { if (FullBoard.IsAt(layer, x, y, Element.ROBO_OTHER, Element.ROBO_OTHER_FLYING, Element.ROBO_OTHER_LASER, Element.ROBO_OTHER_FALLING, Element.LASER_DOWN, Element.LASER_UP, Element.LASER_LEFT, Element.LASER_RIGHT, Element.ZOMBIE_DIE, Element.FEMALE_ZOMBIE, Element.MALE_ZOMBIE, Element.AIM, Element.PATH, Element.GOLD)) { FullBoard.Field[layer, x, y] = (char)Element.EMPTY; } } } } for (int layer = 0; layer < board.Field.GetLength(0); layer++) { for (int x = 0; x < board.Size; x++) { for (int y = 0; y < board.Size; y++) { var absolutePoint = new Point(x, y).RelativeToAbsolute(board.Size, board.Offset); FullBoard.Field[layer, absolutePoint.X, absolutePoint.Y] = board.Field[layer, x, y]; } } } if (board.HeroPosition.Y <= 1) { for (int x = 0; x < board.Size; x++) { var absolutePoint = new Point(x, -1).RelativeToAbsolute(board.Size, board.Offset); FullBoard.Field[0, absolutePoint.X, absolutePoint.Y] = (char)Element.WALL_FRONT; } } if (board.HeroPosition.X >= board.Size - 2) { for (int y = 0; y < board.Size; y++) { var absolutePoint = new Point(board.Size, y).RelativeToAbsolute(board.Size, board.Offset); FullBoard.Field[0, absolutePoint.X, absolutePoint.Y] = (char)Element.WALL_FRONT; } } FullBoard.HeroPosition = board.HeroPosition.RelativeToAbsolute(board.Size, board.Offset); if (!Directory.Exists(Constants.CacheFolder)) { Directory.CreateDirectory(Constants.CacheFolder); } using (FileStream fs = new FileStream($"Cache/{FullBoard.CurrentLevel}.dat", FileMode.OpenOrCreate)) { formatter.Serialize(fs, FullBoard); } //Just print current state (gameBoard) to console /*Console.Clear(); * Console.SetCursorPosition(0, 0);*/ var action = ""; var time = ""; try { turnCounter++; action = WhatToDo(board).ToString(); time = $"Execution Time: {watch.ElapsedMilliseconds} ms"; } catch { } if (action.Contains("ACT(3)")) { Static.TurnsWithoutFire = 0; Static.PerkCooldownDeathRay = 0; Static.PerkCooldownUnstopableLaser = 0; } else { Static.TurnsWithoutFire++; } var str = new StringBuilder(); str.AppendLine(time); str.AppendLine("Answer: " + action); str.AppendLine("Gold collected: " + goldCollected); str.AppendLine("Turns without fire: " + Static.TurnsWithoutFire); str.AppendLine("DeathRay Perk Cooldown: " + Static.PerkCooldownDeathRay); str.AppendLine("Unlimited Fire Perk Cooldown: " + Static.PerkCooldownUnlimitedFire); str.AppendLine("Unstopable Laser Perk Cooldown: " + Static.PerkCooldownUnstopableLaser); str.AppendLine(board.ToString()); str.AppendLine(FullBoard.ToString()); if (PrevBoard != null) { str.AppendLine(PrevFullBoard.ToString()); } if (!action.IsNullOrEmpty()) { prevState = str.ToString(); } for (int layer = 0; layer < board.Field.GetLength(0); layer++) { for (int x = 0; x < board.Size; x++) { for (int y = 0; y < board.Size; y++) { PrevBoard.Field[layer, x, y] = board.Field[layer, x, y]; } } } for (int layer = 0; layer < FullBoard.Field.GetLength(0); layer++) { for (int x = 0; x < FullBoard.Size; x++) { for (int y = 0; y < FullBoard.Size; y++) { PrevFullBoard.Field[layer, x, y] = FullBoard.Field[layer, x, y]; } } } /*Console.WriteLine(str.ToString()); * Console.SetCursorPosition(0, 0);*/ ((WebSocket)sender).Send(action); BoardUpdated?.Invoke(board, str.ToString()); } } }