我的Python扫雷函数在应该是常量值时返回不同的值

问题描述 投票:0回答:1

我使用 Python 类、random 和 Numpy 模块编写了一个扫雷游戏。通过选择难度,它会在 Numpy 的帮助下设置并创建棋盘的尺寸。然后,它也会根据选择的难度,全面随机设置地雷。

当您进行游戏时,特定功能会检查您选择踩踏的点周围的 8 个单元格,并返回那里存在的地雷数量。

经过一些修复后,我最后一次运行代码,希望它能正常工作......我得到的回报是在进行不同的比赛后,同一位置的不同值。

我检查了每个函数以及程序在每次运行时所采用的路径,但我仍然无法找到它在哪里犯了这个错误。

由于该网站的代码相当大,因此这里是 OnlineGDB 链接:

https://onlinegdb.com/JxHI-lRdP

快速预览:

def setupMines(self, mines: int = 15) -> None:
        if len(self.board) <= 5: raise ValueError('Board too small')
        self.mines = set()
        while len(self.mines) < mines:
            rand_row = randint(0, self.__dimension - 1)
            rand_col = randint(0, self.__dimension - 1)
            self.mines.add((rand_row, rand_col))
        for row, col in self.mines:
            self.board[row][col] = 1
    
    def makePlay(self, row: int, col: int) -> None:
        self.row = row - 1
        self.column = col - 1
        if self.board[row - 1][col - 1] == 1:
            for i in 'You stepped on a mine!\nEnding program...':
                print(i, end='')
                wait(0.07)
            exit(0)
        elif self.board[row - 1][col - 1] == 0:
            self.board[row - 1][col - 1] = -1
            self.printBoard()
        self.EndGame()
    
    def checkPlay(self) -> int:
        tip = 0
        aux_row = -1
        for _ in range(3):
            aux_column = -1
            for _ in range(3):
                if (self.row + aux_row, self.column + aux_column) in self.mines: tip += 1
                aux_column += 1
            aux_row += 1
        return tip
python numpy class matrix minesweeper
1个回答
0
投票

这是因为在 printBoard 方法中调用 checkPlay 方法的方式。 每次调用 checkPlay 时,它都会重新检查当前位置(self.row、self.column)周围的地雷,该位置可能会随着您进行新的游戏而改变。这会导致同一位置在不同的比赛后可能会给出不同的地雷数量。

确保每个单元格的地雷数量计算一次并存储; checkPlay 结果被正确存储和打印的位置:

import numpy as np
from random import randint
from time import sleep as wait
from sys import exit

class MineBoard:
    def __init__(self) -> None:
        self.dialogue()

    def setupBoard(self, dimension: int = 9):
        if not isinstance(dimension, int):
            raise TypeError(f'Expected a type: int, instead got type:{type(dimension)}')
        self.__dimension = dimension
        self.board = np.zeros(shape=(dimension, dimension))
        self.revealed_board = np.full((dimension, dimension), '-')
    
    def setupMines(self, mines: int = 15) -> None:
        if len(self.board) <= 5: raise ValueError('Board too small')
        self.mines = set()
        while len(self.mines) < mines:
            rand_row = randint(0, self.__dimension - 1)
            rand_col = randint(0, self.__dimension - 1)
            self.mines.add((rand_row, rand_col))
        for row, col in self.mines:
            self.board[row][col] = 1
    
    def makePlay(self, row: int, col: int) -> None:
        self.row = row - 1
        self.column = col - 1
        if self.board[row - 1][col - 1] == 1:
            for i in 'You stepped on a mine!\nEnding program...':
                print(i, end='')
                wait(0.07)
            exit(0)
        elif self.board[row - 1][col - 1] == 0:
            self.revealed_board[row - 1][col - 1] = self.checkPlay()
            self.printBoard()
        self.EndGame()
    
    def checkPlay(self) -> int:
        tip = 0
        for i in range(max(0, self.row - 1), min(self.__dimension, self.row + 2)):
            for j in range(max(0, self.column - 1), min(self.__dimension, self.column + 2)):
                if (i, j) in self.mines: tip += 1
        return tip
    
    def printBoard(self) -> str:
        for i in range(self.__dimension):
            print('\n')
            for j in range(self.__dimension):
                print(self.revealed_board[i][j], end='\t')
    
    def EndGame(self) -> None:
        scanner = list()
        for i in self.board:
            auxiliar = [x for x in i if x == -1]
            scanner += auxiliar
        if len(scanner) == 0:
            for i in 'Congratulations, you beat the game!!':
                print(i, end='')
                wait(0.3)
            exit(0)
        else: return

    def dialogue(self) -> None:
        print('''\n\nMINESWEEPER\n\n''')
        wait(1.0)
        print('''Tip: Maximize the terminal.\n''')
        wait(1.5)
        choice = int(input('''CHOOSE YOUR DIFFICULTY:
(1) - Easy
(2) - Medium
(3) - Hard

--->> '''))
        match choice:
            case 1:
                self.setupBoard()
                self.setupMines()
            case 2:
                self.setupBoard(15)
                self.setupMines(40)
            case 3:
                self.setupBoard(20)
                self.setupMines(75)
        
        while True:
            print(f'\n\nMake your play! Choose a line and a column! {self.__dimension} by {self.__dimension}')
            row = int(input('\nLine: '))
            col = int(input('Column: '))
            self.makePlay(row=row, col=col)

MineBoard()

添加 self.revealed_board 来存储棋盘的显示状态; makePlay 使用 checkPlay 的结果更新 self.revealed_board; checkPlay 计算一次指定单元格周围的地雷数量,printBoard 打印 self.revealed_board 中的值。

这可确保每个单元格的地雷计数计算并存储一次,从而防止不同玩法中同一位置的值不一致的问题。

玩得开心!

© www.soinside.com 2019 - 2024. All rights reserved.