📜  minesweeper - Python (1)

📅  最后修改于: 2023-12-03 14:44:18.672000             🧑  作者: Mango

Minesweeper - Python

Minesweeper is a classic game where players try to identify all the mines on a game board without detonating them. It is a game of strategy, logic, and luck. It was originally created by Microsoft in the 1980s and has since been adapted to various platforms, including Python.

In this Python implementation of Minesweeper, players must reveal all non-mine tiles and mark all mine tiles on the game board. Players can reveal a tile by clicking on it, and if the tile contains a mine, the game is over. If a tile does not contain a mine, the tile will display the number of adjacent tiles that contain mines. Players can mark a tile as a mine by right-clicking on it, which will place a flag on the tile.

import random

class Minesweeper:
    def __init__(self, rows, cols, mines):
        self.rows = rows
        self.cols = cols
        self.mines = mines
        self.board = [[0 for i in range(cols)] for j in range(rows)]
        self.mine_locations = []
        self.revealed = [[False for i in range(cols)] for j in range(rows)]
        self.flags = [[False for i in range(cols)] for j in range(rows)]
        self.game_over = False
        self.generate_board()
        
    def generate_board(self):
        # randomly place mines on the board
        for i in range(self.mines):
            while True:
                row = random.randrange(self.rows)
                col = random.randrange(self.cols)
                if (row, col) not in self.mine_locations:
                    self.mine_locations.append((row, col))
                    break
            self.board[row][col] = -1
            
        # calculate the number of adjacent mines for each tile
        for row in range(self.rows):
            for col in range(self.cols):
                if self.board[row][col] == -1:
                    continue
                count = 0
                for i in range(-1, 2):
                    for j in range(-1, 2):
                        row_adj = row + i
                        col_adj = col + j
                        if row_adj < 0 or row_adj >= self.rows or col_adj < 0 or col_adj >= self.cols:
                            continue
                        if self.board[row_adj][col_adj] == -1:
                            count += 1
                self.board[row][col] = count
                
    def reveal_tile(self, row, col):
        # reveal the tile at the specified row and col
        if self.flags[row][col]:
            return
        if (row, col) in self.mine_locations:
            self.game_over = True
            return
        self.revealed[row][col] = True
        if self.board[row][col] == 0:
            for i in range(-1, 2):
                for j in range(-1, 2):
                    row_adj = row + i
                    col_adj = col + j
                    if row_adj < 0 or row_adj >= self.rows or col_adj < 0 or col_adj >= self.cols:
                        continue
                    if self.revealed[row_adj][col_adj]:
                        continue
                    self.reveal_tile(row_adj, col_adj)
    
    def toggle_flag(self, row, col):
        # place or remove a flag at the specified row and col
        if not self.revealed[row][col]:
            self.flags[row][col] = not self.flags[row][col])
    
    def display_board(self):
        # display the game board
        for row in range(self.rows):
            row_display = []
            for col in range(self.cols):
                if self.revealed[row][col]:
                    if (row, col) in self.mine_locations:
                        row_display.append('*')
                    else:
                        row_display.append(str(self.board[row][col]))
                elif self.flags[row][col]:
                    row_display.append('F')
                else:
                    row_display.append('.')
            print(' '.join(row_display))
Usage

To play Minesweeper, simply create a new instance of the Minesweeper class and start revealing tiles:

ms = Minesweeper(rows=10, cols=10, mines=20)
ms.display_board()

while not ms.game_over:
    row = input('Enter a row: ')
    col = input('Enter a column: ')
    ms.reveal_tile(int(row), int(col))
    ms.display_board()

if ms.game_over:
    print('Game over! You hit a mine!')
else:
    print('Congratulations! You won!')
Conclusion

Minesweeper is a fun and challenging game that tests your strategic thinking and logic skills. This Python implementation of Minesweeper is a great way to practice programming and have fun at the same time. Give it a try and see how well you can do!