public List <ICommand> MakeReassemblyTrace(TModel srcModel, TModel tgtModel) { Fill doFill = new Fill(); doFill.Diff.Dy = -1; Void doVoid = new Void(); doVoid.Diff.Dy = -1; var result = new List <ICommand>(); result.Add(new Flip()); var current = new TCoord(); var dumpCureTraverse = new TDumpCubeTraverse(srcModel, tgtModel); TState state = new TState(srcModel); List <ICommand> ss = new List <ICommand>(); var iteration = 0; while ((iteration == 0) || !current.IsAtStart()) { var next = dumpCureTraverse.Next(); if (srcModel[next] > 0) { Void curVoid = new Void(); curVoid.Diff = dumpCureTraverse.GetDirection(); result.Add(curVoid); { if (ss.Count == 0) { ss.Add(curVoid); } else { ss[0] = curVoid; } ss.Add(curVoid); TCommandsReader cr = new TCommandsReader(ss); state.Step(cr); } } var move = new StraightMove(); move.Diff = dumpCureTraverse.GetDirection(); result.Add(move); { if (ss.Count == 0) { ss.Add(move); } else { ss[0] = move; } TCommandsReader cr = new TCommandsReader(ss); state.Step(cr); } if ((next.Y > 0) && (tgtModel[next.X, next.Y - 1, next.Z] > 0) && state.Matrix[next.X, next.Y - 1, next.Z] == 0) { result.Add(doFill); { if (ss.Count == 0) { ss.Add(doFill); } else { ss[0] = doFill; } TCommandsReader cr = new TCommandsReader(ss); state.Step(cr); } } if ((next.Y > 0) && (tgtModel[next.X, next.Y - 1, next.Z] == 0) && state.Matrix[next.X, next.Y - 1, next.Z] > 0) { result.Add(doVoid); { if (ss.Count == 0) { ss.Add(doVoid); } else { ss[0] = doVoid; } TCommandsReader cr = new TCommandsReader(ss); state.Step(cr); } } current = next; ++iteration; } result.Add(new Flip()); result.Add(new Halt()); return(result); }
private ICommand MoveBot(Bot bot, List <Bot> newBots, ref int numDeadBots, List <TCoord> filledCoords) { if (bot.NextCommand < (bot.MoveCommands?.Count ?? 0)) { switch (bot.MoveCommands[bot.NextCommand]) { case StraightMove m: TraceMove(bot.Coord, m, coord => interferedCells.Add(coord)); bot.Coord.Apply(m.Diff); break; case LMove m: throw new NotImplementedException(); case Wait w: break; default: throw new Exception($"WTF, unexpected command: {bot.GetType().FullName}"); } ++bot.NextCommand; if (bot.MoveTarget != null && bot.NextCommand == bot.MoveCommands.Count) { bot.MoveTarget = null; } return(bot.MoveCommands[bot.NextCommand - 1]); } if (bot.FissionTarget != null) { interferedCells.Add(bot.FissionTarget.Value); var m = bot.Seeds.Count / 2; newBots.Add( new Bot() { Id = bot.Seeds[0], Coord = bot.FissionTarget.Value, Seeds = bot.Seeds.Skip(1).Take(m).ToList(), FissionTimeout = 3, }); bot.Seeds.RemoveRange(0, m + 1); var ret = new Fission { Diff = bot.FissionTarget.Value.Diff(bot.Coord), M = m, }; bot.FissionTarget = null; return(ret); } if (bot.FusionPTarget != null) { interferedCells.Add(bot.FusionPTarget.Value); if (botPositions.TryGetValue(bot.FusionPTarget.Value, out var another)) { var ret = new FusionP { Diff = bot.FusionPTarget.Value.Diff(bot.Coord) }; bot.Seeds.Add(another.Id); bot.Seeds.AddRange(another.Seeds); bot.Seeds.Sort(); bot.ActedFusionPTarget = bot.FusionPTarget; bot.FusionPTarget = null; return(ret); } throw new InvalidOperationException("Trying to run fusion on not a bot cell!"); } else if (bot.FusionSTarget != null) { var ret = new FusionS { Diff = bot.FusionSTarget.Value.Diff(bot.Coord) }; interferedCells.Add(bot.FusionSTarget.Value); ++numDeadBots; bot.MustDie = true; bot.ActedFusionSTarget = bot.FusionSTarget; bot.FusionSTarget = null; return(ret); } if (bot.FillTarget != null) { interferedCells.Add(bot.FillTarget.Value); availablePositions.Remove(bot.FillTarget.Value); filledCoords.Add(bot.FillTarget.Value); var ret = new Fill { Diff = bot.FillTarget.Value.Diff(bot.Coord) }; bot.FillTarget = null; return(ret); } if (bot.VoidTarget != null) { interferedCells.Add(bot.VoidTarget.Value); availablePositions.Remove(bot.VoidTarget.Value); filledCoords.Add(bot.VoidTarget.Value); var ret = new Void() { Diff = bot.VoidTarget.Value.Diff(bot.Coord) }; bot.VoidTarget = null; return(ret); } throw new Exception($"WTF {numFilled} / {model.NumFilled}"); }
public List <ICommand> MakeTrace(TModel src, TModel model) { if (src.NumFilled != 0) { return(null); } ICommand modifyCommand = new Fill(); ((Fill)modifyCommand).Diff.Dy = -1; if (model.Name.Contains("FD")) { modifyCommand = new Void(); ((Void)modifyCommand).Diff.Dy = -1; } // TState state = new TState(model); var result = new List <ICommand>(); result.Add(new Flip()); var current = new TCoord(); var dumpCureTraverse = new TDumpCubeTraverse(model); var iteration = 0; while ((iteration == 0) || !current.IsAtStart()) { if (iteration == 295) { int a = 0; } var next = model.Name.Contains("FA") ? dumpCureTraverse.Next() : dumpCureTraverse.NextDestroy(); var move = new StraightMove(); move.Diff = dumpCureTraverse.GetDirection(); result.Add(move); // { // List<ICommand> ss = new List<ICommand>(); // ss.Add(move); // TCommandsReader cr = new TCommandsReader(ss); // state.Step(cr); // } if ((next.Y > 0) && (model[next.X, next.Y - 1, next.Z] > 0)) { result.Add(modifyCommand); // { // List<ICommand> ss = new List<ICommand>(); // ss.Add(move); // TCommandsReader cr = new TCommandsReader(ss); // state.Step(cr); // } } current = next; ++iteration; } result.Add(new Flip()); result.Add(new Halt()); return(result); }