C语言五子棋项目
头文件与宏定义
#include <graphics.h>
#include <conio.h>
graphics.h:EasyX 图形库,提供图形绘制功能(画线、画圆、显示文字等)。
conio.h:提供控制台输入输出函数(这里只是为了兼容性,实际用得少)。
#define NUM 15 // 棋盘边的格数
#define WIN_NUM 5 // 连续5个同色棋子胜利
NUM:棋盘一边有15条线,实际有14个格子,15个交叉点。
WIN_NUM:五子棋规则,连成5子获胜。
int pieceArr[NUM][NUM] = { 0 };
pieceArr:二维数组,表示棋盘上的状态。
0:没有棋子
1:黑棋
2:白棋
棋盘绘制部分
Draw_line() - 绘制棋盘格线
void Draw_line(){setlinecolor(BLACK); for (int y = 20; y < 600; y += 40)line(20, y, 580, y); // 画横线 for (int x = 20; x < 600; x += 40) line(x, 20, x, 580); // 画竖线
}
每40像素画一条线,从 (20,20) 开始,到 (580,580) 结束。
保证棋盘大小和比例统一,方便后面落子。
Draw_point() - 绘制棋盘上的星位点(黑色小圆点)
void Draw_point(){ setfillcolor(BLACK); fillcircle(140, 140, 5); fillcircle(460, 140, 5);fillcircle(140, 460, 5); fillcircle(460, 460, 5); fillcircle(300, 300, 5);
}
在棋盘上五个标准位置绘制小圆点。
星位标志,有助于棋手定位。
棋子处理部分
Draw_piece(bool black, int x, int y) - 绘制棋子
void Draw_piece(bool black, int x, int y)
{ int i = x / 40; int j = y / 40;if (black) {setfillcolor(BLACK);pieceArr[i][j] = 1; } else{ setfillcolor(WHITE);pieceArr[i][j] = 2; } fillcircle(20 + i * 40, 20 + j * 40, 15);
}
根据鼠标点击的位置 (x,y),计算落在哪个格子上。
判断是黑棋还是白棋。
修改棋盘数组 pieceArr,记录落子状态。
画出棋子(半径15的圆)。
NicePos(int x, int y) - 判断点击位置是否合法
bool NicePos(int x, int y){ if (x < 20 || x > 580 || y < 20 || y > 580) return false;int i = x / 40;int j = y / 40;return pieceArr[i][j] == 0;}
检查点击位置是否在棋盘区域内。
检查这个格子有没有被占用。
只有合法并且没落子的地方才能继续下棋。
判断胜负部分
GameOver(int x, int y) - 判断当前落子是否获胜
int GameOver(int x, int y)
{ x = x / 40; y = y / 40; int n = pieceArr[x][y];
}
首先把鼠标坐标转成棋盘数组坐标 (i,j)。然后进行四个方向的连续计数:
水平检查(左—右):
int count = 1;
for (int i = x - 1; i >= 0 && pieceArr[i][y] == n; i--) count++;
for (int i = x + 1; i < NUM && pieceArr[i][y] == n; i++) count++;
if (count >= WIN_NUM) return n;
垂直检查(上—下):
count = 1;
for (int j = y - 1; j >= 0 && pieceArr[x][j] == n; j--) count++;
for (int j = y + 1; j < NUM && pieceArr[x][j] == n; j++) count++;
if (count >= WIN_NUM) return n;
左上-右下斜线检查(45度):
count = 1;
for (int i = x - 1, j = y - 1; i >= 0 && j >= 0 && pieceArr[i][j] == n; i--, j--) count++;
for (int i = x + 1, j = y + 1; i < NUM && j < NUM && pieceArr[i][j] == n; i++, j++) count++;
if (count >= WIN_NUM) return n;
右上-左下斜线检查(135度):
count = 1;
for (int i = x + 1, j = y - 1; i < NUM && j >= 0 && pieceArr[i][j] == n; i++, j--) count++;
for (int i = x - 1, j = y + 1; i >= 0 && j < NUM && pieceArr[i][j] == n; i--, j++) count++;
if (count >= WIN_NUM) return n;
如果某个方向连续5个或更多相同棋子,就返回对应的棋子编号(1或者2),表示胜利。
如果四个方向都没有满足,返回0,表示游戏继续。
主函数 main()
int main()
{initgraph(600, 600);loadimage(NULL, _T("1.png"));Draw_line();Draw_point();
初始化绘图窗口 600x600。
加载一张背景图片(可选)。
画棋盘线和星位点。
游戏主循环
ExMessage m;bool black = true;bool gameOver = false;while (!gameOver){m = getmessage(EX_MOUSE);if (m.message == WM_LBUTTONDOWN){if (NicePos(m.x, m.y)){Draw_piece(black, m.x, m.y);int result = GameOver(m.x, m.y);
监听鼠标左键点击。
判断落点是否合法。
绘制棋子,判断输赢。
如果胜利:
if (result == 1){setbkmode(TRANSPARENT);settextcolor(RED);settextstyle(36, 0, _T("宋体"));outtextxy(250, 300, _T("黑棋胜利!"));FlushBatchDraw();gameOver = true;}else if (result == 2){setbkmode(TRANSPARENT);settextcolor(RED);settextstyle(36, 0, _T("宋体"));outtextxy(250, 300, _T("白棋胜利!"));FlushBatchDraw();gameOver = true;}
在屏幕上显示胜利信息。
black = !black;}}}
轮流换手,黑白交替。
游戏结束后等待用户点击退出
while (true){m = getmessage(EX_MOUSE);if (m.message == WM_LBUTTONDOWN)break;}closegraph();return 0;
}
棋局结束后,等待鼠标点击任意处,再关闭窗口退出程序。
五子棋代码整体流程图
【开始】↓
初始化窗口 (600x600),加载背景图↓
绘制棋盘线 + 星位点↓
设置黑棋先手↓
【进入主循环】↓
等待鼠标事件 (ExMessage)↓
鼠标左键点击?↓
是 → 检查点击点是否为空位 (NicePos)↓是 → - 在点击位置绘制棋子 (Draw_piece)- 更新棋盘数组 (pieceArr)- 判断是否胜利 (GameOver)↓胜利?↓是 → 显示胜利信息,结束游戏否 → 切换黑白方,继续否 → 忽略本次点击↓
【循环直到胜利】↓
胜利后,等待一次鼠标点击↓
退出程序 (closegraph)↓
【结束】
点击落子与胜负判断小流程
鼠标左键点击↓
NicePos 判断:- 在棋盘内?- 位置空闲?↓
符合 → - Draw_piece 画出棋子- 更新 pieceArr 数组- GameOver 检查四个方向 (横/竖/斜线)- 连续5个?胜!- 否则继续- 切换黑白玩家
不符合 → - 无操作,继续等待点击