|
|
|
|
# _*_ coding:utf-8 _*_
|
|
|
|
|
# @Time:2023/6/29 9:37
|
|
|
|
|
# @File:X1.py
|
|
|
|
|
# @SoftWare:PyCharm
|
|
|
|
|
# @Project:MS
|
|
|
|
|
# @author:yzf
|
|
|
|
|
from tkinter import scrolledtext, END # 滚动框, 滚动框自动下拉到最后一行
|
|
|
|
|
from pymouse import PyMouse # 模拟鼠标自动点击
|
|
|
|
|
import tkinter as tk # UI界面
|
|
|
|
|
import threading # 多线程任
|
|
|
|
|
import pyautogui # 获取窗口位置信息
|
|
|
|
|
import random # 随机数
|
|
|
|
|
import time # 应用sleep函数睡眠
|
|
|
|
|
|
|
|
|
|
# 全局变量
|
|
|
|
|
TIME_LIMIT = 10 # 扫雷限时
|
|
|
|
|
CLOCK = 0 # 扫雷用时记录
|
|
|
|
|
TIMER_RUN = False # 计时器是否启动
|
|
|
|
|
GAME_OVER = False # 游戏是否结束
|
|
|
|
|
curData = [] # 方块状态数组
|
|
|
|
|
initData = [] # 初始布雷方案数组
|
|
|
|
|
SHOW_BOARD_STATE = [] # 是否计算周围雷数数组
|
|
|
|
|
BUTTONS = {} # 方块按钮字典
|
|
|
|
|
BOARD_ROWS = 20 # 扫雷方块行数
|
|
|
|
|
BOARD_COLS = 20 # 扫雷方块列数
|
|
|
|
|
MINES = 96 # 总的雷数
|
|
|
|
|
mine_number = 0 # 剩余的雷数
|
|
|
|
|
DIGIT_WIDTH = 5 # 数字的大小
|
|
|
|
|
DIGIT_HEIGHT = 1
|
|
|
|
|
FACE_WIDTH = 40 # 笑脸的大小
|
|
|
|
|
FACE_HEIGHT = 40
|
|
|
|
|
mine_number_x = 40 # 计雷数器的位置,不管窗口怎么变,计雷数器位置不变
|
|
|
|
|
mine_number_y = 20
|
|
|
|
|
HEADER_WIDTH = 20 * 40 # 头部栏的大小
|
|
|
|
|
HEADER_HEIGHT = 40
|
|
|
|
|
RIGHT_WIDTH = 300 # 右侧栏宽度,固定不变
|
|
|
|
|
BOTTOM_HEIGHT = 150 # 底部栏高度,固定不变
|
|
|
|
|
face_x = 20 * 40 / 2 # 脸图的位置
|
|
|
|
|
face_y = 20
|
|
|
|
|
clock_x = 20 * 40 - 40 # 计时器的位置
|
|
|
|
|
clock_y = 20
|
|
|
|
|
MINE_WITH_FLAG = 0 # 是地雷被标旗子的按钮总数
|
|
|
|
|
NO_MINE_BUT_FLAG = 0 # 不是地雷但是被标旗子的按钮总数
|
|
|
|
|
OPEN_BUTTONS = 0 # 所有被打开的按钮的总数,等于所有按钮数-所有雷数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def init_mine_map(mines):
|
|
|
|
|
global BOARD_ROWS, BOARD_COLS, initData, curData # 全局变量行数,列数,布雷方案
|
|
|
|
|
initData = [[0 for i in range(BOARD_COLS)] for j in range(BOARD_ROWS)] # 无雷初始化,先列后行
|
|
|
|
|
for i in random.sample(range(BOARD_COLS * BOARD_ROWS), mines):
|
|
|
|
|
initData[i // BOARD_COLS][i % BOARD_COLS] = 'M' # 在BOARD_COLS*BOARD_ROWS范围中随机生成mines个雷
|
|
|
|
|
# 雷行下标为随机数除以列数取整,雷列下标为随机数对列数取模
|
|
|
|
|
curData = initData
|
|
|
|
|
return curData, initData
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set_random_state(): # 随机设置状态
|
|
|
|
|
global curData, BOARD_COLS, BOARD_ROWS
|
|
|
|
|
randomList = ['E', 'M', 'B', 'X', 'F', 1, 2, 3, 4, 5, 6, 7, 8] # 随机状态数列
|
|
|
|
|
curData = [[0 for j in range(BOARD_COLS)] for i in range(BOARD_ROWS)] # 矩阵初始化
|
|
|
|
|
for r in range(BOARD_ROWS):
|
|
|
|
|
for c in range(BOARD_COLS):
|
|
|
|
|
r_index = random.randint(0, len(randomList) - 1) # 获取随机下标
|
|
|
|
|
curData[r][c] = randomList[r_index] # 随机赋予状态
|
|
|
|
|
return curData
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def around(x, y): # 返回对应坐标周围八个方块坐标列表
|
|
|
|
|
global BOARD_ROWS, BOARD_COLS
|
|
|
|
|
return [(i, j) for i in range(max(0, x - 1), min(BOARD_ROWS - 1, x + 1) + 1) # 行号最小为0不为负,最大BOARD_ROWS-1
|
|
|
|
|
for j in range(max(0, y - 1), min(BOARD_COLS - 1, y + 1) + 1) if i != x or j != y] # 不包括自己,即x行y列方块
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_mine_num_data(): # BOARD_ROWS行数,BOARD_COLS列数
|
|
|
|
|
global initData, curData, BOARD_COLS, BOARD_ROWS
|
|
|
|
|
mineNumData = initData # 拷贝布雷方案
|
|
|
|
|
for i in range(BOARD_ROWS):
|
|
|
|
|
for j in range(BOARD_COLS):
|
|
|
|
|
if initData[i][j] == 'M': # 如果为雷,点击则游戏结束,不计算周围的雷数
|
|
|
|
|
continue
|
|
|
|
|
else: # 如果不为雷,则把这个位置值改成周围的雷数0-8
|
|
|
|
|
aroundxy = around(i, j)
|
|
|
|
|
minesum = 0
|
|
|
|
|
for r, c in aroundxy:
|
|
|
|
|
if initData[r][c] == 'M':
|
|
|
|
|
minesum += 1
|
|
|
|
|
mineNumData[i][j] = minesum # 把值改成周围雷的数量
|
|
|
|
|
curData = mineNumData
|
|
|
|
|
return curData, mineNumData
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
init_mine_map(MINES) # 初始化initData赋值给curData并输出
|
|
|
|
|
for i in range(BOARD_ROWS):
|
|
|
|
|
print(curData[i])
|
|
|
|
|
print('\n')
|
|
|
|
|
set_random_state() # 随机设置curData并输出
|
|
|
|
|
for i in range(BOARD_ROWS):
|
|
|
|
|
print(curData[i])
|
|
|
|
|
print('\n')
|
|
|
|
|
get_mine_num_data() # 获取mineNumData赋值给curData并输出,需要调用around函数
|
|
|
|
|
for i in range(BOARD_ROWS):
|
|
|
|
|
print(curData[i])
|
|
|
|
|
print('\n')
|