Ejemplo n.º 1
0
 def test_mark_cells_adjacents(self):
     self.ms = MineSweeper(3, 3, 0)
     self.ms.add_mine(0, 0)
     self.ms.pick_cell(0, 1)
     self.ms.pick_cell(1, 0)
     # Can't mark yet, not enough info! (could be 0,0 or 1,1)
     # B 1 ?
     # 1 ? ?
     # ? ? ?
     self.ms.ai.mark_cells()
     self.assertEqual(self.count_marked_cells(), 0)
     self.ms.add_mine(1, 1)
     # B 2 ?
     # 2 B ?
     # ? ? ?
     self.ms.ai.mark_cells()
     self.assertEqual(self.count_marked_cells(), 0)
     # Reveal top right, Adjacency should give us top left
     # B 2 1
     # 2 B ?
     # ? ? ?
     self.ms.pick_cell(0, 2)
     self.ms.ai.mark_cells()
     self.ms.display_grid()
     self.assertEqual(self.count_marked_cells(), 1)
     self.assertEqual(self.ms.grid[0][0].marked, True)
Ejemplo n.º 2
0
async def msg_handel(source, plain, user, msg_type):
    if plain is None:
        return
    if plain.text == "扫雷":
        await send_msg(source, [Plain(HELP)], user, msg_type)
    if len(plain.text) > 2 and plain.text[:1] == "m":
        commands = plain.text.split(" ")
        if commands[1] == "开始":
            await new_game(source, user, msg_type, 10, 10, 10)
        if commands[1] == "中级":
            await new_game(source, user, msg_type, 16, 16, 40)
        if commands[1] == "高级":
            await new_game(source, user, msg_type, 20, 20, 90)

        if commands[1] == "自定义" and len(commands) == 5:
            try:
                await new_game(source, user, msg_type, int(commands[2]),
                               int(commands[3]), int(commands[4]))
            except ValueError as e:
                await send_msg(source, [Plain(f"错误 {e}")], user, msg_type)
        if commands[1] == "help":
            await send_msg(source, [Plain(HELP)], user, msg_type)

        # 以下命令只有在游戏中才可以使用
        if user.id not in in_gaming_list:
            return
        if commands[1] == "show":
            await send_panel(app, source, user, msg_type)

        if commands[1] == "exit":
            if user.id in in_gaming_list:
                await send_msg(source, [Plain("退出成功")], user, msg_type)
                del in_gaming_list[user.id]
            else:
                await send_msg(source, [Plain("请输入 m 开始 开始游戏")], user,
                               msg_type)
        # 命令长度大于3才可以使用
        if len(commands) < 3:
            return
        if commands[1] == "d":
            try:
                for i in range(2, len(commands)):
                    location = MineSweeper.parse_input(commands[i])
                    in_gaming_list[user.id].mine(location[0], location[1])
                    if in_gaming_list[user.id].state != GameState.GAMING:
                        break
            except ValueError as e:
                await send_msg(source, [Plain(f"错误: {e}")], user, msg_type)
            await send_panel(app, source, user, msg_type)
            if in_gaming_list[user.id].state != GameState.GAMING:
                await send_game_over(app, source, user, msg_type)

        if commands[1] == "t":
            try:
                for i in range(2, len(commands)):
                    location = MineSweeper.parse_input(commands[i])
                    in_gaming_list[user.id].tag(location[0], location[1])
                await send_panel(app, source, user, msg_type)
            except ValueError as e:
                await send_msg(source, [Plain(f"错误: {e}")], user, msg_type)
Ejemplo n.º 3
0
 def test_mark_cells_basic_one(self):
     self.ms = MineSweeper(3, 3, 0)
     self.ms.add_mine(0, 0)
     for y in xrange(len(self.ms.grid)):
         for x in xrange(len(self.ms.grid[0])):
             if y != 0 and x != 0:
                 self.ms.pick_cell(y, x)
     # B 1 0
     # 1 1 0
     # 0 0 0
     self.ms.ai.mark_cells()
     self.ms.display_grid()
     self.assertEqual(self.count_marked_cells(), 1)
     self.assertEqual(self.ms.grid[0][0].marked, True)
Ejemplo n.º 4
0
 def test_mark_cells_adjacents_two(self):
     # B ? B
     # 1 2 1
     # 0 0 0
     self.ms = MineSweeper(3, 3, 0)
     self.ms.add_mine(0, 0)
     self.ms.add_mine(0, 2)
     for y in xrange(1, len(self.ms.grid)):
         for x in xrange(len(self.ms.grid[0])):
             self.ms.pick_cell(y, x)
     self.ms.ai.mark_cells()
     self.assertEqual(self.count_marked_cells(), 2)
     self.assertEqual(self.ms.grid[0][0].marked, True)
     self.assertEqual(self.ms.grid[0][2].marked, True)
Ejemplo n.º 5
0
    def test_final_input_output(self):
        test_input = """4 4
*...
....
.*..
....
3 5
**...
.....
.*...
0 0"""
        test_sweeper = MineSweeper(test_input)
        expected_output = "Field #1:\n*100\n2210\n1*10\n1110\n\nField #2:\n**100\n33200\n1*100"
        self.assertEquals(expected_output, test_sweeper.resolve())
