c语言实战:从零开始实现三子棋游戏 | 来自我的第一个完整c语言项目

张开发
2026/5/18 12:03:11 15 分钟阅读
c语言实战:从零开始实现三子棋游戏 | 来自我的第一个完整c语言项目
经过两天时间我完成了我的小项目--三子棋终于能成功运行啦在之前的时间里我一直仅仅是在完成一些c语言课后小作业并没有真正自己动手完成一个完整的项目。后来在一本有关编程的书里面说真正动手才能提升自己的编程能力所以我也动手想完成这个已经有很多人写过的三子棋项目。经过不断调试我终终终终终于完成今天记录一下我整个开发过程希望想入手这个小项目的小伙伴们能少走一些弯路/一、为什么想写三子棋呢我在最近一段时间学习完了c语言c语言的很多知识点很散不知道给怎么串起来。而三子棋这个项目犹如一个大篓子用到的知识点不多但很全面像什么二维数组、随机数生成、文件调用等等它都有它规则并不算难还挺适合新手的完整完成还非常有成就感。二、项目的整体思路三子棋游戏规则很简单3x3的棋盘玩家下*电脑下#谁能先完成横、竖、斜连成线就算谁赢如果棋盘下满没人赢就算是平局。整个流程也是非常清晰明了1.打印一个游戏菜单选择开始游戏或者退出。2.定义一个空棋盘。3.初始化棋盘将所有位置设为空格。4.打印这个空棋盘。5.玩家输入坐标下棋-打印棋盘-判断是否胜利。6.电脑随机下棋-打印棋盘-判断是否胜利。7.循环往复直到分出胜负亦或是平局。三、多文件结构我进行编译时把代码分成了三个文件这样思路清晰多了。game.h头文件放函数声明、宏定义以及一些特定头文件。game.c游戏功能函数的实现。test.c主函数游戏主要逻辑菜单。这样一来代码可读性大大提升分类好后续修改也更加方便。四、核心功能实现1.棋盘定义以及初始化我使用char sand[3][3]这个二维数组作为棋盘将所有位置初始化为 这样一来打印的就是空棋盘。2.打印棋盘我用 _ 和 | 来画棋盘要注意的是最后一行不要再打印下划线_,不好看。3.玩家下棋玩家输入坐标如 1 2 中间用空格隔开同时有两个判断·坐标要在1~3范围内防止越界。·输入坐标是否被占用。均合法* 代替 。4.电脑下棋用rand生成随机坐标并且判断此位置是否为空格若是空就下 #。5.判断胜负· 三行是否有相同的非空格字符本人在此犯过严重错误后面会提到。· 三列是否有相同的非空格字符。· 两条对角线是否有相同的非空格字符。· 棋盘满了没人胜利则为平局。五、编译时踩的坑1.char类型我却使用了双引号 “ ” 。2.判断相等 写成了赋值 逻辑全错运行时我一脸懵。3.我判断胜负时没加 ,导致我三个空格也被判赢游戏一开始就结束了。六、运行效果展示1.选择1开始游戏选择0结束游戏。2.玩家下棋、电脑下棋交替落子3.玩家胜利/电脑胜利/平局·玩家胜利·电脑胜利·平局七、总结说起来编译时最重要的就是严谨 严谨 再严谨每一个细小的东西都不能放过。在未来严谨我将会一直贯彻。做完这个项目我释然的笑了像是看见自己的“孩子”一样也许从这个时候开始我不再仅仅是“hello wold”更是在“change wold”。八、完整源码我使用的是vs2022这个编译器。· game.h#pragma once#includestdio.h#include stdlib.h#include time.h#define ROW 3#define COL 3void insand(char sand[ROW][COL], int row, int col);void dysand(char sand[ROW][COL], int row, int col);void player_move(char sand[ROW][COL], int row, int col);void dy_move(char sand[ROW][COL], int row, int col);char pd_move(char sand[ROW][COL], int row, int col);void pc_move(char sand[ROW][COL], int row, int col);· game.c#define _CRT_SECURE_NO_WARNINGS#includegame.hvoid insand(char sand[ROW][COL], int row,int col){for (int i 0; i row; i){for (int j 0; j col; j){sand[i][j] ;}}}void dysand(char sand[ROW][COL], int row, int col){for (int i 0; i row; i){for (int j 0; j col; j){printf( %c , sand[i][j]);if (j ! 2){printf(|);}}printf(\n);if (i ! 2){printf(-----------);}printf(\n);}}int m, n;void player_move(char sand[ROW][COL], int row, int col){while (1){printf(请玩家移动);scanf(%d %d, m, n);if ((m ROW m 0) (n COL n 0)){if (sand[m - 1][n - 1] ){sand[m - 1][n - 1] *;break;}else{printf(当前坐标已经有棋子了\n);}}else{printf(输入有误);}}}void dy_move(char sand[ROW][COL], int row, int col){for (int i 0; i row; i){for (int j 0; j col; j){printf( %c , sand[i][j]);if (j ! 2){printf(|);}}printf(\n);if (i ! 2){printf(-----------);}printf(\n);}}static int ml(char sand[ROW][COL], int row, int col){for (int i 0; i row; i){for (int j 0; j col; j){if (sand[i][j] ){return 0;//没满}}}return 1;//满了}char pd_move(char sand[ROW][COL], int row, int col){//玩家赢了//平局//玩家没有赢 继续玩for (int i 0; i ROW; i){for (int j 0; j COL; j){if (sand[0][j]! sand[0][j] sand[1][j] sand[1][j] sand[2][j]){return sand[0][j];}else if(sand[i][0] ! sand[i][0] sand[i][1] sand[i][1] sand[i][2] ){return sand[i][0];}else if(sand[0][0] ! sand[0][0] sand[1][1] sand[1][1] sand[2][2]){return sand[0][0];}else if (sand[0][2] ! sand[0][2] sand[1][1] sand[1][1] sand[2][0]){return sand[0][2];}}}if (ml(sand, ROW, COL) 1){return A;//平局}return B;//没满继续玩}void pc_move(char sand[ROW][COL], int row, int col){printf(电脑移动\n);while (1){int x rand() % row;//[0-row)int y rand() % col;//[0-col)if (sand[x][y] ){sand[x][y] #;break;}}}· test.c#define _CRT_SECURE_NO_WARNINGS#includegame.h//菜单void menu(){printf(------------------------------\n);printf(----------1.开始游戏----------\n);printf(----------0.结束游戏----------\n);printf(------------------------------\n);}void game(){//1.定义一个空棋盘char sand[ROW][COL];//2.初始化棋盘insand(sand, ROW, COL);//3.打印这个棋盘dysand(sand, ROW, COL);char ret 0;//4.进入游戏while (1){//5.玩家移动player_move(sand, ROW, COL);//6.移动完后打印棋盘dy_move(sand, ROW, COL);//7.判断玩家是否胜利ret pd_move(sand, ROW, COL);if (ret ! B){break;}//8.电脑移动pc_move(sand, ROW, COL);//9.移动完后打印棋盘dy_move(sand, ROW, COL);//10.判断电脑是否胜利ret pd_move(sand, ROW, COL);if (ret ! B){break;}}if (ret A){printf(平局\n);}else if (ret *){printf(玩家胜利\n);}else if (ret #){printf(电脑胜利\n);}}int main(){srand((unsigned int)time(NULL));int input 0;do{menu();printf(请输入你的操作);scanf(%d, input);switch (input){case 0:printf(游戏结束\n);break;case 1:game();break;default:printf(输入有误请输入1或者0\n);break;}} while (input ! 0);return 0;}

更多文章