首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扫雷船- Python 3(初学者)

扫雷船- Python 3(初学者)
EN

Code Review用户
提问于 2019-12-28 08:18:22
回答 1查看 2.1K关注 0票数 4

我刚刚创建了扫雷游戏,它的工作非常好(对我来说)。如能就如何改进这一守则提出任何建议,我们将不胜感激:

  • 面向对象
  • 数组
  • 错误处理
  • 函数
  • 更有效的方法
  • 其他:样式(PEP8)、注释、干净代码、递归等

游戏解释:

  • 扫雷舰是隐藏的地雷和非地雷单元的阵列(表).
  • 你可以一个一个地揭露任何细胞。一旦你找到了地雷,你就输了。
  • 如果你能揭露所有非我的细胞,你就赢了。
  • 每个非地雷单元显示包含地雷的相邻单元格的数目。
  • 阅读更多的维基百科维基百科,或者您可以在计算机上试用它。

我的方法:

清洁版

代码语言:javascript
复制
import random


class Minesweeper:

    def __init__(self,width=9,height=10,mine_numbers=12):

        self.width = width
        self.height = height
        self.mine_numbers = mine_numbers        
        self.table = [None]*self.width*self.height

        self.user_cell = False
        self.user_row = False
        self.user_column = False
        self.user_reveal = []


    def game_create(self):
        print(f'Default size is {self.width}*{self.height}, {self.mine_numbers} mines')
        default_size = input('Play default size?(Y/N): ')

        if default_size.lower() == 'n':
            correct_input = False           
            while not correct_input:
                try:
                    self.width = int(input('Enter width: '))
                    self.height = int(input('Enter height: '))
                    self.mine_numbers = int(input('Enter number of mines: '))
                    if self.mine_numbers >= self.width*self.height or self.mine_numbers == 0:
                        print('ERROR: Number of mines can not be 0 or equal/exceed table size')
                    elif self.width > 99 or self.height > 99:
                        print('ERROR: Maximum table size is 99*99')
                    else:
                        self.table = [None]*self.width*self.height
                        self.user_reveal = []
                        correct_input = True
                        return self.width,self.height,self.mine_numbers,self.table,self.user_reveal
                except ValueError:
                    print('ERROR: Try again, number only')              
        else:
            self.table = [None]*self.width*self.height
            self.user_reveal = []
            return self.width,self.height,self.mine_numbers,self.table,self.user_reveal


    def user_input(self):

        correct_input = False

        while not correct_input:
            try:
                self.user_cell = input('Enter {[column][row]} in 4 digits eg. 0105: ')
                int(self.user_cell)
                if len(self.user_cell) != 4:
                    print('ERROR: Only 4 digits allowed')
                elif int(self.user_cell[2:]) > self.height or self.user_cell[2:] == '00':
                    print('ERROR: Row out of range')
                elif int(self.user_cell[:2]) > self.width or self.user_cell[:2] == '00':
                    print('ERROR: Column of range')
                elif self.user_cell in self.user_reveal:
                    print('ERROR: Already revealed')
                else:
                    correct_input = True
            except ValueError:
                print('ERROR: Try again, number only')

        if self.user_cell:
            self.user_row = int(self.user_cell[2:])
            self.user_column = int(self.user_cell[:2])
            self.user_reveal.append(self.user_cell)

        return self.user_cell,self.user_row,self.user_column


    def mines_generator(self):

        user_location = ((self.user_row-1)*self.width)+self.user_column-1
        possible_location = [i for i in range(self.width*self.height) if i != user_location]
        mines_location = random.sample(possible_location,self.mine_numbers)

        for i in mines_location:
            self.table[i] = 9

        return self.table


    def two_dimension_array(self):
        for i in range(self.height):
            self.table[i] = self.table[0+(self.width*i):self.width+(self.width*i)]      

        del self.table[self.height:]

        return self.table


    def complete_table(self):

        temporary_table = [[None for _ in range(self.width)] for _ in range(self.height)]

        for i in range(self.height):
            for j in range(self.width):
                if self.table[i][j] == 9:
                    temporary_table[i][j] = 9
                    continue
                else:
                    counter = 0
                    for k in range(i-1,i+2):
                        if 0 <= k <= self.height-1:
                            for l in range(j-1,j+2):
                                if 0 <= l <= self.width-1:
                                    if self.table[k][l] == 9:
                                        counter += 1
                                        continue
                    temporary_table[i][j] = counter
        self.table = temporary_table

        return self.table


    def adjacent_zero(self,zero_cell):          
        if self.table[int(zero_cell[2:])-1][int(zero_cell[:2])-1] == 0:
            for i in range(int(zero_cell[2:])-1-1,int(zero_cell[2:])-1+2):
                if 0 <= i < self.height:
                    for j in range(int(zero_cell[:2])-1-1,int(zero_cell[:2])-1+2):
                        if 0 <= j < self.width:
                            if str(j+1).zfill(2)+str(i+1).zfill(2) not in self.user_reveal:
                                self.user_reveal.append(str(j+1).zfill(2)+str(i+1).zfill(2))
                                if self.table[i][j] == 0:
                                    self.adjacent_zero(str(j+1).zfill(2)+str(i+1).zfill(2))

        return self.user_reveal


    def first_turn(self):
        self.user_input()
        self.mines_generator()
        self.two_dimension_array()
        self.complete_table()
        self.adjacent_zero(self.user_cell)


    def print_table(self):
        print('\n'*10)
        for row in range(self.height+1):
            cell = '|'
            for column in range(self.width+1):
                if row == 0:
                    cell += f'{column:2}|'
                    continue
                elif column == 0:
                    cell += f'{row:2}|'
                    continue
                elif str(column).zfill(2)+str(row).zfill(2) in self.user_reveal:
                    cell += f'{self.table[row-1][column-1]:2}|'
                    continue        
                else:
                    cell += '{:>3}'.format('|')
            print(cell)


    def end_game(self):

        def reveal_mine():
            for i,j in enumerate(self.table):
                for k,l in enumerate(j):
                    if l == 9:
                        self.table[i][k] = ‘XX’
                        if str(k+1).zfill(2)+str(i+1).zfill(2) not in self.user_reveal:
                            self.table[i][k] = ‘**’
                            self.user_reveal.append(str(k+1).zfill(2)+str(i+1).zfill(2))

        if self.user_cell:
            if self.table[self.user_row-1][self.user_column-1] == 9:
                end_game = True
                reveal_mine()
                self.print_table()
                print('YOU LOSE!')
            elif len(self.user_reveal) == (self.width*self.height)-self.mine_numbers:
                end_game = True
                reveal_mine()
                self.print_table()
                print('YOU WIN!')
            else:
                end_game = False
        else:
            end_game = False

        return end_game


    def restart_game(self):

        restart = input('Restart?(Y/N): ')

        if restart.lower() == 'y':
            return True
        else: 
            return False