Ejemplo n.º 6
0
    def test_reveal_cell_basic(self):
        self.ms = MineSweeper(4, 4, 0)
#        ----------------------------------------
#        0| ?, ?, 1, 0,
#        1| ?, ?, 2, 1,
#        2| ?, ?, ?, ?,
#        3| ?, ?, ?, ?,
#        ----------------------------------------
        self.ms.add_mine(0, 1)
        self.ms.add_mine(2, 3)
        self.ms.pick_cell(0, 3)
        self.ms.display_grid()
        cell = self.ms.ai.reveal_cell()
        self.assertEquals(cell, (2, 1))
Ejemplo n.º 7
0
 def test_mark_cells_basic_three(self):
     self.ms = MineSweeper(3, 3, 0)
     self.ms.add_mine(0, 0)
     self.ms.add_mine(0, 1)
     self.ms.add_mine(0, 2)
     for y in xrange(1, len(self.ms.grid)):
         for x in xrange(len(self.ms.grid[0])):
             self.ms.pick_cell(y, x)
     # B B B
     # 2 3 2
     # 0 0 0
     self.ms.ai.mark_cells()
     self.ms.display_grid()
     self.assertEqual(self.count_marked_cells(), 3)
     self.assertEqual(self.ms.grid[0][0].marked, True)
     self.assertEqual(self.ms.grid[0][1].marked, True)
     self.assertEqual(self.ms.grid[0][2].marked, True)
Ejemplo n.º 8
0
    def test_reveal_cell_complex(self):
        """ Present it a situation where it *must* use adjaceny rules"""
#        ----------------------------------------
#        0| 1, M, B, ?,
#        1| 2, 3, 2, ?,
#        2| 1, M, ?, ?,
#        ----------------------------------------
        self.ms = MineSweeper(3, 4, 0)
        self.ms.add_mine(0, 1)
        self.ms.add_mine(2, 1)
        self.ms.add_mine(0, 2)
        self.ms.pick_cell(0, 0)
        self.ms.pick_cell(1, 0)
        self.ms.pick_cell(2, 0)
        self.ms.pick_cell(1, 1)
        self.ms.pick_cell(1, 2)
        self.ms.mark_cell(0, 1)
        self.ms.mark_cell(0, 2)
        # ----
        pick = self.ms.ai.reveal_cell()
        self.assertIn(pick, {(0, 3), (1, 3), (2, 3)})
        self.assertEqual(self.ms.ai.guessing, False)
Ejemplo n.º 9
0
    def test_brute_force(self):
        """ loop over a number of grids, making sure we only fail on random guesses"""
        wins = 0
        losses = 0
        games = 1
        for i in xrange(games):
            self.ms = MineSweeper(16, 30, 99)  # standard expert grid
            while not self.ms.victory and not self.ms.game_over:
                self.ms.ai.mark_cells()
                pick = self.ms.ai.reveal_cell()
                self.ms.pick_cell(*pick)
            if self.ms.victory:
                wins += 1
            if self.ms.game_over:
                if self.ms.ai.guessing:
                    losses += 1
                else:
                    self.ms.display_grid()
                    print pick
                    assert 0, "Lost on a non guess"

        print "Games:{}\n\tWins:{}\n\tLosses:{}".format(games, wins, losses)
Ejemplo n.º 10
0
    def test_reveal_cell_guess(self):
        """ Present it a situation where it *must* guess"""
#        ----------------------------------------
#        0| 1, M, B, ?,
#        1| 2, 3, 3, ?,
#        2| 1, M, ?, B,
#        ----------------------------------------
        self.ms = MineSweeper(3, 4, 0)
        self.ms.add_mine(0, 1)
        self.ms.add_mine(2, 1)
        self.ms.add_mine(0, 2)
        self.ms.add_mine(2, 3)
        self.ms.pick_cell(0, 0)
        self.ms.pick_cell(1, 0)
        self.ms.pick_cell(2, 0)
        self.ms.pick_cell(1, 1)
        self.ms.pick_cell(1, 2)
        self.ms.mark_cell(0, 1)
        self.ms.mark_cell(0, 2)
        # ----
        pick = self.ms.ai.reveal_cell()
        self.assertIn(pick, {(0, 3), (1, 3), (2, 3)})
        self.assertEqual(self.ms.ai.guessing, True)
Ejemplo n.º 11
0
 def test_add_mine(self):
     ms = MineSweeper(3, 3, 0)
     ms.add_mine(0, 0)
     # M 1 0
     # 1 0 0
     # 0 0 0
     self.assertEqual(ms.grid[0][0].value, -1)
     self.assertEqual(ms.grid[0][1].value, 1)
     self.assertEqual(ms.grid[1][0].value, 1)
     ms.add_mine(1, 1)
     # M 2 1
     # 2 M 1
     # 1 1 1
     self.assertEqual(ms.grid[0][0].value, -1)
     self.assertEqual(ms.grid[1][1].value, -1)
     self.assertEqual(ms.grid[0][1].value, 2)
     self.assertEqual(ms.grid[1][0].value, 2)
     self.assertEqual(ms.grid[0][2].value, 1)
     self.assertEqual(ms.grid[2][0].value, 1)
     self.assertEqual(ms.grid[1][2].value, 1)
     self.assertEqual(ms.grid[2][1].value, 1)
     self.assertEqual(ms.grid[2][2].value, 1)
