猫咪藏在哪个房间

程序说明

本项目我们将用Python语言设计一个计算机程序来模拟“猫咪藏在哪个房间”游戏,该程序中,计算机代替你朋友的角色,而你的角色不变。你将通过一个输入框和几个按钮来操作你的程序,在该项目中,计算机的回应将显示在专用的输出控制台,先不要关心画布的反应。其实,构造每个项目的初始版本时,把一些有用的信息输出到控制台是一种行之有效的开发策略,也就是说,先集中精力实现正确的程序逻辑,然后设法在画布上让信息以某种优美的形式展示出来,因为调试图形输出的逻辑错误有时候极具挑战。程序的文件名称为GuessRoomNumber.py,程序除了要用到前一个项目“杠子老虎鸡虫”已经熟悉的Python语言功能之外,还要使用SimpleGUITk来创建窗口、画布、输入框、按钮等。

通过该项目你可以获得以下能力:

了解二分查找(折半查找)的秘密
理解计算机程序的运行是如何受事件驱动的
增强逻辑思维能力
培养解决问题的能力

编码步骤

我们已经为该小项目提供了一个基本模板,我们建议基础版的“猫咪藏在哪个房间”开发策略为:

1、确定一组存储游戏状态的全局变量。显而易见,你需要一个全局变量来保存程序产生的秘密房间号码,建议该变量的名称为secret_number。为了扩展基础版,你还需要其它一些全局变量。

2、弄清楚如何在给定的low(下限)至high(上限)范围内产生一个随机秘密数字,及秘密房间号。在谈及范围时,我们遵循Python的标准,即包含下限,排除上限,数学上表示为[low, high)。例如[0, 3)意味着该范围包含0、1、2三个数字。我们建议在开始编码时将范围设置为[0,25),即25个房间。

提示:查看random模块包中的函数,你会发现产生这样的随机数非常容易,建议在Python控制台先测试要使用的函数,弄明白它的作用后再往你的项目里添加代码。

3、搞清楚如何利用simpleguitk模块包创建一个文本输入框。你将使用该文本输入框来获取游戏玩家输入的猜测数字。

4、编写事件处理函数guess_room_number(input),参数input保存着玩家输入的猜测值,将该值与秘密房间号进行比较并输出恰当的回应。注意,input为字符串类型,因此在比较之前,你必须将其转化为整型数字。如果玩家猜中了房间号,除了输出恰当的信息之外,请补充输出“请点击房间按钮重新开始游戏”,之后玩家再猜,均输出“请点击房间按钮重新开始游戏”。

提示:课程视频中我们介绍过字符串转化为整型数字的方法。

5、至此,玩家可以无限制的猜测下去,直到猜对为止,猜中后如果希望继续玩一把,必须关闭程序,然后重新运行程序。

6、编写new_game()函数,将产生秘密房间号的代码移到该函数中,也就是说,调用new_game()函数将会计算秘密房间号并将其赋值给一个全局变量,该函数也应当输出一些恰当的信息提示玩家。完成该函数后,你就可以在启动窗口的代码之前调用new_game()。

以上为“猫咪藏在哪个房间”游戏的最初级版本,下面为你的项目添加额外的功能,为了获得满分,你必须完成2个增强的功能:

第1个增强功能:使用simpleguitk模块包添加重新启动游戏的按钮,这样你就无需在玩家猜中后先关闭程序,然后重新运行程序。你必须添加三个按钮:“25个房间”、“36个房间”、“100个房间”,从而允许玩家选择秘密房间号的范围。玩家在游戏运行的任何时刻点击任何一个按钮将重新开始一轮游戏并输出恰当的信息。每个按钮的事件处理函数要为秘密房间号的上限范围(应当是一个全局变量)设置对应的值,然后调用new_game()在新的范围内重新设置秘密房间号,最后设置标志新一轮游戏已经开始的全局变量为True。

在玩该游戏时,可能你已经注意到,如果猫咪藏在25个房间中的某一个,即猜测的范围为[0,25),首先猜12是一个好注意,如果计算机的回应为“太小了”,秘密房间号一定在[13,25)范围内,然后最好猜19,以此类推。这种每次缩小一半猜测范围的技术就是计算机科学领域中著名的二分查找算法。

