目录
主界面显示与选择模式
VGA显示器显示图片,显示图片利用Block Memory Generator将图片像素点储存在RAM里面。
效果图:(防止侵权打了马赛克)
通过开发板上的按键进行模式选择,模式确定
双人对战
双人对战就是采用简单的存数组的办法,这里五子棋的棋盘是采用13*13的大小,为了方便输赢判断也为了方便后续人机模式得分判断,这里数组采用了21*21大小的数组。
效果图:
在数组中黑子数值为1,白子为2,空白为0,简单的原理就是黑子下完白子下,两个玩家共用一个键盘,每当一个玩家落子后就会进行输赢判断,对数组21*21中13*13的区域每一个点进行判断
如下图:(判断以这个点为中心的横竖斜方向是否都为1或者都为2)
人机对战
该程序采用了局部区域计算得分的方法来实现人机下棋操作
效果图:(采用了和双人对战一样的页面)
当玩家(黑子)下完后人机根据当前棋局进行下棋(没有加延时所以是秒下),并且在最后一次下的白子中心还有一个黑点方便玩家知道人机下哪了。
我原本想用剪枝算法来制作人机的,但是我发现我写完程序后发现我的basys3开发板的LUT不能支持我的算法,还有会超出循环上限的问题(当然还有我自身算法能力不够),最后我重写了一个简单的算法,经过不断优化,最终实现了一个简单的人机对战。
具体算法:
我创建了一个新变量(二进制8位,因为开发板资源有限,所以越简单越好)用来存储得分信息,对每一个空白点进行分数计算,对以每一个空白点为中心的9*9区域进行了条件判断(这是我之前为什么存21*21的数组的原因,因为边界上的空白的话左边本来是没有数组的,进行判断就会出现错误,所以我直接省略了边界条件的判断,让它在一定意义上没有边界,但是这也会造成一定的问题,例如情况:边界,0,2,2,2,1,在这种情况下已经不可能连成五个子了,但是它还是会判断这是一个得分比较高的解)
得分计算:
图1 图2
先对中间空白点赋值,先赋为2(白色),然后对其进行是否连成五子判断(如上图1所示),如果能连成五子就将其得分的最高位(位7)赋为1,对其进行是否连成四子判断(如上图2所示),如果能连成四子就将其得分(位5)赋为1,对其进行是否连成三子判断(如下图3所示),如果能连成三子就将其得分(位3)赋为1,对其进行是否连成二子判断(如下图4所示),如果能连成二子就将其得分(位1)赋为1,其他竖和斜方向也是一样的道理。
图3 图4
然后将这个空白点赋为1(黑色),然后对其进行是否连成五子判断,如果能连成五子就将其得分(位6)赋为1,对其进行是否连成四子判断,如果能连成四子就将其得分(位4)赋为1,对其进行是否连成三子判断,如果能连成三子就将其得分(位2)赋为1,对其进行是否连成二子判断,如果能连成二子就将其得分(位0)赋为1,其他竖和斜方向也是一样的道理。
还有一些特殊情况的判断赋值为了提高人机的博弈力,这里不说明了。
最后找到那个得分最高的空白点就行了。
胜利界面显示
最后也有选择按钮用来控制是当前模式的直接下一局还是返回主页面进行重新选择。
在VGA显示中还采用了取字模延时的方法显示字和一些有趣的动图
比如抽象的坤坤打球动图,豌豆射手和向日葵。
部分源码
score=0;
maxa=0;maxb=0;
for(a=0;a<13;a=a+1)
begin
for(b=0;b<13;b=b+1)
begin
if(if_have_2[a+4][b+4]==0)
begin
score1=0;
if_have_2[a+4][b+4]=2;
for(q=0;q<5;q=q+1)
begin
if(if_have_2[a+q][b+4]==2
&&if_have_2[a+1+q][b+4]==2
&&if_have_2[a+2+q][b+4]==2
&&if_have_2[a+3+q][b+4]==2
&&if_have_2[a+4+q][b+4]==2)
begin
score1[7]=1;
end
else
begin
end
if(if_have_2[a+4][b+q]==2
&&if_have_2[a+4][b+1+q]==2
&&if_have_2[a+4][b+2+q]==2
&&if_have_2[a+4][b+3+q]==2
&&if_have_2[a+4][b+4+q]==2)
begin
score1[7]=1;
end
else
begin
end
if(if_have_2[a+q][b+q]==2
&&if_have_2[a+1+q][b+1+q]==2
&&if_have_2[a+2+q][b+2+q]==2
&&if_have_2[a+3+q][b+3+q]==2
&&if_have_2[a+4+q][b+4+q]==2)
begin
score1[7]=1;
end
else
begin
end
if(if_have_2[a+4-q][b+4+q]==2
&&if_have_2[a+5-q][b+3+q]==2
&&if_have_2[a+6-q][b+2+q]==2
&&if_have_2[a+7-q][b+1+q]==2
&&if_have_2[a+8-q][b+q]==2)
begin
score1[7]=1;
end
else
begin
end
end
for(q=0;q<4;q=q+1)
begin
if(if_have_2[a+1+q][b+4]==2
&&if_have_2[a+2+q][b+4]==2
&&if_have_2[a+3+q][b+4]==2
&&if_have_2[a+4+q][b+4]==2)
begin
score1[5]=1;
end
else
begin
end
if(if_have_2[a+4][b+1+q]==2
&&if_have_2[a+4][b+2+q]==2
&&if_have_2[a+4][b+3+q]==2
&&if_have_2[a+4][b+4+q]==2)
begin
score1[5]=1;
end
else
begin
end
if(if_have_2[a+1+q][b+1+q]==2
&&if_have_2[a+2+q][b+2+q]==2
&&if_have_2[a+3+q][b+3+q]==2
&&if_have_2[a+4+q][b+4+q]==2)
begin
score1[5]=1;
end
else
begin
end
if(if_have_2[a+4-q][b+4+q]==2
&&if_have_2[a+5-q][b+3+q]==2
&&if_have_2[a+6-q][b+2+q]==2
&&if_have_2[a+7-q][b+1+q]==2)
begin
score1[5]=1;
end
else
begin
end
end
for(q=0;q<3;q=q+1)
begin
if(if_have_2[a+2+q][b+4]==2
&&if_have_2[a+3+q][b+4]==2
&&if_have_2[a+4+q][b+4]==2)
begin
score1[3]=1;
end
else
begin
end
if(if_have_2[a+4][b+2+q]==2
&&if_have_2[a+4][b+3+q]==2
&&if_have_2[a+4][b+4+q]==2)
begin
score1[3]=1;
end
else
begin
end
...