def main():

    minesweeper = Minesweeper()

    while True:         
        minesweeper.game_create()
        minesweeper.print_table()
        minesweeper.first_turn()

        while not minesweeper.end_game():
            minesweeper.print_table()
            minesweeper.user_input()
            minesweeper.adjacent_zero(minesweeper.user_cell)

        if not minesweeper.restart_game():
            break


if __name__ == '__main__':
    main()

评论版本

代码语言:javascript
复制
import random

class Minesweeper:

    def __init__(self,width=9,height=10,mine_numbers=12):
        # Table generate: change via tables_ize()
        self.width = width
        self.height = height
        self.mine_numbers = mine_numbers        
        self.table = [None]*self.width*self.height
        # User cell input
        self.user_cell = False
        self.user_row = False
        self.user_column = False
        self.user_reveal = []
        '''
        {user_reveal} is changed by
        - {game_create()}: reset user_reveal
        - {user_input()}: append input cell, cannot reveal all adjacent 0 here (first turn - table not yet generated)
        - {adjacent_zero()}: reveal all adjacent 0
        - {end_game()}: append all mines
        '''
        '''
        {*_user_*},{user_cell} = {[column][row]}, index is 1 more than {*_cell_*} index
        {*_cell_*} = {[row][column]}, index is 1 less than {*_user_*} index
        '''


    def game_create(self):
        print(f'Default size is {self.width}*{self.height}, {self.mine_numbers} mines')
        default_size = input('Play default size?(Y/N): ')
        if default_size.lower() == 'n':
            correct_input = False
            while not correct_input:
                try:
                    self.width = int(input('Enter width: '))
                    self.height = int(input('Enter height: '))
                    self.mine_numbers = int(input('Enter number of mines: '))
                    if self.mine_numbers >= self.width*self.height or self.mine_numbers == 0:
                        print('ERROR: Number of mines can not be 0 or equal/exceed table size')
                    elif self.width > 99 or self.height > 99:
                        print('ERROR: Maximum table size is 99*99')
                    else:
                        self.table = [None]*self.width*self.height
                        self.user_reveal = []
                        correct_input = True
                        return self.width,self.height,self.mine_numbers,self.table,self.user_reveal
                except ValueError:
                    print('ERROR: Try again, number only')
        else:
            self.table = [None]*self.width*self.height
            self.user_reveal = []
            return self.width,self.height,self.mine_numbers,self.table,self.user_reveal


    def user_input(self):
        correct_input = False
        while not correct_input:
            try:
                self.user_cell = input('Enter {[column][row]} in 4 digits eg. 0105: ')
                int(self.user_cell)
                if len(self.user_cell) != 4:
                    print('ERROR: Only 4 digits allowed')
                elif int(self.user_cell[2:]) > self.height or self.user_cell[2:] == '00':
                    print('ERROR: Row out of range')
                elif int(self.user_cell[:2]) > self.width or self.user_cell[:2] == '00':
                    print('ERROR: Column of range')
                elif self.user_cell in self.user_reveal:
                    print('ERROR: Already revealed')
                else:
                    correct_input = True
            except ValueError:
                print('ERROR: Try again, number only')

        self.user_row = int(self.user_cell[2:])
        self.user_column = int(self.user_cell[:2])
        if self.user_cell:
            self.user_reveal.append(self.user_cell)
        return self.user_cell,self.user_row,self.user_column


    def mines_generator(self):
        # Exclude first cell from mines generator
        user_location = ((self.user_row-1)*self.width)+self.user_column-1
        possible_location = [i for i in range(self.width*self.height) if i != user_location]
        mines_location = random.sample(possible_location,self.mine_numbers)

        # Assign 'Location with mine' with 9
        for i in mines_location:
            self.table[i] = 9
        return self.table


    def two_dimension_array(self):
        # Save table into 2D array
        for i in range(self.height):
            self.table[i] = self.table[0+(self.width*i):self.width+(self.width*i)]

        # Remove unnessessary elements
        del self.table[self.height:]
        return self.table


    def complete_table(self):
        # Create temporary 2D array
        temporary_table = [[None for _ in range(self.width)] for _ in range(self.height)]
        # For every table[i][j]
        for i in range(self.height):
            for j in range(self.width):
                # If table[i][j] is bomb, continue
                if self.table[i][j] == 9:
                    temporary_table[i][j] = 9
                    continue
                else:
                    counter = 0
                    # For every adjacent neighbor arrays
                    for k in range(i-1,i+2):
                        # Error handling: list index out of range
                        if 0 <= k <= self.height-1:
                            for l in range(j-1,j+2):
                                # Error handling: list index out of range
                                if 0 <= l <= self.width-1:
                                    # Count every adjacent mines
                                    if self.table[k][l] == 9:
                                        counter += 1
                                        continue
                    temporary_table[i][j] = counter
        self.table = temporary_table
        return self.table


    def adjacent_zero(self,zero_cell):  
        # If value is 0 
        if self.table[int(zero_cell[2:])-1][int(zero_cell[:2])-1] == 0:
            # For all neighbor elements
            for i in range(int(zero_cell[2:])-1-1,int(zero_cell[2:])-1+2):
                # Error handling: index out of range
                if 0 <= i < self.height:
                    for j in range(int(zero_cell[:2])-1-1,int(zero_cell[:2])-1+2):
                        if 0 <= j < self.width:
                            # If neighbor element of 0 is not yet append, append all adjacent element
                            if str(j+1).zfill(2)+str(i+1).zfill(2) not in self.user_reveal:
                                self.user_reveal.append(str(j+1).zfill(2)+str(i+1).zfill(2))
                                # If neighbor is also 0, do a recursion
                                if self.table[i][j] == 0:
                                    self.adjacent_zero(str(j+1).zfill(2)+str(i+1).zfill(2))


    def first_turn(self):
        self.user_input()
        self.mines_generator()
        self.two_dimension_array()
        self.complete_table()
        self.adjacent_zero()


    def print_table(self):
        # Clear UI
        print('\n'*10)
        for row in range(self.height+1):
            cell = '|'
            for column in range(self.width+1):
                # Top-row label
                if row == 0:
                    cell += f'{column:2}|' # (Note: try 02 instead of 2)
                    continue
                # First column label
                elif column == 0:
                    cell += f'{row:2}|'
                    continue
                # Revealed cell
                elif str(column).zfill(2)+str(row).zfill(2) in self.user_reveal:
                    cell += f'{self.table[row-1][column-1]:2}|'
                    continue        
                # Not yet revealed cell
                else:
                    cell += '{:>3}'.format('|')
            print(cell)


    def end_game(self):

        # If end: reveal all mines, nested function
        def reveal_mine():
            for i,j in enumerate(self.table):
                for k,l in enumerate(j):
                    if l == 9:
                        self.table[i][k] = ‘XX’
                        if str(k+1).zfill(2)+str(i+1).zfill(2) not in self.user_reveal:
                            self.table[i][k] = ‘**’
                            self.user_reveal.append(str(k+1).zfill(2)+str(i+1).zfill(2))

        # If user choose cell: check if end
        if self.user_cell:
            if self.table[self.user_row-1][self.user_column-1] == 9:
                end_game = True
                reveal_mine()
                self.print_table()
                print('YOU LOSE!')
            elif len(self.user_reveal) == (self.width*self.height)-self.mine_numbers:
                end_game = True
                reveal_mine()
                self.print_table()
                print('YOU WIN!')
            else:
                end_game = False
        # If no cell selected: end = False
        else:
            end_game = False

        return end_game


    def restart_game(self):     
        restart = input('Restart?(Y/N): ')
        if restart.lower() == 'y':
            return True
        else: 
            return False