第2个增强功能:为游戏程序添加限制玩家猜测次数的功能,每次猜测后,你的程序应当补充输出剩余的猜测机会,一旦玩家用完了规定的猜测机会,玩家失败,游戏程序输出相应的提示信息,玩家如果想继续游戏,必须点击房间按钮。

如果玩家按照二分查找策略来猜测,在[low, high)范围内,要保证玩家在n次之内猜中,n必须为满足2 ** n >= high - low + 1的最小整数。因此,对于范围[0,25),n为5,[0,36),n为6,[0,100),n为7,我们可以在三个按钮的事件处理函数中为表示剩余猜测机会的全局变量赋予相应的值(5、6、7),当然我们也可以利用math.log and math.ceil函数通过low和high计算n。

游戏程序初次启动时,猜测的范围应当为[0,25),一轮游戏结束后(玩家猜中后或玩家用完了猜测机会),应提示玩家点击房间按钮开始新一轮游戏,如果玩家此时没有点击按钮继续进行猜测(直接按回车,或输入新的数字再按回车),应当提示玩家点击房间按钮开始新一轮游戏。只要玩家点击房间按钮,当前一轮游戏无条件结束,在按钮载明的范围立即开始新一轮游戏。

项目模板

# "猫咪藏在哪个房间"小项目程序模板
# 程序的输入来自按钮和输入框import simpleguitk as gui  # 简单用户图形界面接口
import random              # 用random.randrange(range_high)随机生成猫咪要藏的房间号
import math                # 用math.log(x, base)计算猜中所需的最少次数# 初始化全局变量
secret_number = None                         # 每个回合计算机随机产生的秘密数字
range_high = 25                              # 房间号的上限new_game_started = True                      # 新一轮游戏是否开始
remaining_guesses = 0                        # 一个回合剩余的猜测次数canvas_height = 500                          # 画布高度,单位为像素
canvas_width = 500                           # 画布宽度,单位为像素room_list = []                               # 所有房间的状态
cat_image = gui.load_image("http://202.201.225.74/video/PythonResoure/ProjectResource/images/project2/cat.png")  # 猫咪图片def new_game():"""启动或重新启动游戏的辅助函数"""# 添加你自己的代码后删除passpass# 初始化所有房间,请不要修改以下3行代码room_list.clear()for i in range(range_high):room_list.append(False)# 为控制面板的控件定义事件处理函数
def range25():# 设置房间号的范围为[0,25)并重新开始游戏# 添加你自己的代码后删除passpassdef range36():# 设置房间号的范围为[0,36)并重新开始游戏# 添加你自己的代码后删除passpassdef range100():# 设置房间号的范围为[0,100)并重新开始游戏# 添加你自己的代码后删除passpasssecret_number = random.randrange(25)def guess_room_number(user_input):"""文本输入框控件的处理函数,也是游戏的主要逻辑实现的函数"""# 添加你自己的代码后删除passpassupdate_room(int(user_input))      # 更新房间状态,请不要修改这行代码# 创建窗口
frame = gui.create_frame("猫咪藏在哪个房间", canvas_width, canvas_height)# 注册控件事件
# 添加你自己的代码后删除pass
pass# 调用new_game初始化一些全局变量并向终端输出新一轮游戏开始的相关信息
new_game()# 请别忘记对照评分标准核对你最终完成的程序
# 请不要修改这行之后的所有代码
def draw(canvas):"""画布显示刷新事件的处理函数"""# 请不要修改该函数root = int(math.sqrt(range_high))length = canvas_width // rootfor row in range(root):for col in range(root):index = root * row + coltext_width = frame.get_canvas_textwidth(str(index), 12, 'sans-serif')top_left = [length * col,length * row]top_right = [length * (col + 1),length * row]bottom_right = [length * (col + 1),length * (row + 1)]bottom_left = [length * col,length * (row + 1)]if not room_list[index]:canvas.draw_polygon([top_left, top_right, bottom_right, bottom_left], 1, 'Red', 'Green')canvas.draw_text(str(index), (top_left[0] + (length - text_width) / 2, top_left[1] + length - 2), 12, 'White', 'sans-serif')else:canvas.draw_polygon([top_left, top_right, bottom_right, bottom_left], 1, 'Red', 'Blue')canvas.draw_text(str(index), (top_left[0] + (length - text_width) / 2, top_left[1] + length - 2), 12, 'White', 'sans-serif')if index != secret_number:no_cat = frame.get_canvas_textwidth('没有猫', 12, 'sans-serif')canvas.draw_text('没有猫', (top_left[0] + (length - no_cat) / 2, top_left[1] + length / 2), 12, 'White', 'sans-serif')else:canvas.draw_image(cat_image, [256,256], [512,512],[top_left[0] + length//2,top_left[1]+length//2 ],[length, length])def update_room(guess):"""更新房间的状态"""# 请不要修改该函数if guess == secret_number:for i in range(range_high):room_list[i] = Trueelif guess < secret_number:if remaining_guesses == 0:for i in range(range_high):room_list[i] = Trueelse:for i in range(0,guess + 1):room_list[i] = Trueelse:if remaining_guesses == 0:for i in range(range_high):room_list[i] = Trueelse:for i in range(guess, range_high):room_list[i] = Trueframe.set_draw_handler(draw)      # 注册显示刷新处理事件,每秒调用draw函数60次
frame.start()                     # 启动窗口框架

