public string GetPasswordValue(PasswordBlueprint blueprint)
        {
            var path = GetPath(blueprint).ToList();

            if (path.Any(z => Math.Min(z.X, z.Y) < 0 || Width <= z.X || Height <= z.Y))
            {
                return(null);
            }
            return(new string(path.Select(z => _matrix[z.Y * Width + z.X]).ToArray()));
        }
        public MatrixPassword CreateRandomMatrixPassword(int length)
        {
            var blueprint = new PasswordBlueprint
            {
                Length = Env.Config.MatrixPasswordLength
            };

            (var shape, var direction) = GetRandomShapeDirection();
            blueprint.Shape            = shape;
            blueprint.Direction        = direction;
            SetRandomLocation(blueprint);
            return(new MatrixPassword(GetPasswordValue(blueprint), blueprint));
        }
 private void SetRandomLocation(PasswordBlueprint blueprint)
 {
     for (int i = 0; i < 9999; i++)
     {
         blueprint.X = Helper.GetRandomInt(Width);
         blueprint.Y = Helper.GetRandomInt(Height);
         if (GetPasswordValue(blueprint) == null)
         {
             continue;
         }
         return;
     }
     throw new ArgumentException("Possible infinite loop detected.");
 }
        public IEnumerable <PasswordBlueprint> GetAllBlueprints(int length)
        {
            var blueprint = new PasswordBlueprint
            {
                Length = length
            };

            for (int x = 0; x < Width; x++)
            {
                blueprint.X = x;
                for (int y = 0; y < Height; y++)
                {
                    blueprint.Y = y;
                    foreach ((var shape, var direction) in ListAllShapeDirections())
                    {
                        blueprint.Shape     = shape;
                        blueprint.Direction = direction;
                        yield return(blueprint);
                    }
                }
            }
        }
        private static IEnumerable <Vec> GetEndlessPath(PasswordBlueprint blueprint)
        {
            var v = new Vec(blueprint.X, blueprint.Y);

            yield return(v);

            var d1 = new Vec(blueprint.Direction[0]);
            var d2 = 1 < blueprint.Direction.Length ? new Vec(blueprint.Direction[1]) : (Vec?)null;

            if (blueprint.Shape == BlueprintShape.Straight)
            {
                while (true)
                {
                    v = v.Add(d1);
                    if (d2.HasValue)
                    {
                        v = v.Add(d2.Value);
                    }
                    yield return(v);
                }
            }
            if (!d2.HasValue)
            {
                throw new ArgumentException($"Expecting two direction for shape '{blueprint.Shape}'.");
            }
            var a = d1;
            var b = d2.Value;

            if (blueprint.Shape == BlueprintShape.Stairs)
            {
                while (true)
                {
                    v      = v.Add(a);
                    (a, b) = (b, a);
                    yield return(v);
                }
            }
            if (blueprint.Shape == BlueprintShape.L)
            {
                v = v.Add(a);
                yield return(v);

                while (true)
                {
                    v = v.Add(b);
                    yield return(v);
                }
            }
            var steps = 1;

            while (true)
            {
                for (int i = 0; i < steps; i++)
                {
                    v = v.Add(a);
                    yield return(v);
                }
                for (int i = 0; i < steps; i++)
                {
                    v = v.Add(b);
                    yield return(v);
                }
                (a, b) = (a.Multiply(-1), b.Multiply(-1));
                steps++;
            }
        }
 private static IEnumerable <Vec> GetPath(PasswordBlueprint blueprint)
 {
     return(GetEndlessPath(blueprint).Take(blueprint.Length));
 }