/*
五子棋
*/
#include<stdio.h>
#include<stdlib.h>
#include<graphics.h>
#include<bios.h>
#include<conio.h>
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
#define SPACE 0x3920
#define BILI 20
#define JZ 4
#define JS 3
#define N 19
int box[N][N]
int step_x,step_y
int key
int flag=1
void draw_box()
没派携void draw_cicle(int x,int y,int color)
void change()
void judgewho(int x,int y)
void judgekey()
int judgeresult(int x,int y)
void attentoin()
void attention()
{
char ch
window(1,1,80,25)
textbackground(LIGHTBLUE)
textcolor(YELLOW)
clrscr()
gotoxy(15,2)
printf("游戏 *** 作规则:")
gotoxy(15,4)
printf("Play Rules:")
gotoxy(15,6)
printf("1、按左右上下方向键移动棋子")
gotoxy(15,8)
printf("1. Press Left,Right,Up,Down Key to move Piece")
gotoxy(15,10)
printf("2、按空格确定落棋子枯伏")
gotoxy(15,12)
printf("2. Press Space to place the Piece")
gotoxy(15,14)
printf("3、禁止在棋盘外按空格")
gotoxy(15,16)
printf("3. DO NOT press Space outside of the chessboard")
gotoxy(15,18)
printf("你是否接受上述的游戏规则(Y/N)")
羡举gotoxy(15,20)
printf("Do you accept the above Playing Rules? [Y/N]:")
while(1)
{
gotoxy(60,20)
ch=getche()
if(ch=='Y'||ch=='y')
break
else if(ch=='N'||ch=='n')
{
window(1,1,80,25)
textbackground(BLACK)
textcolor(LIGHTGRAY)
clrscr()
exit(0)
}
gotoxy(51,12)
printf(" ")
}
}
void draw_box()
{
int x1,x2,y1,y2
setbkcolor(LIGHTBLUE)
setcolor(YELLOW)
gotoxy(7,2)
printf("Left, Right, Up, Down KEY to move, Space to put, ESC-quit.")
for(x1=1,y1=1,y2=18x1<=18x1++)
line((x1+JZ)*BILI,(y1+JS)*BILI,(x1+JZ)*BILI,(y2+JS)*BILI)
for(x1=1,y1=1,x2=18y1<=18y1++)
line((x1+JZ)*BILI,(y1+JS)*BILI,(x2+JZ)*BILI,(y1+JS)*BILI)
for(x1=1x1<=18x1++)
for(y1=1y1<=18y1++)
box[x1][y1]=0
}
void draw_circle(int x,int y,int color)
{
setcolor(color)
setlinestyle(SOLID_LINE,0,1)
x=(x+JZ)*BILI
y=(y+JS)*BILI
circle(x,y,8)
}
void judgekey()
{
int i
int j
switch(key)
{
case LEFT :
if(step_x-1<0)
break
else
{
for(i=step_x-1,j=step_yi>=1i--)
if(box[i][j]==0)
{
draw_circle(step_x,step_y,LIGHTBLUE)
break
}
if(i<1)break
step_x=i
judgewho(step_x,step_y)
break
}
case RIGHT :
if(step_x+1>18)
break
else
{
for(i=step_x+1,j=step_yi<=18i++)
if(box[i][j]==0)
{
draw_circle(step_x,step_y,LIGHTBLUE)
break
}
if(i>18)break
step_x=i
judgewho(step_x,step_y)
break
}
case DOWN :
if((step_y+1)>18)
break
else
{
for(i=step_x,j=step_y+1j<=18j++)
if(box[i][j]==0)
{
draw_circle(step_x,step_y,LIGHTBLUE)
break
}
if(j>18)break
step_y=j
judgewho(step_x,step_y)
break
}
case UP :
if((step_y-1)<0)
break
else
{
for(i=step_x,j=step_y-1j>=1j--)
if(box[i][j]==0)
{
draw_circle(step_x,step_y,LIGHTBLUE)
break
}
if(j<1)break
step_y=j
judgewho(step_x,step_y)
break
}
case ESC :
break
case SPACE :
if(step_x>=1&&step_x<=18&&step_y>=1&&step_y<=18)
{
if(box[step_x][step_y]==0)
{
box[step_x][step_y]=flag
if(judgeresult(step_x,step_y)==1)
{
sound(1000)
delay(1000)
nosound()
gotoxy(30,4)
if(flag==1)
{
setbkcolor(BLUE)
cleardevice()
setviewport(100,100,540,380,1)
/*定义一个图形窗口*/
setfillstyle(1,2)
/*绿色以实填充*/
setcolor(YELLOW)
rectangle(0,0,439,279)
floodfill(50,50,14)
setcolor(12)
settextstyle(1,0,5)
/*三重笔划字体, 水平放?5倍*/
outtextxy(20,20,"The White Win !")
setcolor(15)
settextstyle(3,0,5)
/*无衬笔划字体, 水平放大5倍*/
outtextxy(120,120,"The White Win !")
setcolor(14)
settextstyle(2,0,8)
getch()
closegraph()
exit(0)
}
if(flag==2)
{
setbkcolor(BLUE)
cleardevice()
setviewport(100,100,540,380,1)
/*定义一个图形窗口*/
setfillstyle(1,2)
/*绿色以实填充*/
setcolor(YELLOW)
rectangle(0,0,439,279)
floodfill(50,50,14)
setcolor(12)
settextstyle(1,0,8)
/*三重笔划字体, 水平放大8倍*/
outtextxy(20,20,"The Red Win !")
setcolor(15)
settextstyle(3,0,5)
/*无衬笔划字体, 水平放大5倍*/
outtextxy(120,120,"The Red Win !")
setcolor(14)
settextstyle(2,0,8)
getch()
closegraph()
exit(0)
}
}
change()
break
}
}
else
break
}
}
void change()
{
if(flag==1)
flag=2
else
flag=1
}
void judgewho(int x,int y)
{
if(flag==1)
draw_circle(x,y,15)
if(flag==2)
draw_circle(x,y,4)
}
int judgeresult(int x,int y)
{
int j,k,n1,n2
while(1)
{
n1=0
n2=0
/*水平向左数*/
for(j=x,k=yj>=1j--)
{
if(box[j][k]==flag)
n1++
else
break
}
/*水平向右数*/
for(j=x,k=yj<=18j++)
{
if(box[j][k]==flag)
n2++
else
break
}
if(n1+n2-1>=5)
{
return(1)
break
}
/*垂直向上数*/
n1=0
n2=0
for(j=x,k=yk>=1k--)
{
if(box[j][k]==flag)
n1++
else
break
}
/*垂直向下数*/
for(j=x,k=yk<=18k++)
{
if(box[j][k]==flag)
n2++
else
break
}
if(n1+n2-1>=5)
{
return(1)
break
}
/*向左上方数*/
n1=0
n2=0
for(j=x,k=yj>=1,k>=1j--,k--)
{
if(box[j][k]==flag)
n1++
else
break
}
/*向右下方数*/
for(j=x,k=yj<=18,k<=18j++,k++)
{
if(box[j][k]==flag)
n2++
else
break
}
if(n1+n2-1>=5)
{
return(1)
break
}
/*向右上方数*/
n1=0
n2=0
for(j=x,k=yj<=18,k>=1j++,k--)
{
if(box[j][k]==flag)
n1++
else
break
}
/*向左下方数*/
for(j=x,k=yj>=1,k<=18j--,k++)
{
if(box[j][k]==flag)
n2++
else
break
}
if(n1+n2-1>=5)
{
return(1)
break
}
return(0)
break
}
}
void main()
{
int gdriver=VGA,gmode=VGAHI
clrscr()
attention()
initgraph(&gdriver,&gmode,"c:\\tc")
/* setwritemode(XOR_PUT)*/
flag=1
draw_box()
do
{
step_x=0
step_y=0
/*draw_circle(step_x,step_y,8)*/
judgewho(step_x-1,step_y-1)
do
{
while(bioskey(1)==0)
key=bioskey(0)
judgekey()
}
while(key!=SPACE&&key!=ESC)
}
while(key!=ESC)
closegraph()
}
这是一个简单的程序,会自动计算提子档陪,但不会数目。其行汪蠢它的运行一次估计就差不多会用了。稍微写了点注释。#include<stdio.h>
#include<stdlib.h>
char board[21][21]
char move[5][2]={{-1,0},{1,0},{0,-1},{0,1},{0,0}}
void initBoard()//初始化棋盘
void showBoard()//输出棋盘
char set(int x,int y,char color)//下子
void process(int xx,int yy)//计算提子
int main()
{
FILE * fptr=NULL
char pufile[256]={0}
char op
int s
int x,y,r
char color
char win
int cnt
start:
s=8
while(s!=1 &&s!=2)
{
printf("选择模式:\n1---下棋\n2---看棋谱\n0---退出陵神\n")
printf("下棋模式下,下子请输入s x y(x,y为位置),认输输入g,和棋输入h\n选择:")
scanf("%d",&s)
if(s==0) return 0
//Egg1
if(s==10) printf("Programmer: swordlance :)\n")
//Egg1 end
}
getchar()
printf("输入棋谱路径:")
gets(pufile)
if(s==1) fptr=fopen(pufile,"w")
else fptr=fopen(pufile,"r")
if(!fptr)
{
printf("文件无法打开(创建)!\n")
system("PAUSE")
return -1
}
initBoard()
cnt=0
color='B'
while(op!='g')
{
system("CLS")
showBoard()
printf("(第%d手)",++cnt)
if(s==1)
{
printf("%c 方:",color)
scanf("%c",&op)
//printf("[%c]",op)
if(op=='s')
{
scanf("%d %d",&x,&y)
getchar()
if(set(x,y,color)!=0)
{
printf("该处不能落子!\n")
cnt--
system("PAUSE")
}
else
{
process(x,y)
fprintf(fptr,"%d %d\n",x,y)
if(color=='B') color='W'
else color='B'
}
}
else if(op=='g')
{
printf("%c 方认输。\n",color)
if(color=='B') fprintf(fptr,"0 1\n")
else fprintf(fptr,"0 -1\n")
fflush(fptr)
fclose(fptr)
system("PAUSE")
goto start
}
else if(op=='h')
{
printf("和棋。\n")
fprintf(fptr,"0 0\n")
fflush(fptr)
fclose(fptr)
system("PAUSE")
goto start
}
else
{
printf("参数错误,下子请输入s x y(x,y为位置),认输输入 g,和棋输入h")
cnt--
system("PAUSE")
}
}
else
{
fscanf(fptr,"%d %d",&x,&y)
if(x==0)
{
if(y>0) printf("W 方胜!\n")
else if(y<0) printf("B 方胜!\n")
else printf("和棋!\n")
system("PAUSE")
goto start
}
else
{
printf("%c 方落子(%d,%d)\n",color,x,y)
set(x,y,color)
process(x,y)
if(color=='B') color='W'
else color='B'
}
system("PAUSE")
}
}
system("PAUSE")
return 0
}
void initBoard()
{
int i,j
board[0][0]='O'
for(i=1i<=19i++) board[0][i]='-'
board[0][20]='O'
for(i=1i<=19i++)
{
board[i][0]='|'
for(j=1j<=19j++) board[i][j]='+'
board[i][20]='|'
}
board[20][0]='O'
for(i=1i<=19i++) board[20][i]='-'
board[20][20]='O'
board[4][4]=board[4][10]=board[4][16]=
board[10][4]=board[10][10]=board[10][16]=
board[16][4]=board[16][10]=board[16][16]='*'
}
void showBoard()
{
int i,j
for(i=0i<=20i++)
{
for(j=0j<=20j++)
{
printf("%c",board[i][j])
}
printf("\n")
}
}
char set(int x,int y,char color)
{
if(board[x][y]=='W' || board[x][y]=='B') return -1//不能落子
else board[x][y]=color
return 0
}
//计算提子
void process(int xx,int yy)
{
char his[21][21]={0}//记录算过的棋子以节约效率
char Q[400][2]={0}//某一片棋
int e//Q的长度。
char mcolor//这片棋的颜色
char ecolor//另一种颜色
int QI=0//气数
int i,j,k,l,m
int x,y
for(m=0m<5m++)
{
i=xx+move[m][0]//为了能够完成打劫,先算别人再算自己
j=yy+move[m][1]
if(his[i][j]==0 &&(board[i][j]=='W' || board[i][j]=='B')) //该位置有子开始算气
{
QI=0
his[i][j]=1
mcolor=board[i][j]
ecolor=(board[i][j]=='W'?'B':'W')
//printf("m=%c e=%c\n",mcolor,ecolor)
Q[0][0]=i
Q[0][1]=j
e=1
for(k=0k<ek++)
{
for(l=0l<4l++)
{
x=Q[k][0]+move[l][0]
y=Q[k][1]+move[l][1]
//printf("x=%d y=%d\n",x,y)
//system("PAUSE")
if(x>0 &&y>0 &&x<20 &&y<20 &&his[x][y]==0)
{
if(board[x][y]==mcolor)//己方,长气
{
Q[e][0]=x
Q[e][1]=y
e++
his[x][y]=1
}
else
{
if(board[x][y]=='+') QI++//空地,加气,忽略重复计算
}
}
}
}
//printf("QI=%d\n",QI)
//system("PAUSE")
if(!QI)//死棋,提子
{
for(k=0k<ek++)
{
board[Q[k][0]][Q[k][1]]='+'
his[Q[k][0]][Q[k][1]]=0
}
}
}
}
}
精简版开源AlphaGo来了,你也可以和TA下围棋了程序原理
阿尔法围棋(AlphaGo)是一款围棋人工智能程序。这个程序利用“价值网络”去计算局面,用“策略网络”去选择下子。
深度学习
阿尔法围棋(AlphaGo)的主要工作原理是“深度学习”。“深度学习”是指多层的人工神经网络和训练它的方法。一层神经网络会把大量矩阵数字作为输入,通过非线性激活方法取权重,再产生另一个数据集合作为输出。这就像生物神经大脑的工作机理一样,通过合适的矩阵数量,多层组织链接档搏一起,形成神经网络“大脑”进行精准备蠢橘复杂的处理,就像人们识别物体标注图片一样。
两个大脑
阿尔法围棋(AlphaGo)是通过两个不同神经网络“大脑”合作来改进下棋。这些大脑是多层神经网络跟那些Google图片搜索引擎识别图片在结构上是相似的。它们从多层启发式二维过滤器开始,去处理围棋棋盘的定位,就像图片分类器网络处理图片一样。经过过滤,13 个完全连接的神经网络层产生对它们看到的局面判断。这些层能够做分类和逻辑推理。
这些网络通过反复训练来检查结果,再去校对调整参数,去让下次执行更好。这个处理器有大量的随机性元素,所以人们是不可能精确知道网络是如何“思考”的,但更多的训练后能让它进化到更好。
第一大脑:落子选择器 (Move Picker)
阿尔法围棋(AlphaGo)的第一个神经网络大脑是“监督学习的策略网络(Policy Network)” ,观察棋盘布局企图找到最佳的下一步。事实上,它预测每一个合法下一步的最佳概率,那么最前面猜测的就是那个概率最高的。这可以理解成“落子选择器”。
第二大脑:棋局评估器 (Position Evaluator)
阿尔法围棋(AlphaGo)的第二个大脑相对于落子选择器是回答另一个问题。不是去猜测具体下一步,它预测每一个棋手赢棋的可能,在给定棋子位置情况下。这“局面评估器”就是“价值网络(Value Network)”,通过整体局面判断来辅助落子选择器。这个判断仅仅是大概的,但对于阅读速度提高很有帮助。通过分类潜在的未来局面的“好”与“坏”,AlphaGo能够决定是否通过特殊变种去深入阅读。如果局面评估器说这个特殊变种不行,那么AI就跳过阅读在这一条线上的任何更多落子。[2-6]
主要成绩
研究者让“阿尔法围棋”仿团和其他的围棋人工智能机器人进行了较量,在总计495局中只输了一局,胜率是99.8%。它甚至尝试了让4子对阵CrazyStone、Zen和Pachi三个先进的人工智能机器人,胜率分别是77%、86%和99%。
据国际顶尖期刊《自然》封面文章报道,谷歌研究者开发的名为“阿尔法围棋”(Alpha Go)的人工智能机器人,在没有任何让子的情况下,以5:0完胜欧洲围棋冠军、职业二段选手樊麾。在围棋人工智能领域,实现了一次史无前例的突破。计算机程序能在不让子的情况下,在完整的围棋游戏中击败专业选手,这是第一次。
阿尔法围棋程序的下一个挑战对象是世界围棋冠军李世石。这场人工智能与人类的博弈于2016年3月9日在首尔举行,奖金是由Google提供的100万美金。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)