您的位置:首页 > 编程语言 > Python开发

Python入门面向对象练习:简单封装一个猜诗词小游戏程序

2019-03-12 20:56 344 查看
版权声明:随便整,没版权 https://blog.csdn.net/bosslay/article/details/88429054

注:本篇为家庭作业,只适合新手练习。

玩法介绍:
以面向编程的特性之一封装为主写一个关于诗词的小游戏,分为三种玩法,程序里会随机加载一首古诗词,根据提示对出上下句或者猜出作者或者猜出作者年代,如回答正确,得十分,如不正确则不得分。(此篇仅有两种玩法。)

***封装一(poem)***自定义诗词输出格式

class Poem:
def __init__(self):
self.title = ''
self.dynasty = ''
self.author = ''
self.sentences = []

def __str__(self):
return '{}\n{}\n{}\n{}'.format(
self.title, self.dynasty, self.author, '\n'.join(self.sentences))

***封装二(load_poems)***从本地载入诗词

from enum import Enum
from poem import Poem
Poems = []
def load():
class ReadState(Enum):
Nothing = 0
Title = 1
DynastyAndAuthor = 2
Sentences = 3
print('开始加载诗歌')
f = open('poems.txt', encoding='utf-8')
lines = f.readlines()
state = ReadState.Title
poem = None
for ln in lines:
line = ln.strip()
if len(line) > 0:
try:
if line.startswith('-'):
if poem is not None:
Poems.append(poem)
print('.', end='')
poem = Poem()
poem.title = line.lstrip('-')
state = ReadState.DynastyAndAuthor
continue
if state == ReadState.DynastyAndAuthor:
dynasty_author = line.split(' ')
poem.dynasty = dynasty_author[0]
poem.author = dynasty_author[-1]
state = ReadState.Sentences
continue
if state == ReadState.Sentences:
poem.sentences.append(line)
except IndexError as e:
print(line)
print('\n共加载{}首诗歌'.format(len(Poems)))
print()
load()

封装三(class_poem_dynasty)开始编写猜朝代的单类程序

#单独的类,猜朝代玩法
from load_poems import Poems#引入诗词列表
import random#引入随机库
class Dynasty(object):
"""
建立一个猜诗词朝代的数据模型
"""
def __init__(self):##定义初始属性
self.name= '猜朝代'
self.info = '根据诗词作者,名称,内容,猜朝代,猜对+10分,猜错不得分。'
self.poem = ''#当前诗歌,初始值为空
self.answer = ''#正确答案
self.guess_anwser = ''#猜测答案
@staticmethod
def print_line():##定义一个输出下划线的静态函数
print('-'*50)
@staticmethod
def print_double_lines():
print('='*50)#输出双下划綫的静态函数
def display_info(self):##定义一个输出游戏规则的函数
self.print_double_lines()#输出下划线
print(self.name)#输出游戏名称
self.print_line()#输出下划线
print(self.info)#输出游戏规则
def design_question(self):
"""
一个设计具体玩法的函数
:return:
"""
self.print_line()#输出下划线
print('\n')#输出一个换行
poem = Poems.pop(random.randint(0,len(Poems)-1))##随即取出一首诗词,pop函数避免重复
print(f'{poem.title}\n{poem.author}\n')###输出诗词的作者以及诗词名称
sentence = '\n'.join(poem.sentences)#用换行符将诗词内容合并成一个字符串
if len(sentence) > 7:
#如果诗词内容大于7句,不输出全部内容
sentence = '\n'.join(poem.sentences[:7])+'\n...'###将列表切片,只取前七句,后续输出省略号
print(sentence)##输出诗句
self.poem = poem  # 定义当前的诗词,以便后续输出
self.answer = poem.dynasty##定义正确答案,以便后续对比
def input_anwser(self):
"""
定义一个输入答案的函数
:return:
"""
self.guess_anwser = input(f'这首诗个作者是({self.poem.author}),请写入他/她所在的朝代:')#获取输入的猜测
def compare(self):
"""
对比正确答案与猜测答案的函数
:return:
"""
if self.guess_anwser == self.answer:
print('恭喜你,答对了!')
return True
else:
print(f"回答不正确,正确答案为'{self.answer}'")
return False
def display_poem(self):
"""
输出完整诗词的函数
:return:
"""
print(self.poem)##输出完整的诗词
def run(self):
"""
启动游戏的函数
:return:
"""
self.display_info()##输出玩法介绍
self.design_question()###设计问题
self.input_anwser()##获取猜测答案
self.compare()#对比答案
self.display_poem()##输出整首诗词

if __name__== '__main__':
dy = Dynasty()
dy.run()

封装四(class_poem_author)编写猜诗词作者的单类程序

from load_poems import Poems
import random

class Author(object):
"""
一个猜诗词作者的数据模型
"""
def __init__(self):
self.name = '猜诗词作者'
self.info = '根据诗词内容,朝代,名称,猜出诗词作者,猜对+10分,猜错不得分'
self.poem = ''
self.answer = ''
self.guess_anwser = ''
@staticmethod
def print_lines():
print('-'*50)
@staticmethod
def print_double_lines():
print('='*50)
def display_info(self):
self.print_double_lines()
print(self.name)
self.print_lines()
print(self.info)
def design_questions(self):
print('\n')
poem = Poems.pop(random.randint(0,len(Poems)-1))##随机从Poems列表里提取一首诗词,避免重复使用pop函数
print(f'\n{poem.title}\n{poem.dynasty}')#打印诗词名称以及朝代
sentences = '\n'.join(poem.sentences)##将诗词内容用换行符合并为一个字符串
if len(sentences) > 7 :##判断诗词内容是否多于7行,
sentences = '\n'.join(poem.sentences[:7])+'\n....'#如多于7行 ,无需输出全部内容,切片+省略号代替
print(sentences)###输出诗词内容
self.poem = poem##赋值当前诗词给poem  以便后续输出
self.answer = poem.author#定义正确答案,以便后续比较

