当前位置: 首页 > news >正文

三子棋游戏小课堂

🪐🪐🪐欢迎来到程序员餐厅💫💫💫

今天的主菜是,C语言实现的三子棋小游戏,

              所属专栏:     C语言知识点   

              主厨的主页:Chef‘s blog


前言:

已经学会数组的朋友们注意啦,现在的你已经有能力写出两个小游戏了,一个是扫雷,一个是三子棋,今天咱们就来手搓三子棋代码。

涉及知识点:

  • 随机数的生成:C语言实现随机数
  • 数组的使用

1.游戏要求

1.此游戏为人机对战

2.一方的棋子连成一行或一列或对角线时胜利

3.默认是3*3的棋盘,但可修改

4.玩家可以通过菜单选择开始游戏或退出游戏

2.游戏分析

  • 1.电脑下的棋通过随机数生成
  • 2.我们应该用数组放置双方所下的棋子
  • 3.每时每刻其具有三种情况,即未分出胜负,一方获胜,平局。每次一方下完棋就该判断此时棋局的情况。
  • 4.设置菜单使玩家可以选择退出游戏或开始游戏

3.多文件操作

 为了方便代码的管理和保证游戏实现逻辑的清晰性,我们将采用多文件管理的模式。

        (1)创建头文件game.h,包含所有头文件(其他源文件只需引用它即可),以及所有游戏功能的函数接口。

        (2)创建源文件game.c,负责所有游戏功能对应函数的具体代码实现。

        (3)创建源文件main.c,负责调用函数实现来游戏。

4.  简易菜单的实现

4.1功能介绍

 1.玩家可以通过选择1进入游戏,0退出游戏。

2.选错的话提醒玩家,重新选择。

3.告诉玩家游戏规则

4.2功能实现

#define _CRT_SECURE_NO_WARNINGS 1
#include"源.h"
void menu()
{printf("*********************\n");printf("****开始   :1*******\n");printf("****结束   :0********\n");//打印菜单printf("*********************\n");
}
void rules()
{printf("游戏规则如下:\n");printf("1.此游戏为人机对战\n2.一方的棋子连成一行或一列或对角线时胜利\n3.横坐标是1—3,纵坐标是1—3\n4.输入1是开始游戏输入0是退出游戏\n");
}
int main()
{srand((unsigned int)time(NULL));//设置随机数种子int input = 0;do {rules();menu(); printf("请选择:->");//玩家输入0表示退出游戏,输入1表示开始游戏scanf("%d", &input);switch (input){case 1:printf("开始游玩三子棋,祝您好运!\n");game();//游戏内容的具体实现break;case 0:printf("退出游戏\n");break;default:printf("请输入0 或 1 !\n");//防止有人捣乱,故意输错break;}} while (input);return 0;
}

4.3效果展示

5. 游戏功能实现

  5.1 要实现的函数接口

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define _CRT_SECURE_NO_WARNINGS 1
#define L 3
#define W 3
void initboard(char board[L][W], int l, int w);
void printboard(char board[L][W], int l, int w);
void playermove(char board[L][W], int l, int w);
void computermove(char board[L][W], int l, int w);
char judge(char board[L][W], int l, int w);
void game(void);

5.2初始化棋盘

(1)要求

把棋盘都初始化为空格

(2)代码实现
void initboard(char board[L][W], int l, int  w)
{int x = 0, y = 0;for (x = 0; x < l; x++)for (y = 0; y < w; y++)board[x][y] = ' ';
}

5.3 打印棋盘

    (1)要求

1. 打印出棋盘中的元素。

2. 利用---,|模拟出棋盘框。

