public string Generate(Board _board, GameUnit _unit, GameUnit _finishUnit)
        {
            var stringBuilder = new StringBuilder();
            var words = MagicWordsStore.Words
                                       .Concat(SpecialWords)
                                       .ToArray();
            var usedUnits = new HashSet<GameUnit>();
            while (!_unit.Equals(_finishUnit))
            {
                if (TimeLimiter.NeedStop())
                    break;

                foreach (var powerWord in words.OrderByDescending(x => x.Length))
                {
                    if (TimeLimiter.NeedStop())
                        break;

                    var newlyUsedUnits = new HashSet<GameUnit>();
                    var currentUnit = _unit;
                    var fail = false;
                    for (var i = 0; i < powerWord.Length; ++i)
                    {
                        var command = powerWord[i];
                        newlyUsedUnits.Add(currentUnit);
                        var nextUnit = currentUnit.MakeStep(CommandConverter.Convert(command));
                        var locked = !_board.IsValid(nextUnit);
                        if (newlyUsedUnits.Contains(nextUnit) ||
                            usedUnits.Contains(nextUnit) ||
                            (locked && i < powerWord.Length - 1) ||
                            (locked && !nextUnit.Equals(_finishUnit)))
                        {
                            fail = true;
                            break;
                        }
                        if (!locked)
                        {
                            currentUnit = nextUnit;
                        }
                    }
                    var allUsedUnits = new HashSet<GameUnit>(usedUnits.Union(newlyUsedUnits));
                    if (!fail && ReachableStatesGetter.CanReach(_board, currentUnit, false, allUsedUnits, _finishUnit))
                    {
                        _unit = currentUnit;
                        usedUnits = allUsedUnits;
                        stringBuilder.Append(powerWord);
                        break;
                    }
                }
            }
            foreach (var command in Enum.GetValues(typeof(Command)).Cast<Command>().Except(new[] { Command.Empty }))
            {
                if (!_board.IsValid(_unit.MakeStep(command)))
                {
                    stringBuilder.Append(CommandConverter.CovertToAnyChar(command));
                    break;
                }
            }
            return stringBuilder.ToString();
        }
Exemple #2
0
 public State(GameUnit unit, Command lastCommand, bool isLocked, bool canGoHorisontal, bool? isLastCommandWord)
     : this()
 {
     IsLocked = isLocked;
     Unit = unit;
     LastCommand = lastCommand;
     CanGoHorisontal = canGoHorisontal;
     IsLastCommandWord = isLastCommandWord;
 }
        public static GameUnit[] Get(Board board, GameUnit unit, bool onlyLocked, HashSet<GameUnit> usedUnits = null)
        {
            var newlyUsedUnits = new HashSet<GameUnit>();
            var lockedUnits = onlyLocked ? new HashSet<GameUnit>() : null;
            Dfs(board, unit, newlyUsedUnits, usedUnits ?? new HashSet<GameUnit>(), lockedUnits);

            return onlyLocked
                ? lockedUnits.ToArray()
                : newlyUsedUnits.ToArray();
        }
Exemple #4
0
 public void TestBottomLeft()
 {
     var gameUnit = new GameUnit(Unit.Create(new Point(0, 0), new[]
         {
             new Point(0, 0),
             new Point(1, 0),
             new Point(2, 1),
             new Point(1, 1)
         }), new UnitPosition(new Point(0, 0), 0));
      var actual = gameUnit.BottomLeft();
      Assert.AreEqual(1, actual.Col);
      Assert.AreEqual(1, actual.Row);
 }
 public GameUnit FindBest(GameUnit[] gameUnits, Game game)
 {
     return gameUnits.Select(x => new
                                 {
                                     Score = x.GetAbsolutePoints().Sum(point => point.Row*point.Row),
                                     GameUnit = x,
                                     BottomLeft = x.BottomLeft()
                                 })
                     .OrderByDescending(x => x.BottomLeft.Row)
                     .ThenByDescending(x => x.Score)
                     .ThenBy(x => x.BottomLeft.Col)
                     .First()
                     .GameUnit;
 }