def main():

    minesweeper = Minesweeper()

    while True:         
        minesweeper.game_create()
        minesweeper.print_table()
        minesweeper.first_turn()

        while not minesweeper.end_game():
            minesweeper.print_table()
            minesweeper.user_input()
            minesweeper.adjacent_zero(minesweeper.user_cell)

        if not minesweeper.restart_game():
            break


if __name__ == '__main__':
    main()
EN

回答 1

Code Review用户

回答已采纳

发布于 2020-01-02 15:14:34

我认为实现一个游戏是学习一种新的编程语言的好方法。如果您已经准备好了,您可以尝试使用游戏库(如派克拱廊 )编写Minesweeper的图形版本,以便更多地了解该语言。

以下是我对改进的建议,没有特别的顺序:

注释

当我检查代码时,我会同时阅读代码和注释。这些注释应该能帮助我理解代码的作用。但是对于这段代码,我不认为它们是这样的,因为它们处于相当低的水平上。告诉我与代码本身本质上相同的注释并不是很有趣。相反,注释应该传达的是代码的意图。为什么不知道怎么做。

我建议不要将注释放在单独的行上,而是将它们全部删除,并在模块的顶部用一个大注释来替换它们,在这个模块中,您可以描述Minesweeper类的体系结构:

代码语言:javascript
复制
import random

