(C语言)三子棋(井字棋)娱乐教程

news/2024/11/30 0:28:05/

司机镇楼!!!!!!

口号:好好学习,努力养家

备注:看了正式版看不懂可以转接娱乐版

注意:这是个对于初学者来说的大型工程,分成了三部分来写:test.c,game.c,game.h

正式版:

兄台,也不知道你同不同意,我就放个链接!谢谢!

(18条消息) 三子棋代码实现思路解析与易错点纠正_xbhinsterest11的博客-CSDN博客

这位兄台的就很不错,正式版就用这位大神的吧

娱乐版:

test.c(游戏的测试逻辑)

#define _CRT_SECURE_NO_WARNINGS 1
//游戏的测试逻辑,game.h和game.c才是游戏的主题,这边你可以认为就是个“主函数”
//game为“副函数”船长离不开大副
//船长只是一个主心骨负责统领,大副才是真正干实事的大佬
//#include<stdio.h>证明我存在过,只是后来觉得重复,你不要了,哎!像极了备胎
#include"game.h"//这是自己写的头文件
void menu()
{printf("**************\n");printf("****1.play****\n");printf("****0.exit****\n");printf("**************\n");
}
void game()
{//三子棋,要先有棋盘//要有电脑和人相互下棋的操作//任何下棋后下棋的位置要保存起来//输入的棋子是输入的字符,而棋盘输入是3*3的,我们输入字符输入时是几行几列//所以相当于是一个字符类型的二维数组//******************************************//以上为思考,下面是定义//数据存储到一个字符的二维数组中,玩家下棋是“*”电脑下棋是“#”//这里先构建棋盘,再下棋char board[ROW][COL] = { 0 };//数组的内容应该是全部空格InitBoard(board, ROW, COL);//初始化棋盘//打印棋盘确定是不是初始化正确,不过说实话,你一步步来咋可能错吗?DisplayBoard(board, ROW, COL);//注意哦,不要一看到打印就行到printf,这也打印不出来呀!char ret = 0;while (1){player_move(board,ROW,COL);//玩家下棋一样是在几行几列下棋//是在这个二维数组里面下棋DisplayBoard(board, ROW, COL);//打印棋盘ret = is_win(board, ROW, COL);//马上来一次判断是平局还是继续if (ret != 'C')//-C是继续,-Q是平局{break;//意思就是如果返回值不等于继续-'C'就跳出循环//就是说只要不是继续下棋肯定就是出结果了,不要呆在这个while循环里了}computer_move(board, ROW, COL);//电脑下棋DisplayBoard(board, ROW, COL);//打印棋盘ret = is_win(board, ROW, COL);//注意一定要有,不然你会很困惑,建议尝试去点一下//补充if (ret != 'C'){break;}//到了这里,框架结束,要开始判断输赢了}if(ret == '*'){printf("玩家胜利!\n");}else if(ret == '#'){printf("电脑赢!\n");}else{printf("平局!\n");}
}
void test()
{int input = 0;do{menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:printf("三子棋\n");game();//真正的三子棋游戏break;case 0:printf("退出游戏\n");break;default:printf("选择错误\n");}} while (input);//非零为真,运行选择程序,为零则跳出结束游戏//这就是用do while 的原因,while是零也已经进行了一次do循环
}int main()
{srand((unsigned)time(NULL));test();return 0;
}

game.h(游戏的实现函数声明)

//建议最开始来这么一句,就好像做ppt呀开题要告诉下面的老师,你要讲啥
//游戏的实现函数的声明
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>//这个东东写在这纯属因为啊printf动不动来个未定义
//反正两个c文件都要用,干脆写在都需要调用的game.h里面
#include<time.h>
#include<stdlib.h>
//在头文件里宏定义行和列
//减少不必要的操作且直观清楚
//即如果是10*10的十字棋,只需要在宏定义修改即可
//说实话,你要是觉得也麻烦不想写英文也不用这样
#define ROW 3
#define COL 3
void InitBoard(char board[ROW][COL], int row, int col);//注意区分大小写
//注意:这里的row和ROW不是一个东西
//InitBoard(board,ROW,COL);//初始化棋盘操作
//这句话括号内的参数ROW和COL是int整形,用row表示,这样清楚且不冲突
//这里只是函数声明,函数实现在game.c里进行
void DisplayBoard(char board[ROW][COL], int row, int col);
//啰嗦一句,数组传参,用char a[][]用来接收a[][],或者用指针
//详细说明一下
void player_move(char board[ROW][COL],int row,int col);
//电脑下棋,在ROW*COL的棋盘的(row,col)下棋
void computer_move(char board[ROW][COL], int row, int col);
//判断输赢的代码
//玩家赢-'*'
//电脑赢-'#'
//平局-'Q'
//继续-'C'
char is_win(char board[ROW][COL], int row, int col);

game.c(游戏的实现逻辑)

#define _CRT_SECURE_NO_WARNINGS 1
//游戏的实现逻辑
#include"game.h"
//留一行给未来的老婆,(原谅我复习的时候也不记得这个啥意思了)
void InitBoard(char board[ROW][COL], int row, int col)
{//在board(3*3的棋盘)中下棋,row和col为落子位置的行和列//即将数组全部初始化为空格,构建棋盘int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = ' ';//注意啊,这里有个空格}	}}
//void DisplayBoard(char board[ROW][COL], int row, int col)
//{
//	//此处并不是直接打印空格就行了
//	int i = 0;
//	int j = 0;
//	for (i = 0; i < row; i++)
//	{
//		printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);
//		if (i < row - 1)
//		{
//      //即代表第三行不要打印下面这东东
//			printf("---|---|---\n");
//		}
//		//注意,可以试着打印一下
//		//发现第三行打印的这个———没有必要
//		//哈哈哈,你终于打完了棋盘!congratuation!!!
//		//结果你发现这种方叫做傻瓜打印法,只适用于三子棋
//		//注释掉
//	}
//
//}
void DisplayBoard(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){//数据for (j = 0; j < col; j++){printf(" %c ",board[i][j]);//逗号后面别忘记,说给自己听的if (j < col - 1){printf("|");}//打个比方,3行3列,i=0,j=0,打印第一列,0<3-1,打印|//j=1,打印第二列,1<3-1,打印|//j=2,打印第三列,2=3-1,不打印}printf("\n");//把他们分开,换行,打印完第一行打印第二行//下面打印---|---|---//分割行//把你放在身边怕忘记//井//   |   |    (数组第一行)//---|---|--- (这就是分割线)//   |   |   (数组第二行)//---|---|---  (分割线)//   |   |   (数组第三行)//所以下一步看怎么打印分割线if (i < row - 1)//同理第三行不要了{for (j = 0; j < col; j++){printf("---");if (j < col - 1){printf("|");}}}printf("\n");}//别忘记!}void player_move(char board[ROW][COL], int row, int col)
{printf("玩家下棋:\n");//井字棋,玩家只能下在三行三列这个范围内int x = 0;int y = 0;while (1){scanf("%d %d", &x, &y);//想办法加个条件让他只能3*3if (x >= 1 && x <= row && y >= 1 && y <= row){//下过棋的地方不能再下棋//我们看到的第一行第一列,电脑看到的是第零行零列//所以x-1,y-1if (board[x - 1][y - 1] == ' ')//注意此处是单引号{board[x - 1][y - 1] = '*';break;}else{printf("该坐标被占用,请重新输入!\n");}//留心细节单双引号,单引号在字符常量时使用,表示单个字符。//char c = 'aA'; // 编译出错,单引号只能是一个字符//char c = ''; // 单引号中间没有任何字符时,编译出错//双引号在表示字符串常量时使用,可以表示0到多个字符组成的字符串。//char s1[] = "a";//char s2[] = "a1A";//char s3[] = ""; // 双引号中间可以没有任何字符,表示空字符串}else{printf("坐标非法!请重新输入!\n");}}
}//这样电脑下棋太蠢,待优化
void computer_move(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("电脑下棋:\n");//电脑随机下,更难的不会,初学者望谅解while(1){x = rand() % ROW;//这样余数就只可能是0,1,2三种y = rand() % COL;if (board[x][y] == ' ')//这里没有减一是因为前面xy已经限制好了{board[x][y] = '#';break;//一定要,不然电脑就会一直下棋}//不需要else了,不解释}
}//判断结果
int is_full(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0;}}}return 1;//位置不要放错
}//下面也写死了,需要下多行棋时,需要进行修改
char is_win(char board[ROW][COL], int row, int col)
{int i = 0;//三行的判断for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' '){return board[i][1];}}//三列的判断for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' '){return board[1][i];}}//对角线的情况判断if (board[0][0] == board[1][1] && board[1][1] == board[2][2]&&board[1][1]!=' '){return board[1][1];}if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '){return board[1][1];}//判断平局//即有空格说明没有平局if (1 == is_full(board, row, col))//注意这是在函数char is_win(char board[ROW][COL], int row, int col)里{return 'Q';}//继续return 'C';
}


