Ejemplo n.º 1
0
 def test_initialize_empty_bomb_field(self):
     self.bd = BombDropper(2, 5)
     expected = [
         [False, False, False, False, False],
         [False, False, False, False, False],
     ]
     actual = self.bd.initialize_empty_bomb_field()
     self.assertEqual(actual, expected)
Ejemplo n.º 2
0
 def test_initialize_empty_bomb_field_1_row(self):
     self.bd = BombDropper(1, 10)
     expected = [[
         False, False, False, False, False, False, False, False, False,
         False
     ]]
     actual = self.bd.initialize_empty_bomb_field()
     self.assertEqual(actual, expected)
Ejemplo n.º 3
0
 def test_drop_bombs_large(self):
     height = 200
     width = 200
     row = random.randint(0, height - 1)
     col = random.randint(0, width - 1)
     bomb_count = random.randint(1, height * width - 1)
     self.bd = BombDropper(height, width, row, col, bomb_count)
     actual = self.count_bombs(self.bd.drop_bombs())
     expected = bomb_count
     self.assertEqual(actual, expected)
Ejemplo n.º 4
0
 def __init__(self, height, width, bomb_count=1,
              first_click_row=0, first_click_col=0):
     Game.validate_initial_conditions(height, width, bomb_count,
                                      first_click_row, first_click_col)
     self.bomb_count = bomb_count
     self.flags_left_to_place = bomb_count
     self.cell_count = height * width
     self.bomb_dropper = BombDropper(height, width, first_click_row,
                                     first_click_col, bomb_count)
     self.board = Board(self.bomb_dropper.drop_bombs())
     self.won = False
     self.loss = False
     self.turn = 0
Ejemplo n.º 5
0
class Game:
    MIN_WIDTH = 1
    MIN_HEIGHT = 1
    DEFAULT_SIZE = 10
    MIN_BOMB_COUNT = 1

    def __init__(self, height, width, bomb_count=1,
                 first_click_row=0, first_click_col=0):
        Game.validate_initial_conditions(height, width, bomb_count,
                                         first_click_row, first_click_col)
        self.bomb_count = bomb_count
        self.flags_left_to_place = bomb_count
        self.cell_count = height * width
        self.bomb_dropper = BombDropper(height, width, first_click_row,
                                        first_click_col, bomb_count)
        self.board = Board(self.bomb_dropper.drop_bombs())
        self.won = False
        self.loss = False
        self.turn = 0

    @staticmethod
    def validate_initial_conditions(height, width, bomb_count,
                                    first_click_row, first_click_col):
        if height < Game.MIN_HEIGHT or width < Game.MIN_WIDTH:
            raise ValueError(
                'Cannot create Game with negative dimensions '
                f'({height}, {width}).'
            )
        elif bomb_count not in range(Game.MIN_BOMB_COUNT, height * width):
            raise ValueError(
                'bomb_count  must be positive and less than total number of '
                f'cells ({height * width}) but was {bomb_count}'
            )
        elif first_click_row not in range(0, height):
            raise ValueError(
                f'first_click_row must be in range(0, {height}) but was '
                f'{first_click_row}'
            )
        elif first_click_col not in range(0, width):
            raise ValueError(
                f'first_click_col must be in range(0, {width}) but was '
                f'{first_click_col}'
            )
        else:
            pass  # Input valid

    # -----------------------------------------------------------------------------

    def get_actions(self):
        return self.open_cell, self.toggle_flag, self.chord_cell

    def open_cell(self, row, col):
        print("\nOpening!")
        self.board.reset_affected_positions()

        valid = self.board.open_cell(row, col)
        move = Move(valid=valid,
                    cell=self.board.get_cell(row, col),
                    move_type=Move.MoveType.OPEN,
                    affected_positions=self.board.get_affected_positions())
        self.increment_turn(move)
        if valid:
            self.update_end_game()

        self.board.reset_affected_positions()
        return move

    def toggle_flag(self, row, col):
        print("\nToggling flag!")
        self.board.reset_affected_positions()

        valid = self.board.toggle_flag(row, col)
        move = Move(valid=valid,
                    cell=self.board.get_cell(row, col),
                    move_type=Move.MoveType.TOGGLE_FLAG,
                    affected_positions=self.board.get_affected_positions())
        self.flags_left_to_place += self.change_flag_count(move, row, col)
        self.increment_turn(move)

        self.board.reset_affected_positions()
        return move

    def chord_cell(self, row, col):
        print("\nChording!")
        self.board.reset_affected_positions()

        valid, flag_count = self.board.chord_cell(row, col)
        move = Move(valid=valid,
                    cell=self.board.get_cell(row, col),
                    move_type=Move.MoveType.CHORD,
                    affected_positions=self.board.get_affected_positions(),
                    adjFlagCount=flag_count)
        self.increment_turn(move)
        if valid:
            self.update_end_game()

        self.board.reset_affected_positions()
        return move

    def change_flag_count(self, move, row, col):
        if move.is_valid():
            appearance = self.board.get_single_appearance(row, col)
            return -1 if appearance == Cell.Appearance.FLAG else 1
        else:
            return 0

    def increment_turn(self, move):
        if move.is_valid():
            self.turn += 1

    def update_end_game(self):
        if self.cell_count - self.board.get_opened_cell_count() == self.bomb_count:
            self.won = True
            self.board.convert_all_bombs_to_flags()
            return
        if self.board.get_opened_bomb_count() > 0:
            self.loss = True
            self.board.reveal_board()
            return

    def check_end_game(self):
        assert not (self.won and self.loss)
        return self.won, self.loss

    def get_turn(self):
        return self.turn

    def get_flags_left_to_place(self):
        return self.flags_left_to_place

    def get_single_appearance(self, row, col):
        return self.board.get_single_appearance(row, col)

    def get_all_appearances(self):
        return self.board.get_all_appearances()
