python实现简易数独小游戏

news/2024/11/15 7:09:04/

起源

既然“数独”有一个字是“数”,人们也往往会联想到数学,那就不妨从大家都知道的数学家欧拉说起,但凡想了解数独历史的玩家在网络、书籍中搜索时,共同会提到的就是欧拉的“拉丁方块(Latin square)”。

拉丁方块的规则:每一行(Row)、每一列(Column)均含1-N(N即盘面的规格),不重复。这与前面提到的标准数独非常相似,但少了一个宫的规则

近代发展

数独起源于18世纪初瑞士数学家欧拉等人研究的拉丁方阵(Latin Square)。19世纪80年代,一位美国的退休建筑师格昂斯(Howard Garns)根据这种拉丁方阵发明了一种填数趣味游戏,这就是数独的雏形。20世纪70年代,人们在美国纽约的一本益智杂志《Math Puzzles and Logic Problems》上发现了这个游戏,当时被称为填数字(Number Place),这也是公认的数独最早的见报版本。1984年一位日本学者将其介绍到了日本,发表在Nikoli公司的一本游戏杂志上,当时起名为“数字は独身に限る”(すうじはどくしんにかぎる),就改名为“数独”(すうどく),其中“数”(すう)是数字的意思,“独”(どく)是唯一的意思。后来一位前任香港高等法院的新西兰籍法官高乐德(Wayne Gould)在1997年3月到日本东京旅游时,无意中发现了 [2]  。他首先在英国的《泰晤士报》上发表,不久其他报纸也发表,很快便风靡全英国,之后他用了6年时间编写了电脑程序,并将它放在网站上(这个网站也就是著名的数独玩家论坛),后来因一些原因,网站被关闭,幸好数独大师Glenn Fowler恢复了数据,玩家论坛有了新处所。在90年代国内就有部分的益智类书籍开始刊登,南海出版社在2005年出版了《数独1-2》,随后日本著名数独制题人西尾彻也的《数独挑战》也由辽宁教育出版社出版。《北京晚报》、《扬子晚报》、《羊城晚报》、《新民晚报》、《成都商报》等等报纸媒体也先后刊登了数独游戏。

基础解法

排除法(摒除法)

摒除法:用数字去找单元内唯一可填空格,称为摒除法,数字可填唯一空格称为排除法 (Hidden Single)。

根据不同的作用范围,摒余解可分为下述三种:

数字可填唯一空格在「宫」单元称为宫排除(Hidden Single in Box),也称宫摒除法。

数字可填唯一空格在「行」单元称为行排除法(Hidden Single in Row),也称行摒除法。

数字可填唯一空格在「列」单元称为列排除法(Hidden Single in Column),也称列摒除法。

唯一余数法

唯一余数法:用格位去找唯一可填数字,称为余数法,格位唯一可填数字称为唯余解(Naked Single)。余数法是删减等位群格位(Peer)已出现的数字的方法,每一格位的等位群格位有 20 个

 

完整代码如下:

