python小游戏——猜单词游戏(Hangman)

目录

一、游戏介绍

二、开发环境

三、界面设计

四、工作原理

①、开始时,程序完成以下工作:

②、玩家点击 Guess! 按钮时,程序做以下工作。

五、代码实现

①、开始部分

ⅰ、从文件加载词汇表

ⅱ、将随机获取的单词(秘密词)去除换行符

ⅲ、让小人的所有部分都不可见

ⅳ、根据秘密词中的字母个数显示相同数目的横线

②、玩家点击 Guess! 按钮

ⅰ、如果是一个字母检查猜到的字母

ⅱ、如果是一个词: 

 

六、完整代码:



 

python小游戏——猜单词游戏(Hangman)

一、游戏介绍

猜单词游戏 

Hangman(“上吊的人”之意),是一个双人猜单词游戏。一位玩家想一个字,另一位尝试猜该玩家所想的字中的每一个字母。

要猜的字以一列横线表示,让玩家知道该字有多少个字母。如果猜字的玩家猜中其中一个字母,另一位便须于该字母出现的所有位置上写上该字母。如果猜的字母没有于该字中出现,另一位玩家便会画吊颈公仔的其中一笔。游戏会在以下情况结束:

 

  • 猜字的玩家猜完所有字母,或猜中整个字
  • 另一位玩家画完整幅图:

python小游戏——猜单词游戏(Hangman)_第1张图片

这幅图其实是设计得像一个吊颈的人。。

这幅图的本质各有不同;有玩家在游戏开始前画绞刑架,在游戏期间画人的身体(传统上先画头,再画躯干,然后是左手、同右手,最后是左脚、右脚)。

有玩家在开始时不会画任何图,将绞刑架的每一笔当作游戏的一部分,这种做法实际上给予玩家更多机会。

