三子棋都玩过吧,那C语言现造一个呢???

news2024/7/4 15:07:27

目录

前言

三子棋简介

棋盘介绍

规则介绍

程序设计

基本流程

游戏逻辑

菜单界面打印

创建棋盘并初始化

打印棋盘

玩家落子

电脑落子

判断胜负

1.判定是否和棋

2.判定胜负

 代码总汇

✅Game.h 头文件

✅Game.c

✅Test.c


前言

        🥰想必各位大佬们上学的时候都玩过这种游戏吧,摊牌了我也玩过,巧了我还是在高中上课的时候偷偷玩的,当然不出意外就要出一点小小意外了,当时被老师逮了个正着,现在还能想起来那年夏天语文课上的画面。当然现在我们也要去玩三子棋,咱们今天自己现造一个程序来玩这个游戏。当然这个程序要有一定的C语言基础,其实里面也都是一些基本的一句没有指针、结构体等等这些高难度的知识点,好,各位小客官们坐稳扶好了要发车了。😍😍 

三子棋简介

        🍔《三子棋》是一款古老的民间传统游戏,又被称为黑白棋、圈圈叉叉棋、井字棋、一条龙、九宫棋等。游戏分为双方对战(这里我们设计的是人机对战),双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子连成一条线的一方则视为胜利者,下面我们来详细介绍一下《三子棋》相关的玩法规则🥝

棋盘介绍

        🍪棋盘呈横三行列,纵三列分布,为九宫格样式。因为棋盘结构简单,所以在没有制式棋盘时,我们甚至可以随手拿笔画一个简易棋盘来进行游戏,而这最大的好处就是随便找个地方就可以玩这个简单而有趣的游戏了。

规则介绍

        🍁双方手持若干数量(一般是4-5)的棋子,因为如果棋子摆满棋盘,先手方摆放的棋子数量为5,后手方摆放棋子数量为4。

⭕双方轮流在格子里摆放棋子,先连成三棋一线者视为胜利;

⭕棋盘被摆满棋子仍未分出胜利,视为平局。

程序设计

基本流程

在写三子棋的代码之前,我们来看看实现这个游戏的逻辑:

1.菜单界面选择开始或者退出游戏。
2.创建棋盘并初始化。
3.打印棋盘。
4.玩家落子(玩家输入行列坐标的方式来落子),'*’表示玩家落子。
5.判定胜负关系(输,赢,和棋),'Q’表示和棋。
6.电脑落子(随机位置落子) ,'#’表示电脑落子。
7.判定胜负关系。
8.回到 步骤2 继续执行。

菜单界面打印

void menu()
{
	printf("*********************************\n");
	printf("******1.play    0.exit    *******\n");
	printf("*********************************\n");
}

🔴1表示开始玩游戏 

🔴0表示退出游戏

创建棋盘并初始化

棋盘:使用3行3列的二维数组来表示,元素类型是char。

使用宏定义的原因
⭕推高代码可读性,后续代码中遇到3,方便理解含义。
⭕提高扩展性,如果将来要修改棋盘尺寸,代码修改会很方便。

#define ROW 3
#define LEN 3
void DesplayBoard(char board[ROW][LEN], int row, int len)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < len; j++)
		{
			board[i][j] = ' ';//表示棋盘上的空白区域
		}
	}
}

打印棋盘