以下为完整代码

# "猫咪藏在哪个房间"小项目程序模板
# 程序的输入来自按钮和输入框import simpleguitk as gui  # 简单用户图形界面接口
import random              # 用random.randrange(range_high)随机生成猫咪要藏的房间号
import math                # 用math.log(x, base)计算猜中所需的最少次数# 初始化全局变量
secret_number = None                         # 每个回合计算机随机产生的秘密数字
range_high = 25                              # 房间号的上限
new_game_started = True                      # 新一轮游戏是否开始
remaining_guesses = 0                        # 一个回合剩余的猜测次数
canvas_height = 500                          # 画布高度,单位为像素
canvas_width = 500                           # 画布宽度,单位为像素
room_list = []                               # 所有房间的状态
cat_image = gui.load_image("http://202.201.225.74/video/PythonResoure/ProjectResource/images/project2/cat.png")  # 猫咪图片def new_game():"""启动或重新启动游戏的辅助函数"""# 添加你自己的代码后删除passglobal secret_number, new_game_startedif new_game_started == True:new_game_started = Falserange25()else:secret_number = random.randrange(range_high)# 初始化所有房间,请不要修改以下3行代码room_list.clear()for i in range(range_high):room_list.append(False)# 为控制面板的控件定义事件处理函数
def range25():# 设置房间号的范围为[0,25)并重新开始游戏global range_high, remaining_guessesprint('新的一轮游戏开始')print('您应当在0和24之间猜一个数字')print('您拥有5次机会')range_high = 25remaining_guesses = int(math.log(25, 2)) + 1new_game()def range36():# 设置房间号的范围为[0,36)并重新开始游戏global range_high, remaining_guessesprint('新的一轮游戏开始')print('您应当在0和36之间猜一个数字')print('您拥有6次机会')range_high = 36remaining_guesses = int(math.log(36, 2)) + 1new_game()def range100():# 设置房间号的范围为[0,100)并重新开始游戏global range_high, remaining_guessesprint('新的一轮游戏开始')print('您应当在0和100之间猜一个数字')print('您拥有7次机会')range_high = 100remaining_guesses = int(math.log(100, 2)) + 1new_game()secret_number = random.randrange(25)secret_number = random.randrange(25)def guess_room_number(user_input):"""文本输入框控件的处理函数,也是游戏的主要逻辑实现的函数"""global remaining_guessesuser_input = int(user_input)if remaining_guesses == 0:print("机会已用完,请点击房间号重新开始")else:if user_input == secret_number:print("正确,请点击房间号重新开始")elif user_input > secret_number:print("太大了")remaining_guesses -= 1print('您还有' + str(remaining_guesses) + '机会')elif user_input < secret_number:print("太小了")remaining_guesses -= 1print('您还有' + str(remaining_guesses) + '机会')update_room(int(user_input))      # 更新房间状态,请不要修改这行代码# 创建窗口
frame = gui.create_frame("猫咪藏在哪个房间", canvas_width, canvas_height)# 注册控件事件
# 添加你自己的代码后删除pass
frame.add_button("25个房间", range25, 100)
frame.add_button("36个房间", range36, 100)
frame.add_button("100个房间", range100, 100)
frame.add_input("猜测房间", guess_room_number, 100)# 调用new_game初始化一些全局变量并向终端输出新一轮游戏开始的相关信息
new_game()def draw(canvas):"""画布显示刷新事件的处理函数"""root = int(math.sqrt(range_high))length = canvas_width // rootfor row in range(root):for col in range(root):index = root * row + coltext_width = frame.get_canvas_textwidth(str(index), 12, 'sans-serif')top_left = [length * col,length * row]top_right = [length * (col + 1),length * row]bottom_right = [length * (col + 1),length * (row + 1)]bottom_left = [length * col,length * (row + 1)]if not room_list[index]:canvas.draw_polygon([top_left, top_right, bottom_right, bottom_left], 1, 'Red', 'Green')canvas.draw_text(str(index), (top_left[0] + (length - text_width) / 2, top_left[1] + length - 2), 12, 'White', 'sans-serif')else:canvas.draw_polygon([top_left, top_right, bottom_right, bottom_left], 1, 'Red', 'Blue')canvas.draw_text(str(index), (top_left[0] + (length - text_width) / 2, top_left[1] + length - 2), 12, 'White', 'sans-serif')if index != secret_number:no_cat = frame.get_canvas_textwidth('没有猫', 12, 'sans-serif')canvas.draw_text('没有猫', (top_left[0] + (length - no_cat) / 2, top_left[1] + length / 2), 12, 'White', 'sans-serif')else:canvas.draw_image(cat_image, [256,256], [512,512],[top_left[0] + length//2,top_left[1]+length//2 ],[length, length])def update_room(guess):"""更新房间的状态"""if guess == secret_number:for i in range(range_high):room_list[i] = Trueelif guess < secret_number:if remaining_guesses == 0:for i in range(range_high):room_list[i] = Trueelse:for i in range(0,guess + 1):room_list[i] = Trueelse:if remaining_guesses == 0:for i in range(range_high):room_list[i] = Trueelse:for i in range(guess, range_high):room_list[i] = Trueframe.set_draw_handler(draw)      # 注册显示刷新处理事件,每秒调用draw函数60次
frame.start()                     # 启动窗口框架