# Minesweeper
# -----------
# Minesweeper is a solitaire game in which the goal is to reveal all
# mines on a board. The Minesweeper class implements the game. It has
# the following attributes:
#
# * width: width of board
# ...
# * table: board representation
#
# This example shows how the class should be used:
#
#     ms = Minesweeper()
#     while True:
#         ms.game_create()
#         ...

它为读者提供了代码的概述。

是/否提示

这个堆栈溢出的答案中表示的一种约定是将“是”/“否”提示符中的默认选择大写。所以如果提示符是

代码语言:javascript
复制
Play default size? [Y/n]:

用户知道,只要按回车,就会选择默认大小。是的,我知道这是一个“小细节”,但要制作一个伟大的软件,你必须考虑这些小事情。

整数提示函数

如果用户不想使用默认大小,则会提示用户输入地雷的宽度、高度和数量。考虑制作一个封装提示代码的函数:

代码语言:javascript
复制
def prompt_int(name, lo, hi):
    while True:
        s = input(f'Enter {name} [{lo}..{hi}]: ')
        try:
            v = int(s)
        except ValueError:
            print('ERROR: Try again, number only')
            continue
        if not (lo <= v <= hi):
            print('ERROR: Allowed range %d..%d' % (lo, hi))
            continue
        return v

未使用的返回值

game_createuser_inputmines_generator方法的返回值未使用。

只在一个地方初始化属性,