Ejemplo n.º 12
0
def main_loop():
    # Obtain the width and height of the screen.
    width = field_width * tile_width + 10
    height = field_height * tile_height + digit_height + 15
    smiley_offset = (width // 2 - digit_height // 2, 5)

    win = pygame.display.set_mode((width, height))
    pygame.display.set_caption('Minesweeper')
    clock = pygame.time.Clock()

    minesweeper = MineSweeper(field_width, field_height, field_mines)
    steps = solver(minesweeper)

    run = True
    while run:
        for event in pygame.event.get():
            if (event.type == pygame.QUIT
                    or (event.type == pygame.KEYDOWN
                        and event.key in [pygame.K_q, pygame.K_ESCAPE])):
                run = False
            # Handle mouse clicks.
            if handle_clicks(event, minesweeper,
                             offset=(5, digit_height + 10)):
                # On user input, just in case reset the solver.
                steps = solver(minesweeper)

            if handle_click_smiley(event, minesweeper, offset=smiley_offset):
                # On reset, create a new solver.
                steps = solver(minesweeper)

            if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
                # Reset the minesweeper.
                minesweeper.reset()
                print('RESET')
                steps = solver(minesweeper)

            if event.type == pygame.KEYDOWN and event.key == pygame.K_n:
                # Try twice if in case generator was exhausted in which case we use a newer one.
                # If solver can't solve it in second try don't simply keep calling it.
                tries = 0
                while tries <= 1:
                    try:
                        # Obtain the step from the solver.
                        position, operation = next(steps)
                        if operation == MARK:
                            print(f'[AI] MARK {position[0]}, {position[1]}')
                            minesweeper.toggle(position, force_mark=True)
                        elif operation == UNCOVER:
                            print(f'[AI] UNCOVER {position[0]}, {position[1]}')
                            minesweeper.uncover(position)
                        break
                    except StopIteration:
                        # reset the solver in case previous one exhausted and check if it can solve
                        steps = solver(minesweeper)
                        tries += 1

        win.fill((255, 255, 255))
        # Render the time and number of mines.
        count_surf = number_surface(minesweeper.pending_mines())
        win.blit(count_surf, (5, 5))
        time_surf = number_surface(minesweeper.time_progressed())
        time_rect = time_surf.get_rect()
        win.blit(time_surf, (width - time_rect.width - 5, 5))
        # Render the smiley
        draw_smiley(win, minesweeper, offset=smiley_offset)

        # Render the minesweeper field
        draw_minesweeper(win, minesweeper, offset=(5, digit_height + 10))
        pygame.display.update()
        clock.tick(60)
Ejemplo n.º 13
0
 def __init__(self, size: int):
     super(QMineSweeper, self).__init__()
     self.size = size
     self.mineSweeper = MineSweeper(self.size, 0.10)
     self.initUI()
     self.show()
Ejemplo n.º 14
0
class QMineSweeper(QWidget):
    class QTile(QPushButton):
        def __init__(self, mineSweeper: 'QMineSweeper',
                     tile: MineSweeper.Tile):
            super(QMineSweeper.QTile, self).__init__()
            self.setFocusPolicy(Qt.NoFocus)
            self.setContextMenuPolicy(Qt.CustomContextMenu)
            self.setSizePolicy(QSizePolicy.MinimumExpanding,
                               QSizePolicy.MinimumExpanding)
            self.mineSweeper = mineSweeper
            self.marked = False
            self.tile = tile

        def leftClick(self):
            if self.marked:
                return
            self.tile.reveal()
            self.mineSweeper.score()
            self.repaint()

        def rightClick(self):
            self.marked = not self.marked
            self.refresh()

        def resizeEvent(self, resizeEvent: QResizeEvent):
            font = self.font()
            font.setBold(True)
            font.setPixelSize(round(0.50 * min(self.width(), self.height())))
            self.setFont(font)

        def refresh(self):
            self.setEnabled(not self.tile.revealed)
            text = "★" if self.marked else str(self.tile)
            self.setText(text)

        def sizeHint(self) -> QSize:
            return QSize(40, 40)

    def __init__(self, size: int):
        super(QMineSweeper, self).__init__()
        self.size = size
        self.mineSweeper = MineSweeper(self.size, 0.10)
        self.initUI()
        self.show()

    def initUI(self):
        self.setWindowTitle(self.tr("Minesweeper"))
        layout = QGridLayout()
        layout.setSpacing(5)
        self.setLayout(layout)

        for tile in self.mineSweeper:
            qTile = QMineSweeper.QTile(self, tile)
            layout.addWidget(qTile, tile.row, tile.column)
            qTile.clicked.connect(qTile.leftClick)
            qTile.customContextMenuRequested.connect(qTile.rightClick)
            tile.delegate = qTile

    def score(self):
        score = self.mineSweeper.score()
        if score is not None:
            self.mineSweeper.reveal()
            if score == +1:
                QMessageBox.information(self, self.tr("Victory!"),
                                        self.tr("You won :)"), QMessageBox.Ok)
            if score == -1:
                QMessageBox.critical(self, self.tr("Defeat!"),
                                     self.tr("You lost :("), QMessageBox.Ok)
            for tile in self.mineSweeper:
                tile.delegate.marked = False
            self.mineSweeper.reset()

    def sizeHint(self) -> QSize:
        return QSize(300, 300)
Ejemplo n.º 15
0
 def setUp(self):
     self.minesweeper = MineSweeper()
Ejemplo n.º 16
0
from minesweeper import MineSweeper

m = MineSweeper()
m.set_mines(1)
game_over = False
while not game_over:
    m.print()
    x = int(input("enter x:"))
    y = int(input("enter y:"))
    move_type = input(
        "enter 'o' for open, 'f' for flag or a 'd' for discover:")
    game_over = m.move(move_type, x, y)
 def test_dot_should_return_0(self):
     ms = MineSweeper(".")
     self.assertEquals("0", ms.solve())
Ejemplo n.º 18
0
class MinesweeperTests(unittest.TestCase):
    def setUp(self):
        self.minesweeper = MineSweeper()

    def test_Canary(self):
        self.assertTrue(True)

    def test_expose_an_unexposed_cell(self):
        self.minesweeper.expose_cell(1, 3)

        self.assertEqual(CellStatus.EXPOSED,
                         self.minesweeper.get_cell_status(1, 3))

    def test_expose_an_exposed_cell(self):
        self.minesweeper.expose_cell(4, 3)
        self.minesweeper.expose_cell(4, 3)

        self.assertEqual(CellStatus.EXPOSED,
                         self.minesweeper.get_cell_status(4, 3))

    def test_expose_a_cell_outside_of_the_range(self):
        with self.assertRaises(IndexError):
            self.minesweeper.expose_cell(-1, 2)
        with self.assertRaises(IndexError):
            self.minesweeper.expose_cell(10, 3)
        with self.assertRaises(IndexError):
            self.minesweeper.expose_cell(3, -1)
        with self.assertRaises(IndexError):
            self.minesweeper.expose_cell(3, 10)

    def test_check_initial_status(self):
        self.assertEqual(CellStatus.UNEXPOSED,
                         self.minesweeper.get_cell_status(2, 3))

    def test_seal_unexposed_cell(self):
        self.minesweeper.seal_unseal_cell(4, 3)

        self.assertEqual(CellStatus.SEALED,
                         self.minesweeper.get_cell_status(4, 3))

    def test_unseal_sealed_cell(self):
        self.minesweeper.seal_unseal_cell(4, 3)
        self.minesweeper.seal_unseal_cell(4, 3)

        self.assertEqual(CellStatus.UNEXPOSED,
                         self.minesweeper.get_cell_status(4, 3))

    def test_seal_exposed_cell(self):
        self.minesweeper.expose_cell(4, 3)
        self.minesweeper.seal_unseal_cell(4, 3)

        self.assertEqual(CellStatus.EXPOSED,
                         self.minesweeper.get_cell_status(4, 3))

    def test_expose_sealed_cell(self):
        self.minesweeper.seal_unseal_cell(4, 3)
        self.minesweeper.expose_cell(4, 3)

        self.assertEqual(CellStatus.SEALED,
                         self.minesweeper.get_cell_status(4, 3))

    def test_expose_calls_expose_neighbors(self):
        expose_neighbours_called = False

        class MineSweeperStub(MineSweeper):
            def expose_neighbours(self, row, column):
                nonlocal expose_neighbours_called
                expose_neighbours_called = True

        minesweeper = MineSweeperStub()
        minesweeper.expose_cell(3, 4)

        self.assertTrue(expose_neighbours_called)
        expose_neighbours_called = False

    def test_expose_call_on_exposed_cell_does_not_expose_neighbors(self):
        expose_neighbours_called = False

        class MineSweeperStub(MineSweeper):
            def expose_neighbours(self, row, column):
                nonlocal expose_neighbours_called
                expose_neighbours_called = True

        minesweeper = MineSweeperStub()
        minesweeper.cell_status[4][3] = 2
        minesweeper.expose_cell(4, 3)

        self.assertFalse(expose_neighbours_called)
        expose_neighbours_called = False

    def test_expose_call_on_sealed_cell_does_not_expose_neighbors(self):
        expose_neighbours_called = False

        class MineSweeperStub(MineSweeper):
            def expose_neighbours(self, row, column):
                nonlocal expose_neighbours_called
                expose_neighbours_called = True

        minesweeper = MineSweeperStub()
        minesweeper.cell_status[4][3] = 3
        minesweeper.expose_cell(4, 3)

        self.assertFalse(expose_neighbours_called)
        expose_neighbours_called = False

    def test_expose_neighbors_calls_expose_on_eight_neighbors(self):
        neighbors = []

        class MineSweeperStub(MineSweeper):
            def expose_cell(self, row, column):
                nonlocal neighbors
                neighbors.append((row, column))

        minesweeper = MineSweeperStub()
        minesweeper.expose_neighbours(4, 3)
        neighbors.remove((4, 3))

        self.assertEqual([(3, 2), (3, 3), (3, 4), (4, 2), (4, 4), (5, 2),
                          (5, 3), (5, 4)], neighbors)

    def test_expose_neighbours_top_left_cell_calls_expose_only_existing_cells(
            self):
        neighbors = []

        class MineSweeperStub(MineSweeper):
            def expose_cell(self, row, column):
                nonlocal neighbors
                neighbors.append((row, column))

        minesweeper = MineSweeperStub()
        minesweeper.expose_neighbours(0, 0)
        neighbors.remove((0, 0))

        self.assertEqual([(0, 1), (1, 0), (1, 1)], neighbors)

    def test_expose_neighbours_bottom_left_cell_calls_expose_only_existing_cells(
            self):
        neighbors = []

        class MineSweeperStub(MineSweeper):
            def expose_cell(self, row, column):
                nonlocal neighbors
                neighbors.append((row, column))

        minesweeper = MineSweeperStub()
        minesweeper.expose_neighbours(9, 9)
        neighbors.remove((9, 9))

        self.assertEqual([(8, 8), (8, 9), (9, 8)], neighbors)

    def test_expose_neighbors_border_cell_calls_expose_only_existing_cells(
            self):
        neighbors = []

        class MineSweeperStub(MineSweeper):
            def expose_cell(self, row, column):
                nonlocal neighbors
                neighbors.append((row, column))

        minesweeper = MineSweeperStub()
        minesweeper.expose_neighbours(9, 5)
        neighbors.remove((9, 5))

        self.assertEqual([(8, 4), (8, 5), (8, 6), (9, 4), (9, 6)], neighbors)

    def test_check_mine_at_3_2(self):
        self.assertFalse(self.minesweeper.is_mine_at(3, 2))

    def test_set_and_check_mine_at_3_2(self):
        self.minesweeper.set_mine_at(3, 2)
        self.assertTrue(self.minesweeper.is_mine_at(3, 2))

    def test_check_mine_at_neg1_4(self):
        self.minesweeper.set_mine_at(-1, 4)
        self.assertFalse(self.minesweeper.is_mine_at(-1, 4))

    def test_check_mine_at_10_5(self):
        self.assertFalse(self.minesweeper.is_mine_at(10, 5))

    def test_check_mine_at_5_neg1(self):
        self.assertFalse(self.minesweeper.is_mine_at(5, -1))

    def test_check_mine_at_7_10(self):
        self.assertFalse(self.minesweeper.is_mine_at(7, 10))

    def test_exposing_adjacent_cell_does_not_expose_neighbors(self):
        expose_neighbours_called = False

        class MineSweeperStub(MineSweeper):
            def expose_neighbours(self, row, column):
                nonlocal expose_neighbours_called
                expose_neighbours_called = True

        minesweeper = MineSweeperStub()
        minesweeper.set_mine_at(0, 0)
        minesweeper.expose_cell(0, 1)

        self.assertFalse(expose_neighbours_called)
        expose_neighbours_called = False

    def test_adjacentMinesCountAt_4_6(self):
        self.assertEqual(0,
                         self.minesweeper.calculate_adjacent_mine_count(4, 6))

    def test_set_and_verify_adjacentMinesCountAt_3_4(self):
        self.minesweeper.set_mine_at(3, 4)

        self.assertEqual(0,
                         self.minesweeper.calculate_adjacent_mine_count(3, 4))

    def test_set_mine_at_3_4_and_verify_adjacentMinesCountAt_3_5(self):
        self.minesweeper.set_mine_at(3, 4)

        self.assertEqual(1,
                         self.minesweeper.calculate_adjacent_mine_count(3, 5))

    def test_set_mine_at_3_4_and_2_6_verify_adjacentMinesCountAt_3_5(self):
        self.minesweeper.set_mine_at(3, 4)
        self.minesweeper.set_mine_at(2, 6)

        self.assertEqual(2,
                         self.minesweeper.calculate_adjacent_mine_count(3, 5))

    def test_set_mine_at_0_1_and_verify_adjacentMinesCountAt_0_0(self):
        self.minesweeper.set_mine_at(0, 1)

        self.assertEqual(1,
                         self.minesweeper.calculate_adjacent_mine_count(0, 0))

    def test_adjacentMinesCountAt_0_9(self):
        self.assertEqual(0,
                         self.minesweeper.calculate_adjacent_mine_count(0, 9))

    def test_set_mine_at_9_8_and_verify_adjacentMinesCountAt_9_9(self):
        self.minesweeper.set_mine_at(9, 8)

        self.assertEqual(1,
                         self.minesweeper.calculate_adjacent_mine_count(9, 9))

    def test_adjacentMinesCountAt_9_0(self):
        self.assertEqual(0,
                         self.minesweeper.calculate_adjacent_mine_count(9, 0))

    def test_get_game_status(self):
        self.assertEqual(GameStatus.INPROGRESS,
                         self.minesweeper.get_game_status())

    def test_expose_mined_cell_and_getGameStatus_returns_LOST(self):
        self.minesweeper.set_mine_at(4, 3)
        self.minesweeper.expose_cell(4, 3)
        self.assertEqual(GameStatus.LOST, self.minesweeper.get_game_status())

    def test_game_in_progress_after_all_mines_sealed_but_cells_remain_unexposed(
            self):
        self.minesweeper.set_mine_at(4, 3)
        self.minesweeper.seal_unseal_cell(4, 3)

        self.assertEqual(GameStatus.INPROGRESS,
                         self.minesweeper.get_game_status())

    def test_game_in_progress_all_mines_sealed_not_an_empty_cell(self):
        self.minesweeper.set_mine_at(4, 3)
        self.minesweeper.seal_unseal_cell(4, 3)
        self.minesweeper.seal_unseal_cell(4, 4)

        self.assertEqual(GameStatus.INPROGRESS,
                         self.minesweeper.get_game_status())

    def test_game_in_progress_all_mines_sealed_one_adjacent_cell_unexposed(
            self):
        self.minesweeper.set_mine_at(4, 3)
        self.minesweeper.seal_unseal_cell(4, 3)
        self.minesweeper.expose_cell(0, 0)
        self.minesweeper.cell_status[5][2] = CellStatus.UNEXPOSED

        self.assertEqual(GameStatus.INPROGRESS,
                         self.minesweeper.get_game_status())

    def test_game_won_all_mines_sealed_and_all_other_cells_exposed(self):
        self.minesweeper.set_mine_at(4, 3)
        self.minesweeper.seal_unseal_cell(4, 3)

        self.minesweeper.expose_cell(0, 0)

        self.assertEqual(GameStatus.WIN, self.minesweeper.get_game_status())

    def test_total_mines_from_set_mines(self):
        self.minesweeper.set_mines(0)
        total_mine = 0

        for i in range(self.minesweeper.BOUNDS):
            for j in range(self.minesweeper.BOUNDS):
                if self.minesweeper.is_mine_at(i, j):
                    total_mine += 1

        self.assertEqual(total_mine, 10)

    def test_mine_difference_calling_set_mines_with_different_seeds(self):
        self.minesweeper.set_mines(0)
        self.minesweeper.set_mines(1)
        total_mine = 0

        for i in range(self.minesweeper.BOUNDS):
            for j in range(self.minesweeper.BOUNDS):
                if self.minesweeper.is_mine_at(i, j):
                    total_mine += 1

        self.assertLess(total_mine, 20)
Ejemplo n.º 19
0
 def test_star_should_return_star(self):
     self.assertEquals("*", MineSweeper("*").solve())
Ejemplo n.º 20
0
 def test_star_dot_should_return_star_1(self):
     self.assertEquals("*.", MineSweeper("*1").solve())
Ejemplo n.º 21
0
import sys
from minesweeper import MineSweeper

if __name__ == '__main__':
    ms = MineSweeper(10, 10)
    quit = False

    while (not quit):
        print('Enter position you want to reveal.')
        pos = input().split()
                __default_state_shape__))

        from ai import AI
        from minesweeper import VisualizeAI

        ai = AI(state_shape=__default_state_shape__,
                action_dim=__default_action_dim__,
                verbose=verbose)
        if verbose:
            print("Load AI model from file: [{0}] ...".format(__filename__),
                  end="")

        ai.load_nnet(__filename__)
        if verbose:
            print("OK!")

        vi = VisualizeAI(state_shape=__default_state_shape__,
                         ai=ai,
                         verbose=verbose)

        vi.start()

    if args.play:
        print(
            "Play game. Please close game in terminal after closing window (i.e, Press Ctrl+C)."
        )
        from minesweeper import MineSweeper

        minesweeper = MineSweeper(state_shape=__default_state_shape__,
                                  verbose=verbose)
        minesweeper.start()
