三子棋小游戏(纯C)

2023-11-16

一,代码的初步框架

在这里插入图片描述
我们接下来都是对game()的封装,逐步的完善。

二,棋盘的初始化与棋盘的打印

在这里插入图片描述
上图为棋盘的打印,我们注释掉的三条语句是初步的代码,我们发现初步的代码具有局限性,当我们改变游戏为五子棋。。。N子棋的时候它之后行数会发生变化而列数还只是三列,如图在这里插入图片描述
所以,我们采用优化后的代码,更加的动态。
我们将 %c | %c | %c 拆分打印把 %c |看成一个单元,每列打印一个但是最后一列的’|'不用打印,所以我们用了一个if语句做限制,在打印—|—|—|与前者意思相同这里我们就不再细致讲解。
这里注意棋盘初始化的时候要将数组赋值为格,否则的话会出现问题。(可以自己尝试哟)

玩家下棋与电脑下棋

玩家下棋:
在这里插入图片描述
电脑下棋:(这里我们采用随机数的方式)
在这里插入图片描述
到这我们game()大体部分已经完毕,就差如何判断输赢的问题了。

输赢的判断

在这里插入图片描述

由于我们将判断输赢的函数也做得更加动态(我们改变游戏模式秩序改变#define ROW和COL的值就可以改变,不用再去修改代码,所以这里的代码长度比较长)。
一,胜负分明
1,一横行元素相同。
2,一数列元素相同。
3,正负对角线元素相同。
二,平局棋盘全下满却未出现胜负的情况。
三,继续对局。

完整代码展现

test.c测试文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
	printf("*****************************\n");
	printf("*********  1.play  **********\n");
	printf("*********  0.exit  **********\n");
	printf("*****************************\n");
}
void game()
{
    char ret = 0;
	char board[ROW][COL] = { 0 };
	init_board(board, ROW, COL);//初始化棋盘数组
	print_board(board,ROW,COL);//打印棋盘
	while (1)
	{
		player_board(board, ROW, COL);
		 ret=is_win(board, ROW, COL,'*');
		if (ret != 'C')
			break;
		computer_board(board, ROW, COL);
		ret=is_win(board, ROW, COL,'#');
		if (ret != 'C')
			break;
		if (ret == 'Q')
		{
			printf("平局\n");
			break;
		}
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else
	{
		printf("电脑赢\n");
	}//is_win函数的返回值分为四种
	//返回值为'*'的时候玩家赢
	//返回值为'#'的时候电脑赢
	//返回值为'Q'的时候为平局
	//返回值为'C'的时候表示继续
	
}
int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:game(); break;
		case 0:printf("退出游戏\n"); break;
		default:printf("输入错误,请重新输入\n"); break;
		}
	} while (input);
	return 0;
}

game.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void print_board(char board [ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		//printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		//if(i<row-1)
		//printf("---|---|---\n");
		if (i < row-1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col-1)
					printf("|");
			}
			printf("\n");
		}
	}
}
void init_board(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++)
		{
			board[i][j] = ' ';
		}
	}
}
void player_board(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	
	while(1)
	{
		printf("玩家输入坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x-1][y-1] = '*';
				print_board(board, ROW, COL);
				break;
			}
		}
		else
		{
			printf("输入非法,请重新输入\n");
		}

	}
}
void computer_board(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			print_board(board, ROW, COL);
			break;
		}
	}
}
int is_full(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;
}
int is_win(char board[ROW][COL], int row, int col,char ch)
{
	int i = 0;
	int j = 0;
	int count = 0;
	for (i = 0; i < row; i++)
	{
		count = 0;
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ch)
				count++;
		}
		if (count == ROW)
		{
			return ch;
		}
	}
	for (j = 0; j < col; j++)
	{
		count = 0;
		for (i = 0; i < row; i++)
		{
			if (board[i][j] == ch)
				count++;
		}
		if (count == ROW)
		{
			return ch;
		}
	}

	count = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (i == j)
			{
				if (board[i][j] == ch)
					count++;
			}
		}
	}
	if (count == ROW)
	{
		return ch;
	}
	count = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if ((i + j)==ROW-1)
			{
				if (board[i][j] == ch)
					count++;
			}
		}
	}
	if (count == ROW)
	{
		return ch;
	}
	if (is_full(board, row, col) == 1)
		return 'Q';
	return 'C';
}

game.h头文件