void PrintBoard(char board[ROW][LEN], int row, int len)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < len; j++) 
		{
			printf(" %c ", board[i][j]);
			if (j < len - 1)
				printf("|");
		}
		printf("\n");

		if (i < row - 1)
		{
			for (int j = 0; j < len; j++)
			{
				printf("---");
				if (j < len - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}


玩家落子

玩家输入行列坐标表示落子,使用’ * ’表示玩家落子。
1.玩家落子需要在棋盘范围内。
2.玩家要在棋盘上空的地方落子。
3.如果输入的坐标不满足要重新输入。

//玩家下棋
void PlayerMove(char board[ROW][LEN], int row, int len)
{
	while (true)
	{
		int x, y = 0;
		printf("请输入你想要落子的位置->");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= len)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
				printf("已经被占用,请重新输入:\n");
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	}
	printf("----玩家 *----\n");
}

电脑落子

电脑随机产生行列坐标,'o’表示电脑落子。

注意:
1.要在主函数中使用srand((unsigned int)time(0))详细可见:这是随机数生成详细的介绍
将时间作为随机数种子,确保得到的行列坐标是真随机。
2.要在棋盘上空的地方下棋。

void ComputerBoard(char board[ROW][LEN], int row, int len)
{
	while (true)
	{
		int x = rand() % row;
		int y = rand() % len;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
	printf("----电脑 #----\n");
}

判断胜负

🍁此处约定返回结果的含义:
💧‘*’ 表示玩家获胜
💧‘#’ 表示电脑获胜
💧’ C’ 表示胜负未分
💧 ‘Q’ 表示和棋

1.判定是否和棋

(1)调用isFull函数。
(2)如果数组中有元素为’ ‘,那么没满,返回0。如果全不为’ ',满了,返回1。
(3)如果棋盘满了未分出胜负,和棋。

2.判定胜负

(1)判定所有的行
(2)判定所有的列
(3)判定两条对角线

//判断输赢 玩家赢--> *   电脑赢--> #   平局--> Q   继续--> C
bool IsFull(char board[ROW][LEN], int row, int len)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < len; j++)
		{
			if (board[i][j] == ' ')
				return false;
		}
	}
	return true;
}
char IsWin(char board[ROW][LEN], int row, int len)
{
	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 < len; 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[1][1] != ' ')
		|| (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '))
	{
		return board[1][1];
	}
	//判断是否平局
	if (IsFull(board, row, len))
	{
		return 'Q';
	}
	//继续游戏
	return 'C';
}

 代码总汇

✅Game.h 头文件

#pragma once
#include<stdio.h>
#include<stdbool.h>
#include <time.h>
#include <stdlib.h>
#define ROW 3
#define LEN 3

void DesplayBoard(char board[ROW][LEN], int row, int len);
void PrintBoard(char board[ROW][LEN], int row, int len);
//玩家下棋
void PlayerMove(char board[ROW][LEN], int row, int len);

//电脑下棋
void ComputerBoard(char board[ROW][LEN], int row, int len);

//判断输赢 玩家赢--> *   电脑赢--> #   平局--> Q   继续--> C
char IsWin(char board[ROW][LEN], int row, int len);

✅Game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Game.h"
void DesplayBoard(char board[ROW][LEN], int row, int len)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < len; j++)
		{
			board[i][j] = ' ';
		}
	}
}
void PrintBoard(char board[ROW][LEN], int row, int len)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < len; j++) 
		{
			printf(" %c ", board[i][j]);
			if (j < len - 1)
				printf("|");
		}
		printf("\n");

		if (i < row - 1)
		{
			for (int j = 0; j < len; j++)
			{
				printf("---");
				if (j < len - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}
//玩家下棋
void PlayerMove(char board[ROW][LEN], int row, int len)
{
	while (true)
	{
		int x, y = 0;
		printf("请输入你想要落子的位置->");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= len)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
				printf("已经被占用,请重新输入:\n");
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	}
	printf("----玩家 *----\n");
}

//电脑下棋
void ComputerBoard(char board[ROW][LEN], int row, int len)
{
	while (true)
	{
		int x = rand() % row;
		int y = rand() % len;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
	printf("----电脑 #----\n");
}

//判断输赢 玩家赢--> *   电脑赢--> #   平局--> Q   继续--> C
bool IsFull(char board[ROW][LEN], int row, int len)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < len; j++)
		{
			if (board[i][j] == ' ')
				return false;
		}
	}
	return true;
}
char IsWin(char board[ROW][LEN], int row, int len)
{
	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 < len; 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[1][1] != ' ')
		|| (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '))
	{
		return board[1][1];
	}
	//判断是否平局
	if (IsFull(board, row, len))
	{
		return 'Q';
	}
	//继续游戏
	return 'C';
}

