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;
}

全部评论 6
好像要加-std=c++11才行
8小时前 来自 广东
3哎没人看
昨天 来自 广东
3看你什么 AI



8小时前 来自 浙江
28小时前 来自 广东
1兄弟兄弟你能不能用蓝奏云上传exe
昨天 来自 浙江
1我没蓝奏云
昨天 来自 广东
1你可以注册一下
昨天 来自 浙江
1我试试
昨天 来自 广东
1
两把全平是啥阴
7小时前 来自 浙江
0e
6小时前 来自 广东
0






























有帮助,赞一个