Ejemplo n.º 6
0
 def setUp(self):
     self.bd = BombDropper()
Ejemplo n.º 7
0
class TestBombDropper(unittest.TestCase):
    def setUp(self):
        self.bd = BombDropper()

    def count_bombs(self, field):
        return sum(functools.reduce(lambda x, y: x + y, field))

    def test_validation_neg_height(self):
        with self.assertRaises(InvalidComponent):
            self.bd = BombDropper(-18, 29)

    def test_validation_neg_width(self):
        with self.assertRaises(InvalidComponent):
            self.bd = BombDropper(86, -38)

    def test_validation_zero_height(self):
        with self.assertRaises(InvalidComponent):
            self.bd = BombDropper(0, 8)

    def test_validation_zero_width(self):
        with self.assertRaises(InvalidComponent):
            self.bd = BombDropper(8, 0)

    def test_validate_bomb_count_negative(self):
        with self.assertRaises(InvalidBombCount):
            self.bd = BombDropper(45, 23, 34, 5, -6)

    def test_validate_bomb_count_zero(self):
        with self.assertRaises(InvalidBombCount):
            self.bd = BombDropper(45, 23, 34, 5, 0)

    def test_validate_bomb_count_entirely_filled(self):
        with self.assertRaises(InvalidBombCount):
            self.bd = BombDropper(45, 23, 34, 5, 1035)

    def test_validate_initial_click_negative(self):
        with self.assertRaises(InvalidInitialClick):
            self.bd = BombDropper(10, 4, -3, -2)

    def test_validate_initial_click_positive(self):
        with self.assertRaises(InvalidInitialClick):
            self.bd = BombDropper(10, 4, 32, 2)

    def test_default_init(self):
        self.assertEqual(self.bd.get_height(), 10)
        self.assertEqual(self.bd.get_width(), 10)

    def test_init(self):
        self.bd = BombDropper(35, 29)
        self.assertEqual(self.bd.get_height(), 35)
        self.assertEqual(self.bd.get_width(), 29)

    def test_initialize_empty_bomb_field(self):
        self.bd = BombDropper(2, 5)
        expected = [
            [False, False, False, False, False],
            [False, False, False, False, False],
        ]
        actual = self.bd.initialize_empty_bomb_field()
        self.assertEqual(actual, expected)

    def test_initialize_empty_bomb_field_1_row(self):
        self.bd = BombDropper(1, 10)
        expected = [[
            False, False, False, False, False, False, False, False, False,
            False
        ]]
        actual = self.bd.initialize_empty_bomb_field()
        self.assertEqual(actual, expected)

    def test_initialize_empty_bomb_field_1_col(self):
        self.bd = BombDropper(10, 1)
        expected = [
            [False],
            [False],
            [False],
            [False],
            [False],
            [False],
            [False],
            [False],
            [False],
            [False],
        ]
        actual = self.bd.initialize_empty_bomb_field()
        self.assertEqual(actual, expected)

    def test_drop_bombs_large(self):
        height = 200
        width = 200
        row = random.randint(0, height - 1)
        col = random.randint(0, width - 1)
        bomb_count = random.randint(1, height * width - 1)
        self.bd = BombDropper(height, width, row, col, bomb_count)
        actual = self.count_bombs(self.bd.drop_bombs())
        expected = bomb_count
        self.assertEqual(actual, expected)
Ejemplo n.º 8
0
 def test_validate_initial_click_positive(self):
     with self.assertRaises(InvalidInitialClick):
         self.bd = BombDropper(10, 4, 32, 2)
Ejemplo n.º 9
0
 def test_init(self):
     self.bd = BombDropper(35, 29)
     self.assertEqual(self.bd.get_height(), 35)
     self.assertEqual(self.bd.get_width(), 29)
Ejemplo n.º 10
0
 def test_validate_bomb_count_entirely_filled(self):
     with self.assertRaises(InvalidBombCount):
         self.bd = BombDropper(45, 23, 34, 5, 1035)
Ejemplo n.º 11
0
 def test_validate_bomb_count_zero(self):
     with self.assertRaises(InvalidBombCount):
         self.bd = BombDropper(45, 23, 34, 5, 0)
Ejemplo n.º 12
0
 def test_validation_zero_width(self):
     with self.assertRaises(InvalidComponent):
         self.bd = BombDropper(8, 0)
Ejemplo n.º 13
0
 def test_validation_zero_height(self):
     with self.assertRaises(InvalidComponent):
         self.bd = BombDropper(0, 8)
Ejemplo n.º 14
0
 def test_validation_neg_height(self):
     with self.assertRaises(InvalidComponent):
         self.bd = BombDropper(-18, 29)