Ejemplo n.º 23
0
import time
from minesweeper import MineSweeper

if __name__ == '__main__':
    start = time.time()
    for i in range(0, 300):
        mine = MineSweeper(25, 25, 25)
        mine.mine(5, 10)
    print(time.time() - start)
Ejemplo n.º 24
0
sys.path.insert(
    0,
    os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
                 'src/game'))

from random import randint
from tkinter import *
from tkinter import messagebox

from minesweeper import MineSweeper
from cellstatus import CellStatus
from gamestatus import GameStatus

is_first_click = True
minesweeper = MineSweeper()
minesweeper.set_mines(randint(0, 100))
root = Tk()
root.title('Minesweeper')


def disable_cells():
    for row in range(minesweeper.BOUNDS):
        for col in range(minesweeper.BOUNDS):
            button[row][col].config(state="disabled")


def handle_left_click(row, col):
    minesweeper.expose_cell(row, col)

    if minesweeper.get_game_status() == GameStatus.INPROGRESS:
Ejemplo n.º 25
0
class TestMinesweeperAI(TestCase):

    def setUp(self):
        self.ms = None

    def count_marked_cells(self):
        count = 0
        for row in self.ms.grid:
            for cell in row:
                count += 1 if cell.marked else 0
        return count

    def test_reveal_cell_basic(self):
        self.ms = MineSweeper(4, 4, 0)