#pragma once
#include<stdio.h>
#define ROW 5
#define COL 5
//打印棋盘
void print_board(char[ROW][COL], int row, int col);
//棋盘初始化
void init_board(char board[ROW][COL], int row, int col);
//玩家下棋
void player_board(char board[ROW][COL], int row, int col);
//电脑下棋
void computer_board(char board[ROW][COL], int row, int col);
//判断输赢
int is_win(char board[ROW][COL],int row,int col,char ch);

制作不易,如果对您有帮助,点个赞,留个关注吧。
欢迎大家评论区讨论,如有不对的地方,请大家指正,谢谢。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

三子棋小游戏(纯C) 的相关文章

  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • 将 System.Windows.Input.KeyEventArgs 键转换为 char

    我需要将事件参数作为char 但是当我尝试转换 Key 枚举时 我得到的字母和符号与传入的字母和符号完全不同 如何正确地将密钥转换为字符 这是我尝试过的 ObserveKeyStroke this new ObervableKeyStrok
  • 在 C# 中循环遍历文件文件夹的最简单方法是什么?

    我尝试编写一个程序 使用包含相关文件路径的配置文件来导航本地文件系统 我的问题是 在 C 中执行文件 I O 这将是从桌面应用程序到服务器并返回 和文件系统导航时使用的最佳实践是什么 我知道如何谷歌 并且找到了几种解决方案 但我想知道各种功
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • Rx 中是否有与 Task.ContinueWith 运算符等效的操作?

    Rx 中是否有与 Task ContinueWith 运算符等效的操作 我正在将 Rx 与 Silverlight 一起使用 我正在使用 FromAsyncPattern 方法进行两个 Web 服务调用 并且我想这样做同步地 var o1
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • 如何编写一个同时需要请求和响应Dtos的ServiceStack插件

    我需要提供本地化数据服务 所有本地化的响应 Dto 都共享相同的属性 IE 我定义了一个接口 ILocalizedDto 来标记那些 Dto 在请求端 有一个ILocalizedRequest对于需要本地化的请求 Using IPlugin
  • HttpWebRequest 在第二次调用时超时

    为什么以下代码在第二次 及后续 运行时超时 代码挂在 using Stream objStream request GetResponse GetResponseStream 然后引发 WebException 表示请求已超时 我已经尝试过
  • 如何对 Web Api 操作进行后调用?

    我创建了一个 Web API 操作 如下所示 HttpPost public void Load string siteName string providerName UserDetails userDetails implementat
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 用于 C# 的 TripleDES IV?

    所以当我说这样的话 TripleDES tripledes TripleDES Create Rfc2898DeriveBytes pdb new Rfc2898DeriveBytes password plain tripledes Ke
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • Linq-to-entities,在一个查询中获取结果+行数

    我已经看到了有关此事的多个问题 但它们已经有 2 年 或更长 的历史了 所以我想知道这方面是否有任何变化 基本思想是填充网格视图并创建自定义分页 所以 我还需要结果和行数 在 SQL 中 这将类似于 SELECT COUNT id Id N
  • 使用 GROUP 和 SUM 的 LINQ 查询

    请帮助我了解如何使用带有 GROUP 和 SUM 的 LINQ 进行查询 Query the database IEnumerable
  • 当另一个线程可能设置共享布尔标志(最多一次)时,是否可以读取共享布尔标志而不锁定它?

    我希望我的线程能够更优雅地关闭 因此我尝试实现一个简单的信号机制 我不认为我想要一个完全事件驱动的线程 所以我有一个工作人员有一种方法可以使用关键部分优雅地停止它Monitor 相当于C lock我相信 绘图线程 h class Drawi