属性tablewidthheightmine_numbers都是在构造函数和game_create方法中初始化的。最好将game_create代码放入构造函数中,以便只进行一次初始化。毕竟,它是一个构造函数,因此游戏在其中创建是有意义的。

避免幻数

看起来,如果一个单元格包含9,那么它就是一个地雷。最好是避免神奇的数字,而是使用常量。申报

代码语言:javascript
复制
class Minesweeper:
    CLEAR = 0
    MINE = 9

然后检查单元格是否包含地雷写入。

代码语言:javascript
复制
self.table[i][j] == Minesweeper.MINE

董事会代表

我不清楚为什么板表示(table)被初始化为一维数组,然后改为二维数组。为什么不从一开始就把它变成二维的?

minmax

计数地雷

使用minmax以下列方式计数地雷:

代码语言:javascript
复制
def complete_table(self):
    width, height, table = self.width, self.height, self.table
    for i in range(height):
        for j in range(width):
            if table[i][j] == Minesweeper.MINE:
                continue
            table[i][j] = 0
            for i2 in range(max(0, i - 1), min(i + 2, height)):
                for j2 in range(max(0, j -1), min(j + 2, width)):
                    if table[i2][j2] == Minesweeper.MINE:
                        table[i][j] += 1

minmax用于边界检查是一种常见的模式。第一行只是缩短代码,这样self就不必在任何地方重复。

倾向于以机器友好的格式存储数据

如果某些输入必须以某种方式转换才能被计算机使用,那么它应该以转换后的格式存储。这样,每次使用数据时都不必重复转换。

例如,使用基于1的索引输入user_columnuser_row .这很好,因为这对人类来说是有意义的。但是对于Python来说,基于0的索引更方便,所以一旦从用户读取值,就应该立即进行转换。转换仅仅意味着从它们中减去1。

user_reveal属性也是如此。它存储的序列如下:

代码语言:javascript
复制
['0101', '0201', '0404']

但是它应该以Python友好的格式存储,如下所示:

代码语言:javascript
复制
[(0, 0), (1, 0), (3, 3)]

不要两次存储数据

user_rowuser_column在第一个回合之后与user_reveal列表的最后一个元素相同。这允许我们删除user_rowuser_column属性,而是通过引用user_reveal[-1]获取相同的数据。

不要延迟返回

end_game中有以下内容:

代码语言:javascript
复制
if ...:
    end_game = True
    ...
elif ...:
    end_game = True
    ...
else:
    end_game = False

最好用以下方式来表达

代码语言:javascript
复制
if ...:
    ...
    return True
if ...:
    ...
    return True
return False

因为它使代码流“更直”。

避免嵌套函数

嵌套函数有其用途,但它们也使代码更难理解。海事组织,应该避免这样做。

名称

最后但并非最不重要的是,许多对象的名称可以改进。对于方法和函数,最好包括一个动词来使名称“active”。以下是我建议的改名:

  • first_turn => run_first_turn
  • print_table => print_minefield
  • mines_generator => place_mines
  • mine_numbers => mine_count
  • user_input => read_location
  • end_game => is_game_over
  • user_reveal => revealed_locations (对于集合类型,您希望名称以S结尾)
  • adjacent_zero => reveal_safe_locations
  • reveal_mine => reveal_all_mines
  • complete_table => place_mine_counts
  • table => minefield

最终代码

代码语言:javascript
复制
import itertools
import random

# Minesweeper
# -----------
# Minesweeper is a solitaire game in which the goal is to reveal all
# mines on a board. The Minesweeper class implements the game. It has
# the following attributes:
#
# * width: width of board
# ...
# * minefield: board representation
#
# This example shows how the class should be used:
#
#     ms = Minesweeper()
#     while True:
#         ms.game_create()
#         ...

def prompt_int(name, lo, hi):
    while True:
        s = input(f'Enter {name} [{lo}..{hi}]: ')
        try:
            v = int(s)
        except ValueError:
            print('ERROR: Try again, number only')
            continue
        if not (lo <= v <= hi):
            print('ERROR: Allowed range %d..%d' % (lo, hi))
            continue
        return v