#        ----------------------------------------
#        0| ?, ?, 1, 0,
#        1| ?, ?, 2, 1,
#        2| ?, ?, ?, ?,
#        3| ?, ?, ?, ?,
#        ----------------------------------------
        self.ms.add_mine(0, 1)
        self.ms.add_mine(2, 3)
        self.ms.pick_cell(0, 3)
        self.ms.display_grid()
        cell = self.ms.ai.reveal_cell()
        self.assertEquals(cell, (2, 1))

    def test_reveal_cell_complex(self):
        """ Present it a situation where it *must* use adjaceny rules"""
#        ----------------------------------------
#        0| 1, M, B, ?,
#        1| 2, 3, 2, ?,
#        2| 1, M, ?, ?,
#        ----------------------------------------
        self.ms = MineSweeper(3, 4, 0)
        self.ms.add_mine(0, 1)
        self.ms.add_mine(2, 1)
        self.ms.add_mine(0, 2)
        self.ms.pick_cell(0, 0)
        self.ms.pick_cell(1, 0)
        self.ms.pick_cell(2, 0)
        self.ms.pick_cell(1, 1)
        self.ms.pick_cell(1, 2)
        self.ms.mark_cell(0, 1)
        self.ms.mark_cell(0, 2)
        # ----
        pick = self.ms.ai.reveal_cell()
        self.assertIn(pick, {(0, 3), (1, 3), (2, 3)})
        self.assertEqual(self.ms.ai.guessing, False)

    def test_reveal_cell_guess(self):
        """ Present it a situation where it *must* guess"""