✅Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Game.h"
void menu()
{
	printf("*********************************\n");
	printf("******1.play    0.exit    *******\n");
	printf("*********************************\n");
}
void game()
{
	char board[ROW][LEN] = { 0 };
	DesplayBoard(board, ROW, LEN);
	char ret = 0;
	while (true)
	{
		PlayerMove(board, ROW, LEN);
		PrintBoard(board, ROW, LEN);
		ret = IsWin(board, ROW, LEN);
		if (ret != 'C')
		{
			break;
		}
		ComputerBoard(board, ROW, LEN);
		PrintBoard(board, ROW, LEN);
		ret = IsWin(board, ROW, LEN);
		if (ret != 'C')
		{
			break;
		}
	}
	if ('*' == ret)
	{
		printf("玩家赢\n");
	}
	else if ('#' == ret)
	{
		printf("电脑赢\n");
	}
	else if ('Q' == ret)
	{
		printf("平局\n");
	}
}
int main()
{
	srand(time(0));

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/669046.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编译安装以及升级Nginx

目录 一、前言 1、简介 2、 Nginx模块 3、与Apache的差异 4、优点 二、编译安装 1、关闭防火墙 2、安装依赖包 3、创建运行用户与组 4、编译安装 5、检测配置文件是否正确 6、添加系统服务 三、版本升级 四、总结 一、前言 1、简介 Nginx是一个高性能的HTTP和反…

chatgpt赋能python:Python散点图连线——一种美妙的可视化方法

Python散点图连线——一种美妙的可视化方法 散点图连线是一种常用的可视化方法&#xff0c;可以展示不同维度之间的关系和趋势。在Python中&#xff0c;我们可以使用多种库来绘制散点图连线&#xff0c;例如matplotlib、seaborn和plotly等。本文将介绍如何使用matplotlib和plo…

数学公式库mathjs 安装使用教程

Math.js 是个JavaScript 和 Node.js 的扩展数学库。它包括了灵活的表达式解析器&#xff0c;提供数字&#xff0c;大数值&#xff0c;复杂数值&#xff0c;单位&#xff0c;矩阵等等集成的解决方案。Math.js 很强大又易于使用。 特性 支持数值&#xff0c;大数值&#xff0c…

医疗IT绝缘监测应用

近年来&#xff0c;随着医疗技术的迅猛发展&#xff0c;电子电气相关医疗设备在医院中的应用越来越广泛&#xff0c;各类疾病治疗也越来越依赖医疗电气设备 。人们对医院医疗环境提出更高要求&#xff0c;传统的建筑、电气等设计已难以充分保障其人身安全。患者及医务人员已深陷…

每日学术速递6.10

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Unifying (Machine) Vision via Counterfactual World Modeling 标题&#xff1a;通过反事实世界建模统一&#xff08;机器&#xff09;视觉 作者&#xff1a;Daniel M. Bear, K…

LFS11.3在VMware安装后需要做的准备

参考lfs 11.3和Blfs 11.3 先简单罗列一下要做的步骤&#xff0c;后续有机会再补充一下细节&#xff0c;遇到问题欢迎读者留言。 1、配置vmware中的网络连接 使用vmware net8 net模式&#xff0c;选用VMnet 配置网络连接/etc/sysconfig/ 目录下ifconfig.*** &#xff08;***为…

RK3588平台开发系列讲解(AI 篇)什么是RKNPU

文章目录 一、RKNPU的发展历史二、RKNPU单核架构三、RKNPU性能计算四、RKNPU应用场景沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要讲解什么是RKNPU。 一、RKNPU的发展历史 二、RKNPU单核架构 三、RKNPU性能计算 NPU算力是指每秒可以处理的运算次数,通常…

基于Hata模型的BPSK调制信号小区覆盖模拟matlab完整程序分享

基于Hata信道模型的BPSK调制信号小区覆盖模拟matlab仿真,对比VoIP, Live Video,FTP/Email 完整程序: clc; clear; close all; warning off; addpath(genpath(pwd)); % Random bits are generated here. bits = randi([0, 1], [50,1]); M = 2; t = 1:1:50; trans = pskmod(bi…

支持硬件加速的opencv编译

背景 为了降低cpu的使用率提升系统的接入能力&#xff0c;需要将编解码模块移至GPU处理&#xff0c;opencv默认的发行版中不支持GPU加速&#xff0c;所以需要重新编译opencv使其支持GPU硬件加速。 读者 本文的读者须具备一定的Linux使用经验&#xff0c;如常规软件安装等操作…

扫雷小游戏【C语言】

目录 前言 一、基本实现逻辑 二、实现步骤 1. 我们希望在进入游戏时有一个菜单让我们选择 2. 我们希望可以重复的玩&#xff08;一把玩完了还可以接着玩&#xff09; 3. 采用多文件形式编程 4.要扫雷先得有棋盘&#xff08;创建棋盘R*N&#xff09; 5.初始化棋盘 6.打…

0014-TIPS-pawnyable : Double-Fetch pt_regs

原文 Linux Kernel PWN | 040302 Pawnyable之双取 Double Fetch 题目下载 漏洞代码 #include <linux/module.h> #include <linux/kernel.h> #include <linux/cdev.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/sl…

chatgpt赋能python:Python搜索本地文件指南

Python搜索本地文件指南 在进行开发或者日常使用中&#xff0c;需要对本地的文件进行搜索操作是常见的需求。如果你正在学习Python编程&#xff0c;接下来的内容会为你提供一些如何使用Python进行本地文件搜索的指南。 搜索文件 在Python中搜索本地文件可以使用os模块。该模…

杂记 | 使用FRP搭建内网穿透服务

文章目录 01 需求场景02 项目地址03 文件介绍04 编写配置文件4.1 编写frps.ini4.2 编写frpc.ini 05 测试 01 需求场景 1、有一台云服务器&#xff0c;Linux&#xff08;CentOS7&#xff09;系统 2、云服务器有公网ip&#xff0c;公网可以访问 3、本地电脑是家用笔记本&#xf…

AN10833-MIFARE type identification procedure.pdf

1.2范围 本文档描述了如何区分MIFARE接口卡IC系列的成员。ISO/IEC 14443-3描述了类型A的初始化和防冲突程序&#xff0c;该程序为所有MIFARE卡提供卡类型信息。 MIFARE卡与ISO/IEC 14443-3兼容。因此&#xff0c;已经存在的应用可以很容易地扩展到分别使用较新的MIFARE芯片和所…

017、数据库管理之监控

监控工具 TiDB数据库的监控体系TiDB Dashboard数据库监控系统数据流转监控系统访问地址 报警系统报警级别指标系统常用监控指标Service Port Status 常用监控指标PD的常用监控指标TiDB-Server的常用监控指标TiKV 的常用监控指标Dashboard的常用指标 实验&#xff1a; 通过监控工…

Flink 学习六 Flink 窗口计算API

Flink 学习六 Flink 窗口计算API 1.窗口 (window)概念和分类 窗口 window 是处理无限流的核心就是把无界的数据流,按照一定的规则划分成一段一段的有界的数据流(桶),然后再这个有界的数据流里面去做计算; 2.分类体系 2.1 滚动窗口 相邻窗口之间是没有数据重合 window 大小…

Geocomputation (2)Attribute data operations

Geocomputation &#xff08;2&#xff09;Attribute data operations 属性数据操作 来源&#xff1a;https://github.com/geocompx/geocompy 1.准备 #| echo: false import pandas as pd import matplotlib.pyplot as plt pd.options.display.max_rows 6 pd.options.disp…

chatgpt赋能python:Python搜索函数:快速、高效的搜索利器

Python 搜索函数&#xff1a;快速、高效的搜索利器 如果你经常使用 Python 编程语言&#xff0c;那么你应该知道搜索数据集的重要性。用于搜索的函数在 Python 中是关键而常用的工具。Python 搜索函数是一种高效、快速的搜索利器&#xff0c;它可以让你轻松地找到你需要的数据…

C生万物 | 聊聊枚举与联合体的用法

文章目录 枚举1、枚举类型的定义2、枚举的使用3、枚举的优点 联合体1、联合体类型的定义2、联合体的特点3、联合体大小的计算一道经典面试题&#xff1a;判断当前计算机的大小端存储 总结与提炼 本文&#xff0c;我们就来谈谈C语言中的枚举和联合体&#xff0c;因为这两块知识点…

6月21日第壹简报,星期三,农历五月初四

6月21日第壹简报&#xff0c;星期三&#xff0c;农历五月初四坚持阅读&#xff0c;静待花开1. 中国LPR“对称降息”10个基点&#xff0c;房贷迎今年首次“降息”。2. 孟加拉国正式申请加入金砖国家&#xff0c;中方&#xff1a;欢迎更多伙伴早日加入金砖大家庭。3. 历时近2年波…