class Minesweeper:
    CLEAR = 0
    MINE = 9
    def __init__(self, width = 9, height = 10, mine_count = 12):
        self.revealed_locations = []
        print(f'Default size is {width}*{height}, {mine_count} mines')
        default_size = input('Play default size? [Y/n]: ')
        if default_size.lower() == 'n':
            self.width = prompt_int('width', 0, 99)
            self.height = prompt_int('height', 0, 99)
            self.mine_count = prompt_int('number of mines',
                                           0, self.width * self.height - 1)
        else:
            self.width = width
            self.height = height
            self.mine_count = mine_count
        self.minefield = [[Minesweeper.CLEAR] * self.width
                      for _ in range(self.height)]

    def read_location(self):
        while True:
            s = input('Enter {[column][row]} in 4 digits eg. 0105: ')
            if len(s) != 4:
                print('ERROR: Only 4 digits allowed')
                continue
            try:
                row = int(s[2:]) - 1
                column = int(s[:2]) - 1
            except ValueError:
                print('ERROR: Try again, number only')
                continue
            if not (0 <= row < self.height):
                print('ERROR: Row out of range')
            elif not (0 <= column < self.width):
                print('ERROR: Column of range')
            elif (row, column) in self.revealed_locations:
                print('ERROR: Already revealed')
            else:
                break
        self.revealed_locations.append((row, column))

    def place_mines(self):
        locs = set(itertools.product(range(self.height), range(self.width)))
        locs -= {self.revealed_locations[-1]}
        locs = random.sample(locs, self.mine_count)
        for row, column in locs:
            self.minefield[row][column] = Minesweeper.MINE

    def place_mine_counts(self):
        width, height, minefield = self.width, self.height, self.minefield
        for i in range(height):
            for j in range(width):
                if minefield[i][j] == Minesweeper.MINE:
                    continue
                minefield[i][j] = Minesweeper.CLEAR
                for i2 in range(max(0, i - 1), min(i + 2, height)):
                    for j2 in range(max(0, j -1), min(j + 2, width)):
                        if minefield[i2][j2] == Minesweeper.MINE:
                            minefield[i][j] += 1

    def reveal_safe_locations(self, row, column):
        width, height, minefield = self.width, self.height, self.minefield
        if minefield[row][column] == Minesweeper.CLEAR:
            for i in range(max(0, row - 1), min(row + 2, height)):
                for j in range(max(0, column - 1), min(column + 2, width)):
                    if (i, j) not in self.revealed_locations:
                        self.revealed_locations.append((i, j))
                        if minefield[i][j] == Minesweeper.CLEAR:
                            self.reveal_safe_locations(i, j)

    def run_first_turn(self):
        self.read_location()
        self.place_mines()
        self.place_mine_counts()
        row, column = self.revealed_locations[-1]
        self.reveal_safe_locations(row, column)

    def print_minefield(self):
        print('\n'*10)
        for row in range(self.height + 1):
            cell = '|'
            for column in range(self.width + 1):
                if row == 0 and column == 0:
                    cell += ' .|'
                elif row == 0:
                    cell += f'{column:2}|'
                elif column == 0:
                    cell += f'{row:2}|'
                elif (row - 1, column - 1) in self.revealed_locations:
                    cell += f'{self.minefield[row-1][column-1]:2}|'
                else:
                    cell += '{:>3}'.format('|')
            print(cell)

    def reveal_all_mine(self):
        for i in range(self.height):
            for j in range(self.width):
                if self.minefield[i][j] == Minesweeper.MINE:
                    self.minefield[i][j] = 'XX'
                    if (i, j) not in self.revealed_locations:
                        self.minefield[i][j] = '**'
                        self.revealed_locations.append((i, j))

    def is_game_over(self):
        row, column = self.revealed_locations[-1]
        if self.minefield[row][column] == Minesweeper.MINE:
            self.reveal_all_mines()
            self.print_minefield()
            print('YOU LOSE!')
            return True
        unmined_locations_count = self.width * self.height - self.mine_count
        if len(self.revealed_locations) == unmined_locations_count:
            self.reveal_all_mines()
            self.print_minefield()
            print('YOU WIN!')
            return True
        return False

    def restart_game(self):
        restart = input('Restart? [y/N]: ')
        return restart.lower() == 'y'

def main():
    while True:
        ms = Minesweeper()
        ms.print_minefield()
        ms.run_first_turn()
        while not ms.is_game_over():
            ms.print_minefield()
            ms.read_location()
            row, column = ms.revealed_locations[-1]
            ms.reveal_safe_locations(row, column)
        if not ms.restart_game():
            break

if __name__ == '__main__':
    main()
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/234725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档