import random
import math
import pygame
matrix = []
sds = []def get_random_unit():_num_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]random.shuffle(_num_list)return _num_listdef print_grid(arr):for i in range(9):sds.append(arr[i])def get_row(row):row_arr = []for v in matrix[row]:if v == 0:continuerow_arr.append(v)return row_arrdef get_col(col):col_arr = []for i in range(9):val = matrix[i][col]if val == 0:continuecol_arr.append(matrix[i][col])return col_arrdef get_block(num):col_arr = []seq = num % 3col_end = 9 if seq == 0 else seq * 3row_end = int(math.ceil(num / 3) * 3)for i in range(row_end - 3, row_end):for j in range(col_end - 3, col_end):val = matrix[i][j]if val != 0:col_arr.append(matrix[i][j])return col_arrdef get_block_seq(row, col):col_seq = int(math.ceil((col + 0.1) / 3))row_seq = int(math.ceil((row + 0.1) / 3))return 3 * (row_seq - 1) + col_seqdef get_enable_arr(row, col):avail_arr = get_random_unit()seq = get_block_seq(row, col)block = get_block(seq)row = get_row(row)col = get_col(col)unable_arr = list(set(block + row + col))for v in unable_arr:if v in avail_arr:avail_arr.remove(v)return avail_arrdef main():can_num = {}count = 0for i in range(9):matrix.append([0] * 9)num_list = get_random_unit()for row in range(3):for col in range(3):matrix[row][col] = num_list.pop(0)num_list = get_random_unit()for row in range(3, 6):for col in range(3, 6):matrix[row][col] = num_list.pop(0)num_list = get_random_unit()for row in range(6, 9):for col in range(6, 9):matrix[row][col] = num_list.pop(0)box_list = []for row in range(9):for col in range(9):if matrix[row][col] == 0:box_list.append({'row': row, 'col': col})i = 0while i < len(box_list):count += 1position = box_list[i]row = position['row']col = position['col']key = '%dx%d' % (row, col)if key in can_num:enable_arr = can_num[key]else:enable_arr = get_enable_arr(row, col)can_num[key] = enable_arrif len(enable_arr) <= 0:i -= 1if key in can_num:del (can_num[key])matrix[row][col] = 0continueelse:matrix[row][col] = enable_arr.pop()i += 1print_grid(matrix)if __name__ == "__main__":main()# --------------------华丽の分割线--------------------ac_num = 0
pausE = True
difficulty = 3from tkinter import *
from tkinter import ttk
import time
import pygame as py def setDiff(difF):global difficultyglobal difftry:difficulty = int(difF)diff.destroy()except:pass
diff = Tk()
diff.title('难度选择')
diff.geometry('300x90')
diff.resizable(0,0)
Label(diff,text='选择你要挑战的难度!(0~9)',font=('微软雅黑',9)).pack()
cmb = ttk.Combobox(diff)
cmb.pack()
cmb['value'] = (0,1,2,3,4,5,6,7,8,9)
Button(diff,text='我选好了',command=lambda:setDiff(cmb.get())).pack()
diff.mainloop()
window = Tk()
window.title('数独')
window.geometry('390x500')
window.resizable(0,0)
begin_time = 0
steps = 0
rights = 0
wrongs = 0
dwc = difficulty*9
ac_name = Nonelist = range(1,82)
try:ran = random.sample(list,dwc)
except:if difficulty > 9:ran = random.sample(list,9)elif difficulty < 0:ran = random.sample(list,1)print('难度输入出现问题 你将无法通关')
try:py.mixer.init()py.mixer.music.load('bg.mp3')py.mixer.music.play(-1)
except:print('未检测到名为 bg.mp3  的背景音乐')def setBlock(num,name):global begin_timeif begin_time == 0:begin_time = time.time()global ac_nameglobal ac_numif ac_name != name and name != None and ac_name != None:ac_name.config(text='?',bg='orange',activebackground='orange',relief='groove')if name.cget('bg') != 'green':name.config(text='···',relief='sunken',bg='lightblue',activebackground='lightblue')ac_name = nameac_num = numelse:ac_name = None
def setNum(num):global ac_nameglobal begin_timeglobal dwcglobal ac_numglobal reglobal difficultyglobal stepsglobal wrongsglobal rightsglobal stePtry:b_color = ac_name.cget('bg')if ac_num == num:ac_name.config(text='√',activebackground='green',relief='groove',bg='green')else:   ac_name.config(text='×',activebackground='red',relief='groove')ac_name.flash()ac_name.flash()if ac_num == num:ac_name.config(text=str(num),activebackground='green',background='green',relief='groove')else:ac_name.config(text='?',bg='orange',activebackground='orange',relief='groove')if ac_name.cget('bg') == 'green' and b_color == 'lightblue':dwc -= 1ac_name = Nonerights += 1steps += 1elif b_color == 'lightblue' and ac_name.cget('bg') == 'orange':ac_name = Nonewrongs += 1steps += 1if dwc == 0:ac_name = Noneprint('恭喜,你赢了!')Label(window,text='恭喜,你赢了!',font=('微软雅黑',30),bg='lightgreen').place(x=52,y=50)use_time = round(time.time()-begin_time,1)Label(window,text='用时'+str(use_time)+'秒  正确率'+str(round((rights/steps)*100,1))+'%',bg='yellow').place(x=113,y=121)re.config(text='剩余数字数量:'+str(dwc)+' 难度等级:'+str(difficulty))steP.config(text='步数:'+str(steps)+' 正确:'+str(rights)+' 错误:'+str(wrongs))ac_name = Noneexcept:pass
def tipSs():'''global sdsfor ynfo in sds:print(ynfo)'''global ac_numglobal ac_nametry:ac_name.config(text=str(ac_num))ac_name.flash()ac_name.config(text='···')except:pass
def pauseOr(bgm):global pausEif pausE == True:py.mixer.music.pause()Button(window,text='♪',font=('楷体',7),relief='sunken',bg='white',command=lambda:pauseOr(bgm)).place(x=365,y=11)pausE = Falseelif pausE == False:py.mixer.music.unpause()Button(window,text='♫',font=('楷体',7),relief='sunken',bg='green',command=lambda:pauseOr(bgm)).place(x=365,y=11)pausE = True
j=0
i=0.7
_count = 1
wz = False
# 这里通过win10计算器,两年前的项目写出了算法
def spaceBtn(i,j,ri,rj):name =  'a'+str(i+1)+str(j+1)name = Button(window,text='?',font=('微软雅黑',10),relief='groove',bg='orange',activebackground='orange',command=lambda:setBlock(sds[i][j],name))name.place(x=rj*36,y=ri*38,width=30,height=30)
def numBtn(num):Button(window,text=str(num),font=('楷体',15),relief='sunken',bg='white',activebackground='blue',command=lambda:setNum(num)).place(x=x*42+9,y=380,width=37,height=37)
for info in sds:for jnfo in info:j+=1for znfo in ran:if _count == znfo:wz = True_count += 1if wz == True:spaceBtn(round(i-1),j-1,i,j)wz = Falseelse:Label(window,text=jnfo,font=('微软雅黑',10),relief='ridge',bg='grey').place(x=j*36,y=i*38,width=30,height=30)j=0i+=1
for x in range(0,9):numBtn(x+1)
Button(window,text='提示',command=tipSs).place(x=50,y=430)
bgm = Button(window,text='♫',font=('楷体',7),relief='sunken',bg='green',command=lambda:pauseOr(bgm)).place(x=365,y=11)
re = Label(window,text='剩余数字数量:'+str(dwc)+' 难度等级:'+str(difficulty),relief='sunken')
re.place(x=185,y=470)
steP = Label(window,text='步数:'+str(steps)+' 正确:'+str(rights)+' 错误:'+str(wrongs),relief='sunken')
steP.place(x=5,y=470)
window.mainloop()