(2)实现
void printboard(char board[L][W], int l, int w)
{int i = 0;for (i = 0; i < l-1; i++){for (int j = 0; j < w-1; j++)printf(" %c |", board[i][j]);printf(" %c ", board[i][w-1]);printf("\n");                      //打印前两行for(int j=0;j<w-1;j++)printf("---|");printf("---\n");}for (int j = 0; j < w-1; j++)printf(" %c |", board[i][j]);//打印最后一行printf(" %c ", board[i][w - 1]);printf("\n");
}

(3)效果展示

5.4玩家下棋

(1)要求

1.若输入坐标不在棋盘范围中,或该位置已经有棋了,提醒玩家重新输入

2.坐标有效则更改二维数组中存放的元素为玩家对应符号‘#’

(2)代码实现

void playermove(char board[L][W], int l, int w)
{int x, y;
again:	printf("玩家下棋\n请输入坐标:>");scanf("%d %d", &x, &y);if (x <= l && x > 0 && y <= w && y > 0){if (board[x-1][y-1] == ' ')board[x-1][y-1] = '#';//坐标有效,修改数组else{printf("这个地方有棋子了,换个地方吧!\n");goto again;}}else{printf("下错了,重新下吧!\n");goto again;}
}

      (3)效果展示

5.4电脑下棋

(1)要求

1.若输入坐标不在棋盘范围中,或该位置已经有棋了,则电脑重新输入

2.坐标有效则更改二维数组中存放的元素为电脑对应符号‘*’

(2)代码实现   

void computermove(char board[L][W], int l, int w)
{printf("电脑下棋\n");int x, y;again:  x = rand() % 3 + 1, y = rand() % 3 + 1;//随机数产生坐标if (x <= l && x > 0 && y <= w && y > 0&&board[x - 1][y - 1] == ' ')board[x - 1][y - 1] = '*';elsegoto again;
}

(3)效果展示

5.6判断棋局情况

(1)要求

棋局有三种情况,平局,胜负,或还未结束,根据不同情况返回不同字符

(2)代码实现

char judge(char board[L][W], int l, int w)
{for (int i = 0; i < l; i++){int j = 0;for ( j = 0; j < w-1; j++){if (board[i][j] != board[i][j + 1])break;}if (j == w-1 && board[i][j - 1] != ' ')//检查是否有连成一行return board[i][j - 1];}for (int i = 0; i < l; i++){int j = 0;for (j = 0; j < w-1; j++){if (board[j][i] != board[j+1][i])//检查是否有连成一列break;}if (j == w-1 && board[j-1][i] != ' ')return board[j-1][i];}int x;for ( x = 0; x < l-1; x++)if (board[x][x] != board[x + 1][x + 1])//检查是否连成对角线break;if (x == l-1 && board[x - 1][x - 1] != ' ')return board[x - 1][x - 1];int y;for (y=l-1;  y>0; y--)if (board[y][y] != board[y-1][y-1])//检查是否连成另一条对角线break;if (y == 0 && board[y][y] != ' ')return board[y][y];for (int i = 0; i < l; i++){int j = 0;for (j = 0; j < w; j++){if (board[j][i] == ' ')return 'j';//检查棋盘满了没}}return 'p';//最后一种情况是平局
}

(3)效果展示

5.7调用各个函数实现游戏

void game()
{char b;char board[L][W] = { 0 };initboard(board, L, W);printboard(board, L, W);while (1){playermove(board, L, W);printboard(board, L, W);b = judge(board, L, W);if (b != 'j')break;computermove(board, L, W);printboard(board, L, W);b = judge(board, L, W);if (b != 'j')break;}if (b == '#')printf("你赢了\n");else if (b == '*')printf("你输了\n");elseprintf("平局\n");
}

6. 源码 

  (1)main.c

#include"test.h"
void menu()
{printf("*********************\n");printf("****开始   :1*******\n");printf("****结束   :0********\n");printf("*********************\n");
}
int main()
{srand((unsigned int)time(NULL));int input = 0;do {game();menu(); printf("请选择:->");scanf("%d", &input);switch (input){case 1:printf("开始游玩三子棋,祝您好运!\n");game();break;case 0:printf("退出游戏\n");break;default:printf("请输入0 或 1 !\n");break;}} while (input);return 0;
}

(2)test.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define _CRT_SECURE_NO_WARNINGS 1
#define L 3
#define W 3
void initboard(char board[L][W], int l, int w);
void printboard(char board[L][W], int l, int w);
void playermove(char board[L][W], int l, int w);
void computermove(char board[L][W], int l, int w);
char judge(char board[L][W], int l, int w);
void game(void);

(3)test.c

#include"test.h"
void initboard(char board[L][W], int l, int  w)
{int x = 0, y = 0;for (x = 0; x < l; x++)for (y = 0; y < w; y++)board[x][y] = ' ';
}
void printboard(char board[L][W], int l, int w)
{int i = 0;for (i = 0; i < l-1; i++){for (int j = 0; j < w-1; j++)printf(" %c |", board[i][j]);printf(" %c ", board[i][w-1]);printf("\n");for(int j=0;j<w-1;j++)printf("---|");printf("---\n");}for (int j = 0; j < w-1; j++)printf(" %c |", board[i][j]);printf(" %c ", board[i][w - 1]);printf("\n");
}
void playermove(char board[L][W], int l, int w)
{int x, y;
again:	printf("玩家下棋\n请输入坐标:>");scanf("%d %d", &x, &y);if (x <= l && x > 0 && y <= w && y > 0){if (board[x-1][y-1] == ' ')board[x-1][y-1] = '#';else{printf("这个地方有棋子了,换个地方吧!\n");goto again;}}else{printf("下错了,重新下吧!\n");goto again;}
}
void computermove(char board[L][W], int l, int w)
{printf("电脑下棋\n");int x, y;again:  x = rand() % 3 + 1, y = rand() % 3 + 1;if (x <= l && x > 0 && y <= w && y > 0&&board[x - 1][y - 1] == ' ')board[x - 1][y - 1] = '*';elsegoto again;
}
char judge(char board[L][W], int l, int w)
{for (int i = 0; i < l; i++){int j = 0;for ( j = 0; j < w-1; j++){if (board[i][j] != board[i][j + 1])break;}if (j == w-1 && board[i][j - 1] != ' ')return board[i][j - 1];}for (int i = 0; i < l; i++){int j = 0;for (j = 0; j < w-1; j++){if (board[j][i] != board[j+1][i])break;}if (j == w-1 && board[j-1][i] != ' ')return board[j-1][i];}int x;for ( x = 0; x < l-1; x++)if (board[x][x] != board[x + 1][x + 1])break;if (x == l-1 && board[x - 1][x - 1] != ' ')return board[x - 1][x - 1];int y;for (y=l-1;  y>0; y--)if (board[y][y] != board[y-1][y-1])break;if (y == 0 && board[y][y] != ' ')return board[y][y];for (int i = 0; i < l; i++){int j = 0;for (j = 0; j < w; j++){if (board[j][i] == ' ')return 'j';}}return 'p';
}
void game()
{char b;char board[L][W] = { 0 };initboard(board, L, W);printboard(board, L, W);while (1){playermove(board, L, W);printboard(board, L, W);b = judge(board, L, W);if (b != 'j')break;computermove(board, L, W);printboard(board, L, W);b = judge(board, L, W);if (b != 'j')break;}if (b == '#')printf("你赢了\n");else if (b == '*')printf("你输了\n");elseprintf("平局\n");
}

好啦好啦,终于写完了,完结撒花,感谢观看,下次再见

相关文章:

三子棋游戏小课堂

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 今天的主菜是&#xff0c;C语言实现的三子棋小游戏&#xff0c; 所属专栏&#xff1a; C语言知识点 主厨的主页&#xff1a;Chef‘s blog 前言&…...

golang开源的可嵌入应用程序高性能的MQTT服务

golang开源的可嵌入应用程序高性能的MQTT服务 什么是MQTT&#xff1f; MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的、开放的消息传输协议&#xff0c;设计用于在低带宽、高延迟或不可靠的网络环境中进行通信。MQTT最初由IBM开发&#xf…...

uniapp微信小程序-请求二次封装(直接可用)

一、请求封装优点 代码重用性&#xff1a;通过封装请求&#xff0c;你可以在整个项目中重用相同的请求逻辑。这样一来&#xff0c;如果 API 发生变化或者需要进行优化&#xff0c;你只需在一个地方修改代码&#xff0c;而不是在每个使用这个请求的地方都进行修改。 可维护性&a…...

UE4 C++ 结构体

先在UCLASS()前写入&#xff1a; USTRUCT(BlueprintType) struct FMyStruct //必须以"F"开头 {GENERATED_BODY() //必须添加“GENERATED_BODY()”UPROPERTY(EditAnywhere, BlueprintReadWrite, Category "MyStruct1")int32 Health;UPROPERTY(EditAnywher…...

软件工程知识梳理0-概述

学好软件工程就必须理解软件工程到底是干什么的&#xff0c;为什么需要软件工程&#xff0c;以及怎么干的&#xff01;只有理解了软件工程的本质&#xff0c;才能更好的理解软件工程中各种工程手段和方法的目的。 个人开发模式 —> 小作坊开发模式 —> 软件工程开发模式 …...

贪吃蛇---C语言---详解

引言 C语言已经学了不短的时间的&#xff0c;这期间已经开始C和Python的学习&#xff0c;想给我的C语言收个尾&#xff0c;想起了小时候见过别人的老人机上的贪吃蛇游戏&#xff0c;自己父母的手机又没有这个游戏&#xff0c;当时成为了我的一大遗憾&#xff0c;这两天发现C语…...

Airflow原理浅析

⭐️ airflow基本原理 Apache Airflow 是一个开源的工作流自动化工具&#xff0c;它用于调度和管理复杂的数据工作流。Airflow 的原理基于有向无环图&#xff08;DAG&#xff09;的概念&#xff0c;它通过编写和组织任务的有向图来描述工作流程。 以下是 Apache Airflow 的一…...

uniapp 使用canvas 画海报,有手粘贴即可用

html部分 <view click"doposter">下载海报</view> <canvas canvas-id"myCanvas" type2d style"width: 370px; height: 550px;opcity:0;position: fixed;z-index:-1;" id"myCanvas" />js 部分 drawBackground() {c…...

Vite+Vue3+TS 引入使用Cesium.js

申请 Cesium Token 进入Cesium 注册账号 cesium 离谱的是 E宝 (Epic) 居然可以快捷登录&#xff1f;&#xff01; 登录后点击导航栏的 Access Token 再右侧即可看到默认Token 安装&引入 # Cesium pnpm pnpm install cesium# 如果项目同时存在Three.js 需避免使用pnpm T…...

Cocos creator 动作系统

动作系统简介 是用于控制物体运动的一套系统&#xff0c;完全依赖代码进行实现&#xff0c;动态调节节点的移动。 移动 cc.moveTo 移动到某个坐标&#xff08;x,y&#xff09; //1秒时间内&#xff0c;移动到0,0let action1 cc.moveTo(1,0,0)this.node.runAction(action1)c…...

对Spring当中AOP的理解

AOP(面向切面编程)全称Aspect Oriented Programminge AOP就是把系统中重复的代码抽取出来&#xff0c;单独开发&#xff0c;在系统需要时&#xff0c;使用动态代理技术&#xff0c;在不修改源码的基础上&#xff0c;将单独开发的功能通知织入(应用)到系统中的过程&#xff0c;完…...

【Vue】2-8、Axios 网络请求

cdn&#xff1a;<script src"https://unpkg.com/axios/dist/axios.min.js"></script> 注&#xff1a;使用 CDN 链接就可以不需要去下载对应的 js 文件到本地&#xff0c;只需要联网即可使用&#xff0c;可以减少项目的体积 <!DOCTYPE html> <…...

Vue中嵌入原生HTML页面

Vue中嵌入html页面并相互通信 需求&#xff1a;b2b支付需要从后获取到数据放到form表单提交跳转&#xff0c;如下&#xff1a; 但是vue目前暂时没找到有类似功能相关文档&#xff0c;所以我采用iframe嵌套的方式 1. Vue中嵌入Html <iframe src"/static/gateway.htm…...

streampark+flink一键整库或多表同步mysql到doris实战

streamparkflink一键整库或多表同步mysql到doris实战&#xff0c;此应用一旦推广起来&#xff0c;那么数据实时异构时&#xff0c;不仅可以减少对数据库的查询压力&#xff0c;还可以减少数据同步时的至少50%的成本&#xff0c;还可以减少30%的存储成本&#xff1b; streampar…...

Vim实战:使用 Vim实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…...

学习MySQL ENUM数据类型

学习MySQL ENUM数据类型 ENUM是MySQL中的一个字符串对象&#xff0c;它允许从预定义的值列表中选择一个值。这种数据类型特别适用于值的数量有限且不太可能变化的情况。 定义ENUM类型 在定义ENUM类型时&#xff0c;你需要明确列出所有可能的字符串值。例如&#xff1a; CRE…...

88.合并两个有序数组

88.合并两个有序数组 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 **注意&#xff1a;**最…...

python查询xml类别

第一章 导包 import os from xml.etree.ElementTree import ElementTree第二章 存储类别 # 定义一个空集合用于存储类别 classes set()第三章 遍历所有XML文件 # 遍历指定目录下的所有XML文件 for filename in os.listdir(/home/li/PycharmProjects/Annotations):if filena…...

nginx配置及性能优化

1. 请简述nginx的工作原理&#xff1f; Nginx的工作原理基于事件驱动模型和异步非阻塞I/O处理机制。 具体来说&#xff0c;Nginx接收到客户端的请求后&#xff0c;会将该请求映射到配置文件中指定的location block。这个过程中&#xff0c;Nginx本身并不执行实际的工作&#…...

阿里云如何找回域名,进行添加或删除?

权威域名管理介绍说明&#xff0c;包含添加域名、删除域名、找回域名、域名分组等操作介绍。 一、添加域名 非阿里云注册域名或子域名如需使用云解析DNS&#xff0c;需要通过添加域名功能&#xff0c;将主域名或子域名添加到云解析控制台&#xff0c;才可以启用域名解析服务。…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

鸿蒙Navigation路由导航-基本使用介绍

1. Navigation介绍 Navigation组件是路由导航的根视图容器&#xff0c;一般作为Page页面的根容器使用&#xff0c;其内部默认包含了标题栏、内容区和工具栏&#xff0c;其中内容区默认首页显示导航内容&#xff08;Navigation的子组件&#xff09;或非首页显示&#xff08;Nav…...

Springboot 高校报修与互助平台小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;高校报修与互助平台小程序被用户普遍使用&#xff0c;为…...