C语言实战项目-五子棋V1.0(附带全套源代码)
游戏说明
该项目适合新手拿来练习,所用的知识点不是很多,代码部分只有100多行。主要是图形化界面的应用,本游戏实现了人人对战,可以和好朋友来进行对弈。
游戏目标:
在15×15的棋盘上,玩家轮流落子(黑子先手),尝试在水平、垂直或对角线方向上形成连续的五子,以获得胜利。
操作方法:
- 落子规则: 点击鼠标左键在棋盘上的交叉点处落子,黑子为先手,白子为后手。
- 胜利条件: 当任一玩家在任意方向上连续放置了五个自己的棋子时,即可获胜。
- 游戏结束: 当有玩家达成胜利条件时,游戏会弹出提示框显示胜利者,并询问是否重新开始游戏。
游戏效果展示
游戏代码部分
1.函数的声明及头文件的使用
#define _CRT_SECURE_NO_WARNINGS #include #include #include #include int num =1;//-1表示白子,1表示黑子 HWND hwnd1= NULL; //定义一个二维数组存放数据 int piece[15][15]; //函数声明 void draw_line(); void draw_point(); void draw_piece(int m, int n); void initpiece(); int change_piece(int x, int y); int check(int x, int y); int rules(); void reset_game();
2.主函数
使用的库和函数:
- stdio.h: 标准输入输出库,用于输入输出操作,如 printf 和 scanf。
- easyx.h: EasyX 图形库的头文件,提供了绘图和窗口管理的功能。
- graphics.h: 图形库的头文件,用于图形绘制和界面操作。
- windows.h: Windows API 的头文件,提供了 Windows 操作系统的函数和宏定义。
主要功能和流程:
-
初始化操作:
- 使用 printf 和 scanf 分别输入执黑棋和执白棋的玩家姓名。
- 调用 initgraph(650, 450) 初始化图形界面,创建窗口大小为 650x450 像素的游戏窗口。
-
游戏主循环 (while (1) 循环):
- reset_game() 函数用于初始化棋盘和游戏状态,清空画面并绘制棋盘。
- GetMouseMsg() 用于获取鼠标消息,检测鼠标左键按下事件(WM_LBUTTONDOWN),然后调用 draw_piece(m.x, m.y) 在棋盘上落子。
- rules() 函数检测当前游戏状态,判断是否有玩家获胜。如果有玩家获胜,弹出消息框显示胜利者,然后跳出当前游戏循环。
-
游戏结束和重新开始:
- 当游戏结束(有玩家获胜)时,弹出消息框询问玩家是否要重新开始游戏 (MessageBox 函数)。
- 根据玩家的选择(是/否),决定是否跳出主循环,继续游戏或者关闭程序。
-
关闭程序:
- 调用 closegraph() 函数关闭图形界面,释放资源,并返回 0 终止程序运行。
其他功能和注意事项:
-
棋盘绘制和棋子落子:
- draw_line() 和 draw_point() 函数用于绘制棋盘的网格线和特殊点。
- draw_piece() 函数根据当前落子的位置绘制相应颜色的棋子,实现了落子效果和交替玩家回合。
-
游戏规则和胜利判断:
- check() 函数用于检查某个位置落子后是否达成五子连珠的条件。
- rules() 函数在每一步落子后调用,用于判断是否有玩家胜利。
int main() { char one[5]; char two[5]; printf("请输入执黑棋(先手)的姓名:"); scanf("%s", one); printf("请输入执白棋(后手)的姓名:"); scanf("%s", two); hwnd1= initgraph(650, 450); while (1) { MOUSEMSG m; reset_game(); while (1) { m = GetMouseMsg(); //如果鼠标左健按下 if (m.uMsg == WM_LBUTTONDOWN) draw_piece(m.x, m.y); if (rules() == 1) { if (num == 1) { MessageBox(hwnd1, "白棋获胜", "胜利", MB_OK); } else { MessageBox(hwnd1, "黑棋获胜", "胜利", MB_OK); } break; } } int a = MessageBox(hwnd1, "是否要重新开始", "重新开始", MB_YESNO); if (a != IDYES) { break; } } closegraph(); return 0; }
3.画棋盘
-
绘图函数:
- setlinecolor(color):设置画线的颜色。RGB(rand() % 255, rand() % 255, rand() % 255) 生成一个随机的 RGB 颜色,使得每次绘制的棋盘颜色都不同。
- line(x1, y1, x2, y2):画线函数,用于绘制棋盘的网格线。在这里,通过循环绘制多条水平和垂直线,形成棋盘的格子。
-
循环和计算:
- for (int i = 15; i 12) return 0;
首先检查 (x, y) 是否在数组 piece 的有效范围内。如果 x 或 y 小于 2,或者大于 12,则返回 0,表示位置无效或者超出了数组的边界。
四个方向的连续性检查:
这里对于位置 (x, y),检查了四个方向上的连续性:
水平方向:(x-2, y), (x-1, y), (x, y), (x+1, y), (x+2, y)
垂直方向:(x, y-2), (x, y-1), (x, y), (x, y+1), (x, y+2)
对角线方向(从左上到右下):(x-2, y-2), (x-1, y-1), (x, y), (x+1, y+1), (x+2, y+2)
对角线方向(从左下到右上):(x-2, y+2), (x-1, y+1), (x, y), (x+1, y-1), (x+2, y-2)
如果在任何一个方向上发现连续的五个相同元素(包括 (x, y) 本身),则返回 1,表示检测到了符合条件的连续性。
返回结果:
如果以上所有条件都不满足(即 (x, y) 位置不符合任何连续性条件),则返回 0。
使用的知识点和功能:
数组的访问和边界检查
多个方向上的元素比较和逻辑判断
C 语言中的条件语句和函数定义
int check(int x, int y) { if (x 12 || y>12)return 0; if (piece[x][y] == piece[x - 1][y] && piece[x][y] == piece[x - 2][y] && piece[x][y] == piece[x + 1][y] && piece[x][y] == piece[x + 2][y])return 1; if (piece[x][y] == piece[x][y - 1] && piece[x][y] == piece[x][y - 2] && piece[x][y] == piece[x][y + 1] && piece[x][y] == piece[x][y + 2])return 1; if (piece[x][y] == piece[x - 1][y - 1] && piece[x][y] == piece[x - 2][y - 2] && piece[x][y] == piece[x + 1][y + 1] && piece[x][y] == piece[x + 2][y + 2])return 1; if (piece[x][y] == piece[x - 1][y + 1] && piece[x][y] == piece[x - 2][y + 2] && piece[x][y] == piece[x + 1][y - 1] && piece[x][y] == piece[x + 2][y - 2])return 1; return 0; }
9.游戏规则
函数定义:
int rules()
rules 是一个函数,返回类型为 int,没有参数。
双重循环遍历:
函数通过双重循环遍历一个二维数组 piece,数组的大小是 15x15。
内部的两个循环用于遍历数组的每个元素 (i, j)。
条件检查:
if (piece[i][j] == 0) continue;
如果数组中当前位置 (i, j) 的值为 0,则跳过当前循环,继续下一个元素的检查。这表示如果这个位置为空(或者未被占据),则不执行后续的检查。
if (check(i, j) == 1) return 1;
调用 check 函数,传递当前位置 (i, j) 的坐标作为参数。如果 check 函数返回 1,则说明在当前位置 (i, j) 发现了符合游戏规则的连续相同元素序列。
如果发现任何一个位置满足规则,立即返回 1,表示游戏规则被触发。
返回结果:
如果所有位置都被检查过且没有发现符合规则的情况,则函数返回 0,表示游戏规则未被触发。
使用的知识点和功能:
双重循环:用于遍历二维数组的每个元素。
条件语句:用于检查当前位置的值,并决定是否继续执行和返回。
函数调用:调用 check 函数来检查特定位置是否符合游戏规则。
返回值:函数根据检查结果返回 0 或 1。
//游戏规则 int rules() { for(int i=0;i12)return 0; if (piece[x][y] == piece[x - 1][y] && piece[x][y] == piece[x - 2][y] && piece[x][y] == piece[x + 1][y] && piece[x][y] == piece[x + 2][y])return 1; if (piece[x][y] == piece[x][y - 1] && piece[x][y] == piece[x][y - 2] && piece[x][y] == piece[x][y + 1] && piece[x][y] == piece[x][y + 2])return 1; if (piece[x][y] == piece[x - 1][y - 1] && piece[x][y] == piece[x - 2][y - 2] && piece[x][y] == piece[x + 1][y + 1] && piece[x][y] == piece[x + 2][y + 2])return 1; if (piece[x][y] == piece[x - 1][y + 1] && piece[x][y] == piece[x - 2][y + 2] && piece[x][y] == piece[x + 1][y - 1] && piece[x][y] == piece[x + 2][y - 2])return 1; return 0; } //游戏规则 int rules() { for(int i=0;i
- for (int i = 15; i 12) return 0;
-