python猜数字游戏
本帖最后由 charlian 于 2022-6-15 13:39 编辑from os import write
import random
from statistics import mode
import string
import os
import pyautogui
# 根据游戏级别埋藏数字
def burynumber(lv):
number = 0
for i in range(10):
if i + 1 == lv:
number = random.randint(1, lv * 100)
return number
#根据游戏积分提升游戏级别
def uplevel(integral):
lv = 1
for i in range(10):
if integral >= 100:
lv = 10
break
elif integral >= (lv + i) * 10 and integral <= (lv + i + 1) * 10:
lv = lv + i
return lv
# 游戏说明
def gamecaption():
print("游戏时可输入以下游戏指令:")
print("exit 或 quit 退出游戏(不保存游戏数据)。")
print("save 保存游戏数据的同时退出游戏。")
print('reset 游戏数据重置。')
print("hint,消耗5点游戏积分购买埋藏数字区间提示(上下区间均为1~25)。")
print("buy,消耗2点游戏积分购买额外猜数次数(未消耗永久有效),额外猜数次数上限为10次,需消耗低于10次才能再次购买。")
print("buy2,消耗10点游戏积分购买永久猜数次数(永久有效),永久猜数次数上限为3次。")
print("cls,清空屏幕!\n")
def game():
bret = 0
try:
f = open("gamedata.txt")
bret = True
f.close()
except IOError:
bret = False
print("游戏数据为空,新建游戏数据……")
f = open("gamedata.txt", 'w')
f.close()
integral = 10# 游戏积分,初始为10
ncount = 10# 猜数字次数,初始为10
lv = 1# 游戏级别,初始为1
gamestate = 0# 游戏状态,根据不同值处理不同事件 1:保存游戏数据退出游戏 2:不玩了 3:游戏积分小于0 GAME OVER 4:游戏数据重置 重新开始
buyncount = 0# 额外猜数次数,初始为0,未消耗永久有效
buyncount2 = 0# 额外永久猜数次数,初始为0,永久有效
num = ' '# 猜的数字
count = 0# 第几轮猜数游戏
if bret == False:
# 文件不存在,写入初始数据
integral_str = '游戏积分:' + '%d' % integral
lv_str = '游戏级别:' + '%d' % lv
buyncount_str = '额外猜数次数:' + '%d' % buyncount
buyncount2_str = '额外永久猜数次数:' + '%d' % buyncount2
with open("gamedata.txt", "w") as f:
f.write(integral_str)
f.write('\n')
f.write(lv_str)
f.write('\n')
f.write(buyncount_str)
f.write('\n')
f.write(buyncount2_str)
f.write('\n')
f.close()
else:
# 读取游戏数据
with open("gamedata.txt", 'r') as f:
str = f.readlines()
f.close()
# print(str)
integral_str = str.split(':').replace('\n', '')
lv_str = str.split(':').replace('\n', '')
buyncount_str = str.split(':').replace('\n', '')
buyncount2_str = str.split(':').replace('\n', '')
# print('游戏积分:%s' % integral_str)
# print('游戏级别:%s' % lv_str)
# print('额外猜数次数:%s' % buyncount_str)
# print('额外永久猜数次数:%s' % buyncount_str)
integral = int(integral_str)
lv = int(lv_str)
buyncount = int(buyncount_str)
buyncount2 = int(buyncount2_str)
while integral >= 0:
count += 1
print('\n-----------------------第%d轮猜数游戏-----------------------' % count)
gamecaption()
ncount = 10
lv = uplevel(integral)
print('您目前游戏积分:%d' % integral)
print('您目前游戏级别:%d' % lv)
print('您目前额外猜数次数:%d' % buyncount)
print('您目前永久猜数次数:%d' % buyncount2)
number = burynumber(lv)
# print("埋藏的数字为:%d" % number)
if buyncount != 0:
ncount += buyncount
if buyncount2 != 0:
ncount += buyncount2
print('您目前游戏级别:%d级,游戏积分达到升级条件时会自动升级,游戏级别限制为10级' % lv)
print('已埋藏好数字,数字区间范围在1~%d之间,您有%d次猜数次数。\n猜对奖励10点游戏积分,未猜对扣除1点游戏积分。'
'\n每轮猜数游戏结束将判定游戏积分,游戏积分低于0,则GAME OVER!' % (
lv * 100, ncount))
while ncount != 0:
print('剩余猜数次数:%d' % ncount)
num = input('请猜数:')
if num == 'buy':
n = int(input('2点游戏积分 / 额外猜数次数,您想买多少次:'))
if n * 2 <= integral:
if buyncount + n > 10:
if buyncount + n < 10:
print('购买失败!额外猜数次数存储上限为10次!您目前额外猜数次数:%d,还可购买%d次额外猜数次数' % (buyncount, 10 - buyncount))
else:
print('您目前额外猜数次数已达上限,无法继续购买!')
else:
if integral - n * 2 < 11:
print('购买失败!请预留至少10点游戏积分!您目前游戏积分:%d' % integral)
else:
integral -= n * 2
buyncount += n
ncount += buyncount
print('您消耗%d点游戏积分购买%d次额外猜数次数,您目前游戏积分:%d' % (n * 2, n, integral))
else:
print('游戏积分不足,购买失败!')
if num == 'buy2':
n = int(input('请输入购买次数, 10点游戏积分 / 额外永久猜数次数:'))
if n * 2 <= integral:
if buyncount2 + n > 3:
print('购买失败!额外永久猜数次数存储上限为3次!您目前额外永久猜数次数:%d,还可购买%d次额外永久猜数次数' % buyncount2, 10 - buyncount2)
else:
if integral - n * 10 < n * 10 + 10:
print('购买失败!请预留至少10点游戏积分!您目前游戏积分:%d' % integral)
else:
integral -= n * 2
buyncount2 += n
ncount += buyncount2
print('您消耗%d点游戏积分购买%d次额外永久猜数次数,您目前游戏积分:%d' % (int(n) * 2, int(n), integral))
else:
print('游戏积分不足,购买失败!')
if num == 'save':
integral_str = '游戏积分:' + '%d' % integral
lv_str = '游戏级别:' + '%d' % lv
buyncount_str = '额外猜数次数:' + '%d' % buyncount
buyncount_str2 = '额外永久猜数次数:' + '%d' % buyncount2
with open("gamedata.txt", "w") as f:
f.write(integral_str)
f.write('\n')
f.write(lv_str)
f.write('\n')
f.write(buyncount_str)
f.write('\n')
f.write(buyncount_str2)
f.write('\n')
f.close()
gamestate = 1
break
elif num == 'exit' or num == 'quit':
gamestate = 2
break
elif num == 'reset':
gamestate = 4
os.remove('gamedata.txt')
break
elif num == 'hint':
min = random.randint(1, 25)
max = random.randint(1, 25)
number_min = number - min
number_max = number + max
while number_min < 0:
min = random.randint(1, 25)
number_min = number - min
integral -= 5
print('消耗5点游戏积分获取埋藏数字区间提示:埋藏的数字在「%d~%d」之间,剩余游戏积分:%d' % (number_min, number_max, integral))
ncount += 1
elif num == 'cls':
#Pycharm 实现代码清除run标签页(程序输出)界面
#https://blog.csdn.net/u011699626/article/details/122139919
#pyautogui.hotkey('Alt', 'c')
os.system('cls')
ncount += 1
else:
if num.isdigit():
num = int(num)
if num < number:
integral -= 1
print('您猜的数太小了!扣除1点游戏积分,剩余游戏积分:%d' % integral)
elif num > number:
integral -= 1
print('您猜的数太大了!扣除1点游戏积分,剩余游戏积分:%d' % integral)
else:
integral += 10
print('神啦!您居然猜对了!埋藏的数确实是:%d。奖励10点游戏积分,剩余游戏积分:%d' % (number, integral))
gamestate = 0
break
else:
ncount += 1
ncount -= 1
if ncount == 0:
if buyncount != 0:
buyncount = 0
print('很遗憾!您没有猜对数字!埋藏的数字为:%d' % number)
else:
n = ncount - buyncount
if n == 0 and buyncount != 0:
buyncount -= 1
if integral < 0:
gamestate = 3
if gamestate == 1:
print('游戏数据已保存,ByeBye!')
break
elif gamestate == 2:
print('ByeBye!')
break
elif gamestate == 3:
print('您的游戏积分小于0,GAME OVER!')
break
elif gamestate == 4:
print('游戏数据已重置,请重新打开游戏!')
break
if __name__ == "__main__":
game()
修复了2个小bug,已打包成exe,可直接运行。
下载地址:
https://wwt.lanzoum.com/iVs6X06g1dsf
密码:h1ms 我试着逆了一下lz的exe,过程挺曲折的,在此贴出供参考。首先
python pyinstxtractor.py 猜数字游戏.exe
可以看到pyinstxtractor为我们分析出了可能的入口文件:[+] Possible entry point: 猜数字游戏.pyc。接着
uncompyle6 猜数字游戏.pyc > 猜数字游戏.py
报错`ValueError: bad marshal data (unknown type code)`。百度可知解决方案:
`struct.pyc`的magic number肯定是对的,以它为准,替换掉`猜数字游戏.pyc`的magic number即可。
接下来发现这个pyc是python3.10的,所以我们要换用pycdc工具。
./pycdc 猜数字游戏.pyc > 1.py
我们遇到了以下异常:`Unsupported opcode: JUMP_IF_NOT_EXC_MATCH`。反编译得到的代码很少。
根据参考链接1,我们给不支持的opcode加上对应的处理代码,就可以让程序不退出了。
ASTree.cpp
// temporary solution
case Pyc::JUMP_IF_NOT_EXC_MATCH_A:
case Pyc::RERAISE_A:
case Pyc::WITH_EXCEPT_START:
break;
但是这种做法得到的代码错误太多了,并不可靠。如果想进行下一步的分析,只能:
1. 等pycdc的维护者更新代码。
2. 成为pycdc的维护者😡。
3. 用pycdas拿到反汇编码,自己读:`./pycdas 猜数字游戏.pyc > 1.txt`。
最后我看了一下得到的代码,基本上和lz给出的源码吻合。 非常感谢提供的代码,我学习了一下。
# 根据游戏级别埋藏数字
def burynumber(lv):
number = 0
for i in range(10):
if i + 1 == lv:
number = random.randint(1, lv * 100)
return number
不知道这个for循环的意义是什么。 感谢分享,页面能有独立的窗口就更好了 猜数游戏还能这样玩,学习了!感谢大佬热心分享!在我的记忆中猜数游戏是“PYTHON从入门到精通”里的那个小小游戏,是我肤浅了。。。 liu2514 发表于 2022-6-14 18:58
猜数游戏还能这样玩,学习了!感谢大佬热心分享!在我的记忆中猜数游戏是“PYTHON从入门到精通”里的那个小 ...
同,我也以为是哪个 xxxxx小小学习下寻Thanks♪(・ω・)ノ 有没有编译好的哇? 拿回去跑跑,谢谢了 非常不错,值得学习 这个还是用易语言 VB做比较友好 本帖最后由 uouobb 于 2022-7-5 17:29 编辑
请猜数:100
您猜的数太小了!扣除1点游戏积分,剩余游戏积分:12
剩余猜数次数:1
请猜数:
是级别问题。。。
页:
[1]
2