C语言实现简单的井字棋游戏

 更新时间:2021年04月28日 09:51:24   作者:肖舎  
这篇文章主要为大家详细介绍了C语言实现简单的井字棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C语言实现简单井字棋游戏的具体代码,供大家参考,具体内容如下

1.什么是井字棋

井字棋相信大部分人都玩过

规则:双方轮流放子,当某一方的三个子连成一线(行,列,对角)时,该方获胜。

2.游戏前的准备

1. 菜单

游戏正式开始前我们可以为用户提供一个选择菜单,笔者做了一个最简单的游戏开始菜单:

代码:

/*菜单*/
int menu()
{
 printf("###########################\n");
 printf("##   1.Play 2.Exit   ##\n");
 printf("###########################\n");
 return 0;
}

2. 打印棋盘

要玩游戏我们首先要有一个3*3的棋盘,棋子信息则用一个二维数组来表示,并进行初始化:

char chess[ROW][COL] = { '\0' }; //ROW=3,COL=3

显示棋盘我们可以写一个函数:

/*显示棋盘*/
int ShowBroad(char chess[][COL])
{
 system("cls");  //刷新界面
 printf(" %c | %c |%c          Player:   X\n",chess[0][0],chess[0][1],chess[0][2]);
 printf(" ----------        Computer: O\n");
 printf(" %c | %c |%c \n", chess[1][0], chess[1][1], chess[1][2]);
 printf(" ----------\n");
 printf(" %c | %c |%c \n", chess[2][0], chess[2][1], chess[2][2]);

}

将棋盘打印出来的同时在旁边显示出玩家和电脑所用的棋子。棋盘效果:

由于电脑是随机落子的,这样我们就会用到随机数,于是可以在后面加上随机数的种子,为之后的随机数做准备。
至此,准备工作就完成了,这部分的代码如下:

int a ,count =0;
char chess[ROW][COL] = { '\0' };
menu();        //显示菜单
printf("Please Enter Your Chose:>\n ");
scanf("%d", &a);
if (a != 1){ return 0; }
ShowBroad(chess);
srand((unsigned)time(NULL));

其中count是用来统计已占用的格子。

3.游戏开始

做完准备工作后我们开始正式的游戏逻辑编写。游戏逻辑可以这样考虑:

先由用户输入一个坐标,进行胜负和平局判断,若未产生任何结果则由电脑落子,之后同样进行胜负判断,如此循环直到产生胜负或平局。

基于此,我们将所有游戏过程写在一个死循环中,直到产生游戏结果则跳出。

1. 玩家落子

代码:

 if ((user_x >= 1 && user_x <= 3) && (user_y >= 1 && user_y <= 3)&&\
   chess[user_x-1][user_y-1]=='\0'){  //输入是否合法
   chess[user_x - 1][user_y - 1] = 'X';
   count++;
   if (Judge(chess) == 'X'){    //判断玩家赢
    ShowBroad(chess);
    printf("You Win! :)\n");
    break;
   }
  else if (count == 9){     //判断平局
    ShowBroad(chess);
    printf("Draw!\n");
    break;
   }

解释:当用户输入坐标在棋盘内并且该位置尚未被落子时,(user_x >= 1 && user_x <= 3) && (user_y >= 1 && user_y <= 3)&&\ chess[user_x-1][user_y-1]=='\0')将棋盘对应坐标元素改写成“X”(chess[user_x - 1][user_y - 1] = 'X';),之后将格子占用数count+1.

2. 判断胜平

为了判断是否胜利,我们可以写一个函数,将棋盘现在的数据传入,在里面逐行逐列判断。

代码:

/*判断*/
char Judge(char chess[][COL])
{
 for (int i = 0; i < COL; i++){  //判断行
  if (chess[i][0] == chess[i][1] && chess[i][1] == chess[i][2] && chess[i][2] != '\0')
  {
   return chess[i][0];
  }
 }
 for (int i = 0; i < COL; i++){  //判断列
  if (chess[0][i] == chess[1][i] && chess[1][i] == chess[2][i] && chess[2][i] != '\0')
  {
   return chess[0][i];
  }
 }
 if (chess[0][0] == chess[1][1] && chess[1][1] == chess[2][2] && chess[2][2] != '\0')  
  {        //判断对角线
   return chess[0][0];
  }
 if (chess[0][2] == chess[1][1] && chess[1][1] == chess[2][0] && chess[2][0] != '\0')
  {
   return chess[0][2];
  }
  return ' ';
}

此时是玩家落子之后,不会产生负,所以不需要判断是否输了。检查Judge()的返回值。当玩家胜利时输出胜利,游戏结束,当平局时输出平局,游戏结束

if (Judge(chess) == 'X'){  //判断玩家赢
    ShowBroad(chess);
    printf("You Win! :)\n");
    break;
   }
   else if (count == 9){   //判断平局
    ShowBroad(chess);
    printf("Draw!\n");
    break;
   }

3. 电脑落子

电脑是随机落子的,于是需要给chess()传入随机的x和y,于是这里用到rand()