主要外部依赖库:tkinter,pygame

需要改动地方:    py.mixer.music.load('bg.mp3'),在同一目录准备自己喜欢的游戏背景音乐重命名为bg即可

游戏运行效果如下:

下拉框选择不同等级难度,开始游戏,点击问号方块再点击下方数字即可填入

点击黄色问号方块再点击提示就会显示一秒钟的答案,之后再填入即可

详细来源:

用python实现带界面的数独小游戏_eyz2022的博客-CSDN博客_python 数独游戏

 

 

 

 

 


http://www.ppmy.cn/news/563444.html

相关文章

1.数独游戏(生成题目解唯一)

前几天在玩数独游戏的时候&#xff0c;产生了一个大胆的想法&#xff1a; 数独app上的题目都是现成的&#xff0c;干脆自己写一个可以随机生成数独的程序算了 一、需求提出&#xff1a; 1.随机生成数独题目&#xff0c;要求该题目有解&#xff08;有一个解最好&#xff09;&a…

(附代码)数独大作业【读取数独,解数独,生成唯一解数独(随机,特定形状,不同难度生成),玩数独】

注:未经同意不要转载。 上学期简单的做了一个数独程序&#xff0c;实现了一些功能&#xff0c;想简单的为大家提供的思路。 为了避免某些情况出现&#xff0c;具体代码暂时先不发了&#xff0c;有不太懂的地方可以评论提问啊。 下面是我的具体报告&#xff1a; 一&#xff…

让程序自动玩数独游戏让你秒变骨灰级数独玩家

程序自动填网页数独游戏 有个玩数独游戏的网站&#xff1a;https://www.sudoku.name/index-cn.php 当然这类玩数独游戏的网站很多&#xff0c;现在我们先以该网站为例进行演示。 玩过的都非常清楚数独的基本规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一…

项目集活动—项目集交付阶段活动

项目集交付阶段活动包括协调和管理项目集实际交付所需执行的项目集活动。这些活动包括围绕 变更控制、报告和信息发布所开展的活动&#xff0c;以及围绕成本、采购、质量和风险所开展的活动。 这些活动提供了贯穿整个项目集生命周期的支持活动和流程&#xff0c;旨在提供项目集…

为什么要做数据治理

在数聚股份看来&#xff0c;数据治理是管理企业数据资源、提高数据价值的一种方法。它是一种综合性的管理方式&#xff0c;旨在帮助企业提高数据管理效率&#xff0c;加强数据安全管理&#xff0c;优化数据质量。随着企业数据规模的不断增大&#xff0c;数据治理越来越成为企业…

java中如何实现字符串反转

java中如何实现字符串反转 方式1&#xff1a;通过创建StringBuilder或StringBuffer对象&#xff0c;并使用其reverse()方法实现字符串的反转 上代码&#xff1a; /*** 给定一个字符串&#xff0c;通过创建SpringBuilder对象的方式将字符串进行反转* return*/public static …

Adobe Photoshop CC 2014 15.2.1 32/64位中文特别安装版+绿色版

软件名称:Photoshp CC 2014软件版本:15.2.0.230软件语言:简体中文 软件官网:http://www.adobe.com/cn/软件大小:139M+165M软件依赖:vc++ 2008、2010、2012运行库 运行环境:Windows vista/Win7/Win8/Win8.1测试环境:windows8.1 x64/x86(32位在虚拟机中测试) 更新人:r…

win7 64位系统PS、AI、PSD缩略图预览补丁

MysticThumbs支持Windows 7 / Vista / XP&#xff0c;32位和64位。除了预览PSD以外&#xff0c;还支持DDS、SGI缩略图显示。 Mystic Thumbs是一款用来支持win7 64位操作系统psd缩略图的小插件。现在win7系统已经被越来越多的人接受&#xff0c;甚至win7 64位系统都有着大量的用…