(小陈c语言)井字棋-初步实现以及改进方向

2023-11-18

        作为小学上课偷偷和同桌在草稿本上玩的小游戏-井字棋,如今在电脑上也可以自己写出来玩。如图:

不要惊讶,下面我们来看看怎么实现这个代码。(正文开始)

1.菜单界面:用多个printf 来打印即可,注意中间最好是空的不要连着字。

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

 2.游戏界面:不同于扫雷,我们只需要一个二维数组即可完成这个游戏,我们需要一个3*3的二维数组,用一个函数将数组初始化全为空格,然后打印数组,然后你会发现啥也没有,因为那些横竖的线并不在数组中,那么如果要打印出格子的话需要在打印数组的同时打印格子。代码以及展示图如下。

void displayboard(char board[ROW][LINE]) {
	int i;
	int j;
	int k;
	for (i = 0; i < ROW; i++) {
		for (j = 0; j < LINE; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < (LINE - 1)) {
				printf(" | ");
			}//除每一行最后一个不打印,其余都打印空格
		}
		printf("\n");
		if (i < (ROW - 1))
		{
		for (k = 0; k < LINE; k++) {
				printf(" --- ");
			}//除第一行和最后一行不打印
		}
		printf("\n");
	}
}

 3.用户操作:接下来就是用户来下棋了,我们只需要用户选择需要下的位置,然后将空格换成标识符就可以了,但是还需要判断这个位置有没有被占用,或者这个是否是个合法坐标。

if (board[x - 1][y - 1] != ' ') {
		printf("the location is used\n");
	}
else if (x > 0 && x <=ROW && y <= LINE && y>0) {
		board[x - 1][y - 1] = '*';
	}
		else {
			printf("illagle location\n");
		}

 4.电脑下棋:不要妄想电脑会堵你的路,作为“人工智障”他只会下棋,我们只让他随机下棋就可以了,那么就需要头文件<stdlib.h>和<time.h>,然后判断这个位置是否被占用,如果没被占用就是这个位置啦。

void computer_move(char board[ROW][LINE]) {
	int x;
	int y;
	x = rand() % ROW+1;
	y = rand() % LINE+1;
	while (1)
	{
		if (board[x][y] == ' ') {
			board[x][y] = '#';
			break;
		}
	}
	

5.判断输赢:如何判断输赢呢,我们需要判断三个标识符是否连成一条线,那么就会用三种情况,横着的,竖着的,斜着的那么我们可以用if来判断,每次在用户下完,和电脑下完都需要检验。

//ROw win
	for(i=0;i<ROW;i++){
		if (board[i][0] == board[i][1] && board[i ][1] == board[i][2] && board[i][0] == '*') {
			return 'p';
		}
		else if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] == '#') {
			return 'c';
		}
	}
	//line win
	for (i = 0; i < LINE; i++) {
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[i][i]== '*') {
			return 'p';
		}
		else if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[i][i] == '#') {
			return 'c';
		}
	}

	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == '*') {
		return 'p';
	}
	else if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == '#') {
		return 'c';
	}

返回值在主函数中判断

if (w == 'p') {
			printf("\nplayer win\n");
			break;
		}
		else if (w == 'c'){
			printf("\ncomputer win\n");
			break;
		}
		computer_move(board);
		w = is_win(board);
		displayboard(board);
			if (w == 'p') {
				printf("\nplayer win\n");
				break;
			}
			else if (w == 'c'){
				printf("\ncomputer win\n");
				break;
			}

(这里判断有点冗余了还需要改进)

反思和改进

        这个程序最大的问题就是电脑下棋的不智能性,只能随便下棋,当然如果要需要更高级的只有人工智能才能解决了,这个后续还会持续学习的;第二个就是在判断的时候条件的冗余,这个后续还需要改进。

(下面是完整代码展示)

game.h

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

void iniboard(char board[ROW][LINE]);

void displayboard(char board[ROW][LINE]);

void player_move(char board[ROW][LINE]);

void computer_move(char board[ROW][LINE]);

char is_win(char board[ROW][LINE]);

test.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void iniboard(char board[ROW][LINE]) {
	int i,j;
	for (i = 0; i < ROW; i++) {
		for ( j = 0; j < LINE; j++)
		{
			board[i][j] = ' ';
		}
	}
}

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

