【C语言】 -- 三子棋(代码+解析)2

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: 【C语言】 -- 三子棋(代码+解析)2

4.4 电脑下棋

定义ComputerMove()函数,代码实现:

void ComputerMove(char board[ROW][COL], int row, int col)
{
  int x = 0;
  int y = 0;
  printf("电脑下棋:>\n");
  while (1)
  {
    x = rand() % row;
    y = rand() % col;
    if (board[x][y] == ' ')
    {
      board[x][y] = '#';
      break;
    }
  }
}

这里也是存在一些问题,解决办法如下:


1.如何实现电脑随机输入一个坐标?


答:我们利用srand()函数来实现随机数字,但是srand()函数需要一个随机值,这里的随机值就是利用时间戳,因为时间在时刻改变着,不同的时间经过srand处理过后就得到了我们需要的随机值。因为要用时间戳,所以需要调用time函数,代码实现:

#include <time.h>

srand()函数的使用:

srand((unsigned int)time(NULL));

2.如何处理电脑随机坐标的合法性?

答:在使用srand()函数处理的随机值不再经过处理可能会出现大于棋盘的格数,所以我们需要再对srand()函数处理的随机值再进行处理,代码实现:

x = rand() % row;//0~2
y = rand() % col;//0~2

对srand传过来的随机值进行取模处理,我们的棋盘是3*3的,所以取模后得到的随机值是在0~2范围里。


3.如果出现坐标被占用的情况怎么处理?


答:我们使用while循环,如果给出的坐标位置判断不是空格,就说明是被占用,经过循环最后给出合法的坐标,实现落子后就会触发break跳出循环。

4.5 判断输赢

定义IsWin()函数,代码实现:

char IsWin(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][0] != ' ')
      return board[i][0];//如果连成,返回这个符号就是代表哪一玩家胜利
  }
    //三列连成
  for (i = 0; i < col; i++)
  {
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
      return board[0][i];//如果连成,返回这个符号就是代表哪一玩家胜利
  }
    //两对角线连成
  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][0];//如果连成,返回这个符号就是代表哪一玩家胜利
  //判断是否平局
  if (1 == IsFull(board, row, col))
  {
    return 'Q';
  }
  return 'C';
}

判断输赢的代码逻辑是根据游戏规则来写,行、列、对角线三子连成就认定哪一方胜出,若棋盘下满都没出现三子连成认定为平局。分别用这些符号表示:


4.5.1 三行连成

代码实现:

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];
  }

4.5.2 三列连成

代码实现:

for (i = 0; i < col; i++)
  {
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
      return board[0][i];
  }

4.5.3 两对角线连成

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][0];

4.5.4 平局判断

如果棋盘被下满还是没有分出胜负便是平局。

如何判断是否棋盘被下满呢?

答:我们遍历棋盘的每一个格子,如果没有一个是空格了,就返回数字 1 ,否则返回数字 0 。

定义IsFull()函数,代码实现:

int IsFull(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;
}

IsFull()函数仅仅实现棋盘格是否被占满。在IsWin()函数中判断返回值是否是 1 ,如果是就是平局,我们这里只对棋盘格被占满判断,只需要判断返回值 1 ,如果是0便是没有占满,不用考虑,继续下棋就行。

代码实现:

if (1 == IsFull(board, row, col))
  {
    return 'Q';
  }

判断 1 == IsFull(),就返回字符'Q'。(规定 Q 是平局)

5、game()函数详解

void game()
{
  srand((unsigned int)time(NULL));
  //存放数据需要一个3*3的二维数组
  char board[ROW][COL] = { 0 };
  //初始化棋盘
  InitBoard(board, ROW, COL);
  //显示棋盘
  DisplayBoard(board, ROW, COL);
  char ret = 0;
  while (1)
  {
    //玩家下棋 - *
    PlayerMove(board, ROW, COL);
    //打印棋盘
    DisplayBoard(board, ROW, COL);
    //判断输赢
    ret = IsWin(board, ROW, COL);
    if (ret != 'C')
    {
      break;
    }
    //电脑下棋 - #
    ComputerMove(board, ROW, COL);
    //打印棋盘
    DisplayBoard(board, ROW, COL);
    //判断输赢
    if (ret != 'C')
    {
      break;
    }
  }
  if ('*' == ret)
    printf("玩家赢\n");
  else if ('#' == ret)
    printf("电脑赢\n");
  else
    printf("平局\n");
}