http://www.ppmy.cn/news/559614.html

相关文章

计算机械效率的三种方式,专题+三种四类简单机械的机械效率(共张ppt).ppt

文档介绍&#xff1a; 专题三三种四类简单机械的机械效率专题三三种四类简单机械的机械效率考向解读在安徽中考的考纲中,“理解机械效率的普遍意义”这一要求奠定了不同机械的机械效率在安徽中考中的考查方向。关于三种四类简单机械的机械效率,安徽中考每年必考,2009年和2013年…

计算机专业开题报告论证记录如何写,浙江大学软件学院研究生开题报告论证流程说明...

浙江大学软件学院研究生开题报告论证流程说明 (5页) 本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01; 17.90 积分 浙江大学软件学院研究生开题报告论证流程说明浙江大学软件学院研究生开题报告论证流程…

计算机应用基础第2单元,高教社山东版计算机应用基础第2单元.ppt

高教社山东版计算机应用基础第2单元课件详解 计算机应用基础 技能拓展 2.添加用户账户 对于已存在的用户账户&#xff0c;在更改账户窗口中&#xff0c;可以更改账户名、创建密码、选择账户类型以及删除账户等操作。 更改用户账户窗口 第2单元 计算机应用基础 技能拓展 3.使用3…

C语言 模除循环,C语言程序设计模三循环程序设计训练.ppt

