python五子棋课程设计报告(python五子棋设计参考文献)
求一个编写的五子棋小游戏python的代码,求借鉴啊!!急急急。。。
#五子棋import?appuifw,e32,key_codes
from?graphics?import?*def?cn(x):return?x.decode('utf-8')
def?quit():?_quit=1
global?running
running=1
def?redraw(rect):?canvas.blit(img)def?default():
?global?con,color,font
?con={"l":15,"x":15,"y":33,"r":13,"n":15}
?color={"bg":0x7777bb,"fg":0x333333,"p1":0x000000,"p2":0xffffff,"w":0xff0000}
?font=u"Sans?MT?936_S60"def?initial():
?global?img,canvas,con,color,cur_x,cur_y,turn,pos1,pos2,pos
?appuifw.app.screen='full'
?appuifw.app.body=canvas=appuifw.Canvas()
?img=Image.new((240,320))
?img.clear(color["bg"])
?cur_x=7
?cur_y=7
?turn=1
?pos1=[]
?pos2=[]
?pos=[]
?for?i?in?range(con["n"]*con["n"]):
??pos.append(0)def?paint_back():
?global?img,color,font
?#img.text((90,25),cn('欢乐五子棋'),color["fg"],font)
?for?i?in?range(con["x"],con["x"]+con["l"]*con["n"]-1,con["l"]):
??img.line((i,con["y"],i,con["y"]+con["l"]*(con["n"]-1)),color["fg"])
?for?i?in?range(con["y"],con["y"]+con["l"]*con["n"]-1,con["l"]):
??img.line((con["x"],i,con["x"]+con["l"]*(con["n"]-1),i),color["fg"])
?img.text((40,270),cn('玩家1'),color["p1"],font)
?img.text((160,270),cn('玩家2'),color["p2"],font)
?img.point((90,263),color["p1"],width=con["r"],fill=color["p1"])
?img.point((144,263),color["p2"],width=con["r"],fill=color["p2"])
?
def?paint_cur(x,y,sh):
?global?img,con,color,pos1,pos2,running
?if?running1:return
?ax=con["x"]+con["l"]*x
?ay=con["y"]+con["l"]*y
?b=con["l"]/2
?if?sh0:
??c=color["p"+str(sh)]
??if?rp((x,y))0:
???c=color["w"]
?if?sh==0:
??c=color["bg"]
?img.line((ax-b,ay-2,ax-b,ay-b,ax-2,ay-b),c)
?img.line((ax-b,ay+2,ax-b,ay+b,ax-2,ay+b),c)
?img.line((ax+b,ay-2,ax+b,ay-b,ax+2,ay-b),c)
?img.line((ax+b,ay+2,ax+b,ay+b,ax+2,ay+b),c)
?redraw(())def?paint_q(x,y,z):
?global?img,con,color
?ax=con["x"]+con["l"]*x
?ay=con["y"]+con["l"]*y
?b=con["l"]/2
?if?z==0:
??c=color["bg"]
?else:
??c=color["p"+str(z)]
?img.point((ax,ay),c,width=con["r"],fill=c)
?redraw(())
?if?z==0:
??img.line((ax-b,ay,ax+b,ay),c)
??img.line((ax,ay-b,ax,ay+b),c)
??
def?k_up():
?global?cur_x,cur_y,con,turn
?paint_cur(cur_x,cur_y,0)
?cur_y=cur_y-1
?if?cur_y==-1:
??cur_y=con["n"]-1
?paint_cur(cur_x,cur_y,turn)def?k_down():
?global?cur_x,cur_y,con,turn
?paint_cur(cur_x,cur_y,0)
?cur_y=cur_y+1
?if?cur_y==con["n"]:
??cur_y=0
?paint_cur(cur_x,cur_y,turn)def?k_left():
?global?cur_x,cur_y,con,turn
?paint_cur(cur_x,cur_y,0)
?cur_x=cur_x-1
?if?cur_x==-1:
??cur_x=con["n"]-1
?paint_cur(cur_x,cur_y,turn)def?k_right():
?global?cur_x,cur_y,con,turn
?paint_cur(cur_x,cur_y,0)
?cur_x=cur_x+1
?if?cur_x==con["n"]:
??cur_x=0
?paint_cur(cur_x,cur_y,turn)def?rp(x):
?global?con,pos
?if?(x[0]0?or?x[0]=con["n"]?or?x[1]0?or?x[1]=con["n"]):return?0
?#print?x,pos[x[0]*con["n"]+x[1]]
?return?pos[x[0]*con["n"]+x[1]]def?wp(x,y):
?global?con,pos
?pos[x[0]*con["n"]+x[1]]=y
??
def?win():
?for?i?in?pos1:
??k=0
??for?j?in?range(0,6):
???if?rp((i[0]+j,i[1]))==1:
????k=k+1
???else:
????break
??if?k=5:
???return?1
??k=0
??for?j?in?range(0,6):
???if?rp((i[0],i[1]+j))==1:
????k=k+1
???else:
????break
??if?k=5:
???return?1
??k=0
??for?j?in?range(0,6):
???if?rp((i[0]+j,i[1]+j))==1:
????k=k+1
???else:
????break
??if?k=5:
???return?1
??k=0
??for?j?in?range(0,6):
???if?rp((i[0]+j,i[1]-j))==1:
????k=k+1
???else:
????break
??if?k=5:
???return?1?for?i?in?pos2:
??k=0
??for?j?in?range(0,6):
???if?rp((i[0]+j,i[1]))==2:
????k=k+1
???else:
????break
??if?k=5:
???return?2
??k=0
??for?j?in?range(0,6):
???if?rp((i[0],i[1]+j))==2:
????k=k+1
???else:
????break
??if?k=5:
???return?2
??k=0
??for?j?in?range(0,6):
???if?rp((i[0]+j,i[1]+j))==2:
????k=k+1
???else:
????break
??if?k=5:
???return?2
??k=0
??for?j?in?range(0,6):
???if?rp((i[0]+j,i[1]-j))==2:
????k=k+1
???else:
????break
??if?k=5:
???return?2
?return?0
?
def?k_enter():
?global?cur_x,cur_y,turn,pos1,pos2,con,color,font,running
?if?running1:return
?if?rp((cur_x,cur_y))==0:
??if?turn==1:
???pos1.append((cur_x,cur_y))
???img.rectangle((35,255,100,272),color["bg"])
???img.rectangle((135,255,200,272),color["p2"])
??if?turn==2:
???pos2.append((cur_x,cur_y))
???img.rectangle((35,255,100,272),color["p1"])
???img.rectangle((135,255,200,272),color["bg"])
??paint_q(cur_x,cur_y,turn)
??wp((cur_x,cur_y),turn)
??if?win()0:
???#img.text((80,300),cn('玩家')+str(turn)+cn("获胜!"),color["fg"],font)
???img.rectangle((35,255,100,272),color["bg"])
???img.rectangle((135,255,200,272),color["bg"])
???paint_cur(cur_x,cur_y,0)
???running=2
?turn=3-turn
?paint_cur(cur_x,cur_y,turn)def?bindkey():
?canvas.bind(key_codes.EKeyUpArrow,?k_up)
?canvas.bind(key_codes.EKeyDownArrow,k_down)
?canvas.bind(key_codes.EKeyLeftArrow,?k_left)
?canvas.bind(key_codes.EKeyRightArrow,k_right)
?canvas.bind(key_codes.EKeySelect,k_enter)default()
initial()
paint_back()
paint_cur(cur_x,cur_y,1)
img.rectangle((35,255,100,272),color["p1"])
bindkey()redraw(())
appuifw.app.exit_key_handler?=?quit()
_quit=0
while?(1-_quit):
?e32.ao_sleep(0.2)
?redraw(())
判断变量user是否等于字符串user的语句是
首先举例写一个用户密码登入接口
单引号是用来将_user变量为luwei字符串,也就是说_user等于字符串luwei
如果不加单引号_user=luwei那这个就是变量的意思
_user='luwei'
_password='123456'
input是交互式语法类似shell中的read -p一样,就是需要用户手动输入数字的
user=input("user:")
password=input("password:")
if是判断语法,当_user等于user(用户输入的账户时)并且 _password等于password(用户输入的密码时)输入正确
则提示登入成功
其中print是输出字符,和shell中echo一样,那么其中的逗号,_user就是变量输出登入用户的名字,因为要区分开输出内容,所以要逗号隔开
if _user==user and _password==password :
print("登入成功",_user)
else意思是如果用户或者密码输入的不对
则直接提示输出用户或密码错误
else:
print("登入用户或密码错误")
在python if判断语句不需要像shell中的if有结束语句,但是注意事项在python中if语法需要换行格式的,不然会报错
完整格式
二,while循环语法
就拿猜年龄举个例子
定义age变量年龄28岁
age=28
count定义循环次数变量
count=0
当while循环次数小于3时候结束while循环
while count 3:
定义guess_age变量为用户交互式(用户输入的数字),注意python3.0默认格式为字符串ste,需要将格式改为数字格式为int,不然会报错
guess_age=int(input(“guess age:”))
判断输入的年龄是否正确,berak(破坏本次while循环程序的意思)
if guess_age == age:
print("yes,lt'is")
break
如果是输入的是大于的
elif guess_age age:
print("lt‘s small")
那除了大于或者等于肯定就是小于了
else:
print("lt'is big")
+=1每次循环结束后count的变量+1
count +=1
这一段if为另加,表示输入3次如果都是错误,是否还要继续,
当count的变量为3的时候
if count ==3
countine_confirm=input("do you want to keep guessing..?")
那么需要用户输入任意键或者n,任意键为继续,n为不继续,其中!=n,表示除了输入n以外都为继续猜
if countine_confirm = !='n'
如果为任意键,那么将count变量为0,重新猜3次
count=0
如果猜3次都错误,那么程序自动退出
else:
print("you have tried too many times....fuck off")
完整格式
三,for循环语法
i为临时变量,其实(0,10,2)表示能被2整除的0-10之间的数输出
for i in range (0,10,2):
判断i小于6
if i 6:
print("loop",i)
当大于6的时候
else:
continue表示当i大于6的时候,那么直接重新跳到if重新循环而不执行print("luwei")这一行
continue
print("luwei")
输出结果是这样的
完整格式
文章知识点与官方知识档案匹配
Python入门技能树基础语法循环
198433 人正在系统学习中
点击阅读全文
打开CSDN,阅读体验更佳
完整图文版教程 优质的Python基础入门教程 讲解清晰 05、Python控制语句-循环语句2(共21页).pptx
完整图文版教程 优质的Python基础入门教程 03、Python基本语法1 (共32页).pptx 完整图文版教程 优质的Python基础入门教程 03、Python基本语法2 (共17页).pptx 完整图文版教程 优质的Python基础入门教程 03、...
python中如何用语句判断变量的类型是否是字符串类型?
python中如何用语句判断变量的类型是否是字符串类型? 使用 isinstance('abc',str)语句,判断'abc'是否为字符串类型,该语句返回为True。
继续访问
通过代码审计学习变量覆盖漏洞
前言: 这篇文章是我在 前几个月写的,然后如今才打算发布的,咳咳,也没啥可以写的,就写一下变量覆盖的形成,如何代码审计查找白盒专属的变量覆盖漏洞 变量覆盖是有啥用处? 变量覆盖可以使用我们自定义的变量去覆盖 源代码中的变量,去修改代码运行的逻辑。变量覆盖与其他漏洞结合后 伤害是比较大的,比如商品购买的支付系统如果存在变量覆盖的话可能出现0元支付下单的情况,或者说 登录管理员后台的时候,通过变量覆盖,进行登录后台(这篇文章讲解的就是 duomicms的变量覆盖进入后台,小白也很容易懂) 正文 变量覆盖产生原因
继续访问
ASP循环语句之for ... next语句
for ... next :指定语句运行的次数 语句的格式 以下为引用内容:%for 变量=1 to N (总量)step M (步长)重复执行的语句next% 示例: 以下为引用内容:%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%!DOCTYPE html ...
继续访问
tcl introduction
I just search and foun it out, then copy it here. -:) Tcl简介(一):Tcl 语法Tcl 语法Tcl是一种很通用的脚本语言,它几乎在所有的平台上都可以释运行,其强大的功能和简单精妙的语法会使你感到由衷的喜悦,这片文章对 Tcl有很好的描述和说明。极具可读性,我并不是原封不动的翻译而是加上了一些自己的体会和例子,如有错误
继续访问
python2.7入门---循环语句(for嵌套循环)
咱们直接先来看for循环。Python for循环可以遍历任何序列的项目,如一个列表或者一个字符串。然后再来看一下它的语法结构:for iterating_var in sequence: statements(s) 这是他的工作流程图: 来,咱们看实例来:#!/usr/bin/python # -*- coding: UTF-8 -*- for letter in ...
继续访问
完整图文版教程 优质的Python基础入门教程 讲解清晰 05、Python控制语句-循环语句1 (共27页).pptx
完整图文版教程 优质的Python基础入门教程 03、Python基本语法1 (共32页).pptx 完整图文版教程 优质的Python基础入门教程 03、Python基本语法2 (共17页).pptx 完整图文版教程 优质的Python基础入门教程 03、...
python2.7入门---循环语句(while)
接下来就要了解循环语句了。我们都知道,程序在一般情况下是按顺序执行的。编程语言提供了各种控制结构,允许更复杂的执行路径。循环语句允许我们执行一个语句或语句组多次,下面是在大多数编程语言中的循环语句的一般形式: Python提供了for循环和while循环(在Python中没有do..while循环),我们通过表单看一下:循环类型描述while 循环在给定的判断条件为 true 时执行...
继续访问
100-days-of-Python-Beginner-Projects
Python的100天入门项目 Begginer从100天的Python项目开始... 这些项目探索了基本的python语法和编程概念(使用变量,数据类型,控制流和逻辑运算符,随机化,Python列表,循环,函数,参数,字典,嵌套,作用域和调试)
tcl/tk实例详解——for
for循环,熟悉其它语言程序的循环命令的话就可以忽视此文了。 命令请参考: for循环,循环格式为:for start test next body start为起始的设置,test为测试循环是否还进行的条件,next为每次循环体执行一次后需要做
继续访问
Python入门-系列游戏开发-贪吃蛇
深入理解并掌握python中数组、函数等语法知识、掌握python中Tkinter模块的用法。加深对面向对象知识的理解。
继续访问
Python入门-系列游戏开发-五子棋
本 课 程,资料齐全(源码、课程笔记),课程中通过Python开发的五子棋,旨在让朋友们对Python的基础知识有一个全面的了解。应用Python基础,能够完成图形界面程序的开发。
继续访问
Python 元组-元组变量的循环遍历
Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言,随着版本的不断更新和语言新功能的添加,逐渐被人们用于独立的、大型项目的开发和设计 Python解释器易于扩展,...
Python入门-基础语法笔记
1.vi技巧: 中英切换:shift wq = x 2.注释 单行:# 多行:三个单引号或三个双引号 amp;quot;amp;quot;amp;quot; print(amp;quot;hello worldamp;quot;) amp;quot;amp;quot;amp;quot; 3.编码 文件中有中文,不管是否为注释,p
继续访问
Python--- for循环
for 循环详解 for 循环语法结构 for 变量 in 可迭代对象: for 循环逻辑 从购物过程理解 for 循环 购物车 我们都有在超市购物的经历,将一件一件的商品放进购物车:
继续访问
Python零基础入门篇?〗- Python中的循环
什么是循环? 循环就是有着周而复始的运动或变化的规律;在 Python 中,循环的操作也叫做 '遍历' 。 与现实中一样,Python 中也同样存在着无限循环的方法与有限循环的方法。接下来我们就先看看它们分别是什么样子?
继续访问
最新发布 Python从入门到入土-基础语法
Python 对缩进有严格的要求,同一个源文件里,缩进必须保持一致,例如都是2个空格或者4个空格。Python 这么做的理由是使用缩进更简洁,同时不用考虑"{"要放在哪一行,而且是用缩进足够Python解释器正确解析。但是使用缩进如果没有编辑器自动检测和格式化也会带来一些不必要的麻烦。函数是代码复用的最简单形式。现在可以系统认识下函数的参数。作用域是编程语言里的一个重要的概念,特别是块作用域,编程语言一般会使用明确的符号标记一个作用域的开始和结束。...
求解用python 编写五子棋怎样编写判断输赢的函数,应该从哪方面考虑呢?最好有代码,,,,谢谢
你都做到这个程度了,当然就是高手了。 把棋子位置放在一个数据里。然后做一个路径搜索算法。只搜索8个方向,如果某个方向有5个子连在一起就赢了。
这是个笨方法,还有很多优化的地方,比如上一次搜索后,建立一个路径数组。下一次,只需要检验上一次结果,并将新的棋子放进路径里就可以了。 这样就效率很高了。
具体的你自己研究。这个对你来说应该轻松啦。
五子棋游戏程序设计(VB)
五子棋的AI构想 有句话叫“当局者迷,旁观者清。”,但这句话在由AI所控制的计算机玩家上是不成立的,因为计算机必须知道有那些获胜方式,并计算出每下一步棋到棋盘上任一格子的获胜几率,也就是说,一个完整的五子棋的AI构想必须:
1、能够知道所有的获胜组合; 2、建立和使用获胜表; 3、设定获胜的分数; 4、使电脑具有攻击和防守的能力; 一、求五子棋的获胜组合 在一场五子棋的游戏中,计算机必须要知道有那些的获胜组合,因此我们必须求得获胜组合的总数。我们假定当前的棋盘为10*10。 (1)计算水平方向的获胜组合数,每一列的获胜组合是:6,共10列,所以水平方向的获胜组合数为:6*10=60 (2)计算垂直方向的获胜组合总数,每一行的获胜组合是:6,共10行,则垂直方向的获胜组合数为:6*10=60 (3)计算正对角线方向的获胜组合总数,正对角线上的获胜组合总数为6+(5+4+3+2+1)*2=36 (4)计算反对角线方向的获胜组合总数,反对角线上的获胜组合总数为6+(5+4+3+2+1)*2=36 ,这样所有的获胜组合数为:60+60+36+36=192 二、建立和使用获胜表 我们已经计算出了一个10*10的五子棋盘会有192种获胜方式,这样我们可以利用数组建立获胜表,获胜表的主要作用是:1,判断当前的获胜方式是否有效;2,判断当前的获胜方式中到底有多少子落入该获胜组合中。详细的使用您将在后面的程序中可以看出。 三,分数的设定 在游戏中为了让计算机能够决定下一步最佳的走法,必须先计算出计算机下到棋盘上任一空格的分数,而其中最高分数便是计算机下一步的最佳走法。 原理:我们判定当前讨论的空格与当前讨论的点有几种获胜的方式,有几种该空格就加几分。这种原理初听起来似乎是无法入手,没关系,当您了解我们后面的程序后您就会明白这种决策原理了。 这种决策有一些缺陷,因为如果只根据这个模型设计,就有可能出现电脑或玩家有三个子连成一线的时候,计算机却判断不出,它认为其他某些空格是当前的获胜的最佳位置而不去攻击或防守。没关系我们完全可以通过一个加强算法来改变当前的分值情况,也就是说当电脑或玩家有三个子或四个子连成一线时,我们通过加强算法将当前与三个子或四个子有关的空格的分值提高,从而可以弥补这一缺憾。 四、攻击与防守 以上的方式,事实上计算机只是计算出了最佳的攻击位置,为了防守我们还应计算当前玩家的最佳的攻击位置。这样有什么用呢?道理很简单,如果玩家最佳攻击位置的分数大于计算机最佳攻击位置上的分数,那么计算机就将下一步的棋子摆在玩家的最佳攻击位上以阻止玩家的进攻,否则计算机便将棋子下在自己的最佳攻击位置上进行攻击。 事实上,这个AI构想是很强大的如果你不是很厉害的五子棋高手的话,可能很快会被计算机打败。我在联众上可是中级棋手啊,跟这种构想打的时候胜率也不是很高。 使用vb.net编写五子棋 一、编写前的准备: 1、用计算机的思想描述整个下棋的过程 考虑步骤: (1)为了简便我们可以先让电脑先走第一步棋,电脑每走一步就会封掉许多玩家的获胜可能情况。 (2)当玩家走棋的时候我们首先应该考虑玩家走棋的合法性。 (3)如果合法,那么玩家也会封掉许多电脑的获胜的可能情况。 (4)电脑的思考路径:首先判断当前玩家和电脑的所有获胜组合是否需要进行加强赋值,
是进行加强赋值,否则进行普通的赋值。 (5)比较当前玩家和电脑谁的分值最大。将分值最大的点作为电脑的下一步走法。 2、利用vb.net窗体和图形工具建立五子棋的棋盘界面 (1)添加一个picturebox控件 作用:使用picturebox控件绘制棋子和棋盘 (2)添加一个label控件 作用:显示当前的获胜标志,也就是当某一方获胜或和棋时显示此标签。 (3)添加一个mainmenu控件 作用:控制游戏的开始或结束 (4)添加一个mediaplay组件 作用:使程序可以播放音乐。 3、设置整体框价 我们采取10*10的棋盘,为主要的平台。利用数组定义整个棋盘桌面,利用数组定义获胜组合以及获胜标志等。 二,声明全局数组和变量 定义虚拟桌面: Dim table(9, 9) As Integer 定义当前玩家桌面空格的分数: Dim pscore(9, 9) As Integer 定义当前电脑桌面空格的分数: Dim cscore(9, 9) As Integer 定义玩家的获胜组合: Dim pwin(9, 9, 191) As Boolean 定义电脑的获胜组合: Dim cwin(9, 9, 191) As Boolean 定义玩家的获胜组合标志: Dim pflag(191) As Boolean 定义电脑的获胜组合标志:
Dim cflag(191) As Boolean 定义游戏有效标志: Dim theplayflag As Boolean 三、初始化游戏 '*****************************************************************************
'** 模块名称: initplayenvironment
'**
'** 描述: 此函数主要功能如下:
'** 1. 设置背景音乐。
'** 2. 设置游戏状态有效。
'** 3. 初始化游戏状态标签。
'** 4. 直接指定电脑的第一步走法。
'** 5. 初始化基本得分桌面。
'** 6. 电脑和玩家获胜标志初始化。
'** 7. 初始化所有获胜组合。
'** 8. 重新设定玩家的获胜标志。
'**
'*****************************************************************************
Sub initplayenvironment()
player.FileName = ".\music\zhyu01.mid"
player.Play()
theplayflag = True
'游戏有效
Label1.Visible = False
'游戏状态标签不显示
PictureBox1.Refresh()
'清空picturebox1的内容
yuandian(130, 130)
'调用绘图函数绘制当前电脑先走的位置
Dim i, j, m, n As Integer
For i = 0 To 9
For j = 0 To 9
table(i, j) = 0
Next
Next
'桌面初始化
For i = 0 To 191
pflag(i) = True
cflag(i) = True
Next
'获胜标志初始化
table(4, 4) = 1
'由于我们设定电脑先手,并下了4,4位所以将其值设为1
''' ******** 初始化获胜组合 ********
n = 0
For i = 0 To 9
For j = 0 To 5
For m = 0 To 4
pwin(j + m, i, n) = True
cwin(j + m, i, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 9
For j = 0 To 5
For m = 0 To 4
pwin(i, j + m, n) = True
cwin(i, j + m, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 5
For j = 0 To 5
For m = 0 To 4
pwin(j + m, i + m, n) = True
cwin(j + m, i + m, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 5
For j = 9 To 4 Step -1
For m = 0 To 4
pwin(j - m, i + m, n) = True
cwin(j - m, i + m, n) = True
Next
n = n + 1
Next
Next
''' ******** 初始化获胜组合结束 ********
For i = 0 To 191
If pwin(4, 4, i) = True Then
pflag(i) = False
End If
Next
'由于电脑已下了4,4位所以我们需要重新设定玩家的获胜标志
End Sub
四,处理鼠标事件 '*****************************************************************************
'** 模块名称: themousedown
'**
'** 描述: 此函数主要实行以下功能:
'** 1. 判定当前游戏标志是否有效。
'** 2. 将实际坐标转化成虚拟坐标。
'** 3. 绘制玩家的棋子。
'** 4. 执行检查获胜函数。
'** 5. 执行电脑算法函数。
'**
'*****************************************************************************
Sub themousedown(ByVal x As Integer, ByVal y As Integer)
If theplayflag = False Then
Exit Sub
End If
'检查游戏状态是否有效
Dim i, j As Integer
Dim zhx, zhy As Integer
zhx = Int((x - 10) / 30)
zhy = Int((y - 10) / 30)
For i = 0 To 9
For j = 0 To 9
If table(zhx, zhy) 0 Then
Exit Sub
End If
Next
Next
'检查当前鼠标点击的格子是否有效
Dim mycolor As Color
Dim g As System.Drawing.Graphics
g = PictureBox1.CreateGraphics
mycolor = Color.White
Dim brush1 As System.Drawing.Brush = New SolidBrush(mycolor)
g.FillEllipse(brush1, zhx * 30 + 10, zhy * 30 + 10, 30, 30)
'绘制玩家的棋子
table(zhx, zhy) = 2
For i = 0 To 191
If cwin(zhx, zhy, i) = True Then
cflag(i) = False
End If
Next
'重设电脑的获胜标志
checkwin()
'检查当前玩家是否获胜
diannao()
'调用电脑算法
End Sub 五、获胜检查算法。 '*****************************************************************************
'** 模块名称: checkwin
'**
'** 描述: 此模块执行以下功能:
'** 1. 检查是否和棋。
'** 2. 检查电脑是否获胜。
'** 3. 检查玩家是否获胜。
'**
'*****************************************************************************
Sub checkwin()
Dim i, j, k, m, n As Integer
Dim ca As Integer
Dim pa As Integer
Dim cnormal As Integer = 0
For i = 0 To 191
If cflag(i) = False Then
cnormal = cnormal + 1
End If
Next
If cnormal = 190 Then
Label1.Visible = True
Label1.Text = "和棋,请重新开始!"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
'设定和棋规则
For i = 0 To 191
If cflag(i) = True Then
ca = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 1 Then
If cwin(j, k, i) = True Then
ca = ca + 1
End If
End If
Next
Next
If ca = 5 Then
Label1.Visible = True
Label1.Text = "电脑获胜,请重新开始"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
End If
Next
'检查电脑是否获胜
For i = 0 To 191
If pflag(i) = True Then
pa = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 2 Then
If pwin(j, k, i) = True Then
pa = pa + 1
End If
End If
Next
Next
If pa = 5 Then
Label1.Visible = True
Label1.Text = "玩家获胜,请重新开始"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
End If
Next
'检查玩家是否获胜
End Sub 六、电脑算法 '*****************************************************************************
'** 模块名称: diannao
'**
'** 描述: 此程序主要执行以下功能:
'** 1. 初始化赋值系统。
'** 2. 赋值加强算法。
'** 3. 计算电脑和玩家的最佳攻击位。
'** 4. 比较电脑和玩家的最佳攻击位并决定电脑的最佳策略。
'** 5. 执行检查获胜函数。
'**
'***************************************************************************** Sub diannao()
Dim i, j, k, m, n As Integer
Dim dc As Integer
Dim cab As Integer
Dim pab As Integer
For i = 0 To 9
For j = 0 To 9
pscore(i, j) = 0
cscore(i, j) = 0
Next
Next
'初始化赋值数组
''' ******** 电脑加强算法 ********
For i = 0 To 191
If cflag(i) = True Then
cab = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 1 Then
If cwin(j, k, i) = True Then
cab = cab + 1
End If
End If
Next
Next
Select Case cab
Case 3
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If cwin(m, n, i) = True Then
cscore(m, n) = cscore(m, n) + 5
End If
End If
Next
Next
Case 4
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If cwin(m, n, i) = True Then
yuandian(m * 30 + 10, n * 30 + 10)
table(m, n) = 1
For dc = 0 To 191
If pwin(m, n, dc) = True Then
pflag(dc) = False
checkwin()
Exit Sub
End If
Next
End If
End If
Next
Next
End Select
End If
Next
For i = 0 To 191
If pflag(i) = True Then
pab = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 2 Then
If pwin(j, k, i) = True Then
pab = pab + 1
End If
End If
Next
Next
Select Case pab
Case 3
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If pwin(m, n, i) = True Then
pscore(m, n) = pscore(m, n) + 30
End If
End If
Next
Next
Case 4
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If pwin(m, n, i) = True Then
yuandian(m * 30 + 10, n * 30 + 10)
table(m, n) = 1
For dc = 0 To 191
If pwin(m, n, dc) = True Then
pflag(dc) = False
checkwin()
Exit Sub
End If
Next
End If
End If
Next
Next
End Select
End If
Next
''' ******** 电脑加强算法结束 ******** ' ******** 赋值系统 ********
For i = 0 To 191
If cflag(i) = True Then
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 0 Then
If cwin(j, k, i) = True Then
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 1 Then
If cwin(m, n, i) = True Then
cscore(j, k) = cscore(j, k) + 1
End If
End If
Next
Next
End If
End If
Next
Next
End If
Next
For i = 0 To 191
If pflag(i) = True Then
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 0 Then
If pwin(j, k, i) = True Then
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 2 Then
If pwin(m, n, i) = True Then
pscore(j, k) = pscore(j, k) + 1
End If
End If
Next
Next
End If
End If
Next
Next
End If
Next
''' ******** 赋值系统结束 ********
''' ******** 分值比较算法 ********
Dim a, b, c, d As Integer
Dim cs As Integer = 0
Dim ps As Integer = 0
For i = 0 To 9
For j = 0 To 9
If cscore(i, j) cs Then
cs = cscore(i, j)
a = i
b = j
End If
Next
Next
For i = 0 To 9
For j = 0 To 9
If pscore(i, j) ps Then
ps = pscore(i, j)
c = i
d = j
End If
Next
Next
If cs ps Then
yuandian(a * 30 + 10, b * 30 + 10)
table(a, b) = 1
For i = 0 To 191
If pwin(a, b, i) = True Then
pflag(i) = False
End If
Next
Else
yuandian(c * 30 + 10, d * 30 + 10)
table(c, d) = 1
For i = 0 To 191
If pwin(c, d, i) = True Then
pflag(i) = False
End If
Next
End If
''' ******** 分值比较算法结束 ********
checkwin()
End Sub 七、绘制棋子 '*****************************************************************************
'** 模块名称: yuandian
'**
'** 描述: 此函数主要进行电脑棋子的绘制。
'**
'***************************************************************************** Sub yuandian(ByVal x As Integer, ByVal y As Integer)
Dim mycolor As Color
Dim g As System.Drawing.Graphics
g = PictureBox1.CreateGraphics
Dim zhx, zhy As Integer
zhx = Int((x - 10) / 30)
zhy = Int((y - 10) / 30)
mycolor = Color.Black
Dim brush1 As System.Drawing.Brush = New SolidBrush(mycolor)
g.FillEllipse(brush1, zhx * 30 + 10, zhy * 30 + 10, 30, 30)
End Sub
python版本五子棋
机器博弈是人工智能领域的重要分支,它的研究对象多以复杂的棋牌类智力游戏为主,已经得到解决的棋类游戏,几乎全部都应归功于机器博弈近半个世纪的发展。计算机解决问题的优势在于能把不易解析的问题,借助于现代计算机的运算速度优势枚举出所有的合理情形而得解;然而,博弈问题的复杂程度决定了它不能过度依赖机器的计算能力。许多待解决的或已经解决的棋类,其状态空间复杂度或博弈树复杂度量级都太过庞大,所以我们需要添加约束,并且采用合理的算法进行优化。
五子棋问题是人工智能中的一个经典问题。当今世界,AlphaGo已经执围棋之牛耳,五子棋领域却鲜少有人问津。本文根据课堂所学知识结合文献、博客,基于两种开发语言实现了一个智能对战的AI五子棋游戏平台。
本文所做工作如下:
(1) 五子棋界面实现;
(2) 智能判定棋盘走势;
(3) 改进了棋盘扫描方式;
(4) 改良了系统评分表评估方式;
(5) 实现了基于点评分表估值找出最佳落子方式。
五子棋AI问题的最大问题是如何实现智能对弈,即当人落子之后,算法如何解读当前的棋盘并且对其进行分析解读,得到电脑方的最佳落子点。其次还有一个问题是如何判断胜利,这可以作为前面棋盘局势判定的一个子问题,也可以看做是一个单独的问题,不过这个问题总体来说较为简单,所以不做详细说明。
五子棋的整体知识构建包含以下部分:
(1) 棋盘局面表示法
(2) 棋局胜利判定
(3) 棋型知识库
(4) 智能博弈流程
对于问题(1),采用数组表示法。棋盘中的各交叉点有三种状态,不妨令 0表示空(未放置棋子) ,-1 表示有黑子 ,1 表示有白子,数组表示法的基本思想是:以交叉点对应的数组索引值来表达物理位置 ,以交叉点对应的元素值表达状态(空、 黑子、 白子)。令 V = {0 ,1 ,-1} ,棋盘 的第 i 个交叉点的状态 Si ∈V ,任何棋局都可以表示成一个 n ×n 的二元组。
对于问题(2), 采用数组表示法时,想知道任意两个元素 Si 和Sj 是否共线,要通过 i 和 j 之间的数值规律来判断。从这方面看,数组表示法是一种原始、低效的表示方法,但是对于评分表算法来说其性能损失是可以接受的。要判断是否有一方已经胜利,只需要对整个棋盘判定当前落子点的纵、横、正斜、反斜四个方向的最长延伸出四个位置看是否能连成一条同色直线即可。具体的操作可以视为:从落子点出发,向两个方向延伸,如果遇到同色,那么计数器加一,遇到非同色(空白或者异色)则停止在该方向的延伸,一个计数器记下该方向上的两头的连续同色棋子数。等到四个方向都探索完毕,如果四个计数器中有一个计数器达到了5,那么即可判断出已经有五子连珠了,此局结束。
问题(3)棋型知识库主要包括各种既定的棋盘形式,有如下几种:
2 活四 :有两个连五点(即有两个点可以形成五),图中白点即为连五点。当活四出现的时候,整个局势已经无法阻止连五了,活四的归属方一定能取得胜利;
2 冲四 :有一个连五点,如下面三图,均为冲四棋型。图中白点为连五点。 相对比活四来说,冲四的威胁性就小了很多,因为这个时候,只要跟着防守在那个唯一的连五点上,冲四就没法形成连五。
2 活三 :可以形成活四的三,如下图,代表两种最基本的活三棋型。图中白点为活四点。活三棋型是进攻中最常见的一种,因为活三之后,如果对方不以理会,将可以下一手将活三变成活四,而活四是无法防守的。所以,面对活三的时候,需要非常谨慎对待。在没有更好的进攻手段的情况下,必须对其进行防守,以防止其形成可怕的活四棋型。
2 眠三: 只能够形成冲四的三,如下各图,分别代表最基础的六种眠三形状。图中白点代表冲四点。眠三的棋型与活三的棋型相比,危险系数下降不少,因为眠三棋型即使不去防守,下一手它也只能形成冲四,而对于单纯的冲四棋型,是可以很简单的防守住的。
2 活二 :能够形成活三的二,如下图,是三种基本的活二棋型。图中白点为活三点。
2 眠二 :能够形成眠三的二。图中四个为最基本的眠二棋型,细心且喜欢思考的同学会根据眠三介绍中的图2-13找到与下列四个基本眠二棋型都不一样的眠二。图中白点为眠三点。
对于上述的棋型,我们主要考虑的是活四、冲四、活三、眠三这几种主要的进攻棋型的防守与构成,整体棋型遵从以下原则:优先考虑数目,同等数目的情况下考虑是活是眠。评分表算法的设计整体偏向于防守。
对于问题(4),当下棋型的评估分析,算法严格遵从以下流程:
当人类方落下一子,算法启动,扫描全局,得到人类棋子的集合和电脑棋子的集合。全局扫描之后,对当前局势进行排序、计算。对每个集合的每个空白点位置打分,打分依据是根据这个点周围四个方向上的同色连续棋子的数量。按照这些最后得到的评分,得出最大值。得到人类方和电脑方的两个最大值之后,进行比较,如果人类方局势较好(分数较高),则算法将下一次落子位置设置为人类方得分最高的点,尽力降低人类方的下一步得分;如果电脑方的分数较高,那么则直接在使得分数最高的点落子即可。
本次课程设计,一共设计了两个版本,一个Java版本,为19X19的棋盘,配备简单的消息提示,基于AWT实现GUI,开发工具IntelliJ IDEA 2018.1
另一个版本是使用Python设计,核心算法相同,但是受限于图片源文件,为15X15棋盘,基于pygame实现GUI,开发工具是:JetBrains PyCharm 2018.2.4 x64
因为近期时间较为紧迫,所以《人工智能》这门课我选择了较为简单的五子棋问题进行课程设计。在本次课程设计中,我的编码能力、调试能力、算法解读实现能力、函数优化能力等各方面有了长足的进步。在本次的设计过程中也出现了几个问题,下面对这些问题进行一个简单的描述:
(1) 对棋盘局势的判断力不够,因为只是简单的对当前的棋盘局势进行判断,基本等同于一个粗通规则而且天赋不高的五子棋选手。如果对手很细心,而且熟练经营各种布局策略,那么基本这个算法就会被钻研出习惯,从而被轻易针对,而且针对方案百试不爽;
(2) 判断棋局形式的时候对边界的评分算法跟中心区域的评分算法一致,无法有效提前识别边界,降低边界空白点的权重;
(3) 用户图形界面需要改进,另外可以增设PK模式以及选色、选择棋盘大小功能等;
后续可以尝试用博弈树算法尝试与当前算法进行比较。评分表算法牺牲了更高的精度,以求迅速的得出最佳落子点;而博弈树可以通过提前落子进行全局预判进行更全方位的对人类方的围追堵截。
另外,可以通过在课堂上学到的知识,比如BFS、DFS、A*算法、决策树算法 等应用于五子棋的智能决策中。
《人工智能》这门课让我对于图、知识表示、智能决策等各个方面有了更好地认识与体验,课堂设计内容充实有趣,让我受益匪浅,希望今后可以更加深入这个方面,并且将课堂上学到的知识应用于实践之中。