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)
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)
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_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)
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())
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_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_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_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_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_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)
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)
def __init__(self, size: int): super(QMineSweeper, self).__init__() self.size = size self.mineSweeper = MineSweeper(self.size, 0.10) self.initUI() self.show()
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)
def setUp(self): self.minesweeper = MineSweeper()
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())
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)
def test_star_should_return_star(self): self.assertEquals("*", MineSweeper("*").solve())
def test_star_dot_should_return_star_1(self): self.assertEquals("*.", MineSweeper("*1").solve())
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()
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)
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:
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)
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)