#        ----------------------------------------
#        0| 1, M, B, ?,
#        1| 2, 3, 3, ?,
#        2| 1, M, ?, B,
#        ----------------------------------------
        self.ms = MineSweeper(3, 4, 0)
        self.ms.add_mine(0, 1)
        self.ms.add_mine(2, 1)
        self.ms.add_mine(0, 2)
        self.ms.add_mine(2, 3)
        self.ms.pick_cell(0, 0)
        self.ms.pick_cell(1, 0)
        self.ms.pick_cell(2, 0)
        self.ms.pick_cell(1, 1)
        self.ms.pick_cell(1, 2)
        self.ms.mark_cell(0, 1)
        self.ms.mark_cell(0, 2)
        # ----
        pick = self.ms.ai.reveal_cell()
        self.assertIn(pick, {(0, 3), (1, 3), (2, 3)})
        self.assertEqual(self.ms.ai.guessing, True)

    def test_brute_force(self):
        """ loop over a number of grids, making sure we only fail on random guesses"""
        wins = 0
        losses = 0
        games = 1
        for i in xrange(games):
            self.ms = MineSweeper(16, 30, 99)  # standard expert grid
            while not self.ms.victory and not self.ms.game_over:
                self.ms.ai.mark_cells()
                pick = self.ms.ai.reveal_cell()
                self.ms.pick_cell(*pick)
            if self.ms.victory:
                wins += 1
            if self.ms.game_over:
                if self.ms.ai.guessing:
                    losses += 1
                else:
                    self.ms.display_grid()
                    print pick
                    assert 0, "Lost on a non guess"

        print "Games:{}\n\tWins:{}\n\tLosses:{}".format(games, wins, losses)

    def test_mark_cells_basic_one(self):
        self.ms = MineSweeper(3, 3, 0)
        self.ms.add_mine(0, 0)
        for y in xrange(len(self.ms.grid)):
            for x in xrange(len(self.ms.grid[0])):
                if y != 0 and x != 0:
                    self.ms.pick_cell(y, x)
        # B 1 0
        # 1 1 0
        # 0 0 0
        self.ms.ai.mark_cells()
        self.ms.display_grid()
        self.assertEqual(self.count_marked_cells(), 1)
        self.assertEqual(self.ms.grid[0][0].marked, True)

    def test_mark_cells_basic_three(self):
        self.ms = MineSweeper(3, 3, 0)
        self.ms.add_mine(0, 0)
        self.ms.add_mine(0, 1)
        self.ms.add_mine(0, 2)
        for y in xrange(1, len(self.ms.grid)):
            for x in xrange(len(self.ms.grid[0])):
                self.ms.pick_cell(y, x)
        # B B B
        # 2 3 2
        # 0 0 0
        self.ms.ai.mark_cells()
        self.ms.display_grid()
        self.assertEqual(self.count_marked_cells(), 3)
        self.assertEqual(self.ms.grid[0][0].marked, True)
        self.assertEqual(self.ms.grid[0][1].marked, True)
        self.assertEqual(self.ms.grid[0][2].marked, True)

    def test_mark_cells_adjacents(self):
        self.ms = MineSweeper(3, 3, 0)
        self.ms.add_mine(0, 0)
        self.ms.pick_cell(0, 1)
        self.ms.pick_cell(1, 0)
        # Can't mark yet, not enough info! (could be 0,0 or 1,1)
        # B 1 ?
        # 1 ? ?
        # ? ? ?
        self.ms.ai.mark_cells()
        self.assertEqual(self.count_marked_cells(), 0)
        self.ms.add_mine(1, 1)
        # B 2 ?
        # 2 B ?
        # ? ? ?
        self.ms.ai.mark_cells()
        self.assertEqual(self.count_marked_cells(), 0)
        # Reveal top right, Adjacency should give us top left
        # B 2 1
        # 2 B ?
        # ? ? ?
        self.ms.pick_cell(0, 2)
        self.ms.ai.mark_cells()
        self.ms.display_grid()
        self.assertEqual(self.count_marked_cells(), 1)
        self.assertEqual(self.ms.grid[0][0].marked, True)

    def test_mark_cells_adjacents_two(self):
        # B ? B
        # 1 2 1
        # 0 0 0
        self.ms = MineSweeper(3, 3, 0)
        self.ms.add_mine(0, 0)
        self.ms.add_mine(0, 2)
        for y in xrange(1, len(self.ms.grid)):
            for x in xrange(len(self.ms.grid[0])):
                self.ms.pick_cell(y, x)
        self.ms.ai.mark_cells()
        self.assertEqual(self.count_marked_cells(), 2)
        self.assertEqual(self.ms.grid[0][0].marked, True)
        self.assertEqual(self.ms.grid[0][2].marked, True)
