예제 #1
0
        public Image Build(Game game, int multiplier)
        {
            var imageWidth = (4 * game.Board.Width + 2) * multiplier;
            var imageHeight = (3 * game.Board.Height + 1) * multiplier;

            Image boardImage = new Bitmap(imageWidth, imageHeight);
            using (var graphics = Graphics.FromImage(boardImage))
            using (Brush borderBrush = new SolidBrush(Color.Black))
            using (var borderPen = new Pen(borderBrush, 2))
            using (var unitBrush = new SolidBrush(Hexagon.UnitColor))
            using (var lockedBrush = new SolidBrush(Hexagon.LockedColor))
            {
                var hexagonFactory = new HexagonFactory(multiplier);
                for (var y = 0; y < game.Board.Field.Length; y++)
                {
                    for (int x = 0; x < game.Board.Field[y].Length; x++)
                    {
                        var cell = game.Board.Field[y][x];
                        var isLocked = cell == CellState.Busy;

                        var isCurrentUnitPoint = game.Current != null && IsCurrentUnitPoint(game.Current.GetAbsolutePoints(), x, y);
                        var isCurrentUnitPivot = game.Current != null && game.Current.UnitPosition.PivotLocation.Equals(y, x);

                        var hexagon = hexagonFactory.Create(x, y, isLocked, isCurrentUnitPoint, isCurrentUnitPivot);
                        DrawHexagon(hexagon, graphics, borderPen, unitBrush, lockedBrush, x, y);
                    }
                }
            }

            return boardImage;
        }
예제 #2
0
        public PlayedGameInfo Play(Game game)
        {
            var stringBuilder = new StringBuilder();

            while (game.State != GameState.GameOver && game.State != GameState.Error)
            {
                if (TimeLimiter.NeedStop())
                    break;

                var gameUnits = ReachableStatesGetter.Get(game.Board, game.Current, true);

                var finishUnit = bestPositionFinder.FindBest(gameUnits, game);

                var commandString = commandStringGenerator.Generate(game.Board, game.Current, finishUnit);
                stringBuilder.Append(commandString);

                for (var i = 0; i < commandString.Length; i++)
                {
                    var command = commandString[i];
                    game = game.TryMakeStep(command);
                }
            }

            return new PlayedGameInfo(stringBuilder.ToString(), game.Score, bestPositionFinder.Name);
        }
예제 #3
0
        public Game[] Build(string inputFilename)
        {
            var games = new List<Game>();

            var input = new InputReader().Read(inputFilename);

            var board = Board.CreateEmpty(input.height, input.width);
            foreach (var busyCell in input.filled)
            {
                board.Fill(busyCell.ToPoint());
            }

            var units = input.units.Select(x => x.ToUnit()).ToArray();
            foreach (var seed in input.sourceSeeds)
            {
                var generator = new RandomGenerator(seed);
                var unitSequence = generator.Generate().Select(x => units[x % units.Length]).Take(input.sourceLength).ToArray();

                var game = new Game(board, null, unitSequence, 0, 0, 0, input.id, seed, string.Empty, 0);
                game = game.TrySpawnNew();

                games.Add(game);
            }

            return games.ToArray();
        }
예제 #4
0
        public void TestIsValid()
        {
            var game = new Game(Board.Create(new[]
            {
                ".........",
                "....*....",
                "...*.*...",
                "....*....",
                ".........",
                ".........",
            }), null, null, 0, 0, 0, -1, -1, string.Empty, 0);

            var actual = game.IsValid(new GameUnit(
                Unit.Create(new Point(0, 0), new[] { new Point(3, 1), new Point(5, 1), new Point(4, 2), new Point(3, 3), new Point(5, 3) }),
                new UnitPosition(new Point(0, 0), 0)
            ));
            Assert.IsTrue(actual);

            actual = game.IsValid(new GameUnit(
                                      Unit.Create(new Point(0, 0),
                                                  new[]
                                                      {
                                                          new Point(3, 1), new Point(5, 1), new Point(4, 2),
                                                          new Point(3, 3), new Point(5, 3), new Point(3, 2),
                                                      }),
                                      new UnitPosition(new Point(0, 0), 0)
                                      ));
            Assert.IsFalse(actual);
        }
예제 #5
0
 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;
 }
예제 #6
0
        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;
        }
예제 #7
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());
        }
