HINSTANCE hInst
HWND hWnd
ATOMMyRegisterClass(HINSTANCE hInstance)
BOOLInitInstance(HINSTANCE, int)
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM)
void MyPaint()
BOOL XiaQi(int whichPlay, LPARAM lParam)
BOOL IsWin(int whichPlay)
void SetMap()
HBITMAP bmp[3],bg,bufBmp
HDC mdc,hdc,bufDC
int who=1
const int h=11,w=12
const int picH=40,picW=40
int map[w][h]
unsigned long now,pass
void SetMap()
{
for(int i=0i<wi++)
{
for(int j=0j<hj++)
{
map[i][j]=0
}
}
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg
MyRegisterClass(hInstance)
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE
}
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) )
{
TranslateMessage( &msg )
DispatchMessage( &msg )
}
else
{
now=GetTickCount()
if(pass-now>=40)
{
MyPaint()
}
}
}
return msg.wParam
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex
wcex.cbSize = sizeof(WNDCLASSEX)
wcex.style = CS_HREDRAW | CS_VREDRAW
wcex.lpfnWndProc = (WNDPROC)WndProc
wcex.cbClsExtra = 0
wcex.cbWndExtra = 0
wcex.hInstance = hInstance
wcex.hIcon = NULL
wcex.hCursor = NULL
wcex.hCursor = LoadCursor(NULL, IDC_ARROW)
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1)
wcex.lpszMenuName = NULL
wcex.lpszClassName = "canvas"
wcex.hIconSm = NULL
return RegisterClassEx(&wcex)
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance
hWnd = CreateWindow("canvas", "五子棋" , WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,0,0, 0, NULL, NULL, hInstance, NULL)
if (!hWnd)
{
return FALSE
}
SetMap()
bmp[0]=(HBITMAP)LoadImage(NULL,"white.bmp",IMAGE_BITMAP,picW,picH,LR_LOADFROMFILE)
bmp[1]=(HBITMAP)LoadImage(NULL,"red.bmp",IMAGE_BITMAP,picW,picH,LR_LOADFROMFILE)
bmp[2]=(HBITMAP)LoadImage(NULL,"black.bmp",IMAGE_BITMAP,picW,picH,LR_LOADFROMFILE)
if(!bmp[0] || !bmp[1] || !bmp[2])
{
MessageBox(hWnd,"找不要需要的资源,程序将退出.","错误提示",MB_ICONERROR)
ExitProcess(0)
}
MoveWindow(hWnd,10,10,640,480,true)
ShowWindow(hWnd, nCmdShow)
UpdateWindow(hWnd)
hdc=GetDC(hWnd)
SetTextColor(hdc,RGB(255,0,0))
TextOut(hdc,500,100,"红方先下棋",strlen("红方先下棋"))
mdc=CreateCompatibleDC(hdc)
bufDC=CreateCompatibleDC(hdc)
bufBmp=CreateCompatibleBitmap(hdc,w*picW,h*picW)
SelectObject(mdc,bufBmp)
MyPaint()
return TRUE
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int i=0
switch (message)
{
case WM_LBUTTONDOWN:
if(XiaQi(who,lParam))
{
MyPaint()
if(who==1)
{
if(IsWin(who))
{
MessageBox(hWnd,"红方获胜.","恭喜",MB_OK)
SetMap()
}
who=2
SetTextColor(hdc,RGB(0,0,0))
TextOut(hdc,500,100,"轮到黑方下棋",strlen("轮到黑方下棋"))
}
else
{
if(IsWin(who))
{
MessageBox(hWnd,"黑方获胜.","恭喜",MB_OK)
SetMap()
}
who=1
SetTextColor(hdc,RGB(255,0,0))
TextOut(hdc,500,100,"轮到红方下棋",strlen("轮到红方下棋"))
}
}
break
case WM_DESTROY:
for(i=0i<3i++)
{
DeleteObject(bmp[i])
}
ReleaseDC(hWnd,bufDC)
DeleteObject(bufBmp)
ReleaseDC(hWnd,mdc)
ReleaseDC(hWnd,hdc)
PostQuitMessage(0)
break
default:
return DefWindowProc(hWnd, message, wParam, lParam)
}
return 0
}
void MyPaint()
{
SelectObject(mdc,bg)
for(int i=0i<wi++)
{
for(int j=0j<hj++)
{
SelectObject(bufDC,bmp[map[i][j]])
BitBlt(mdc,picW*i,picW*j,picW*w,picH*h,bufDC,0,0,SRCCOPY)
}
}
BitBlt(hdc,0,0,picW*w,picH*h,mdc,0,0,SRCCOPY)
pass=GetTickCount()
}
BOOL XiaQi(int whichPlay, LPARAM lParam)
{
if( LOWORD(lParam) <= picW*w &&LOWORD(lParam)>=0 &&
HIWORD(lParam) <= picH*h &&HIWORD(lParam)>=0)
{
int x=0,y=0
for(int i=1i<=wi++)
{
if( i*picW >= LOWORD(lParam) )
{
x=i
x--
break
}
}
for(int j=1j<=hj++)
{
if( j*picH >= HIWORD(lParam) )
{
y=j
y--
break
}
}
if(whichPlay==1)
{
if(map[x][y]==0)
{
map[x][y]=1
}
else
{
return FALSE
}
}
else
{
if(map[x][y]==0)
{
map[x][y]=2
}
else
{
return FALSE
}
}
return TRUE
}
else
{
return FALSE
}
}
BOOL IsWin(int whichPlay)
{
int num=0
for(int i=0i<wi++)
{
for(int j=0j<hj++)
{
if(whichPlay==1)
{
if(map[i][j]==2 || map[i][j]==0 )
{
num=0
}
if(map[i][j]==1 )
{
num++
if(num==5)
{
return TRUE
}
}
}
else
{
if(map[i][j]==1 || map[i][j]==0)
{
num=0
}
if(map[i][j]==2)
{
num++
if(num==5)
{
return TRUE
}
}
}
}
}
num=0
for( i=0i<wi++)
{
for(int j=0j<hj++)
{
if(whichPlay==1)
{
if(map[j][i]==2 || map[j][i]==0)
{
num=0
}
if(map[j][i]==1)
{
num++
if(num==5)
{
return TRUE
}
}
}
else
{
if(map[j][i]==1||map[j][i]==0)
{
num=0
}
if(map[j][i]==2)
{
num++
if(num==5)
{
return TRUE
}
}
}
}
}
num=0
int k=0
for(i=w-1i>=0i--)
{
for(int j=0j<=ij++)
{
if(whichPlay==1)
{
if(map[j+k][j]==0 || map[j+k][j]==2)
{
num=0
}
if(map[j+k][j]==1)
{
num++
}
if(num==5)
{
return TRUE
}
}
else
{
if(map[j+k][j]==0 || map[j+k][j]==1)
{
num=0
}
if(map[j+k][j]==2)
{
num++
}
if(num==5)
{
return TRUE
}
}
}
num=0
k++
}
num=0
k=0
for(i=w-1i>=0i--)
{
for(int j=0j<=ij++)
{
if(whichPlay==1)
{
if(map[j][j+k]==0 || map[j][j+k]==2)
{
num=0
}
if(map[j][j+k]==1)
{
num++
}
if(num==5)
{
return TRUE
}
}
else
{
if(map[j][j+k]==0 || map[j][j+k]==1)
{
num=0
}
if(map[j][j+k]==2)
{
num++
}
if(num==5)
{
return TRUE
}
}
}
num=0
k++
}
num=0
for(i=0i<wi++)
{
k=i
for(int j=w-1j>=ij--,k++)
{
if(whichPlay==1)
{
if(map[j][k]==0 || map[j][k]==2)
{
num=0
}
if(map[j][k]==1)
{
num++
}
if(num==5)
{
return TRUE
}
}
else
{
if(map[j][k]==0 || map[j][k]==1)
{
num=0
}
if(map[j][k]==2)
{
num++
}
if(num==5)
{
return TRUE
}
}
}
num=0
}
num=0
for( i=w-1i>=0i--)
{
k=0
for(int j=ij>=0j--,k++)
{
if(whichPlay==1)
{
if(map[j][k]==0 || map[j][k]==2)
{
num=0
}
if(map[j][k]==1)
{
num++
}
if(num==5)
{
return TRUE
}
}
else
{
if(map[j][k]==0 || map[j][k]==1)
{
num=0
}
if(map[j][k]==2)
{
num++
}
if(num==5)
{
return TRUE
}
}
}
num=0
}
return FALSE
}
专门给你写的楼档宴裂主,满意的话补分哦~发现问题给我发消息,我修正
有简单的ai,最好是两个人玩或者左右互搏
开始的有说明菜单
代码的第三行WIN改成几就是几子棋
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#define WIN 5
char *view[19][19]
char *const BLACK="○",*const WHITE="●",*const POS="¤"
char *const LT="┌",*const TOP="┬",*const RT="┐"
char *const LEFT="├",*const CENTER="┼",*const RIGHT="┤"
char *const LF="└",*const FOOT="┴",*const RF="┘"
int step[4][2]={1,1,1,-1,1,0,0,1}
int pro
int side
int px,py
int end
int pvc
int pside
int dpx,dpy
int round
int style
void show(int x,int y)
{
int i,j
printf("\t\t%d子棋\n第%d手\n",WIN,round)
for(i=0i<19i++)
{
for(j=0j<19j++)
if(i==x&&j==y)
printf("%s",POS)
else
printf("%s",view[i][j])
puts("")
}
if(side)
printf("\n%s黑方回合",BLACK)
else
printf("\n%s白方回合",WHITE)
}
void login()
{
char sel
getch()
puts("* *** 作说明*\n")
puts("方向↑ : W键 或者 小键盘8")
puts("方向↓ : S键 或者 小键盘5")
puts("方向← : A键 或者 小键盘4")
puts("方向→ : D键 或者 小键盘6")
puts("落子 : 其他任意键\n")
system("pause"祥肆)
system("cls")
puts("*请选择模式*\n")
pvc=0
do
{
pvc=!pvc
if(pvc)
printf("\r单人游戏")
else
printf("\r双行闭人游戏")
sel=getch()
}while(sel!='\r')
puts("\n")
if(pvc)
{
pside=1
do
{
pside=!pside
if(pside)
printf("\r选择黑棋(先行)")
else
printf("\r选择白棋(后行)")
sel=getch()
}while(sel!='\r')
puts("\n")
style=1
do
{
style=!style
if(style)
printf("\r电脑风格进攻")
else
printf("\r电脑风格防守")
sel=getch()
}while(sel!='\r')
}
system("cls")
}
void initial()
{
int i,j
srand(time(NULL))
view[0][0]=LT
for(i=1i<18i++)
view[0][i]=TOP
view[0][18]=RT
for(i=1i<18i++)
{
view[i][0]=LEFT
for(j=1j<18j++)
view[i][j]=CENTER
view[i][18]=RIGHT
}
view[18][0]=LF
for(i=1i<18i++)
view[18][i]=FOOT
view[18][18]=RF
px=9,py=9
end=0
side=1
pro=1
for(i=0i<WINi++)
pro*=WIN
show(px,py)
}
int final(int base,int direction)
{
return
direction==1?18:direction==0?-1:0
}
int judge(int x,int y)
{
int i,j,num,t
for(t=0t<4t++)
{
i=x,j=y,num=1
while(i!=final(i,-step[t][0])
&&j!=final(j,-step[t][1])
&&view[i-step[t][0]][j-step[t][1]]==view[x][y])
i-=step[t][0],j-=step[t][1],num++
i=x,j=y
while(i!=final(i,step[t][0])
&&j!=final(j,step[t][1])
&&view[i+step[t][0]][j+step[t][1]]==view[x][y])
i+=step[t][0],j+=step[t][1],num++
if(num>=WIN)
return 1
}
return 0
}
void move()
{
char cmd=getch()
switch(cmd)
{
case 119:case 56:
if(!px)
px=18
else
px--break
case 115:case 53:
if(px==18)
px=0
else
px++break
case 97: case 52:
if(!py)
py=18
else
py--break
case 100:case 54:
if(py==18)
py=0
else
py++break
default:
if(view[px][py]!=BLACK
&&view[px][py]!=WHITE)
{
if(side)
view[px][py]=BLACK
else
view[px][py]=WHITE
side=!side
if(judge(px,py))
end=1
}
}
}
void win()
{
if(side)
puts("\r白方胜! ")
else
puts("\r黑方胜! ")
}
int uabs(int i)
{
return i<0?-i:i
}
int cml(int i)
{
return i>0?i-19:19+i
}
void AI_move(int ai_side,int dis)
{
int i,j
char *AI_SIDE=ai_side?BLACK:WHITE
i=dpx-px
j=dpy-py
if(uabs(i)>9)
i=cml(i)
if(uabs(j)>9)
j=cml(j)
while(i||j)
{
if(i)
{
i>0?(i--,px++):(i++,px--)
if(px<0||px>18)
px=cml(px)
}
if(j)
{
j>0?(j--,py++):(j++,py--)
if(py<0||py>18)
py=cml(py)
}
if(dis)
{
system("cls")
show(px,py)
}
}
view[px][py]=AI_SIDE
if(judge(px,py))
end=1
side=!side
}
void computer_attack(int ai_side)
{
int fx,fy,i,j,same,len,tlen,t,tsame,maxscore=0,score,u
char *AI_SIDE=ai_side?BLACK:WHITE
char *P_SIDE=AI_SIDE==WHITE?BLACK:WHITE
for(fx=0fx<19fx++)
for(fy=0fy<19fy++)
{
if(view[fx][fy]==BLACK||view[fx][fy]==WHITE)
continue
same=0,len=0
for(t=0t<4t++)
{
i=fx,j=fy,tlen=1,tsame=0,u=pro
while(i!=final(i,-step[t][0])
&&j!=final(j,-step[t][1])
&&view[i-step[t][0]][j-step[t][1]]!=P_SIDE
&&(fx-i!=WIN*step[t][0]|| fy-j!=WIN*step[t][1]))
{
if(view[i-step[t][0]][j-step[t][1]]==AI_SIDE)
tsame+=u,u*=WIN
else
u/=WIN
i-=step[t][0],j-=step[t][1],tlen++
}
i=fx,j=fy,u=pro
while(i!=final(i,step[t][0])
&&j!=final(j,step[t][1])
&&view[i+step[t][0]][j+step[t][1]]!=P_SIDE
&&(i-fx!=WIN*step[t][0]|| j-fy!=WIN*step[t][1]))
{
if(view[i+step[t][0]][j+step[t][1]]==AI_SIDE)
tsame+=u,u*=WIN
else
u/=WIN
i+=step[t][0],j+=step[t][1],tlen++
}
if(tlen>=WIN)
same+=tsame,len+=tlen
}
score=same+len
if(score>maxscore)
{
maxscore=score
dpx=fx,dpy=fy
}
}
}
void first_round()
{
if(round==1)
{
dpx=rand()%10+5,dpy=rand()%10+5
}
if(round==2)
{
dpx=px+rand()%3-1,dpy=py+rand()%3-1
dpx==-1?dpx+=2:0
dpx==19?dpx-=2:0
dpy==-1?dpy+=2:0
dpy==19?dpy-=2:0
}
}
void AI_think(int def)
{
int tpx=px,tpy=py,tside=side
char *tview[19][19]
if(round<3)
{
first_round()
return
}
memcpy(tview,view,19*19*sizeof(char*))
while(!end)
{
if(side==tside)
{
computer_attack(!pside)
AI_move(!pside,0)
}
else
{
computer_attack(pside)
AI_move(pside,0)
}
}
memcpy(view,tview,19*19*sizeof(char*))
px=tpx,py=tpy
end=0
if(side!=tside)
{
side=tside
computer_attack(!pside)
return
}
else
{
while(def-->0)
{
computer_attack(pside)
AI_move(pside,0)
}
memcpy(view,tview,19*19*sizeof(char*))
px=tpx,py=tpy
side=tside
if(end)
computer_attack(pside)
else
computer_attack(!pside)
end=0
}
}
void turn()
{
int tside=side
round++
if(pvc&&side!=pside)
{
AI_think(style?2:WIN)
AI_move(!pside,1)
}
else
{
while(tside==side)
{
move()
system("cls")
show(px,py)
}
}
}
int main()
{
login()
initial()
while(!end)
turn()
win()
system("pause")
}
我写过五子棋程序,也思考过棋类程序的算法,希望能给楼主参考双方对弈棋类算法,其基本思想就是人工智能中关念败吵于 最小-最大问题 的 alpha-beta 剪枝,楼主可搜索一下,这个随便一本人工智能书里都有讲。
下面就是具体程序中该如何实现其思想
一般都要先有一个招法生成器,用于给出当前局面下所有可走的行棋可能。对四子棋来说就仔侍相当简单了,只要看一下每一列,只要未满即可。
然后要有一个局面评估函数,大体评价下双方局势的分数。此函数尽量简单能反映优劣即可,因为后面的 alpha-beta 算法要大量调用此函数
最后实现 alpha-beta 的算法,采用迭代加深的广度优先搜索能有效剪枝。(剪枝效率取决于前面的局面评估函数,如果评估函数能非常准确的估值,那么将会大大减小搜索范围,但复杂的评估函数又会增加开销,这是一个枯李两难的抉择)
不过对于四子棋由于非常简单,楼主也可以尝试仅用简单的广度优先搜索。按每个局面 7 列只有 7 种走法来算,5步深的全搜索也只有 1 万多种情况。对一般人来说5步深也足够强了。不满意的话再考虑上面的正统算法。
然后是一点小技巧,关于棋盘的存储和运算,尽量采用位棋盘和位运算来完成,多利用位运算的并行性来提高效率
这里毕竟字数有限,如果还想更深入了解的话推荐来这里看看:http://www.elephantbase.net/computer.htm
一个相当好的棋类算法网站
虽然是讲象棋的,但基本思路都一样,绝对能学到很多东西。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)