private RefillFlowRecord DoApply(Container2D_Rectangular container, FillInfo[,] fillInfoMap) { var ret = new RefillFlowRecord(); var slots = container.WrapperRect; container.ForeachSlot((x, y, slot)=>{ if (null != slot) return; var fi = fillInfoMap[y, x]; if (fi.IsOnSpot){ ret.OnSpotList.Add(new Pos2D(x, y)); } }); var ends = CollectRefillEnds(container, fillInfoMap); var dir = new Dictionary<int, Tuple<SlotWrapper2D, int>>(); foreach (var e in ends) { var pos = fillInfoMap[e.y, e.x].ancestorPos; int inverseDepth = 0; while (container.IsLegalPosition(pos.x, pos.y)) { var s = slots[pos.y, pos.x]; if (null != s) { inverseDepth++; if (!dir.ContainsKey(s.Trait)) { dir.Add(s.Trait, new Tuple<SlotWrapper2D, int>(s, inverseDepth)); } else if (dir[s.Trait].item2 < inverseDepth) { dir[s.Trait].item2 = inverseDepth; } } pos = fillInfoMap[pos.y, pos.x].ancestorPos; } } var list = new List<Tuple<SlotWrapper2D, int>>(); foreach (var kvp in dir) { list.Add(kvp.Value); } list.Sort((lhr, rhr)=>{ return (lhr.item2 < rhr.item2) ? -1 : 1; }); foreach (var t in list) { var src = t.item1.pos; var moveTo = DepthFirstSearch(slots, fillInfoMap, src.x, src.y); var dst = moveTo.item1; var path = new RefillFlowRecord.Path(); path.src = src.Clone(); path.dst = dst.Clone(); container.SwapSlot(src.x, src.y, dst.x, dst.y); var cur = path.dst; do { path.movements.Add(cur); cur = fillInfoMap[cur.y, cur.x].ancestorPos; } while (cur != path.src); path.movements.Add(path.src); path.movements.Reverse(); ret.NonFillMovements.Add(path); } ret.FillMovements = CollectFillPathList(container, fillInfoMap); return ret; }
public OperationOutput PerformOperation(OperationInput op) { var ret = new OperationOutput(); ret.IsRejected = true; foreach (var plm in plmRecords) { if ((plm.x1 == op.x1 && plm.y1 == op.y1 && plm.x2 == op.x2 && plm.y2 == op.y2) || (plm.x1 == op.x2 && plm.y1 == op.y2 && plm.x2 == op.x1 && plm.y2 == op.y1)) { ret.IsRejected = false; break; } } if (ret.IsRejected) { return(ret); } else { ret.episodes = new List <OperationOutput.Episode>(); } foreground.SwapSlot(op.x1, op.y1, op.x2, op.y2); var lmRecords = new List <LMRecord2D_Retangular>(); lmRecords = SeekContainerLM(foreground); do { var elimination = new OperationOutput.Episode(OperationOutput.EpisodeType.ELIMINATION); elimination.elimination = new List <Pos2D>(); var sandbox = CollectContainerEliminate(foreground, lmRecords); foreground.ForeachSlot((x, y, slot) => { if (sandbox[y, x]) { elimination.elimination.Add(new Pos2D(x, y)); foreground.ClearSlot(x, y); } }); ret.episodes.Add(elimination); foreach (var sc in scoreRules) { sc.Apply(sandbox); } ret.episodes.Add(DoRefill()); lmRecords = SeekContainerLM(foreground); if (0 == lmRecords.Count) { plmRecords = SeekContainerPLM(foreground); if (plmRecords.Count >= minimalPlayablePLM) { break; } else { foreground.RecreateSubjects(true); MakeContainerStable(foreground); MakeContainerPlayable(foreground); var shuffle = new OperationOutput.Episode(OperationOutput.EpisodeType.SHUFFLE); shuffle.shuffle = new SlotAttribute[foreground.Height, foreground.Width]; foreground.ForeachSlot((x, y, slot) => { shuffle.shuffle[y, x] = slot.slotAttribute; }); ret.episodes.Add(shuffle); plmRecords = SeekContainerPLM(foreground); break; } } }while (true); return(ret); }
private RefillFlowRecord DoApply(Container2D_Rectangular container, FillInfo[,] fillInfoMap) { var ret = new RefillFlowRecord(); var slots = container.WrapperRect; container.ForeachSlot((x, y, slot) => { if (null != slot) { return; } var fi = fillInfoMap[y, x]; if (fi.IsOnSpot) { ret.OnSpotList.Add(new Pos2D(x, y)); } }); var ends = CollectRefillEnds(container, fillInfoMap); var dir = new Dictionary <int, Tuple <SlotWrapper2D, int> >(); foreach (var e in ends) { var pos = fillInfoMap[e.y, e.x].ancestorPos; int inverseDepth = 0; while (container.IsLegalPosition(pos.x, pos.y)) { var s = slots[pos.y, pos.x]; if (null != s) { inverseDepth++; if (!dir.ContainsKey(s.Trait)) { dir.Add(s.Trait, new Tuple <SlotWrapper2D, int>(s, inverseDepth)); } else if (dir[s.Trait].item2 < inverseDepth) { dir[s.Trait].item2 = inverseDepth; } } pos = fillInfoMap[pos.y, pos.x].ancestorPos; } } var list = new List <Tuple <SlotWrapper2D, int> >(); foreach (var kvp in dir) { list.Add(kvp.Value); } list.Sort((lhr, rhr) => { return((lhr.item2 < rhr.item2) ? -1 : 1); }); foreach (var t in list) { var src = t.item1.pos; var moveTo = DepthFirstSearch(slots, fillInfoMap, src.x, src.y); var dst = moveTo.item1; var path = new RefillFlowRecord.Path(); path.src = src.Clone(); path.dst = dst.Clone(); container.SwapSlot(src.x, src.y, dst.x, dst.y); var cur = path.dst; do { path.movements.Add(cur); cur = fillInfoMap[cur.y, cur.x].ancestorPos; } while (cur != path.src); path.movements.Add(path.src); path.movements.Reverse(); ret.NonFillMovements.Add(path); } ret.FillMovements = CollectFillPathList(container, fillInfoMap); return(ret); }