예제 #8
0
        public HistoryValidateResult Validate(Game game, string commands)
        {
            var usedPositions = new Dictionary<int, HashSet<string>>();
            for (var i = 0; i <= game.UnitsSequence.Length; i ++)
            {
                usedPositions.Add(i, new HashSet<string>());
            }

            InsertPosition(usedPositions, game);

            for (var i = 0; i < commands.Length; i ++)
            {
                game = game.TryMakeStep(commands[i]);

                if (game.State == GameState.GameOver && i != commands.Length - 1)
                {
                    return new HistoryValidateResult
                    {
                        IsValid = false,
                        WrongMoveNumber = i + 1,
                        Reason = "Game is over"
                    };
                }
                if (game.State == GameState.GameOver && i == commands.Length - 1)
                {
                    return new HistoryValidateResult
                    {
                        IsValid = true
                    };
                }

                if (IsPositionUsed(usedPositions, game))
                {
                    return new HistoryValidateResult
                    {
                        IsValid = false,
                        WrongMoveNumber = i,
                        Reason = "Position is already used"
                    };
                }

                InsertPosition(usedPositions, game);
            }

            return new HistoryValidateResult {IsValid = true};
        }
        public void TestValidate(string commands, bool expected)
        {
            var validator = new GameHistoryValidator();

            var board = Board.Create(new[]
            {
                "...",
                "...",
                "..."
            });
            var unit = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var unit2 = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var unit3 = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var game = new Game(board, null, new[] { unit, unit2, unit3 }, 0, 0, 0, -1, -1, string.Empty, 0).TrySpawnNew();

            var actual = validator.Validate(game, commands);
            Assert.AreEqual(expected, actual.IsValid);
        }
예제 #10
0
        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)
            };
        }
예제 #11
0
        public void TestMakeCommandSouthEast()
        {
            var board = Board.Create(new[]
            {
                "...",
                "...",
                "..."
            });
            var unit = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var unit2 = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var game = new Game(board, null, new[] { unit, unit2 }, 0, 0, 0, -1, -1, string.Empty, 0);

            var actual = game.TrySpawnNew();
            Assert.AreEqual(GameState.NewIsSpawned, actual.State);

            actual = actual.TryMakeStep('l');
            Assert.AreEqual(GameState.Ok, actual.State);
            Assert.AreEqual(1, actual.Current.UnitPosition.PivotLocation.Col);
            Assert.AreEqual(1, actual.Current.UnitPosition.PivotLocation.Row);

            actual = actual.TryMakeStep('l');
            Assert.AreEqual(GameState.Ok, actual.State);
            Assert.AreEqual(2, actual.Current.UnitPosition.PivotLocation.Col);
            Assert.AreEqual(2, actual.Current.UnitPosition.PivotLocation.Row);

            actual = actual.TryMakeStep('l');
            Assert.AreEqual(GameState.NewIsSpawned, actual.State);
            Assert.AreEqual(string.Join(Environment.NewLine, new[]
            {
                "...",
                "...",
                "..*"
            }), actual.Board.ToString());
        }
예제 #12
0
파일: Form1.cs 프로젝트: Erop147/ICFPC_2015
 private void startGameButton_Click(object sender, EventArgs e)
 {
     commandIndex = 0;
     command = string.Empty;
     scoresLabel.Text = 0.ToString();
     stateLabel.Text = string.Empty;
     currentGame = games[GetGameIndexValue()];
     historyStepIndex = 0;
     gamesHistory = new List<Game>(1000);
     executing = false;
     DrawBoard();
 }
예제 #13
0
파일: Form1.cs 프로젝트: Erop147/ICFPC_2015
        private void ExecuteGameStep(char commandChar)
        {
            if (gamesHistory.Count == 0)
                gamesHistory.Add(currentGame);

            currentGame = currentGame.TryMakeStep(commandChar);

            DrawBoard();

            ++historyStepIndex;
            if (gamesHistory.Count - historyStepIndex == 0)
                gamesHistory.Add(currentGame);
            else
                gamesHistory[historyStepIndex] = currentGame;

            if (needStopExecute || command != null && commandIndex + 1 == command.Length ||
                currentGame.State == GameState.Error || currentGame.State == GameState.GameOver)
            {
                timer.Stop();
                executeComandButton.Enabled = true;
                openGameButton.Enabled = true;
                gameIndexCombobox.Enabled = true;
                multipierTextBox.Enabled = true;
                startGameButton.Enabled = true;
                stopExecuteCommandButton.Enabled = false;
                needStopExecute = false;
                executing = false;
                return;
            }

            ++commandIndex;
        }
예제 #14
0
파일: Form1.cs 프로젝트: Erop147/ICFPC_2015
        private void nextButton_Click(object sender, EventArgs e)
        {
            if (historyStepIndex + 1 == gamesHistory.Count)
                return;

            ++commandIndex;
            ++historyStepIndex;
            currentGame = gamesHistory[historyStepIndex];
            DrawBoard();
        }