python项目之猫咪藏在哪个房间相关推荐

  1. 猫咪藏在哪个房间python作业_猫咪生气躲进房间,众人找到后,猫咪一脸疑问:听说你们在找我...

    以前,养猫的人不多,而且养猫的方式也不一样,人们每天忙得都顾不上和猫玩耍,观察它们.所以就说猫咪养不熟,高冷什么的,这就是因为不了解所以产生的误解. 如今,养猫的人越来越多,而且人们的空闲时间也多了, ...

  2. 猫咪藏在哪个房间python_猫咪总喜欢把自己藏在不可思议的地方,这是为什么呢?...

    相信有很多猫咪的主人都会有这样有趣的发现,有很多猫咪就像是活在水中那样,就像是液体般一样的存在.有很多猫咪都会藏在一些非常不可思议的地方,就好像一些小盒子里面,还有一些用来装东西的小容器里面.这样就会 ...

  3. 猫咪藏在哪个房间python项目_铲屎官必读:猫咪为什么都喜欢藏在盒子里?

    原标题:铲屎官必读:猫咪为什么都喜欢藏在盒子里? Защитные механизмы 保护机制 Каждому животному присущи разные защитные механизмы ...

  4. python游戏猫咪藏在哪个房间_tes体系风格已经定型,EZ加猫咪似乎成唯一解,在藏还是真没了?...

    #瓦罗兰特电竞赛# 对于tes这支队伍来说,在打完了MSC之后,似乎所有的人都认为,这就是LPL的头号种子,甚至说是世界上最强的那支队伍.然而实际上呢?经过了大半个夏季赛的考验之后,似乎tes的问题暴 ...

  5. python猫咪藏在哪个房间_Python分析Airbnb北京房源,去北京旅游到底应该住哪里?...

    说来惭愧,阿花花从小到大,除了在妈妈肚子里的时候去过一次北京,就再也没有和这片土地发生过关系了.好想吃北京的爆肚.涮肉.豆汁儿.烤鸭.炸酱面.卤煮火烧.豌豆黄.麻团.驴打滚.焦圈balabala... ...

  6. 猫咪藏在哪个房间python_盘点:猫咪玩“躲猫猫”喜欢藏的几个地方,这下再也不愁找不到了...

    一觉醒来,家里的猫不在身边,将被子掀起来自己找,还是没有,床底下?依旧没有,然后找遍整个房间--不知道诸位铲屎官有没有这样的经历,猫咪"人间蒸发",然后又神不知鬼不觉地出现在身边, ...

  7. 猫咪藏在哪个房间python_猫咪在家总是藏起来,这是怎么回事?

    猫在一个环境里挑选领地和藏身处的本能.明晃晃的领地不能和藏身处是一个地方,就像机关暗道不能和卧室是连在一起一样.比较隐蔽的地方给新到环境的猫一种感觉安全又可控的空间.客厅对于小猫来说,就像一个巨大的宫 ...

  8. 猫咪藏在哪个房间python_你家猫咪喜欢藏在哪睡觉?这只猫咪选择了一个奇怪的地方...

    嗨,大家好,这里是小仙女和猫的原创文章,欢迎大家关注哦!你家猫咪喜欢藏在哪睡觉?这只猫咪选择了一个奇怪的地方. 猫咪的性格独立,情绪喜怒无常,一举一动经常不按章法来,它们的行为总是让人猜不透,即使是养 ...

  9. 猫咪藏在哪个房间python_小猫咪自闭躲进塑料袋,更多家里意想不到的地方猫咪都可以藏在哪里?...

    猫友sunshine家的橘猫,一言不发就躲进塑料袋 喂喂,你变成一团纸巾吗 旁边的白猫一脸淡定 还有哪些地方意想不到可以藏猫的? 感觉他们在商议晚上大吉大利,今晚吃鸡. 地方一,这些藏身之处一定是有特 ...