——摘抄自维基百科(https://zh.wikipedia.org/wiki/%E7%8C%9C%E5%96%AE%E8%A9%9E%E9%81%8A%E6%88%B2)

二、开发环境

  • GUI工具:   PyQt5
  • python:Python 3.9.2

三、界面设计

显示了上吊小人的各个部分,不过程序运行时,我们首先会隐藏小人的所有部分。玩家猜错一个字母时,就会显示这个小人的下一部分。如果整个小人都显示出来,玩家可以再猜一次,
然后游戏结束!
玩家猜一个字母时,程序会查看这个字母是否在秘密词中。如果确实是秘密词中的字母,就把这个字母显示出来。在窗口下方,玩家可以看见到目前为止他猜过的所有字母。玩家什么时候都可以尝试猜词。

python小游戏——猜单词游戏(Hangman)_第2张图片

四、工作原理

①、开始时,程序完成以下工作:

  • 从文件加载词汇表;
  • 从每行的末尾去除换行符;
  • 让小人的所有部分都不可见; 
  • 从词汇表随机选择一个词;
  • 根据秘密词中的字母个数显示相同数目的横线。 

②、玩家击 Guess! 按钮时,程序做以下工作。

  • 检查猜的是一个字母还是一个词。
  • 如果是一个字母: 

         ■   检查秘密词,查看是否包含这个字母。
         ■   如果玩家猜对了,用这个字母取代横线,显示这个字母出现在什么位置。
         ■   如果玩家猜错了,显示小人的另一部分。
         ■   把猜出的字母增加到 Previous guesses 显示区。
         ■   查看玩家是否已经猜出单词(猜出所有字母)。

  • 如果是一个词: 

         ■   检查玩家猜得正确与否。
         ■   如果正确,显示一个对话框,指出 You Won!(你赢了!)并开始新游戏。

查看玩家是不是已经没有机会了,如果是,显示一个对话框,指出 You Lost (你失败了),并显示这个秘密词到底是什么。

五、代码实现

①、开始部分

ⅰ、从文件加载词汇表

f = open("words.txt", "r")
self.lines = f.readlines()
f.close()

ⅱ、将随机获取的单词(秘密词)去除换行符

self.currentword = random.choice(self.lines)  #随机获取单词
self.currentword = self.currentword.strip()

ⅲ、让小人的所有部分都不可见

 self.pieces = [self.head, self.body, self.leftarm, self.leftleg, self.rightarm, self.rightleg]
 self.gallows = [self.line1, self.line2, self.line3, self.line4]     

   #隐藏人
        for i in self.pieces:
            i.setFrameShadow(QtWidgets.QFrame.Plain)
            i.setHidden(True)
        for i in self.gallows:
            i.setFrameShadow(QtWidgets.QFrame.Plain)

ⅳ、根据秘密词中的字母个数显示相同数目的横线

#如果不是字母,直接显示该字
def dashes(word):
    letters = "abcdefghijklmnopqrstuvwxyz"
    new_string = ''
    for i in word:
        if i in letters:
            new_string += "-"
        else:
            new_string += i

    return new_string

②、玩家击 Guess! 按钮

ⅰ、如果是一个字母检查猜到的字母

 #输入是单个字母来排查进行可能出现在词的位置
        if len(guess) == 1:
            if guess in self.currentword:
                locations = find_letters(guess, self.currentword)
                self.word.setText(replace_letters(str(self.word.text()), locations, guess))

                if str(self.word.text()) == self.currentword:
                    self.win()

            else:
                self.wrong()
       

   如果玩家猜对了,这个字母出现在什么位置

  find_letters() 函数会查找某个字母在单词中出现的所有位置,并返回一个包含这些位置的列表。

def find_letters(letter, a_string):
    locations = []
    start = 0

    while a_string.find(letter, start, len(a_string)) != -1:
        location = a_string.find(letter,start, len(a_string))
        locations.append(location)
        start = location + 1

    print("locations = ", locations)
    return locations

 如果玩家猜对了,用这个字母取代该秘密字横线位置

replace_letters() 函数从 find_letters() 得到列表,用正确的字母替换这些位置上的横线

def replace_letters(string, locations, letter):
    new_string = ''
    for i in range(0, len(string)):
        if i in locations:
            new_string = new_string + letter
        else:
            new_string = new_string + string[i]
    print("new_string = ", new_string)        
    return new_string

 

 

ⅱ、如果是一个词: 

         ■   检查玩家猜得正确与否。
         ■   如果正确,显示一个对话框,指出 You Won!(你赢了!)并开始新游戏。

 else:  #若不是单字直接判断
            if guess == self.currentword:
                self.win()
            else:
                self.wrong()

 

六、完整代码:

import sys
from PyQt5 import QtCore,QtGui, QtWidgets,uic
import random

form_class = uic.loadUiType("myhangman.ui")[0] 

#发现字母
def find_letters(letter, a_string):
    locations = []
    start = 0

    while a_string.find(letter, start, len(a_string)) != -1:
        location = a_string.find(letter,start, len(a_string))
        locations.append(location)
        start = location + 1

    print("locations = ", locations)
    return locations

def replace_letters(string, locations, letter):
    new_string = ''
    for i in range(0, len(string)):
        if i in locations:
            new_string = new_string + letter
        else:
            new_string = new_string + string[i]
    print("new_string = ", new_string)        
    return new_string


#初始值显示的状态,如果不是字母,直接显示该字
def dashes(word):
    letters = "abcdefghijklmnopqrstuvwxyz"
    new_string = ''
    for i in word:
        if i in letters:
            new_string += "-"
        else:
            new_string += i

    return new_string

class MyWidget(QtWidgets.QMainWindow, form_class):
    def __init__(self, parent = None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)

        #相应操作关联
        self.btn_guess.clicked.connect(self.btn_guess_clicked)
        self.actionExit.triggered.connect(self.menuExit_selected)
        
        self.pieces = [self.head, self.body, self.leftarm, self.leftleg, self.rightarm, self.rightleg]
        self.gallows = [self.line1, self.line2, self.line3, self.line4]
        self.pieces_shown = 0
        self.currentword = ""
        
        #获取文件的的单字
        f = open("words.txt", "r")
        self.lines = f.readlines()
        f.close()
        self.new_game()

    def new_game(self):
        self.guesses.setText("") 
        self.currentword = random.choice(self.lines)  #随机获取单词
        self.currentword = self.currentword.strip()

        #隐藏人
        for i in self.pieces:
            i.setFrameShadow(QtWidgets.QFrame.Plain)
            i.setHidden(True)
        for i in self.gallows:
            i.setFrameShadow(QtWidgets.QFrame.Plain)

        self.word.setText(dashes(self.currentword))
        self.pieces_shown = 0
        
    def btn_guess_clicked(self):
        guess = str(self.guessBox.text())
        if str(self.guesses.text()) != "":
            self.guesses.setText(str(self.guesses.text()) + " , "+ guess)
        else:
            self.guesses.setText(guess)

        #输入是单个字母来排查进行可能出现在词的位置
        if len(guess) == 1:
            if guess in self.currentword:
                locations = find_letters(guess, self.currentword)
                self.word.setText(replace_letters(str(self.word.text()), locations, guess))

                if str(self.word.text()) == self.currentword:
                    self.win()

            else:
                self.wrong()
        else:  #若不是单字直接判断
            if guess == self.currentword:
                self.win()
            else:
                self.wrong()
        self.guessBox.setText("")

    def win(self):
        QtWidgets.QMessageBox.information(self, "Hangman", "You win!")
        self.new_game()

    def wrong(self):
        #显示小人
        self.pieces_shown += 1
        for i in range(self.pieces_shown):
            self.pieces[i].setHidden(False)
        if self.pieces_shown == len(self.pieces):
            message = "You lose. The word was " + self.currentword
            QtWidgets.QMessageBox.warning(self, "Hangman", message)
            self.new_game()

    def menuExit_selected(self):
        self.close()

app = QtWidgets.QApplication(sys.argv)
myapp = MyWidget(None)
myapp.show()
app.exec_()
            

代码实测可用:其资源压缩包下载: https://download.csdn.net/download/qq_41070511/19666764

视频链接:https://www.bilibili.com/video/BV1Fb4y1o7pi?p=1&share_medium=iphone&share_plat=ios&share_source=QQ&share_tag=s_i×tamp=1623983007&unique_k=GSKCCW

 

你可能感兴趣的:(python,python,游戏,pyqt5)