void player_move(char board[ROW][LINE]) {
	printf("is your turn(enter the location)>");
	int x, y;
	scanf("%d %d", &x, &y);
	if (board[x - 1][y - 1] != ' ') {
		printf("the location is used\n");
	}
	else if (x > 0 && x <=ROW && y <= LINE && y>0) {
		board[x - 1][y - 1] = '*';
	}
		else {
			printf("illagle location\n");
		}
	
}
void computer_move(char board[ROW][LINE]) {
	int x;
	int y;
	x = rand() % ROW+1;
	y = rand() % LINE+1;
	while (1)
	{
		if (board[x][y] == ' ') {
			board[x][y] = '#';
			break;
		}
	}
	
}
char is_win(char board[ROW][LINE]) {
	int i = 0;
	//ROw win
	for(i=0;i<ROW;i++){
		if (board[i][0] == board[i][1] && board[i ][1] == board[i][2] && board[i][0] == '*') {
			return 'p';
		}
		else if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] == '#') {
			return 'c';
		}
	}
	//line win
	for (i = 0; i < LINE; i++) {
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[i][i]== '*') {
			return 'p';
		}
		else if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[i][i] == '#') {
			return 'c';
		}
	}

	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == '*') {
		return 'p';
	}
	else if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == '#') {
		return 'c';
	}
	

}

game.cpp

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

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

void game() {
	char board[ROW][LINE];
	iniboard(board);
	displayboard(board);
	char w;
	while (1) {
		player_move(board);
		w = is_win(board);
		displayboard(board);
		
		if (w == 'p') {
			printf("\nplayer win\n");
			break;
		}
		else if (w == 'c'){
			printf("\ncomputer win\n");
			break;
		}
		computer_move(board);
		w = is_win(board);
		displayboard(board);
			if (w == 'p') {
				printf("\nplayer win\n");
				break;
			}
			else if (w == 'c'){
				printf("\ncomputer win\n");
				break;
			}
	}
	
	
}
void test() {
	int input;
	srand((unsigned int)time(NULL));
	do{
		menu();
		printf("please enter your choice:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("the game is over");
			break;
		default:
			printf("the choice is fault\n");
			break;
		}
	} while (input);
 }


int main() {
	test();
}

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