void computer(char chess[][COL])
{
 int x, y;
 while (1){
  x = rand() % (COL) + 0;
  y = rand() % (COL) + 0;
  if (chess[x][y] == '\0'){
   chess[x][y] = 'O';
   break;
  }
 }
 ShowBroad(chess);
}

这里要注意当随机的坐标未被落子时才能使用,所以用死循环来查找一个合法的坐标,当找到时电脑才能落子,之后跳出循环,并刷新棋盘。

4. 判断负

与上面一样,我们调用Judge()函数来判断,当返回的是“O”时候,输出信息,游戏结束。

if (Judge(chess) == 'O'){   //判断电脑赢
    printf("You Lost!\n");
    break;
   }

最终游戏界面:

结束

至此,一个简单的井字棋游戏就完成了,内容简陋,可以优化的地方还有很多,各位可自行扩展。由这个简单的三子棋我们还能进一步发展成五子棋,做出更多的内容,先挖个五子棋的坑,以后来填。

main函数代码:

int main()
{
 int a ,count =0;
 char chess[ROW][COL] = { '\0' };
 menu();           //显示菜单
 printf("Please Enter Your Chose:>\n ");
 scanf("%d", &a);
 if (a != 1){ return 0; }
 ShowBroad(chess);
 srand((unsigned)time(NULL));
 while (1)
 {
  int user_x, user_y;
  printf("Please Enter:<x,y>\n");
  scanf("%d%d", &user_x, &user_y);   //玩家落子
  if ((user_x >= 1 && user_x <= 3) && (user_y >= 1 && user_y <= 3)&&\
   chess[user_x-1][user_y-1]=='\0'){  //输入是否合法
   chess[user_x - 1][user_y - 1] = 'X';
   count++;
   if (Judge(chess) == 'X'){    //判断玩家赢
    ShowBroad(chess);
    printf("You Win! :)\n");
    break;
   }
   else if (count == 9){     //判断平局
    ShowBroad(chess);
    printf("Draw!\n");
    break;
   }
   computer(chess);      //电脑落子
   count++;
   if (Judge(chess) == 'O'){    //判断电脑赢
    printf("You Lost!\n");
    break;
   }
  }
  else continue;
 }
 system("pause");
 return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 配置CLion管理Qt项目国际化支持的方法

    配置CLion管理Qt项目国际化支持的方法

    这篇文章主要介绍了配置CLion管理Qt项目国际化支持的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • OpenCV实现倾斜文字校正

    OpenCV实现倾斜文字校正

    这篇文章主要为大家详细介绍了OpenCV实现倾斜文字校正,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C语言详解select函数的使用

    C语言详解select函数的使用

    C语言中select函数的使用 一般用connect、accept、recv或recvfrom这类函数,程序阻塞,直至该套接字上接受到数据后程序才能继续运行。但是使用select函数可以实现非阻塞方式的程序
    2022-05-05
  • MATLAB全网最全的colormap的使用教程详解

    MATLAB全网最全的colormap的使用教程详解

    众所周知,MATLAB中的colormap只有少得可怜的几种,有很多应用在很特殊的图形中的colormap几乎都没有,而每次写代码都要去找颜色的图属实太麻烦。所以本文将包全部集成了进来,终于有了这套包含200个colormap的工具函数,希望对大家有所帮助
    2023-02-02
  • C++ 详细讲解对象的构造顺序

    C++ 详细讲解对象的构造顺序

    对象的构造往往和构造函数会牵扯在一起,构造函数的函数可能会由非常复杂的逻辑所组成,不同类的构造函数的程序逻辑很可能是相互依赖的,当这种相互依赖一旦成立,那么对象的构造顺序很可能导致难以调试的Bug出现
    2022-04-04
  • C++获取文件大小数值的三种方式介绍

    C++获取文件大小数值的三种方式介绍

    最近在做项目时经常需要获得文件的大小操作,虽然在网络上已经有许多篇博客介绍了,但是还是想总结出自己一篇,记录一下自己在项目中是怎么获得文件大小的
    2022-10-10
  • C/C++如何实现两矩阵相乘之模拟法

    C/C++如何实现两矩阵相乘之模拟法

    C++矩阵运算矩阵运算包括矩阵相加、相减、相乘、转置、求逆矩阵等等,用计算机程序实现矩阵运算的方法算法很多,这篇文章主要给大家介绍了关于C/C++如何实现两矩阵相乘之模拟法的相关资料,需要的朋友可以参考下
    2023-02-02
  • 深入探讨linux下进程的最大线程数、进程最大数、进程打开的文件数

    深入探讨linux下进程的最大线程数、进程最大数、进程打开的文件数

    本篇文章是对linux下进程的最大线程数、进程最大数、进程打开的文件数进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 离线安装visual studio2022+QT5.12的实现步骤

    离线安装visual studio2022+QT5.12的实现步骤

    近期有需求离线配置C++与QT环境,本文主要介绍了离线安装visualstudio2022+QT5.12的实现步骤,具有一定的参考价值,感兴趣的可以了解一下
    2024-06-06
  • C语言基于EasyX库实现有颜色弹跳小球

    C语言基于EasyX库实现有颜色弹跳小球

    这篇文章主要为大家详细介绍了C语言基于EasyX库实现有颜色弹跳小球,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01

最新评论