private RobotMove FindSafePlace(Map map) { // if (map.IsSafeMove(map.Robot, map.Robot.Add(new Vector(0, 1)), 1, map.WaterproofLeft)) return RobotMove.Up; if(map.IsSafeMove(map.Robot, map.Robot, 1, map.WaterproofLeft)) return RobotMove.Wait; var waveRun = new WaveRun(map, map.Robot); Tuple<Vector, Stack<RobotMove>> target = waveRun.EnumerateTargets((lmap, position, stepNumber) => true).FirstOrDefault(); if(target == null) return RobotMove.Abort; return target.Item2.Any() ? target.Item2.Peek() : RobotMove.Wait; }
private RobotMove FindMovableRock(Map map) { var left = new Vector(-1, 0); var right = new Vector(1, 0); var up = new Vector(0, 1); var leftRobot = map.Robot.Add(left); var rightRobot = map.Robot.Add(right); var upRobot = map.Robot.Add(up); var leftCheck = map.GetCell(leftRobot) != MapCell.Wall && map.IsSafeMove(map.Robot, map.Robot.Add(left), 1, map.WaterproofLeft); var rightCheck = map.GetCell(rightRobot) != MapCell.Wall && map.IsSafeMove(map.Robot, map.Robot.Add(right), 1, map.WaterproofLeft); if (map.GetCell(leftRobot).IsRock() && map.GetCell(leftRobot.Add(left)) == MapCell.Empty && leftCheck) return RobotMove.Left; if (map.GetCell(rightRobot).IsRock() && map.GetCell(rightRobot.Add(right)) == MapCell.Empty && rightCheck) return RobotMove.Right; if (map.GetCell(upRobot).IsRock() && map.GetCell(leftRobot).IsMovable() && leftCheck) return RobotMove.Left; if (map.GetCell(upRobot).IsRock() && map.GetCell(rightRobot).IsMovable() && rightCheck) return RobotMove.Right; var waveRun = new WaveRun(map, map.Robot); moveRockTarget = waveRun.EnumerateTargets( (lmap, position, used) => { if (lmap.GetCell(position.Add(up)).IsRock() && (lmap.GetCell(position.Add(left)).IsMovable() || lmap.GetCell(position.Add(right)).IsMovable())) return true; if (lmap.GetCell(position).IsMovable() && lmap.GetCell(position.Add(left)).IsRock() && lmap.GetCell(position.Add(left).Add(left)).IsRockMovable()) return true; if (lmap.GetCell(position).IsMovable() && lmap.GetCell(position.Add(right)).IsRock() && lmap.GetCell(position.Add(right).Add(right)).IsRockMovable()) return true; if (lmap.GetCell(position) == MapCell.Earth && lmap.GetCell(position.Add(right)).IsRock() && lmap.GetCell(position.Add(right).Add(right)) != MapCell.Wall && !lmap.GetCell(position.Add(right).Add(right)).IsRock()) return true; if (lmap.GetCell(position) == MapCell.Earth && lmap.GetCell(position.Add(left)).IsRock() && lmap.GetCell(position.Add(right).Add(right)) != MapCell.Wall && !lmap.GetCell(position.Add(right).Add(right)).IsRock()) return true; return false; }).FirstOrDefault(); if(moveRockTarget == null) return RobotMove.Abort; return moveRockTarget.Item2.Any() ? moveRockTarget.Item2.Peek() : RobotMove.Abort; }