Ejemplo n.º 26
0
 def __init__(self, size: int):
     super(QMineSweeper, self).__init__()
     self.size = size
     self.mineSweeper = MineSweeper(self.size, 0.10)
     self.initUI()
     self.show()
Ejemplo n.º 27
0
 def test_dot_should_return_0(self):
     ms = MineSweeper(".")
     self.assertEquals("0", ms.solve())
Ejemplo n.º 28
0
class QMineSweeper(QWidget):

    class QTile(QPushButton):
        def __init__(self, mineSweeper: 'QMineSweeper', tile: MineSweeper.Tile):
            super(QMineSweeper.QTile, self).__init__()
            self.setFocusPolicy(Qt.NoFocus)
            self.setContextMenuPolicy(Qt.CustomContextMenu)
            self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
            self.mineSweeper = mineSweeper
            self.marked = False
            self.tile = tile

        def leftClick(self):
            if self.marked:
                return
            self.tile.reveal()
            self.mineSweeper.score()
            self.repaint()

        def rightClick(self):
            self.marked = not self.marked
            self.refresh()

        def resizeEvent(self, resizeEvent: QResizeEvent):
            font = self.font()
            font.setBold(True)
            font.setPixelSize(round(0.50 * min(self.width(), self.height())))
            self.setFont(font)

        def refresh(self):
            self.setEnabled(not self.tile.revealed)
            text = "★" if self.marked else str(self.tile)
            self.setText(text)

        def sizeHint(self) -> QSize:
            return QSize(40, 40)

    def __init__(self, size: int):
        super(QMineSweeper, self).__init__()
        self.size = size
        self.mineSweeper = MineSweeper(self.size, 0.10)
        self.initUI()
        self.show()

    def initUI(self):
        self.setWindowTitle(self.tr("Minesweeper"))
        layout = QGridLayout()
        layout.setSpacing(5)
        self.setLayout(layout)

        for tile in self.mineSweeper:
            qTile = QMineSweeper.QTile(self, tile)
            layout.addWidget(qTile, tile.row, tile.column)
            qTile.clicked.connect(qTile.leftClick)
            qTile.customContextMenuRequested.connect(qTile.rightClick)
            tile.delegate = qTile

    def score(self):
        score = self.mineSweeper.score()
        if score is not None:
            self.mineSweeper.reveal()
            if score == +1:
                QMessageBox.information(self, self.tr("Victory!"), self.tr("You won :)"), QMessageBox.Ok)
            if score == -1:
                QMessageBox.critical(self, self.tr("Defeat!"), self.tr("You lost :("), QMessageBox.Ok)
            for tile in self.mineSweeper:
                tile.delegate.marked = False
            self.mineSweeper.reset()

    def sizeHint(self) -> QSize:
        return QSize(300, 300)
Ejemplo n.º 29
0
async def new_game(source, user, msg_type, row: int, column: int, mines: int):
    if user.id in in_gaming_list:
        await send_msg(source, [Plain("你已经在游戏中了")], user, msg_type)
        return
    in_gaming_list[user.id] = MineSweeper(row, column, mines)
    await send_panel(app, source, user, msg_type)