C语言五子棋项目

头文件与宏定义

cpp 复制代码
#include <graphics.h>
#include <conio.h> 

graphics.h:EasyX 图形库,提供图形绘制功能(画线、画圆、显示文字等)。

conio.h:提供控制台输入输出函数(这里只是为了兼容性,实际用得少)。

cpp 复制代码
#define NUM 15 // 棋盘边的格数
#define WIN_NUM 5 // 连续5个同色棋子胜利 

NUM:棋盘一边有15条线,实际有14个格子,15个交叉点。

WIN_NUM:五子棋规则,连成5子获胜。

cpp 复制代码
int pieceArr[NUM][NUM] = { 0 }; 

pieceArr:二维数组,表示棋盘上的状态。

0:没有棋子

1:黑棋

2:白棋

棋盘绘制部分

Draw_line() - 绘制棋盘格线

cpp 复制代码
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() - 绘制棋盘上的星位点(黑色小圆点)

cpp 复制代码
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) - 绘制棋子

cpp 复制代码
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) - 判断点击位置是否合法

cpp 复制代码
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) - 判断当前落子是否获胜

cpp 复制代码
int GameOver(int x, int y) 
{ 
   x = x / 40; 
   y = y / 40; 
   int n = pieceArr[x][y]; 
}

首先把鼠标坐标转成棋盘数组坐标 (i,j)。然后进行四个方向的连续计数:

水平检查(左---右):

cpp 复制代码
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;

垂直检查(上---下):

cpp 复制代码
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度):

cpp 复制代码
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度):

cpp 复制代码
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()

cpp 复制代码
int main()
{
    initgraph(600, 600);
    loadimage(NULL, _T("1.png"));
    Draw_line();
    Draw_point();

初始化绘图窗口 600x600。

加载一张背景图片(可选)。

画棋盘线和星位点。

游戏主循环

cpp 复制代码
    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);

监听鼠标左键点击。

判断落点是否合法。

绘制棋子,判断输赢。

如果胜利:

cpp 复制代码
                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;
                }

在屏幕上显示胜利信息。

cpp 复制代码
                black = !black;
            }
        }
    }

轮流换手,黑白交替。

游戏结束后等待用户点击退出

cpp 复制代码
    while (true)
    {
        m = getmessage(EX_MOUSE);
        if (m.message == WM_LBUTTONDOWN)
            break;
    }
    closegraph();
    return 0;
}

棋局结束后,等待鼠标点击任意处,再关闭窗口退出程序。

五子棋代码整体流程图

css 复制代码
【开始】
    ↓
初始化窗口 (600x600),加载背景图
    ↓
绘制棋盘线 + 星位点
    ↓
设置黑棋先手
    ↓
【进入主循环】
    ↓
等待鼠标事件 (ExMessage)
    ↓
鼠标左键点击?
    ↓
是 → 检查点击点是否为空位 (NicePos)
      ↓
    是 → 
        - 在点击位置绘制棋子 (Draw_piece)
        - 更新棋盘数组 (pieceArr)
        - 判断是否胜利 (GameOver)
          ↓
        胜利?
          ↓
        是 → 显示胜利信息,结束游戏
        否 → 切换黑白方,继续
    否 → 忽略本次点击
    ↓
【循环直到胜利】
    ↓
胜利后,等待一次鼠标点击
    ↓
退出程序 (closegraph)
    ↓
【结束】

点击落子与胜负判断小流程

css 复制代码
鼠标左键点击
    ↓
NicePos 判断:
  - 在棋盘内?
  - 位置空闲?
    ↓
符合 → 
    - Draw_piece 画出棋子
    - 更新 pieceArr 数组
    - GameOver 检查四个方向 (横/竖/斜线)
        - 连续5个?胜!
        - 否则继续
    - 切换黑白玩家
不符合 → 
    - 无操作,继续等待点击
相关推荐
苏三说技术7 分钟前
基于SpringBoot的课程管理系统
java·spring boot·后端
hello_ejb310 分钟前
聊聊Spring AI Alibaba的ObsidianDocumentReader
java·人工智能·spring
桦说编程33 分钟前
警惕AI幻觉!Deepseek对Java线程池中断机制的理解有误
java·后端·deepseek
jackson凌44 分钟前
【Java学习笔记】选择结构
java·笔记·学习
极客先躯1 小时前
高级java每日一道面试题-2025年4月21日-基础篇[反射篇]-如何使用反射获取一个类的所有方法?
java·面试·反射·基础篇
掉鱼的猫1 小时前
开发 MCP Proxy(代理)也可以用 Solon AI MCP 哟!
java·mcp
佩奇的技术笔记1 小时前
Java学习手册:HTTP 协议基础知识
java·http
博弈美业系统Java源码1 小时前
连锁美业管理系统「数据分析」的重要作用分析︳博弈美业系统疗愈系统分享
java·大数据·前端·后端·创业创新
秋野酱1 小时前
基于javaweb的SpringBoot扶农助农平台管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
暮乘白帝过重山1 小时前
为什么Spring中@Bean注解默认创建单例Bean
java·spring