闲暇时刻写了一个python模拟扫雷脚本
本帖最后由 三滑稽甲苯 于 2020-9-30 17:00 编辑首先上代码:
# 导入库
from random import randint as rnd
from os import system
from time import sleep
# 定义MineField类
class MineField():
def __init__(self, x, y, n):# 初始化
if x <= 36 and y <=36 and n <x*y:self.x = x; self.y = y; self.n = n# 判断行列数是否满足要求并记录
else: raise ValueError('Invalid input.')
self.field = []# 游戏数据存储
for i in range(x*y): self.field.append({'type': 0, 'status': 0})# 初始化数据
self.flagged = 0; self.known = 0; self.status = 0
self.theme = (10*('-'), (' ', '1', '2', '3', '4', '5', '6', '7', '8', '*'), 10*('!'))# 使用theme以便修改呈现效果
'''
type status self.status
0 nothing 0 unknown -1 defeat
1-8 numbers1 known 0 unknown
9 mine 2 flagged 1 success
'''
def surroundings(self, n):# 获得给点方格附近方格
result = set()
y = n // self.x; x = n % self.x
possible = {(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)}
for d in possible:
tx = d + x; ty = d + y
if 0 <= tx < self.x and 0 <= ty < self.y: result.add(ty * self.x + tx)
return result
def generate(self):# 生成雷
mines = set(); count = 0; self.known = 0
x = self.x; y = self.y
while count < self.n:
tmp = rnd(0, x*y)
while tmp in mines: tmp = rnd(0, x*y)
mines.add(tmp); count += 1
# print('Field_gen:', self.field)# debug
print(mines)
for mine in mines:
self.field['type'] = 9
for surrounding in self.surroundings(mine):
if self.field['type'] != 9: self.field['type'] += 1# ; print(surrounding,'+= 1')# debug
def show(self):# 呈现
s = f'{self.flagged}/{self.n}\n '
index = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
t = 0
for i in range(self.x): s += index
for y in range(self.y):
s += '\n'; s += index
for x in range(self.x):
info = self.field
s += self.theme]]
t += 1
return s
def (self, n):# 打开某未知方格
t = self.field['type']
if t == 0:
self.field['status'] = 1; self.known += 1
for surrounding in self.surroundings(n):
if self.field['status'] == 0:
self.open_unknown(surrounding)
# print('Open #', surrounding)# debug
elif t == 9: self.field['status'] = 1; self.known += 1; self.status = -1
else: self.field['status'] = 1; self.known += 1
def open_known(self, n):# 打开某已知方格附近的方格
surroundings = self.surroundings(n)
flagged = 0
for surrounding in surroundings:
if self.field['status'] == 2: flagged += 1
if flagged == self.field['type']:
for surrounding in surroundings:
if self.field['status'] == 0: self.open_unknown(surrounding)
def open(self, n):# 判断情况,调用open_known抑或open_unknown
t = self.field['status']
if t == 0: self.open_unknown(n)
elif t == 1: self.open_known(n)
else: pass
if self.known + self.n == self.x * self.y: self.status = 1
def flag(self, n):# 标记雷
self.flagged += 1 - self.field['status']
self.field['status'] = 2 - self.field['status']
def convert(s):# 行列数为字母时转化为数字
if '0' <= s <= '9': return int(s)
elif 'a' <= s <= 'z': return ord(s) - ord('a') + 10
elif 'A' <= s <= 'Z': return ord(s) - ord('A') + 10
else: raise ValueError('Invalid input.')
m = MineField(15,15,6)# 生成MineField实例(15*15,6颗雷)
m.generate()# 生成雷
while m.status == 0:# 主循环
system('cls')# 清空界面
print(m.show())# 显示
i = input('>')# 输入指令
cmd = i.split()
# 处理指令
if cmd == 'open' or cmd == 'o':
target = convert(cmd) + convert(cmd) * m.x
m.open(target)
elif cmd == 'flag' or cmd == 'f':
target = convert(cmd) + convert(cmd) * m.x
m.flag(target)
elif cmd == 'exit': break
elif cmd == 'help':
system('cls')
print('Help:\nopen: open/o x y\nflag: flag/f x y\nexit: exit')
input('Press enter to continue...')
else:
system('cls')
print('Invalid!')
input('Press enter to continue...')
if m.status == 1:# 扫雷成功
system('cls')
print(m.show())
for c in 'You ': print(c, end='', flush=True); sleep(0.15)
for c in 'WON!': print(c, end='', flush=True); sleep(0.5)
print()
input('Press enter to exit...')
elif m.status == -1:# 扫雷失败
system('cls')
print(m.show())
for c in 'You ': print(c, end='', flush=True); sleep(0.15)
for c in 'LOST!': print(c, end='', flush=True); sleep(0.5)
print()
if input('Inspect?(y)') == 'y':
m.theme = ((' ', '1', '2', '3', '4', '5', '6', '7', '8', '*'), (' ', '1', '2', '3', '4', '5', '6', '7', '8', '*'), (' ', '1', '2', '3', '4', '5', '6', '7', '8', '*'))
print(m.show())
input('Press enter to exit...')
注意:行、列不可超过36。
首次使用输入'help'来获取帮助。
欢迎学习,转载请注明出处。
截图:
.py文件(包含视频演示/历史版本):https://www.lanzoux.com/b00zs1ehg 密码:ei8c
github:https://github.com/PRO-2684/MineSweeping
更新日志
8.30 首版
9.12 支持更多的行、列(10->36)
9.30 更详尽的注释 2079898548 发表于 2020-8-30 13:21
看的我人傻了,我觉得吧,竖排唉太近了,还有-换成*会不会更好看点
*默认是雷{:1_896:}
你可以自行修改p12, 121行theme变量来实现自定义图标显示:victory: 看的我人傻了,我觉得吧,竖排唉太近了,还有-换成*会不会更好看点{:301_999:} 感觉好难啊 来学习一下! 前来学习 有点意思 有Python交流群吗?我是新手刚入门,想找一群志同道合的朋友一起学习 正在学习,还一头雾水的样子 感谢分享
页:
[1]
2