(小陈c语言)井字棋-初步实现以及改进方向 的相关文章

  • 是否有与 posix_memalign 对应的 C++ 版本?

    当我打电话时posix memalign http man7 org linux man pages man3 posix memalign 3 html为类型的对象分配对齐的内存Foo在我的 C 代码中 我需要做一个reinterpret
  • 如何从 C# 中的 dataTable.Select( ) 查询中删除单引号?

    所以我有一个经销商名称列表 我正在我的数据表中搜索它们 问题是 一些傻瓜必须被命名为 Young s 这会导致错误 drs dtDealers Select DealerName dealerName 所以我尝试替换字符串 尽管它对我不起作
  • 在c#中执行Redis控制台命令

    我需要从 Redis 控制台获取 客户端列表 输出以在我的 C 应用程序中使用 有没有办法使用 ConnectionMultiplexer 执行该命令 或者是否有内置方法可以查找该信息 CLIENT LIST是 服务器 命令 而不是 数据库
  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • 如何在C(Linux)中的while循环中准确地睡眠?

    在 C 代码 Linux 操作系统 中 我需要在 while 循环内准确地休眠 比如说 10000 微秒 1000 次 我尝试过usleep nanosleep select pselect和其他一些方法 但没有成功 一旦大约 50 次 它
  • 查找进程的完整路径

    我已经编写了 C 控制台应用程序 当我启动应用程序时 不使用cmd 我可以看到它列在任务管理器的进程列表中 现在我需要编写另一个应用程序 在其中我需要查找以前的应用程序是否正在运行 我知道应用程序名称和路径 所以我已将管理对象搜索器查询写入
  • 如何判断计算机是否已重新启动?

    我曾经使用过一个命令行 SMTP 邮件程序 作为试用版的限制 它允许您在每个 Windows 会话中最多接收 10 封电子邮件 如果您重新启动计算机 您可能还会收到 10 个以上 我认为这种共享软件破坏非常巧妙 我想在我的应用程序中复制它
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • 识别 Visual Studio 中的重载运算符 (c++)

    有没有办法使用 Visual Studio 快速直观地识别 C 中的重载运算符 在我看来 C 中的一大问题是不知道您正在使用的运算符是否已重载 Visual Studio 或某些第三方工具中是否有某些功能可以自动突出显示重载运算符或对重载运
  • 如何在 Qt 应用程序中通过终端命令运行分离的应用程序?

    我想使用命令 cd opencv opencv 3 0 0 alpha samples cpp cpp example facedetect lena jpg 在 Qt 应用程序中按钮的 clicked 方法上运行 OpenCV 示例代码
  • 为什么从字典中获取时会得到 Action<> 的克隆?

    我有以下字典 private Dictionary
  • WPF DataGridTemplateColumn 组合框更新所有行

    我有这个 XAML 它从 ItemSource 是枚举的组合框中选择一个值 我使用的教程是 http www c sharpcorner com uploadfile dpatra combobox in datagrid in wpf h
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 在 Windows Phone silverlight 8.1 上接收 WNS 推送通知

    我有 Windows Phone 8 1 silverlight 应用程序 我想使用新框架 WNS 接收通知 我在 package appxmanifest 中有
  • GCC 的“-Wl,option”和“-Xlinker option”语法之间有区别吗?

    我一直在查看一些配置文件 并且看到它们都被使用 尽管在不同的体系结构上 如果您在 Linux 机器上使用 GCC 将选项传递给链接器的两种语法之间有区别吗 据我所知 阅读 GCC 手册时 他们的解释几乎相同 From man gcc Xli
  • 我可以在“字节数”设置为零的情况下调用 memcpy() 和 memmove() 吗?

    当我实际上没有什么可以移动 复制的时候 我是否需要处理这些情况memmove memcpy 作为边缘情况 int numberOfBytes if numberOfBytes 0 memmove dest source numberOfBy
  • 是否可以在不连接数据库的情况下检索 MetadataWorkspace?

    我正在编写一个需要遍历实体框架的测试库MetadataWorkspace对于给定的DbContext类型 但是 由于这是一个测试库 我宁愿不连接到数据库 它引入了测试环境中可能无法使用的依赖项 当我尝试获取参考时MetadataWorksp