逻辑顺序:创建一个数组 -- 初始化棋盘 -- 打印棋盘 -- 玩家下棋 -- 打印棋盘 -- 判断输赢(赢/输/平局:本局结束;没结果:继续) -- 电脑下棋 -- 打印棋盘 -- 判断输赢 (赢/输/平局:本局结束;没结果:继续)

逻辑顺序图示:


6、整体效果展示


完整代码在代码仓库,入口在这:


https://gitee.com/xiaobai-is-working-hard-jy/c-language-jy/tree/master/game_%E4%B8%89%E5%AD%90%E6%A3%8B/game_%E4%B8%89%E5%AD%90%E6%A3%8B


相关文章
|
9月前
|
算法 PyTorch 算法框架/工具
昇腾 msmodelslim w8a8量化代码解析
msmodelslim w8a8量化算法原理和代码解析
684 5
|
11月前
|
搜索推荐 UED Python
实现一个带有昼夜背景切换的动态时钟:从代码到功能解析
本文介绍了一个使用Python和Tkinter库实现的动态时钟程序,具有昼夜背景切换、指针颜色随机变化及整点和半点报时功能。通过设置不同的背景颜色和随机变换指针颜色,增强视觉吸引力;利用多线程技术确保音频播放不影响主程序运行。该程序结合了Tkinter、Pygame、Pytz等库,提供了一个美观且实用的时间显示工具。欢迎点赞、关注、转发、收藏!
459 94
|
9月前
|
传感器 监控 Java
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
361 5
|
10月前
|
人工智能 文字识别 自然语言处理
保单AI识别技术及代码示例解析
车险保单包含基础信息、车辆信息、人员信息、保险条款及特别约定等关键内容。AI识别技术通过OCR、文档结构化解析和数据校验,实现对保单信息的精准提取。然而,版式多样性、信息复杂性、图像质量和法律术语解析是主要挑战。Python代码示例展示了如何使用PaddleOCR进行保单信息抽取,并提出了定制化训练、版式分析等优化方向。典型应用场景包括智能录入、快速核保、理赔自动化等。未来将向多模态融合、自适应学习和跨区域兼容性发展。
|
12月前
|
自然语言处理 搜索推荐 数据安全/隐私保护
鸿蒙登录页面好看的样式设计-HarmonyOS应用开发实战与ArkTS代码解析【HarmonyOS 5.0(Next)】
鸿蒙登录页面设计展示了 HarmonyOS 5.0(Next)的未来美学理念,结合科技与艺术,为用户带来视觉盛宴。该页面使用 ArkTS 开发,支持个性化定制和无缝智能设备连接。代码解析涵盖了声明式 UI、状态管理、事件处理及路由导航等关键概念,帮助开发者快速上手 HarmonyOS 应用开发。通过这段代码,开发者可以了解如何构建交互式界面并实现跨设备协同工作,推动智能生态的发展。
712 10
鸿蒙登录页面好看的样式设计-HarmonyOS应用开发实战与ArkTS代码解析【HarmonyOS 5.0(Next)】
|
11月前
|
SQL Java 数据库连接
如何在 Java 代码中使用 JSqlParser 解析复杂的 SQL 语句?
大家好,我是 V 哥。JSqlParser 是一个用于解析 SQL 语句的 Java 库,可将 SQL 解析为 Java 对象树,支持多种 SQL 类型(如 `SELECT`、`INSERT` 等)。它适用于 SQL 分析、修改、生成和验证等场景。通过 Maven 或 Gradle 安装后,可以方便地在 Java 代码中使用。
3460 11
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
939 14
|
9月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
890 29
|
9月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
362 4
|
9月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

推荐镜像

更多
  • DNS