private Enlistment EnlistVolatileInternal( IEnlistmentNotification notification, EnlistmentOptions options) { EnsureIncompleteCurrentScope(); /* FIXME: Handle options.EnlistDuringPrepareRequired */ Volatiles.Add(notification); /* FIXME: Enlistment.. ? */ return(new Enlistment()); }
protected T CreateNewInstance(IMap <string, INode> childNodes, IStateTreeNode meta) { var observables = Mutables.Select(mutable => new ObservableProperty { Type = mutable.Kind, Name = mutable.Name, Default = mutable.Default }).ToList(); var volatiles = Volatiles.Select(xvolatile => new Observable.VolatileProperty { Type = xvolatile.Kind, Name = xvolatile.Name, Default = xvolatile.Default }).ToList(); var computeds = Views.Select(view => new ComputedProperty { Type = view.Kind, Name = view.Name, Compute = view.View }).ToList(); // var actions = Actions.Select(action => new ActionMethod { Name = action.Name, Action = action.Action }); ObservableTypeDef typeDef = new ObservableTypeDef(observables, volatiles, computeds); var instance = ObservableObject <T, INode> .FromAs(typeDef, Proxify, Name, this, meta); return(instance); }
private void MoveBot(TBot bot, CoordDiff diff, Volatiles volatiles) { if (EnableValidation) { var miniDiff = new CoordDiff(Math.Sign(diff.Dx), Math.Sign(diff.Dy), Math.Sign(diff.Dz)); var current = bot.Coord; var end = bot.Coord; end.Apply(diff); while (!current.Equals(end)) { volatiles.Update(current, bot); current.Apply(miniDiff); if (this[current]) { throw new InvalidStateException($"Coord {current} is occupied when moving bot {bot.Bid}"); } } volatiles.Update(end, bot); } bot.Coord.Apply(diff); }
private void Fuse(Dictionary <int, CoordDiff> fusionPrimaries, Dictionary <int, CoordDiff> fusionSecondaries, Volatiles volatiles) { if (fusionPrimaries.Count != fusionSecondaries.Count) { throw new InvalidStateException( $"Fusion count mismatch: {fusionPrimaries.Count} primaries, {fusionSecondaries.Count} secondaries"); } foreach (var(primaryIdx, ndP) in fusionPrimaries) { var prim = Bots[primaryIdx]; var primaryCoord = prim.Coord; var secondaryCoord = primaryCoord; secondaryCoord.Apply(ndP); bool foundSecondary = false; foreach (var(secondaryIdx, ndS) in fusionSecondaries) { var sec = Bots[secondaryIdx]; if (sec != null && sec.Coord.Equals(secondaryCoord)) { var sanityCheckCoord = sec.Coord; sanityCheckCoord.Apply(ndS); if (!sanityCheckCoord.Equals(primaryCoord)) { throw new InvalidStateException($"Fusion coord mismatch: {sanityCheckCoord} vs. {primaryCoord}"); } prim.Seeds.Add(sec.Bid); prim.Seeds.AddRange(sec.Seeds); prim.Seeds.Sort(); volatiles.Update(prim.Coord, prim); volatiles.Update(sec.Coord, sec); Bots[secondaryIdx] = null; Energy -= 24; foundSecondary = true; break; } } if (!foundSecondary) { throw new InvalidStateException($"no secondary bot at {secondaryCoord} for bot {prim.Bid} at {primaryCoord}"); } } Bots = Bots.Where(x => x != null).ToList(); }
public void Step(TCommandsReader commands) { if (Harmonics == EHarmonics.Low) { Energy += 3 * Model.R * Model.R * Model.R; } else if (Harmonics == EHarmonics.High) { Energy += 30 * Model.R * Model.R * Model.R; } Energy += 20 * Bots.Count; var botsCount = Bots.Count; var fusionPrimaries = new Dictionary <int, CoordDiff>(); var fusionSecondaries = new Dictionary <int, CoordDiff>(); var volatiles = new Volatiles(EnableValidation); for (var botIdx = 0; botIdx < botsCount; ++botIdx) { var command = commands.GetCommand(botIdx); var bot = Bots[botIdx]; switch (command) { case Halt halt: { volatiles.Update(bot.Coord, bot); break; } case Wait wait: { volatiles.Update(bot.Coord, bot); break; } case Flip flip: { volatiles.Update(bot.Coord, bot); if (Harmonics == EHarmonics.High) { Harmonics = EHarmonics.Low; } else { Harmonics = EHarmonics.High; } break; } case StraightMove move: { MoveBot(bot, move.Diff, volatiles); Energy += 2 * move.Diff.MLen(); break; } case LMove lMove: { MoveBot(bot, lMove.Diff1, volatiles); MoveBot(bot, lMove.Diff2, volatiles); Energy += 2 * (lMove.Diff1.MLen() + 2 + lMove.Diff2.MLen()); break; } case Fission fission: { bot.Seeds.Sort(); var newBot = new TBot { Bid = bot.Seeds[0] }; for (var i = 1; i <= fission.M; ++i) { newBot.Seeds.Add(bot.Seeds[i]); } bot.Seeds.RemoveRange(0, fission.M + 1); newBot.Coord = bot.Coord; newBot.Coord.Apply(fission.Diff); volatiles.Update(bot.Coord, bot); volatiles.Update(newBot.Coord, newBot); Bots.Add(newBot); Energy += 24; break; } case Fill fill: { var newCoord = bot.Coord; newCoord.Apply(fill.Diff); volatiles.Update(bot.Coord, bot); volatiles.Update(newCoord, bot); if (Matrix[newCoord.X, newCoord.Y, newCoord.Z] > 0) { Energy += 6; } else { Matrix[newCoord.X, newCoord.Y, newCoord.Z] = 1; if (EnableValidation) { if (Harmonics == EHarmonics.Low && !IsGrounded(newCoord, new HashSet <TCoord>())) { throw new InvalidStateException($"{newCoord} is not grounded"); } } Energy += 12; } break; } case Void @void: { var newCoord = bot.Coord; newCoord.Apply(@void.Diff); volatiles.Update(bot.Coord, bot); volatiles.Update(newCoord, bot); if (Matrix[newCoord.X, newCoord.Y, newCoord.Z] > 0) { Matrix[newCoord.X, newCoord.Y, newCoord.Z] = 0; Energy -= 12; } else { Energy += 3; } break; } case FusionP fusionP: { fusionPrimaries.Add(botIdx, fusionP.Diff); break; } case FusionS fusionS: { fusionSecondaries.Add(botIdx, fusionS.Diff); break; } default: throw new InvalidStateException($"unknown item type {command}"); } } if (fusionPrimaries.Count > 0) { Fuse(fusionPrimaries, fusionSecondaries, volatiles); } SortBots(); commands.Advance(botsCount); }