Exemple #6
0
 public Game(Board board, GameUnit current, Unit[] unitsSequence, int currentUnitNumber, int lastUnitLinesCleared, int score, int problemId, long seed, string lastSymbols, int wordsMask)
     : this()
 {
     Board = board;
     Current = current;
     UnitsSequence = unitsSequence;
     CurrentUnitNumber = currentUnitNumber;
     LastUnitLinesCleared = lastUnitLinesCleared;
     Score = score;
     ProblemId = problemId;
     Seed = seed;
     LastSymbols = lastSymbols;
     WordsMask = wordsMask;
 }
        public GameUnit FindBest(GameUnit[] positions, Game game)
        {
            var orderedPositions = positions
                .Select(x =>
                    new
                    {
                        GameUnit = x,
                        Profit = GetScore(x.UnitPosition, game)
                    })
                .OrderByDescending(x => x.Profit.BusyRows)
                .ThenByDescending(x => x.Profit.DiverScore + x.Profit.ReachableCount + x.Profit.DensityScore);

            return orderedPositions
                .First()
                .GameUnit;
        }
Exemple #8
0
        public void TestGetPivotLocation3()
        {
            var game = new Game(Board.CreateEmpty(5, 7), null, null, 0, 0, 0, -1, -1, string.Empty, 0);
            var unit = Unit.Create(new Point(2, 4), new[]
            {
                new Point(2, 1), new Point(5, 1), new Point(1, 2), new Point(3, 2), new Point(4, 2), new Point(6, 2), new Point(7, 2), new Point(4, 3), new Point(5, 3),
            });

            var actual = game.GetPivotLocation(unit);
            Assert.AreEqual(1, actual.Col);
            Assert.AreEqual(3, actual.Row);

            var gameUnit = new GameUnit(unit, new UnitPosition(actual, 0));
            Assert.IsTrue(game.IsValid(gameUnit));
            Console.WriteLine(game.Board.Place(gameUnit.GetAbsolutePoints()).ToString());
        }
        private static void Dfs(Board board, GameUnit unit, HashSet<GameUnit> newlyUsedUnits, HashSet<GameUnit> previouslyUsedUnits, HashSet<GameUnit> lockedUnits)
        {
            newlyUsedUnits.Add(unit);

            foreach (var command in Commands)
            {
                var nextUnit = unit.MakeStep(command);
                if (!previouslyUsedUnits.Contains(nextUnit) && !newlyUsedUnits.Contains(nextUnit))
                {
                    if (board.IsValid(nextUnit))
                    {
                        Dfs(board, nextUnit, newlyUsedUnits, previouslyUsedUnits, lockedUnits);
                    }
                    else if (lockedUnits != null)
                    {
                        lockedUnits.Add(unit);
                    }
                }
            }
        }
        public void TestGet()
        {
            var board = Board.Create(new string[]
                {
                    "...",
                    "*.*",
                    "..."
                });
            var unit = Unit.Create(new Point(0, 0), new[] {new Point(0, 0), new Point(0, 1)});
            var gameUnit = new GameUnit(unit, new UnitPosition(new Point(1, 0), 0));
            var actual = ReachableStatesGetter.Get(board, gameUnit, false);

            CollectionAssert.AreEquivalent(new[]
                {
                    new UnitPosition(new Point(1, 0), 0),
                    new UnitPosition(new Point(1, 0), 5),
                    new UnitPosition(new Point(0, 0), 5),
                    new UnitPosition(new Point(1, 1), 0),
                    new UnitPosition(new Point(1, 1), 1)
                }, actual.Select(x => x.UnitPosition));
        }
        private Profit GetScore(UnitPosition position, Game game)
        {
            var unit = game.Current.Unit;
            var points = new GameUnit(unit, position).GetAbsolutePoints();
            var board = game.Board.Clone();

            foreach (var point in points)
            {
                board.Fill(point);
            }

            var diverScore = 0;
            for (int i = 0; i < board.Height; i++)
            {
                for (int j = 0; j < board.Width; j++)
                {
                    if (board.Field[i][j] == CellState.Busy)
                    {
                        diverScore += i * i;
                    }
                }
            }

            var busyCount = 0;
            for (var i = 0; i < board.Height; i++)
            {
                if (board.Field[i].All(x => x == CellState.Busy))
                {
                    busyCount++;
                }
            }

            return new Profit
            {
                BusyRows = busyCount,
                DiverScore = diverScore,
                DensityScore = CalcDensity(board, points)
            };
        }
        private static bool Dfs2(Board board, GameUnit unit, HashSet<GameUnit> newlyUsedUnits, HashSet<GameUnit> previouslyUsedUnits, HashSet<GameUnit> lockedUnits, GameUnit finishUnit)
        {
            if (unit.Equals(finishUnit))
                return true;
            newlyUsedUnits.Add(unit);

            foreach (var command in Commands)
            {
                var nextUnit = unit.MakeStep(command);
                if (!previouslyUsedUnits.Contains(nextUnit) && !newlyUsedUnits.Contains(nextUnit))
                {
                    if (board.IsValid(nextUnit) && Dfs2(board, nextUnit, newlyUsedUnits, previouslyUsedUnits, lockedUnits, finishUnit))
                    {
                        return true;
                    }
                    else if (lockedUnits != null)
                    {
                        lockedUnits.Add(unit);
                    }
                }
            }
            return false;
        }
