private void PerformMove(Game game, GameModel.Players player, int row, int column)
        {
            if (game.BaseTable[row][column] == FieldTypes.Mined)
            {
                AddPoints(game, player);
                RecordMove(game, player, row, column);

                return;
            }

            ResetStreakBonus(game, player);

            var neighboringMineCount = GetMinesAroundField(game, row, column);

            if (neighboringMineCount == 0)
            {
                DoRecursiveMove(game, player, row, column);
            }
            else
            {
                RecordMove(game, player, row, column);
            }

            game.NextPlayer = player == GameModel.Players.Player1
                ? GameModel.Players.Player2
                : GameModel.Players.Player1;
        }
        private bool CheckPlayerCanMove(Game game, GameModel.Players player)
        {
            if (game.Status == GameModel.GameStatus.Finished || game.Status == GameModel.GameStatus.NotStarted)
            {
                return(false);
            }

            return(game.NextPlayer == player);
        }
        private void RecordMove(Game game, GameModel.Players player, int row, int col)
        {
            if (game.BaseTable[row][col] == FieldTypes.Mined)
            {
                game.VisibleTable[row][col] = player == GameModel.Players.Player1
                    ? GameModel.VisibleFieldType.Player1FoundMine
                    : GameModel.VisibleFieldType.Player2FoundMine;
            }
            else
            {
                var minesAround = GetMinesAroundField(game, row, col);
                switch (minesAround)
                {
                case 0:
                    game.VisibleTable[row][col] = GameModel.VisibleFieldType.MinesAround0;
                    break;

                case 1:
                    game.VisibleTable[row][col] = GameModel.VisibleFieldType.MinesAround1;
                    break;

                case 2:
                    game.VisibleTable[row][col] = GameModel.VisibleFieldType.MinesAround2;
                    break;

                case 3:
                    game.VisibleTable[row][col] = GameModel.VisibleFieldType.MinesAround3;
                    break;

                case 4:
                    game.VisibleTable[row][col] = GameModel.VisibleFieldType.MinesAround4;
                    break;

                case 5:
                    game.VisibleTable[row][col] = GameModel.VisibleFieldType.MinesAround5;
                    break;

                case 6:
                    game.VisibleTable[row][col] = GameModel.VisibleFieldType.MinesAround6;
                    break;

                case 7:
                    game.VisibleTable[row][col] = GameModel.VisibleFieldType.MinesAround7;
                    break;

                case 8:
                    game.VisibleTable[row][col] = GameModel.VisibleFieldType.MinesAround8;
                    break;
                }
            }
        }
        private void DoRecursiveMove(Game game, GameModel.Players player, int row, int column)
        {
            var rowOverflown = row < 0 || row >= game.Rows;
            var colOverflown = column < 0 || column >= game.Columns;

            if (rowOverflown || colOverflown)
            {
                return;
            }

            var isMined   = game.BaseTable[row][column] == FieldTypes.Mined;
            var isMovedOn = game.VisibleTable[row][column] != GameModel.VisibleFieldType.Unknown;

            if (isMined || isMovedOn)
            {
                return;
            }

            RecordMove(game, player, row, column);

            for (var rowOffset = -1; rowOffset <= 1; ++rowOffset)
            {
                for (var colOffset = -1; colOffset <= 1; ++colOffset)
                {
                    // The same field for which this recursion step was called for, skip.
                    if (rowOffset == 0 && colOffset == 0)
                    {
                        continue;
                    }

                    var recursionRow = row + rowOffset;
                    var recursionCol = column + colOffset;

                    var hasZeroMinesAround = GetMinesAroundField(game, row, column) == 0;
                    if (hasZeroMinesAround)
                    {
                        DoRecursiveMove(game, player, recursionRow, recursionCol);
                    }
                }
            }
        }
        private void AddPoints(Game game, GameModel.Players player)
        {
            var targetPlayer = player == GameModel.Players.Player1 ? game.Player1 : game.Player2;
            var bonus        = targetPlayer.StreakBonus;

            targetPlayer.Points += PointsForMineFound;

            if (bonus == 0)
            {
                targetPlayer.StreakBonus = 1;
            }
            else
            {
                targetPlayer.Points      += bonus;
                targetPlayer.StreakBonus *= 2;

                if (targetPlayer.StreakBonus > MaxStreakBonus)
                {
                    targetPlayer.StreakBonus = MaxStreakBonus;
                }
            }
        }
 private string GetPlayerIdByPlayerOrder(Game game, GameModel.Players player)
 {
     return(player == GameModel.Players.Player1
         ? game.Player1.PlayerId
         : game.Player2.PlayerId);
 }
        private void ResetStreakBonus(Game game, GameModel.Players player)
        {
            var targetPlayer = player == GameModel.Players.Player1 ? game.Player1 : game.Player2;

            targetPlayer.StreakBonus = 0;
        }