随机推荐

  • C++友元声明与定义依赖关系

    ifndef A H define A H include
  • 小程序日期(日历)时间 选择器组件

    封装一个小程序日期 日历 时间 选择器组件 简要说明 一共两个版本 date time picker 和 date time picker plus date time picker 弹窗层是 基于 vant weapp 的 van pop
  • 机器学习之数据预处理

    1 导入需要的库 Numpy Pandas 2 导入数据集 3 处理丢失数据 数据可能是因为各种原因丢失 未了不降低机器学习模型的性能 需要处理数据 我们可以用整列的平均值 或中间值替换丢失的数据 我们用sklearn preprocess
  • STM32F103-定时器

    STM32F103系列的单片机一共有11个定时器 其中 1个系统嘀嗒定时器 2个看门狗定时器 2个基本定时器 TIM6和TIM7 4个通用定时器 TIM2 TIM5 2个高级定时器 TIM1和TIM8 基本定时器 TIM6和TIM7 只具有
  • springmvc+mongodb+maven 项目搭建配置

    操作步骤我就不再细化了 项目能运行 测试过了 先上配置 另一篇文章上代码 源码地址 http pan baidu com s 1pJslZ0v 项目结构 pom xml
  • react井字棋---最全井字棋小游戏教程

    上一期我们利用create react app搭建了好了一个react项目 这期我们通过跟随React官方教程 编写一个 井字棋 小游戏 来熟悉react的基本用法 首先来看下 井字棋 的最终实现效果 从演示中我们可以看到 这个游戏大致有以
  • JavaScript Math

    JavaScript Math 算数 对象 Math 算数 对象的作用是 执行常见的算数任务 在线实例 round 如何使用 round random 如何使用 random 来返回 0 到 1 之间的随机数 max 如何使用 max 来返
  • 14.进程间通信

    一 进程间通信概述 1 目的 1 数据传输 一个进程需要将它的数据发送给另一个进程 2 资源共享 多个进程之间共享同样的资源 3 通知事件 一个进程需要向另一个或一组进程发送消息 通知它们发生了某种事件 4 进程控制 有些进程希望完全控制另
  • 再谈Linux epoll惊群问题的原因和解决方案

    差别是什么 差别只是西装 缘起 近期排查了一个问题 epoll惊群的问题 起初我并不认为这是惊群导致 因为从现象上看 只是体现了CPU不均衡 一共fork了20个Server进程 在请求负载中等的时候 有三四个Server进程呈现出比较高的
  • Git进行pull时,出现please enter the commit message for your changes...

    在服务端更新代码时 git pull时总是出现需要编辑一个commit message git status 查看了下 原来是服务端有部分代码需要commit后尚未push导致 这种问题 解决办法如下 如果你本地仓库不需要push 这里编辑
  • 自定义指令、具名卡槽的使用与演示

    目录 一 v model简化代码 二 sync修饰符 三 ref 与 refs 四 自定义指令 五 插槽 默认插槽 六 具名卡槽 一 v model简化代码 1 目标 父组件通过v model简化代码 实现子组件和父组件数据双向绑定 2 如
  • np.array()函数

    函数调用方法 numpy array object dtype None 各个参数意义 object 创建的数组的对象 可以为单个值 列表 元胞等 dtype 创建数组中的数据类型 返回值 给定对象的数组 普通用法 import numpy
  • 【C语言】用迭代法求平方根。

    include
  • jar包启动、停止、重启脚本

    启动命令 sh start sh start 停止命令 sh start sh stop 重启命令 sh start sh restart 注意 1 把test jar改成自己的jar包名 2 把文件命名为start sh 在linux环境
  • JavaScript(7)本地存储,函数深入理解

    1 本地存储 1 1本地存储特性 数据存储在用户浏览器中 设置和读取数据方便 而且页面刷新不丢失数据 容量较大 sessionStorage约5M localStorage约20M 只能存储字符串 可以将对象JSON stringify 编
  • css - 选择器

    css 选择器 css选择器用于选择html元素 为其设置css样式 选择器不会选择纯文本 只选择html元素 ID选择器 html标签的唯一编号由id属性指定 通过使用id的形式可以选择指定的元素对象 慎用id选择器 因为css不会检测i
  • 我所理解的DRM显示框架

    什么是DRM DRM全称是DirectRenderingManager 是linux主流的一种显示框架 支持多图层合成 为用户图层提供统一的API libdrm 来访问GPU 实现统一管理 它是为了解决多个程序对video card访问协同
  • 数据结构 数学知识复习

    文章目录 指数 对数 级数 模运算 证明方法 归纳法证明 反例法证明 指数 X A X B
  • 无监督聚类评价指标

    无监督聚类评价指标 文章目录 无监督聚类评价指标 SEE SC和CH 寻找k 评价指标 轮廓系数法 SC 评价指标 CH系数法 无监督聚类算法结果好坏的评价指标 Compactness 紧密性 CP Separation 间隔性 SP Da
  • 三子棋小游戏(纯C)

    N子棋 以三子棋为例 一 代码的初步框架 二 棋盘的初始化与棋盘的打印 玩家下棋与电脑下棋 输赢的判断 完整代码展现 一 代码的初步框架 我们接下来都是对game 的封装 逐步的完善 二 棋盘的初始化与棋盘的打印 上图为棋盘的打印 我们注释