예제 #15
0
파일: Form1.cs 프로젝트: Erop147/ICFPC_2015
        private void previousButton_Click(object sender, EventArgs e)
        {
            if (historyStepIndex == 0)
                return;

            --commandIndex;
            --historyStepIndex;
            currentGame = gamesHistory[historyStepIndex];
            DrawBoard();
        }
예제 #16
0
        public void TestMakeCommandWest()
        {
            var board = Board.Create(new[]
            {
                "...",
                "...",
                "..."
            });
            var unit = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var unit2 = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var game = new Game(board, null, new[] { unit, unit2 }, 0, 0, 0, -1, -1, string.Empty, 0);

            var actual = game.TrySpawnNew();
            Assert.AreEqual(GameState.NewIsSpawned, actual.State);

            actual = actual.TryMakeStep('p');
            Assert.AreEqual(GameState.Ok, actual.State);

            actual = actual.TryMakeStep('p');
            Assert.AreEqual(GameState.NewIsSpawned, actual.State);
            Assert.AreEqual(string.Join(Environment.NewLine, new[]
            {
                "*..",
                "...",
                "..."
            }), actual.Board.ToString());
        }
예제 #17
0
파일: Form1.cs 프로젝트: Erop147/ICFPC_2015
 private void gameIndexCombobox_SelectedValueChanged(object sender, EventArgs e)
 {
     currentGame = games[GetGameIndexValue()];
     gamesHistory = new List<Game>(1000);
     DrawBoard();
 }
예제 #18
0
 private static void InsertPosition(Dictionary<int, HashSet<string>> usedPositions, Game game)
 {
     usedPositions[game.CurrentUnitNumber].Add(GetPositionString(game));
 }
예제 #19
0
 private static bool IsPositionUsed(Dictionary<int, HashSet<string>> usedPosition, Game game)
 {
     return usedPosition[game.CurrentUnitNumber].Contains(GetPositionString(game));
 }
예제 #20
0
        public void TestMakeCommandWithUpdatedScore()
        {
            var board = Board.Create(new[]
            {
                "*..",
                "*.*",
                "***"
            });
            var unit = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var unit2 = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var game = new Game(board, null, new[] { unit, unit2 }, 0, 12, 200, -1, -1, string.Empty, 0);

            var actual = game.TrySpawnNew();
            Assert.AreEqual(GameState.NewIsSpawned, actual.State);

            actual = actual.TryMakeStep('l');
            Assert.AreEqual(GameState.Ok, actual.State);
            Assert.AreEqual(1, actual.Current.GetAbsolutePoints().First().Col);
            Assert.AreEqual(1, actual.Current.GetAbsolutePoints().First().Row);

            actual = actual.TryMakeStep('l');
            Assert.AreEqual(GameState.NewIsSpawned, actual.State);
            Assert.AreEqual(2, actual.LastUnitLinesCleared);
            Assert.AreEqual(832, actual.Score);
        }
예제 #21
0
 private static string GetPositionString(Game game)
 {
     return game.Current.ToCoordinatesString();
 }
예제 #22
0
        public void TestMakeCommandTurnCounterClockWise()
        {
            var board = Board.Create(new[]
            {
                "...",
                "...",
                "..."
            });
            var unit = Unit.Create(new Point(0, 1), new[] { new Point(0, 0), });
            var unit2 = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var game = new Game(board, null, new[] { unit, unit2 }, 0, 0, 0, -1, -1, string.Empty, 0);

            var actual = game.TrySpawnNew();
            Assert.AreEqual(GameState.NewIsSpawned, actual.State);

            actual = actual.TryMakeStep('k');
            Assert.AreEqual(GameState.Ok, actual.State);
            Assert.AreEqual(0, actual.Current.GetAbsolutePoints().First().Col);
            Assert.AreEqual(1, actual.Current.GetAbsolutePoints().First().Row);

            actual = actual.TryMakeStep('k');
            Assert.AreEqual(GameState.Ok, actual.State);
            Assert.AreEqual(1, actual.Current.GetAbsolutePoints().First().Col);
            Assert.AreEqual(2, actual.Current.GetAbsolutePoints().First().Row);
        }
예제 #23
0
        public void TestMakeCommandWithUpdatedScore2()
        {
            var board = Board.Create(new[]
            {
                ".....",
                ".....",
                ".....",
                ".....",
                ".....",
            });
            var unit = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var unit2 = Unit.Create(new Point(0, 0), new[] { new Point(0, 0), });
            var game = new Game(board, null, new[] { unit, unit2 }, 0, 0, 200, -1, -1, "e", 0);

            var actual = game.TrySpawnNew();
            Assert.AreEqual(GameState.NewIsSpawned, actual.State);

            actual = actual.TryMakeStep('i');
            Assert.AreEqual(GameState.Ok, actual.State);

            actual = actual.TryMakeStep('!');
            Assert.AreEqual(GameState.Ok, actual.State);

            Assert.AreEqual(506, actual.Score);
        }
