コード例 #1
0
        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);
        }
コード例 #2
0
        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());
                    }
                }
            }
        }