Exemple #13
0
        public Game TrySpawnNew()
        {
            if (Current != null)
            {
                throw new Exception("Current unit is not null");
            }
            if (CurrentUnitNumber == UnitsSequence.Length)
            {
                return GameOver();
            }
            var unit = UnitsSequence[CurrentUnitNumber];
            var pivot = GetPivotLocation(unit);
            var gameUnit = new GameUnit(unit, new UnitPosition(pivot, 0));

            if (!IsValid(gameUnit))
            {
                return GameOver();
            }

            return SpawnedNew(gameUnit);
        }
Exemple #14
0
 private Game MoveCurrent(GameUnit gameUnit, string lastSymbols, int newScore, int wordsMask)
 {
     var clone = this;
     clone.Current = gameUnit;
     clone.State = GameState.Ok;
     clone.LastSymbols = lastSymbols;
     clone.Score = newScore;
     clone.WordsMask = wordsMask;
     return clone;
 }
Exemple #15
0
 private Game SpawnedNew(GameUnit gameUnit)
 {
     var clone = this;
     clone.Current = gameUnit;
     clone.State = GameState.NewIsSpawned;
     return clone;
 }
Exemple #16
0
 public bool IsValid(GameUnit gameUnit)
 {
     foreach (var point in gameUnit.GetAbsolutePoints())
     {
         if (!InField(point))
         {
             return false;
         }
         if (Field[point.Row][point.Col] == CellState.Busy)
         {
             return false;
         }
     }
     return true;
 }
 public static bool CanReach(Board board, GameUnit unit, bool onlyLocked, HashSet<GameUnit> usedUnits, GameUnit finishUnit)
 {
     var newlyUsedUnits = new HashSet<GameUnit>();
     var lockedUnits = onlyLocked ? new HashSet<GameUnit>() : null;
     return Dfs2(board, unit, newlyUsedUnits, usedUnits ?? new HashSet<GameUnit>(), lockedUnits, finishUnit);
 }
        private bool CanMove(GameUnit unit, string word, out GameUnit nextUnit)
        {
            var tuple = new Tuple<GameUnit, string>(unit, word);
            if (moves.TryGetValue(tuple, out nextUnit))
            {
                return nextUnit != null;
            }

            var gameUnits = new HashSet<GameUnit>();
            gameUnits.Add(unit);
            nextUnit = unit;
            foreach (var command in word)
            {
                nextUnit = nextUnit.MakeStep(CommandConverter.Convert(command));
                if (gameUnits.Contains(nextUnit) || !board.IsValid(nextUnit))
                {
                    moves[tuple] = null;
                    return false;
                }
                gameUnits.Add(nextUnit);
            }

            moves[tuple] = nextUnit;
            return true;
        }
        public string Generate(Board _board, GameUnit _unit, GameUnit _finishUnit)
        {
            board = _board;
            target = _finishUnit;
            moves = new Dictionary<Tuple<GameUnit, string>, GameUnit>();
            words = MagicWordsStore.Words.Concat(SpecialWords).OrderByDescending(x => x.Length).ToArray();
            dp = new Dictionary<State, DpInfo>();

            var state = new State(_unit, Command.Empty, false, true, null);
            CalcDp(state);
            var stringBuilder = new StringBuilder();

            while (!(state.Unit.Equals(target) && state.IsLocked))
            {
                var dpInfo = dp[state];
                stringBuilder.Append(dpInfo.Word);
                state = dpInfo.NextState.Value;
            }

            return stringBuilder.ToString();
        }
Exemple #20
0
 public bool IsValid(GameUnit gameUnit)
 {
     return Board.IsValid(gameUnit);
 }