最新文章

  1. LoadRunner 技巧之 手动关联与预关联
  2. 一文看尽4种SLAM中零空间的维护方法
  3. 七天入门linux,RHCE认证学习笔记-第七天
  4. 如何利用CSS给同一个网页中的超链接设置设置不同的样式?
  5. java int与integer的区别
  6. 1079. Total Sales of Supply Chain (25)
  7. java语言中的 继承_Java语言有关继承的总结
  8. UIView常见方法总结
  9. 组件使用中的细节点02
  10. Spring Boot集成Redis缓存之RedisTemplate的方式
  11. 宏定义中有浮点数_GEO是什么?还可以定义新的数据类型吗?
  12. 为什么设置行高文字就能居中
  13. 树形$dp$学习笔记
  14. ORACLE数据库测试题(一)
  15. Android开发之onCreate
  16. itemCF matlab算法,推荐系统初探:ItemCF算法实现知乎问题推荐
  17. 打造全能网管——网吧常用工具软件介绍
  18. 1 100的奇数和编程php,用PHP求出1—100中的基数之和,偶数之和
  19. jspx框架使用总结-页面开发
  20. websocket ping pong

热门文章

  1. inter uhd graphics630显卡驱动_现有190个UHD频道
  2. python常用的库
  3. 人工智能Java SDK:安全帽检测
  4. 安装Matplotlib
  5. Linux命令行安卓模拟器,linux下安卓模拟器加速
  6. 107、基于51单片机智能快递柜收取件存储柜快递箱自助存储柜系统设计
  7. python快捷键设置_Pycharm快捷键配置
  8. 思科Telnet远程登录
  9. thinking in asp 之二 高端大气上档次
  10. mc4 安卓x86_现代战争4:决战时刻 免谷歌版