PyQt5 – 数字猜谜游戏

  • Post category:Python

根据你的要求,我会详细讲解Python的PyQt5数字猜谜游戏的完整使用攻略,包含以下几个章节:

  1. 环境准备
  2. PyQT5 简介
  3. 数字猜谜游戏的功能设计与实现
  4. 两条示例说明

1. 环境准备

在开始使用PyQT5开发数字猜谜游戏之前,需要先确保以下几点:

  • Python环境已经安装
  • PyQT5已经安装

如果Python环境不确定是否安装,可以在命令行中输入以下命令进行检查:

python --version

如果Python环境已经安装,会显示Python的版本号。如果没有安装,则需要先安装Python环境。

检查PyQT5是否已安装,可以在命令行中输入以下命令:

pip show PyQt5

如果已经安装,会显示PyQT5的版本号。如果没有安装,则需要先安装PyQT5。

2. PyQT5 简介

PyQT是一个Python库,提供了构建桌面应用程序所需的多个组件和模块。其中,PyQT5是最新版本,支持Python3.x环境。PyQT5包含了大量的组件,可以用于构建各种类型的桌面应用程序,比如窗口应用、工具栏应用、系统托盘应用、游戏等。

使用PyQT5开发程序,需要掌握以下几个基本概念:

  • QApplication:每个PyQT5应用都需要实例化一个QApplication对象,它是整个应用的所在环境。
  • QDialog:对话框是一种最常用的UI组件,表示一个模态窗口,可以用于接受用户输入、显示消息等。
  • QLabel:标签组件可以用于显示静态文本或动态文本,比如显示游戏说明、结果等。
  • QLineEdit:文本框组件可以用于接受用户输入,比如让用户输入猜测的数字。
  • QMessageBox:消息框组件可以用于显示不同类型的消息,比如错误消息、警告消息、询问消息等。
  • QPushButton:按钮组件可以用于响应用户的单击事件,比如“开始游戏”按钮、“重新开始”按钮等。

3. 数字猜谜游戏的功能设计与实现

数字猜谜游戏的主要功能如下:

  • 程序生成一个随机的3位数
  • 用户通过文本框输入猜测的数字
  • 用户点击“猜测”按钮进行猜测
  • 如果猜测错误,则程序会给出提示,告知用户猜测的数字中,有几个数字和位置与答案完全相同,有几个数字和位置不相同但在答案中包含,有几个数字不在答案中
  • 用户可以通过“再来一次”按钮重新开始游戏

下面是一个完整的示例代码,包含上述功能的实现:

# 导入需要的模块
import sys
import random
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QDialog, QLabel, QLineEdit, \
    QMessageBox, QPushButton


class GuessNumberDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle('Guess Number Game')
        self.setFixedSize(300, 200)

        self.numberLabel = QLabel('I have a number between 100 and 999.', self)
        self.numberLabel.move(20, 20)

        self.guessLabel = QLabel('Your guess:', self)
        self.guessLabel.move(20, 60)

        self.guessLineEdit = QLineEdit(self)
        self.guessLineEdit.move(80, 60)
        self.guessLineEdit.setFixedWidth(120)
        self.guessLineEdit.setFocus()

        self.guessButton = QPushButton('Guess', self)
        self.guessButton.move(80, 110)
        self.guessButton.clicked.connect(self.checkGuess)

        self.resetButton = QPushButton('Play Again', self)
        self.resetButton.move(170, 110)
        self.resetButton.clicked.connect(self.resetGame)

        self.resultLabel = QLabel(self)
        self.resultLabel.move(20, 160)
        self.resultLabel.setFixedWidth(260)
        self.resultLabel.setAlignment(Qt.AlignCenter)

        self.numbers = random.sample(range(0, 10), 3)
        self.numberString = ''.join(str(n) for n in self.numbers)

    def checkGuess(self):
        guessText = self.guessLineEdit.text()
        if len(guessText) != 3 or not guessText.isnumeric():
            QMessageBox.warning(self, 'Warning', 'Please enter a 3-digit number.')
            return

        guessNumbers = [int(char) for char in guessText]
        correctPositions = sum([1 for i, n in enumerate(guessNumbers) if n == self.numbers[i]])
        correctNumbers = len(set(guessNumbers) & set(self.numbers)) - correctPositions
        incorrectNumbers = 3 - correctPositions - correctNumbers

        self.resultLabel.setText('Your guess is {}. {} are correct, {} are partial, and {} are incorrect.'
                                  .format(guessText, correctPositions, correctNumbers, incorrectNumbers))

    def resetGame(self):
        self.guessLineEdit.clear()
        self.resultLabel.clear()
        self.numbers = random.sample(range(0, 10), 3)
        self.numberString = ''.join(str(n) for n in self.numbers)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    guessNumberDialog = GuessNumberDialog()
    guessNumberDialog.show()
    sys.exit(app.exec_())

以上代码实现了数字猜谜游戏的主要功能,具体实现细节如下:

  • 在类GuessNumberDialog中,初始化函数__init__中,通过PyQT5的标签组件(QLabel)和文本框组件(QLineEdit),实现了游戏界面的UI设计。
  • 在UI设计中,需要通过按钮组件(QPushButton)响应用户的单击事件,并通过函数checkGuess实现猜测的逻辑。
  • 在函数checkGuess中,通过判断用户输入的数字是否合法,再进行猜测的判断。正确的数字和位置会得到一个“1”,在答案中但不在正确的位置上会得到一个“0.5”,否则会得到一个“0”。
  • 在函数resetGame中,重新生成一个随机三位数字,并清空输入和显示结果。

