学习了一下井字棋游戏的视频,准备写一下井字棋的代码,顺便加深印象,篇幅较长,内容比较详细,如有错误和改进请及时指出,欢迎讨论。
1.井字棋设计思路:
1.菜单显示 //让用户选择玩游戏还是退出
2.打印棋盘 //打印3*3的棋盘格
3.玩家和电脑下棋 //让用户输入坐标下棋,让电脑随机下棋
4.状态检测 //判断玩家输赢,平局或者继续游戏
1.菜单显示
这里定义menu函数打印菜单,在main()函数中do-while循环中接收用户的输入(input)1或者0,输入1进入游戏主体,输入0则break跳出循环,输入其他则要求重新输入因为while (input!=0);
void menu(){
printf("-----------------------\n");
printf("----------1.Play-------\n");
printf("----------0.Exit-------\n");
}
以下是main()函数:(game( )函数是游戏的主体,在文章的最后组装其他函数完成)
int main(){
int input =0;
srand((unsigned int) time(NULL));
do{
menu(); //显示选择菜单
scanf("%d",&input);
switch (input) {
case 1 :
printf("开始游戏\n");
game(); //运行游戏的主体
break;
case 0 :
printf("退出游戏\n");
break;
default :printf("输入错误,重新输入\n");
break;}
}while (input!=0);
return 0;
}
2.打印棋盘
因为3*3的棋盘所以我们要定义一个3*3的二维数组来存放玩家和电脑的棋子,并且要把他们初始化为空格即' '。
#define ROW 3
#define COL 3
char board[ROW][COL]={0};
//遍历所有的元素初始化为空
void InitialBoard(char board[ROW][COL]){
for (int i = 0;i<ROW;i++){
for (int j=0;j<COL;j++){
board[i][j]=' ';
}
}
}
接着要打印出空棋盘,类似于 棋子 | 棋子 | 棋子
--------|----------|--------
棋子 | 棋子 | 棋子
--------|----------|--------
棋子 | 棋子 | 棋子
我想先解释一下一个地方,例如就是在三个元素中打印两个竖杠( | )的时候,不能将元素和竖杠放在一起一口气打印,加一个if条件,使竖杠在最后一次循环(j=COL-1)
时不打印,就会生成三个元素两个隔断的效果。 棋子 | 棋子 | 棋子
for (int i =0;i<ROW;i++){
for (int j=0;j<COL;j++){
printf(" %c ",board[i][j]);
if(j!=COL-1){
printf("|");}
}
printf("\n");
}
其次,我们还要打印棋盘的横向的分割线,下面是打印棋盘的完整代码:
中间我写了一个虚线,虚线以上代码可以表示为打印 (棋子) | (棋子) | (棋子),虚线以下代码可以表示为打印三行棋子两条分割线的代码,三行两条分割线原理和上面的例子相同 if (i ! = ROW-1),
这里的”---“可以看作是虚线上面的” %c “,这可能会帮助你理解。
//打印棋盘
void DisplayBoard(char board[ROW][COL]){
for (int i =0;i<ROW;i++){
for (int j=0;j<COL;j++){
printf(" %c ",board[i][j]);
if(j!=COL-1){
printf("|");}
}
printf("\n");
//------------------------------------------------
//------------------------------------------------
if(i!=ROW-1){
for(int a=0;a<ROW;a++){
printf("---");
if(a!=COL-1)
printf("|");}
}
printf("\n");
}
}
3.玩家和电脑下棋
刚才我们已经初始化board这个3*3的数组中每个数组的元素(棋子)为空格,下棋的书写其实就是接收坐标,然后更改对应的元素(棋子),这里我定义的玩家棋子符号是字母‘O’,电脑是字母‘X’。
这里用scanf函数接收输入的(x y)坐标,首先判断坐标是否输入的合理,即(0<x<=ROW)和(0<y<=COL),如果不对重新输入,接着判断所在坐标上是否有棋子,如果为空,那么下棋
board[x-1][y-1]='O';这里写成x-1,y-1是因为玩家下意识会输入1 2 3行或列而不是0 1 2行或列,这个可以自己进行调整,我的是九宫格左上角为(1 1)坐标。
最后把if条件放进while(1)死循环中,只有正确的坐标才可以跳出循环,否则会被一直要求输入坐标。
//玩家下棋
void Player_game(char board[ROW][COL]){
int x,y=0;
while(1){
printf("玩家请下棋(x y)");
scanf("%d %d",&x,&y);
if(x>0&&x<=ROW&&y>0&&y<=COL){
if(board[x-1][y-1]==' '){
board[x-1][y-1]='O';
break;
}else{
printf("位置已经有棋子,请重新选择");
}
}else{
printf("输入错误,请重新输入");
}
}
}
下面是电脑下棋,我设计的电脑是随机下棋,rand()%ROW的余数一定在0到ROW-1之间
(0 1 2),然后把if条件放进while(1)死循环中,一直到电脑下完棋为止,这里rand()函数记得引用头文件和在main()函数中设置时间戳,见main()函数:srand((unsigned int) time(NULL));
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//电脑下棋
void Computer_game(char board[ROW][COL]){
while(1){
printf("电脑请下棋\n");
int x=rand()%ROW;
int y=rand()%COL;
if(board[x][y]==' '){
board[x][y]='X';
break;
}
}
}
4.状态检测
首先检测游戏状态,根据不同的状态返回不同的结果玩家获胜,电脑获胜,平局或者继续进行游戏四种情况。
判断是否获胜就是看三个是否一样并且其中一个不为空格(三行三列,两个对角线),如果有一样的就return返回棋子字符,玩家胜就是返回'O',电脑胜返回'X'。如果不满足一方获胜的条件那么只有两种情况,平局和继续游戏,这里我用for循环计算3*3棋子中是否有空格,如果有return返回'C'表示游戏继续,如果没有return返回'E'表示平局
char IsWin(char board[ROW][COL]){
int i,j=0;
//判断行是否满足三个
for(i = 0;i<ROW;i++){
if(board[i][0]==board[i][1]&&board[i][1]==board[i][2]&&board[i][0]!=' '){
return board[i][0];
}
}
//判断列是否满足三个
for(j = 0;j<ROW;j++){
if(board[0][j]==board[1][j]&&board[2][j]==board[0][j]&&board[0][j]!=' '){
return board[0][j];
}
}
//看两个对角线是否满足三个
if(board[0][0]==board[1][1]&&board[1][1]==board[2][2]&&board[0][0]!=' '){
return board[0][0];
}
if(board[0][2]==board[1][1]&&board[1][1]==board[2][0]&&board[0][2]!=' '){
return board[0][2];
}
//判断棋盘是否下满,即是否平局
int coun=0;
for(i=0;i<ROW;i++){
for(j=0;j<COL;j++){
if(board[i][j]==' '){
coun++;
}
}
}
if(coun==0){
return 'E';
}else{
return 'C';
}
}
最后,完成游戏,把函数组装进game()函数
(result用于接受IsWin()的返回值打印游戏状态)
首先初始化棋子,展示棋盘,接着不断的:玩家下棋判断游戏状态,电脑下棋判断游戏状态,直到状态检测函数的返回值不为'C'(说明胜负平),跳出循环打印胜负平。
void game(){
char result=0;//用于接受状态检测函数的返回值
InitialBoard(board);
DisplayBoard(board);
while(1){
Player_game(board);
DisplayBoard(board);
result=IsWin(board);
if(result!='C'){
break;
}
result=IsWin(board);
Computer_game(board);
DisplayBoard(board);
if(result!='C'){
break;
}
}
if(result=='O'){
printf("你赢了\n");
}else if(result=='X'){
printf("你输了\n");
}else if(result=='E'){
printf("平局\n");
}
}
文章最后,附上游玩的图片,因为电脑是随机下所以比较笨,如果有改进的想法欢迎讨论,
文章比较冗长,如果你能读到这里我深表感激,希望这篇文章能帮助到你。