public TempPath GetFirstTempPath(int firstFilled) { var skip = firstFilled < 2 ? 0 : firstFilled - 2; var row = Start.Row + skip; var path = new TempPath(this, new Position(Start.Col, row), BlockPath.Init[skip]); return(path); }
public static IEnumerable <MoveCandiate> GetPaths(Field field, Block current, int[] targets, int maxRow) { var dones = new bool[current.RotationVariations.Length, field.RowCount + 1, 10]; TempPath first = current.GetFirstTempPath(field.FirstFilled); dones[0, first.Position.Row + 1, first.Position.Col] = true; var stack = new Stack <TempPath>(); stack.Push(first); while (stack.Count != 0) { var temp = stack.Pop(); if (temp.Position.Row > maxRow) { continue; } var test = field.Test(temp.Block, temp.Position); // No reason the investigate if (test == Field.TestResult.False) { continue; } var tr = temp.TurnRight(); if (tr.Position.Col >= 0 && tr.Position.Col <= tr.Block.ColumnMaximum && !dones[(int)tr.Block.Rotation, tr.Position.Row + 1, tr.Position.Col]) { dones[(int)tr.Block.Rotation, tr.Position.Row + 1, tr.Position.Col] = true; stack.Push(tr); } var tl = temp.TurnLeft(); if (tl.Position.Col >= 0 && tl.Position.Col <= tl.Block.ColumnMaximum && !dones[(int)tl.Block.Rotation, tl.Position.Row + 1, tl.Position.Col]) { dones[(int)tl.Block.Rotation, tl.Position.Row + 1, tl.Position.Col] = true; stack.Push(tl); } if (temp.Position.Col < temp.Block.ColumnMaximum && !dones[(int)temp.Block.Rotation, temp.Position.Row + 1, temp.Position.Col + 1]) { dones[(int)temp.Block.Rotation, temp.Position.Row + 1, temp.Position.Col + 1] = true; stack.Push(temp.Right()); } if (temp.Position.Col > 0 && !dones[(int)temp.Block.Rotation, temp.Position.Row + 1, temp.Position.Col - 1]) { dones[(int)temp.Block.Rotation, temp.Position.Row + 1, temp.Position.Col - 1] = true; stack.Push(temp.Left()); } // we have a fit. if (test == Field.TestResult.True) { if (temp.Block.TouchPosition(temp.Position, targets)) { var unique = temp.Block.Variations.Length == temp.Block.RotationVariations.Length; // if the block is rotation only, first check if counter part did not arrive already. if (!unique) { var rot_org = (int)temp.Block.Rotation & 1; var rot_acc = rot_org | 2; unique = dones[rot_org, temp.Position.Row + 1, temp.Position.Col] ^ dones[rot_acc, temp.Position.Row + 1, temp.Position.Col]; } if (unique) { var apply = field.Apply(temp.Block, temp.Position); yield return(new MoveCandiate(temp.Path, apply)); } } } else { if (!dones[(int)temp.Block.Rotation, temp.Position.Row + 2, temp.Position.Col]) { dones[(int)temp.Block.Rotation, temp.Position.Row + 2, temp.Position.Col] = true; stack.Push(temp.Down()); } } } }