在实现数字猜谜游戏的过程中,需要掌握PyQT5的常用组件,并学会如何响应用户的操作,进而实现游戏逻辑。

4. 两条示例说明

示例一:修改游戏内容

我们可以通过修改游戏的内容,改变游戏的玩法。例如,将游戏改成“猜单词”,需要在UI设计中修改标签和文本框上的文字,并在checkGuess函数中实现单词判断的逻辑。

class GuessWordDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle('Guess Word Game')
        self.setFixedSize(300, 200)

        self.wordLabel = QLabel('I think of a fruit or vegetable.', self)
        self.wordLabel.move(20, 20)

        self.guessLabel = QLabel('Your guess:', self)
        self.guessLabel.move(20, 60)

        self.guessLineEdit = QLineEdit(self)
        self.guessLineEdit.move(80, 60)
        self.guessLineEdit.setFixedWidth(120)
        self.guessLineEdit.setFocus()

        self.guessButton = QPushButton('Guess', self)
        self.guessButton.move(80, 110)
        self.guessButton.clicked.connect(self.checkGuess)

        self.resetButton = QPushButton('Play Again', self)
        self.resetButton.move(170, 110)
        self.resetButton.clicked.connect(self.resetGame)

        self.resultLabel = QLabel(self)
        self.resultLabel.move(20, 160)
        self.resultLabel.setFixedWidth(260)
        self.resultLabel.setAlignment(Qt.AlignCenter)

        self.word = random.choice(['apple', 'banana', 'carrot', 'celery'])

    def checkGuess(self):
        guessText = self.guessLineEdit.text()
        if guessText not in ['apple', 'banana', 'carrot', 'celery']:
            QMessageBox.warning(self, 'Warning', 'Please enter a valid fruit or vegetable.')
            return

        if guessText == self.word:
            self.resultLabel.setText('Congratulations! You win!')
        else:
            self.resultLabel.setText('Your guess "{}" is incorrect. Try again.'.format(guessText))

    def resetGame(self):
        self.guessLineEdit.clear()
        self.resultLabel.clear()
        self.word = random.choice(['apple', 'banana', 'carrot', 'celery'])

以上代码实现了猜单词游戏的主要功能,可以通过修改标签、文本框文字和随机单词列表,实现各种主题的单词猜测游戏。

示例二:保存游戏记录

我们可以通过添加文件读写功能,将游戏的记录保存到文件中。例如,每次游戏结束后,将猜测的数字和结果记录到文件中,并在游戏开始时读取之前的记录,显示到UI组件上。

class GuessNumberDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle('Guess Number Game')
        self.setFixedSize(300, 200)

        self.numberLabel = QLabel('I have a number between 100 and 999.', self)
        self.numberLabel.move(20, 20)

        self.guessLabel = QLabel('Your guess:', self)
        self.guessLabel.move(20, 60)

        self.guessLineEdit = QLineEdit(self)
        self.guessLineEdit.move(80, 60)
        self.guessLineEdit.setFixedWidth(120)
        self.guessLineEdit.setFocus()

        self.guessButton = QPushButton('Guess', self)
        self.guessButton.move(80, 110)
        self.guessButton.clicked.connect(self.checkGuess)

        self.resetButton = QPushButton('Play Again', self)
        self.resetButton.move(170, 110)
        self.resetButton.clicked.connect(self.resetGame)

        self.resultLabel = QLabel(self)
        self.resultLabel.move(20, 160)
        self.resultLabel.setFixedWidth(260)
        self.resultLabel.setAlignment(Qt.AlignCenter)

        self.numbers = random.sample(range(0, 10), 3)
        self.numberString = ''.join(str(n) for n in self.numbers)

        self.loadGame()

    def checkGuess(self):
        # 判断猜测是否正确,如果正确,记录到文件中
        # 界面显示结果
        # ...
        self.saveGame()

    def resetGame(self):
        # 游戏重新开始时,加载上次猜测的数字和结果,并显示到UI组件上
        # ...
        self.loadGame()

    def saveGame(self):
        guessText = self.guessLineEdit.text()
        resultText = self.resultLabel.text()
        record = '{}\n{}'.format(guessText, resultText)
        with open('guess_number_records.txt', 'a') as f:
            f.write(record)

    def loadGame(self):
        records = []
        try:
            with open('guess_number_records.txt', 'r') as f:
                records = f.readlines()
        except FileNotFoundError:
            pass

        lastRecord = records[-1] if records else ''
        if lastRecord:
            lastGuess, lastResult = lastRecord.split('\n')
            lastGuess = lastGuess.strip()
            lastResult = lastResult.strip()

            self.guessLineEdit.setText(lastGuess)
            self.resultLabel.setText(lastResult)
            self.numbers = [int(char) for char in lastGuess]
            self.numberString = ''.join(str(n) for n in self.numbers)
        else:
            self.resultLabel.setText('Let\'s play a game! I have a number between 100 and 999.')

以上代码实现了游戏记录的保存和读取功能,可以通过添加文件读写相关的代码,实现各种游戏数据的保存和使用。