随机推荐

  • ubuntu上安装微信

    一 下载安装Wine环境包 http archive ubuntukylin com software pool partner ukylin wine 70 6 3 25 amd64 deb 二 下载安装微信包 http archive
  • Oracle:修改表空间和数据文件的名称

    1 修改表空间名称 alter tablespace tablespace name1 rename to tablespace name2 2 修改数据文件名称 1 先将联机状态的需要修改的表空间设置为脱机状态 ALTER TABLESP
  • 解决Value '0000-00-00 ' can not be represented as java.sql.Timest

    在使用MySql 时 数据库中的字段类型是timestamp的 默认为0000 00 00 会发生异常 java sql SQLException Value 0000 00 00 can not be represented as jav
  • javascript画全年日历

    前些日子闲聊群里有人提了用js画全年日历的需求 趁闲暇时间画了个小demo 下面还是先上效果图吧 高亮显示的是今天的日期和标记要高亮显示的日期 也添加了点击事件的钩子 自己可以实现钩子函数 从而操作点击的日期值 下面还是先上dai 日历视图
  • Linux 系统 /var/log/journal/ 垃圾日志清理

    CentOS系统中有两个日志服务 分别是传统的 rsyslog 和 systemd journal systemd journald是一个改进型日志管理服务 可以收集来自内核 系统早期启动阶段的日志 系统守护进程在启动和运行中的标准输出和错
  • 第1章 Java基础(二)

    1 11 重写和重载的概念 难度 重点 白话解析 这道题它的重点不仅仅是在面试中 因为后续在做开发的时候会接触到大量的重写或重载 也正是因为他们 才实现了Java的多态特性 1 重写 好好理解下 就是本来父亲写好了一个方法 然后儿子觉得父亲
  • 你的Qt按钮可以加载Gif圆形的头像吗?

    先上效果 先看要求 我们首先要求 1 这是一个按钮 所以可以想到重写控件的基类一定是QPushButton 2 我们要求可以播放Gif图片 由此可想到 图片的加载肯定绕不开QMoive 3 头像是圆形的 猜想是不是可以通过样式表 或者重新p
  • 第36步 深度学习图像识别:TensorFlow-gpu环境配置

    基于WIN10的64位系统演示 一 写在前面 从这一期开始分享基于深度学习图像识别的学习笔记和代码 相比于之前的ML分类模型 图像识别的门槛会更高 包括硬件方面 代码复杂度和基础理论知识等 同样 首先把必要的深度学习框架 类似做ML分类 要
  • Windows巧用git实现笔记自动备份

    Windows巧用git实现笔记自动备份 准备git仓库 配置自动上传脚本 设置 Windows 自动定时任务 参考文献 今天突然发现 可以 使用Gitee加上Windows定时任务 实现Windows端的笔记 自动备份 多端同步 历史回溯
  • gin 获取get 所有参数_Golang Gin 实战(三)

    在 上一篇 Golang Gin 实战 二 简便的Restful API 实现 文章中 我们留了一个疑问 假如我们有很多用户 我们要为他们一个个注册路由 路径 吗 路由路径 如下URL users 123 users 456 users 2
  • 【Android】相对布局(RelativeLayout)最全解析

    Android 相对布局 RelativeLayout 最全解析 一 相对布局 RelativeLayout 概述 二 根据父容器定位 三 根据兄弟控件定位 一 相对布局 RelativeLayout 概述 相对布局 RelativeLay
  • 【模型融合】集成学习(boosting, bagging, stacking)原理介绍、python代码实现(sklearn)、分类回归任务实战

    文章目录 概览 boosting bagging Stacking 投票 平均 Stack 代码实现 1 分类 1 0 数据集介绍 1 1 boosting 1 2 bagging 1 3 stacking 2 回归 2 0 数据集介绍 s
  • xenserver6.5 重启后退不出 maintenance mode 的解决

    环境 XenServer 6 5 开源版本 故障起因 2017 6 9 因虚拟机在访问里面的服务时特别的卡慢 所以对宿主主机进行物理重启 但是重启后用xencenter却启不起来xen服务器 显示在维护模式 exit maintenance
  • v-model是什么?怎么使用?

    v model是什么 怎么使用 v model用于表单数据的双向绑定 其实它就是一个语法糖 这个背后就做了两个操作 v bind绑定一个value属性 v on指令给当前元素绑定input事件 v model很好地体现了vue双向绑定的理念
  • C++11 chrono计时

    我的C 文章列表 C 中Duration Time point和Clocks 万里归来少年心的博客 CSDN博客 time point C 11中的chrono库 实现时间相关的功能 1 time point time point表示一个时
  • 什么是php 服务器地址,服务器地址是什么

    服务器地址是服务器的ip地址 IP地址就是给每个连接在互联网上的主机分配的一个32位地址 有这种地址 才保证了用户在连网的计算机上操作时 能够高效而且方便地从千千万万台计算机中选出所需的对象来 本文操作环境 Windows7系统 Dell
  • AI 对抗超级细菌:麦克马斯特大学利用深度学习发现新型抗生素 abaucin

    内容一览 鲍曼不动杆菌是一种常见的医院获得性革兰氏阴性病原体 通常表现出多重耐药性 利用传统方法 发现抑制此菌的新型抗生素很困难 但利用机器学习可以快速探索化学空间 从而增加发现新型抗菌分子的可能性 近期 国际期刊 Nature Chemi
  • Java生成纳秒时间戳

    记一次生成高精度时间戳 类似与 net的时间戳 码着备忘 long timestamp System currentTimeMillis 1000000L System nanoTime 1000000L System currentTim
  • 函数的防抖与节流

    一 防抖与节流的联系 相同点 防抖 Debounce 和节流 Throttle 都是用来控制某个函数在一定时间内触发次数 两者都是为了减少触发频率 以便提高性能以及避免资源浪费 不同点 节流是第一个说了算 后续都会被节流阀屏蔽掉 防抖是最后
  • (小陈c语言)井字棋-初步实现以及改进方向

    作为小学上课偷偷和同桌在草稿本上玩的小游戏 井字棋 如今在电脑上也可以自己写出来玩 如图 不要惊讶 下面我们来看看怎么实现这个代码 正文开始 1 菜单界面 用多个printf 来打印即可 注意中间最好是空的不要连着字 void menu p