def input_answer(self):
#获取猜测答案
self.guess_anwser = input(f'这首诗词的名称是《{self.poem.title}》,朝代是({self.poem.dynasty}),请输入诗词作者:')
def compare(self):
if self.answer == self.guess_anwser:
print('回答正确!')
return True
else:
print(f'回答错误!这首诗词的作者是({self.poem.author})')
def display_poem(self):
print(self.poem)
def run(self):
"""
启动程序的函数,给出一个类的实例,将所有函数串连运作起来
:return:
"""
self.display_info()
self.design_questions()
self.input_answer()
self.compare()
self.display_poem()

if __name__ == '__main__':
author1 = Author()
author1.run()

封装五(poem_game)编写一个游戏类的父类数据模型

import random
from load_poems import Poems

class Game(object):
"""
定义一个父类 游戏的数据模型
"""
def __init__(self):
"""初始化函数"""
self.answewr = ''
self.guess_answer = ''
self.poem = ''

@staticmethod
def print_line():##输出下
20000
划线的静态函数
print('-'*50)
@staticmethod
def print_double_line():#输出双下划线的静态函数
print('='*50)
##功能性函数
def display_info(self):
"""输出游戏名称与简介的函数"""
self.print_double_line()#输出双行下划线
print(self.name)#输出当前游戏名称
self.print_line()#输出单行下划线
print(self.info)#输出游戏简介
def design_questions(self):
"""设计具体游戏规则的函数"""
self.print_line()  # 输出下划线
print('\n')  # 输出一个换行
# self.poem = random.choice(Poems)##从诗词列表里随机提取一首诗词
poem = Poems.pop(random.randint(0, len(Poems) - 1))  ##随即取出一首诗词,pop函数避免重复
def input_answer(self):
"""获取玩家输入结果的函数,游戏各异"""
pass
def compare(self):
"""对比玩家猜测与正确答案的函数"""
if self.answer == self.guess_answer:##做出判断
print('回答正确!')
# 返回波尔值 以确定是否加分
return True
else:
print(f'回答错误!正确答案为{self.answer}')
return False
def dispaly_poem(self):
"""输出整首诗词的函数"""
print(self.poem)

def run(self):
"""启动程序,串连运作所有函数的函数"""
self.design_questions()#调用游戏规则函数
self.input_answer()#调用获取玩家输入函数
result = self.compare()#调用判断结果韩束,并且返回一个波尔值 True or False
self.dispaly_poem()#调用输出整首诗词函数
#再次将结果返回到调用run()函数的对象当中
return result

封装六(class_play_game)编写一个玩游戏的数据模型

from class_poem_dynasty import Dynasty#从单独的猜朝代的程序里引入Dynasty数据模型
from class_poem_author import Author#从单独的猜诗人的程序里引入  Author数据模型
class PlayGame(object):
"""
一个模仿玩诗词游戏的数据模型
"""
def __init__(self):
self.games = [Dynasty(),Author()]#定义一个列表,包含两个游戏对象
self.score = 0#定义初始分数为0
def run(self):
"""
功能性函数,用于启动程序
:return:
"""
Author.print_double_lines()#二话不说,先来两条横线
for idx , game in enumerate(self.games):#枚举遍历出游戏对象
print(f'{idx +1}        {game.name}')##输出序列号以及游戏名称
while True:##此处有bug,正在寻找改进方法
index = input('请选择玩法:')#获取玩家选择的序号
if not index.isdigit():#判断是否为数字型
print('请按照序号选择玩法!')
else:
index = int(index)#将字符串转换为整数
while index -1 < 0 or index -1 > len(self.games) -1:#判断是否超出范围
index = input('请按照序号选择玩法:')
game = self.games[index -1]#从列表选择游戏
result = game.run()#获取返回的波尔值,用来判断是否加分
if result:
self.score += 10
Dynasty.print_line()#再来一条横线
print(f'目前得分{self.score}')#输出分值
Author.print_lines()#输出横线,again~!
is_next = input('回车继续,任意字符结束:')#是否要继续玩游戏
if is_next != '':#回车的结果为一个空字符
print('谢谢使用,欢迎再来!')
break
if __name__ == '__main__':

play = PlayGame()
play.run()

输出界面如下

总结

**"""
三种游戏甚至更多有关诗词类的可开发的小游戏中,总结规则如下:
1.建立一个数据模型class类
2.定义初始化函数→基本属性def__init__(包含正确答案,猜测答案,当前诗词的属性值)
3.两个用来输出下划线的静态函数@staticmethod(装饰,非必要,)
4.定义功能性函数:
4.1.def display_info(self)#用于输出游戏名称以及简介
4.2.def design_question(self)用于设计具体的游戏内容
4.3.def input_answer(self)用于获取玩家的输入猜测答案
4.4.def compare(self)用于对比正确答案与猜测答案
4.5.def display_poem(self)用于输出整首完整的诗词
4.6.def run(self) 启动程序,将所有函数串联运作起来

通过以上规则发现,大部分的诗词游戏所需要的函数方法都基本相同,
不一样的函数就在于‘设计游戏规则’以及‘获取猜测答案’这两个函数里,
(以下未能实现,正在改进…)
因而可以建立一个关于诗词游戏的父类,
通过继承关系将父类的方法继承到子类,
也就是每一个单独的诗词游戏(实例)里.
不一样的地方可以子类重写,因此可以减少代码量.
So let’s do it!

“”"
**
BUG: 1.分值无法同步
2. 封装六里获取玩家选取的序号判断有bug

未完

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: