
三子棋应该是是大家最早接触到的棋类游戏,用C语言达成三子棋对新手来讲是一种很好的训练
撰写三子棋仅需用到数组、函数和生成随机数的常识,所以最适合成为编程学习者撰写的第一个小游戏。
1、代码达成第一部分是网站源码复制就能用,每个自概念函数在第二部分设计思路中都有详细讲解,结合代码达成和设计思路理解会有一个更好的成效
#define_CRT_SECURE_NO_WARNINGS1#includestdio.h#includetime.h#includestdlib.h#defineROW3#defineCOL3voidreset(chararr[ROW][COL])//将棋盘arr[ROW][COL]数据赋值为空格{for(inti=0;iROW;i++){for(intj=0;jCOL;j++){arr[i][j]=;}}}voiddis_play(chararr[ROW][COL])//打印棋盘{for(inti=0;iROW;i++)//for每一次进来,打印一行数组和一条分割线{//数组行为:(空格)元素(空格)|(空格)元素(空格)|(空格)元素(空格)//分割线为:---|---|---for(intj=0;jCOL;j++)//一行数组{printf(%c,arr[i][j]);if(jCOL-1)//为了美观,最后的|不打印{printf(|);}}printf(/n);for(intk=0;kCOL;k++)//一行分割线{printf(---);if(kCOL-1)//为了美观,最后的|不打印{printf(|);}}printf(/n);}}voidplayer_move(chararr[ROW][COL])//玩家下棋{introw=0,col=0;while(1){printf(玩家下棋,请输入坐标:);scanf(%d%d,row,col);if(arr[row-1][col-1]==)//判断能否下棋{arr[row-1][col-1]=*;break;}printf(输入错误,请第三输入/n);}}voidcomputer_move(chararr[ROW][COL])//电脑下棋{introw=rand()%ROW;//生成行号intcol=rand()%COL;//生成列标printf(电脑下棋:/n);while(1){if(arr[row][col]==)//判断能否下棋{arr[row][col]=#;break;}row=rand()%ROW;col=rand()%COL;}}intis_full(chararr[ROW][COL])//用于在is_win()中判断是不是为平局{for(inti=0;iROW;i++){for(intj=0;jCOL;j++){if(arr[i][j]==)return0;}}return1;}charis_win(chararr[ROW][COL])//三子棋胜利无非就三种状况:行相同、列相同和对角线相同。除开胜利还有平局{for(inti=0;iROW;i++)//判断行{if(arr[i][0]==arr[i][1]arr[i][1]==arr[i][2]arr[i][0]!=)returnarr[i][0];}for(inti=0;iCOL;i++)//判断列{if(arr[0][i]==arr[1][i]arr[1][i]==arr[2][i]arr[0][i]!=)returnarr[0][i];}//判断对角线if(arr[0][0]==arr[1][1]arr[1][1]==arr[2][2]arr[0][0]!=)returnarr[0][0];if(arr[0][2]==arr[1][1]arr[1][1]==arr[2][0]arr[0][2]!=)returnarr[0][2];//判断平局if(is_full(arr)){returnq;}//都不满足游戏继续运行returncreturnc;}voidmeau(){printf(------------------/n);printf(|1.play|/n);printf(|----------------|/n);printf(|0.exit|/n);printf(------------------/n);}voidgame(){chararr[ROW][COL];//初始化棋盘charch;reset(arr);//将棋盘里每个元素赋值为空格dis_play(arr);do{player_move(arr);dis_play(arr);ch=is_win(arr);if(ch!=c){break;}computer_move(arr);dis_play(arr);ch=is_win(arr);if(ch!=c){break;}}while(1);switch(ch)//依据返回字符判断结果{case#:printf(电脑胜利/n);break;case*:printf(玩家胜利/n);break;caseq:printf(平局/n);break;}}intmain(){srand((unsigned)time(NULL));intinput=0;do{meau();scanf(%d,input);switch(input){case1:game();break;case0:break;default:printf(输入错误/n);}}while(input);return0;}2、设计思路main()函数搭建框架
1.main()函数搭建框架:像所有些电脑游戏一样,大家需要一个菜单,通过菜单选择进入游戏和退出游戏,当一盘游戏结束时可以第三选择进入或者退出,菜单用printf()打印就能解决,循环的进入游戏用do while()循环就能解决
达成代码如下
voidmeau(){printf(------------------/n);printf(|1.play|/n);printf(|----------------|/n);printf(|0.exit|/n);printf(------------------/n);}voidgame(){}intmain(){intinput=0;do{meau();scanf(%d,input);switch(input){case1:game();break;case0:break;default:printf(输入错误/n);}}while(input);return0;}
2.当大家进入case 1,运行game()函数;第一大家需要一个容器来存放大家的游戏数据,此时创建字符二维数组arr[3][3]作为容器,玩家下的棋用*表示电脑用#表示。由于行和列都为3,后面常常要用,大家对他进行宏概念一下
#defineROW3#defineCOL3dis_play( )函数
》.dis_play( ):大家下棋一定需要棋盘来显示大家的数据,大家通过架构一个函数dis_play()将数组打印出来来达成这一功能
dis_play()的功能其实就是把arr[ROW][COL]以棋盘形式打印显示出来,需要借用一些特殊字符|和_辅助打印
#defineROW3/行:3#defineCOL3/列:3voiddis_play(chararr[ROW][COL]){for(inti=0;iROW;i++)/for每一次进来,打印一行数组和一条分割线{for(intj=0;jCOL;j++)//打印数组{printf(%c,arr[i][j]);if(jCOL-1){printf(|);}}printf(/n);for(intk=0;kCOL;k++)//打印分割线{printf(---);if(kCOL-1){printf(|);}}printf(/n);}}
初步运行代码,打印棋盘:

》reset ( ) :大家下完一盘棋,还想下该如何解决?这个时候大家架构一个函数reset(),将棋盘数组的每个元素重置为空格
reset()函数,遍历数组,赋值为空格
voidreset(chararr[ROW][COL]){for(inti=0;iROW;i++){for(intj=0;jCOL;j++){arr[i][j]=;//赋值空格}}}player_move( )函数
》player_move( ):玩家下棋,不可以随意下,下过的地方不可以下,大家架构一个player_move()函数完成这一功能
player_move( )函数功能其实就是为数组arr[ROW][COL]赋值,数组元素为空格的地方就是可以下棋的地方
输入坐标时,和大家技术员思维不同,正常人觉得行是从1开始而不是从0开始,玩家输入的数据需要减1才能正常赋值
voidplayer_move(chararr[ROW][COL]){introw=0,col=0;while(1){printf(玩家下棋,请输入坐标:);scanf(%d%d,row,col);if(arr[row-1][col-1]==){arr[row-1][col-1]=*;break;}printf(输入错误,请第三输入/n);}}
玩家下棋

》computre_move()电脑下棋,为了更容易达成大家这里让他再棋盘上随机下,需要生成随机数的常识,大家需要架构一个函数
用头文件#includestdlib.h中的rand()函数可以生成一个0~32767的伪随机数,但用rand()前先要用srand()设置伪随机数起点
起点只须写一次,大家将srand((unsigned)time(NULL))概念在主函数,此处是一种固定的写法,time()函数需要引time.h头文件将rand()%3即%ROW可以生产0、1、2这三个随机数,可以用来做数组的行号和列标
intmain(){srand((unsigned)time(NULL));/设置起点的固定写法intinput=0;do{meau();scanf(%d,input);switch(input){case1:game();break;case0:break;default:printf(输入错误/n);}}while(input);return0;}voidcomputer_move(chararr[ROW][COL]){introw=rand()%ROW;//借助随机数生成行号列标intcol=rand()%COL;printf(电脑下棋:/n);while(1){if(arr[row][col]==)//判断是不是为空格{arr[row][col]=#;break;}row=rand()%ROW;col=rand()%COL;}}
电脑下棋

》is_win()光下棋也不可以,每当玩家或电脑下一步棋需要有东西来判断到底是玩家赢了还是电脑赢了还是平局还是继续,大家架构is_win()函数完成这一功能
is_win()函数功能最后是返回一个字符,电脑赢返回#,玩家赢返回*,平局返回q,以上状况都不符合就返回c(continue)
三子棋胜利无非就三种状况:行相同、列相同和对角线相同大家用for和if语句就能判断
平局的状况其实就是棋盘满了,大家架构一个is_fuii()函数,棋盘满了,该函数返回1不然返回0;
intis_full(chararr[ROW][COL]){for(inti=0;iROW;i++){for(intj=0;jCOL;j++){if(arr[i][j]==)/棋盘还有空格则return0return0;}}return1;}charis_win(chararr[ROW][COL])/is_win()函数{for(inti=0;iROW;i++)/判断是不是有行相同{if(arr[i][0]==arr[i][1]arr[i][1]==arr[i][2]arr[i][0]!=)returnarr[i][0];}for(inti=0;iCOL;i++)/判断是不是有列相同{if(arr[0][i]==arr[1][i]arr[1][i]==arr[2][i]arr[0][i]!=)returnarr[0][i];}/判断对角线是不是相同if(arr[0][0]==arr[1][1]arr[1][1]==arr[2][2]arr[0][0]!=)returnarr[0][0];if(arr[0][2]==arr[1][1]arr[1][1]==arr[2][0]arr[0][2]!=)returnarr[0][2];if(1==is_full(arr))/is_full()返回1则returnq{returnq;}returnc;/都不满足,returnc}