예제 #24
0
        public void TestMoveZigZag()
        {
            MagicWordsStore.AddWords(new [] { "aba" });

            var board = Board.Create(new[]
            {
                ".....",
                ".....",
                ".....",
                ".....",
                ".....",
            });
            var unit = Unit.Create(new Point(0, 0), new[] { new Point(1, 0), new Point(0, 1), });
            var game = new Game(board, null, new[] { unit }, 0, 0, 200, -1, -1, string.Empty, 0).TrySpawnNew();

            Console.WriteLine(board.Place(game.Current.GetAbsolutePoints()));
            Console.WriteLine();
            Assert.AreEqual(string.Join(Environment.NewLine, new[]
            {
                "..*..",
                ".*...",
                ".....",
                ".....",
                "....."
            }), board.Place(game.Current.GetAbsolutePoints()).ToString());

            game = game.TryMakeStep('a');
            Console.WriteLine(board.Place(game.Current.GetAbsolutePoints()));
            Console.WriteLine();
            Assert.AreEqual(string.Join(Environment.NewLine, new[]
            {
                ".....",
                ".*...",
                ".*...",
                ".....",
                "....."
            }), board.Place(game.Current.GetAbsolutePoints()).ToString());

            game = game.TryMakeStep('a');
            Console.WriteLine(board.Place(game.Current.GetAbsolutePoints()));
            Console.WriteLine();
            Assert.AreEqual(string.Join(Environment.NewLine, new[]
            {
                ".....",
                ".....",
                ".*...",
                "*....",
                "....."
            }), board.Place(game.Current.GetAbsolutePoints()).ToString());
        }
예제 #25
0
        public void TestTrySpawnNew2()
        {
            var board = Board.CreateEmpty(10, 5);
            var game = new Game(board, null, new Unit[0], 0, 0, 0, -1, -1, string.Empty, 0);

            var actual = game.TrySpawnNew();

            Assert.AreEqual(GameState.GameOver, actual.State);
        }
예제 #26
0
        public void TestTrySpawnNew3()
        {
            var board = Board.Create(new[]
            {
                "..*...",
                "......",
                "......"
            });
            var unit = Unit.Create(new Point(0, 0), new[] { new Point(-1, 0), new Point(0, 0), new Point(1, 0), new Point(0, 1), });
            var game = new Game(board, null, new[] { unit }, 0, 0, 0, -1, -1, string.Empty, 0);

            var actual = game.TrySpawnNew();

            Assert.AreEqual(GameState.GameOver, actual.State);
        }
예제 #27
0
 private static Task<PlayedGameInfo> Play(Game game, IPlayer player)
 {
     return Task.Run(() => player.Play(game));
 }
예제 #28
0
파일: Game.cs 프로젝트: Erop147/ICFPC_2015
        public Game TryMakeStep(char ch)
        {
            var command = CommandConverter.Convert(ch);
            if (command == Command.Empty)
            {
                return this;
            }
            if (Current == null)
            {
                throw new Exception("Current game unit is null");
            }

            if (!IsValid(Current))
            {
                throw new Exception("Current game unit is not valid, new step is impossible");
            }

            var newGameUnit = Current.MakeStep(command);
            var lastSymbols = LastSymbols.Insert(LastSymbols.Length, ch.ToString());
            if (lastSymbols.Length == 52)
            {
                lastSymbols = lastSymbols.Substring(1);
            }
            int wordsMask;
            var wordsScore = CalculateWordsScore(lastSymbols, out wordsMask);

            if (!IsValid(newGameUnit))
            {
                var lockedCells = Current.GetAbsolutePoints();
                var updateResult = Board.Place(lockedCells).Update();
                var additionalScore = CalculateScore(LastUnitLinesCleared, updateResult.RowsCleaned, Current.Unit.Points.Length);

                var gameWithNewUnit = new Game(updateResult.NewBoard, null, UnitsSequence, CurrentUnitNumber + 1, updateResult.RowsCleaned, Score + additionalScore + wordsScore, ProblemId, Seed, lastSymbols, wordsMask);
                return gameWithNewUnit.TrySpawnNew();
            }

            return MoveCurrent(newGameUnit, lastSymbols, Score + wordsScore, wordsMask);
        }