C语言程序设计模三循环程序设计训练 知识点 goto语句语法格式&#xff1a; goto 语句标号&#xff1b; 语句标号是按标识符规定书写的符号&#xff0c;放在某一语句行的前面&#xff0c;标号后加冒号。 语句标号起标识语句的作用&#xff0c;与goto语句配合使用。执行goto语句后…

计算机组成原理在除法运算中 商符,计算机组成原理第03章.ppt

计算机组成原理第03章.ppt 定点数除法运算——阵列除法 阵列除法器(不恢复余数法) * 定点数除法运算——阵列除法 ①Ri≥0, C1(够减&#xff0c;补数相加有进位);商上1,q1;Ri12Ri-Y,作减法,p1&#xff1b;即pCq1。 ② Ri&#xff1c;0, C0(不够减&#xff0c;补数相加无进位);商…

技术人员近业务,会困死在一条船上吗?

U盘式生存&#xff0c;是著名自媒体人“罗胖”&#xff08;罗振宇&#xff09;提出的一个概念&#xff0c;他认为&#xff0c;未来中国人必须适应“U盘化生存”&#xff0c;概括起来16个字&#xff1a;“自带信息&#xff0c;不装系统&#xff0c;随时插拔&#xff0c;自由协作…

唯库拼课课程大合集更新111门

001 60天引爆你打学习力&#xff08;完结&#xff09; 002 阿何谈时间管理&#xff08;完结&#xff09; 003 普通人也能掌握的神奇记忆&#xff08;完结&#xff09; 004 阿何思维导图&#xff08;完结&#xff09; 005 阿何写作课&#xff08;完结&#xff09; 006 跟恶…

10年观察1000家企业,我发现干大事的老板,都有4个特质

能够成为500强&#xff0c;一定是从组织、制度、人才、工具&#xff0c;各个维度全面领先&#xff0c;跑赢市场的企业。 来源 | 正和岛 作者 | 赵小云 2021年过去了&#xff0c;2022是新的开始。 回顾这一年&#xff0c;你一定有无数感慨涌上心头。 如果用一个词来形容过去一年…