C++五子棋,dev可运行看你如不如ai
2026-08-29 15:16:58
发布于:广东
此代码不涉及任何OPEN GL
纯c++原生头文件
代码如下复制即可(赢了图片发评论区)
tips按R键重置
#include <windows.h>
#include <cstring>
#define SIZE 15
#define SEARCH_DEPTH 4
int board[SIZE][SIZE];
HWND hWnd;
int winPlayer;
int dir[4][2]={{1,0},{0,1},{1,1},{1,-1}};
const int SCORE_WIN=10000000;
const int SCORE_LIVE4=900000;
const int SCORE_DEAD4=500000;
const int SCORE_LIVE3=100000;
const int SCORE_DEAD3=30000;
const int SCORE_LIVE2=5000;
bool CheckWin(int x,int y,int color)
{
for(int d=0;d<4;d++)
{
int dx=dir[d][0],dy=dir[d][1];
int cnt=1;
for(int k=1;k<5;k++)
{
int nx=x+dx*k,ny=y+dy*k;
if(nx>=0&&nx<SIZE&&ny>=0&&ny<SIZE&&board[ny][nx]==color) cnt++;
else break;
}
for(int k=1;k<5;k++)
{
int nx=x-dx*k,ny=y-dy*k;
if(nx>=0&&nx<SIZE&&ny>=0&&ny<SIZE&&board[ny][nx]==color) cnt++;
else break;
}
if(cnt>=5) return true;
}
return false;
}
int CalcLine(int x,int y,int dx,int dy,int color)
{
int s=0;
for(int st=-4;st<=0;st++)
{
int c=0,left=0,right=0;
int sx=x+st*dx;
int sy=y+st*dy;
for(int i=0;i<5;i++)
{
int nx=sx+dx*i;
int ny=sy+dy*i;
if(nx<0||nx>=SIZE||ny<0||ny>=SIZE){
if(i==0) left=1;
if(i==4) right=1;
continue;
}
if(board[ny][nx]==color) c++;
else if(board[ny][nx]!=0){
if(i==0) left=1;
if(i==4) right=1;
}
}
if(left&&right) continue;
if(c==4&&!left&&!right) s+=SCORE_LIVE4;
else if(c==4&&(left^right)) s+=SCORE_DEAD4;
else if(c==3&&!left&&!right) s+=SCORE_LIVE3;
else if(c==3&&(left^right)) s+=SCORE_DEAD3;
else if(c==2&&!left&&!right) s+=SCORE_LIVE2;
}
return s;
}
int EvalPoint(int x,int y,int color)
{
if(board[y][x]!=0) return -SCORE_WIN;
int total=0;
for(int d=0;d<4;d++)
{
int dx=dir[d][0],dy=dir[d][1];
total+=CalcLine(x,y,dx,dy,color);
}
int dx0=x-7,dy0=y-7;
total+= 200/(1+dx0*dx0+dy0*dy0);
return total;
}
int EvalBoard(int ai)
{
int op=3-ai;
int s=0;
for(int y=0;y<SIZE;y++)
{
for(int x=0;x<SIZE;x++)
{
if(board[y][x]==ai) s+=EvalPoint(x,y,ai);
if(board[y][x]==op) s-=EvalPoint(x,y,op);
}
}
return s;
}
void GetCandidate(bool cand[SIZE][SIZE])
{
memset(cand,0,sizeof(bool)*SIZE*SIZE);
bool hasChess=false;
for(int y=0;y<SIZE;y++)
{
for(int x=0;x<SIZE;x++)
{
if(board[y][x]!=0){
hasChess=true;
for(int dy=-2;dy<=2;dy++){
for(int dx=-2;dx<=2;dx++){
int nx=x+dx,ny=y+dy;
if(nx>=0&&nx<SIZE&&ny>=0&&ny<SIZE&&board[ny][nx]==0){
cand[ny][nx]=true;
}
}
}
}
}
}
if(!hasChess){
cand[7][7]=true;
}
}
int AlphaBeta(int depth,int alpha,int beta,int isMax,int ai)
{
if(depth==0) return EvalBoard(ai);
int op=3-ai;
bool cand[SIZE][SIZE];
GetCandidate(cand);
if(isMax)
{
int best=-SCORE_WIN;
for(int y=0;y<SIZE;y++)
{
for(int x=0;x<SIZE;x++)
{
if(!cand[y][x]) continue;
board[y][x]=ai;
if(CheckWin(x,y,ai)){board[y][x]=0;return SCORE_WIN;}
int val=AlphaBeta(depth-1,alpha,beta,0,ai);
board[y][x]=0;
if(val>best) best=val;
if(best>alpha) alpha=best;
if(alpha>=beta) return best;
}
}
return best;
}
else
{
int best=SCORE_WIN;
for(int y=0;y<SIZE;y++)
{
for(int x=0;x<SIZE;x++)
{
if(!cand[y][x]) continue;
board[y][x]=op;
if(CheckWin(x,y,op)){board[y][x]=0;return -SCORE_WIN;}
int val=AlphaBeta(depth-1,alpha,beta,1,ai);
board[y][x]=0;
if(val<best) best=val;
if(best<beta) beta=best;
if(alpha>=beta) return best;
}
}
return best;
}
}
void AiThink(int &outX,int &outY,int ai)
{
int bestVal=-SCORE_WIN;
outX=7;outY=7;
bool cand[SIZE][SIZE];
GetCandidate(cand);
for(int y=0;y<SIZE;y++)
{
for(int x=0;x<SIZE;x++)
{
if(!cand[y][x]) continue;
board[y][x]=ai;
if(CheckWin(x,y,ai))
{
board[y][x]=0;
outX=x;outY=y;
return;
}
int cur=AlphaBeta(SEARCH_DEPTH-1,-SCORE_WIN,SCORE_WIN,0,ai);
board[y][x]=0;
if(cur>bestVal)
{
bestVal=cur;
outX=x;outY=y;
}
}
}
}
void ResetGame()
{
memset(board,0,sizeof(board));
winPlayer=0;
int ax,ay;
AiThink(ax,ay,1);
board[ay][ax]=1;
InvalidateRect(hWnd,NULL,TRUE);
}
LRESULT CALLBACK WndProc(HWND hw,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_KEYDOWN:
if(wParam==0x52){ResetGame();}
break;
case WM_LBUTTONDOWN:
{
if(winPlayer!=0) break;
int mx=LOWORD(lParam);
int my=HIWORD(lParam);
int cx=mx/40;
int cy=my/40;
if(cx>=0&&cx<SIZE&&cy>=0&&cy<SIZE&&board[cy][cx]==0)
{
board[cy][cx]=2;
if(CheckWin(cx,cy,2))
{
winPlayer=2;
InvalidateRect(hw,NULL,FALSE);
return 0;
}
int ax,ay;
AiThink(ax,ay,1);
board[ay][ax]=1;
if(CheckWin(ax,ay,1))
{
winPlayer=1;
}
InvalidateRect(hw,NULL,FALSE);
}
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc=BeginPaint(hw,&ps);
Rectangle(hdc,0,0,600,600);
for(int i=0;i<SIZE;i++)
{
MoveToEx(hdc,i*40,0,NULL);
LineTo(hdc,i*40,560);
MoveToEx(hdc,0,i*40,NULL);
LineTo(hdc,560,i*40);
}
for(int y=0;y<SIZE;y++)
{
for(int x=0;x<SIZE;x++)
{
if(board[y][x]==0)continue;
COLORREF col=board[y][x]==1?RGB(0,0,0):RGB(255,255,255);
HBRUSH br=CreateSolidBrush(col);
SelectObject(hdc,br);
Ellipse(hdc,x*40+4,y*40+4,x*40+36,y*40+36);
DeleteObject(br);
}
}
if(winPlayer!=0)
{
HFONT bigFont=CreateFontA(48,0,0,0,FW_BOLD,0,0,0,GB2312_CHARSET,0,0,0,0,"");
HFONT oldFont=(HFONT)SelectObject(hdc,bigFont);
char buf[64];
if(winPlayer==1) strcpy(buf,"AI Win!");
else strcpy(buf,"You Win!");
SetBkMode(hdc,TRANSPARENT);
SetTextColor(hdc,RGB(255,0,0));
TextOutA(hdc,140,560,buf,strlen(buf));
SelectObject(hdc,oldFont);
DeleteObject(bigFont);
}
EndPaint(hw,&ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hw,msg,wParam,lParam);
}
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int)
{
WNDCLASSEX wc={0};
wc.cbSize=sizeof(wc);
wc.lpfnWndProc=WndProc;
wc.hInstance=hInst;
wc.lpszClassName="GobangAI";
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
RegisterClassEx(&wc);
hWnd=CreateWindowEx(0,"GobangAI","五子棋AI(R重置)",WS_OVERLAPPEDWINDOW,100,100,620,660,NULL,NULL,hInst,NULL);
ShowWindow(hWnd,SW_SHOW);
memset(board,0,sizeof(board));
winPlayer=0;
int ax,ay;
AiThink(ax,ay,1);
board[ay][ax]=1;
MSG msg={0};
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}

全部评论 11
- 置顶
大家可以看一下这个https://www.acgo.cn/discuss/rest/92418
2026-08-31 来自 广东
0 好像要加-std=c++11才行
2026-08-30 来自 广东
3d
2026-08-31 来自 广东
1
哎没人看
2026-08-29 来自 广东
3看你什么 AI



2026-08-30 来自 浙江
2其实是傻包
2026-08-31 来自 广东
0
2026-08-30 来自 广东
1兄弟兄弟你能不能用蓝奏云上传exe
2026-08-29 来自 浙江
1我没蓝奏云
2026-08-29 来自 广东
1你可以注册一下
2026-08-29 来自 浙江
1我试试
2026-08-29 来自 广东
1
d
1周前 来自 广东
0d
2026-09-01 来自 广东
0d
2026-09-01 来自 广东
0d
2026-09-01 来自 广东
0两把全平是啥阴
2026-08-30 来自 浙江
0e
2026-08-30 来自 广东
0d
2026-09-03 来自 广东
0






























有帮助,赞一个