IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言三子棋游戏代码+思路分析 -> 正文阅读

[C++知识库]C语言三子棋游戏代码+思路分析

1.测试页面的代码

#define _CRT_SECURE_NO_WARNINGS 1
# include<stdio.h>
#include"game.h"
#include<stdlib.h>
#include<time.h>
//菜单
void menu() {
	printf("**********欢迎来到三子棋游戏***********\n");
	printf("******1.play.**********0.exit.*********\n");
	printf("***************************************\n");
}

//游戏
void game() {
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	char ret = 0;

	while (1) {
		//玩家下棋
		PlayerMove(board, ROW, COL);
		//判断输赢
		ret = Is_Wins(board, ROW, COL);
		if (ret != 'C') {//若是不继续游戏则跳出while循环
			break;
		}
		//下完棋打印
		DisplayBoard(board, ROW, COL);

		//电脑下棋
		ComputerMove(board, ROW, COL);
		ret = Is_Wins(board, ROW, COL);
		if (ret != 'C') {//若是不继续游戏则跳出while循环
			break;
		}
		//下完棋打印
		DisplayBoard(board, ROW, COL);
	}

	//打印出最终结果图
	DisplayBoard(board, ROW, COL);
	if (ret == '*') {
		printf("玩家赢\n");
	}
	else if (ret == '#') {
		printf("电脑赢\n");
	}
	else if (ret == 'Q') {
		printf("平局\n");
	}
}

int main() {
	int input = 0;
	//给电脑下棋的随机性做一个时间戳
	srand((unsigned int)time(NULL));
	do {
		menu();
		printf("请输入你的选择:>\n");
		scanf("%d", &input);
		switch (input) {
		case 1:
			game();
			break;
		case 0:
			printf("即将退出程序!\n");
			exit(0);
			break;
		default:
			printf("输入错误!\n");
			break;
		}
	} while (input);
	return 0;
}

2.头文件game.h代码--函数声明

#pragma once
#pragma once
#include<stdio.h>
#define ROW 3
#define COL 3
//初始化棋盘的函数声明
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘函数声明
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋函数声明
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋函数声明
void ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢
char Is_Wins(char board[ROW][COL], int row, int col);

3.game.c函数代码

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

//初始化棋盘的函数
void InitBoard(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 DisplayBoard(char board[ROW][COL], int row, int col) {
	int i = 0;
	for (i = 0; i < row; i++) {
		int j = 0;
		for (j = 0; j < col; j++) {
			printf(" %c ", board[i][j]);//打印出三行的空格
			if (j < col - 1) {//每一行的分隔符
				printf("|");
			}
		}
		printf("\n");

		if (i < row - 1) {//不打印第三行的---
			int j = 0;
			for (j = 0; j < col; j++) {
				printf("---");
				if (j < col - 1) {//第三列不打印 |
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

//玩家下棋函数
void PlayerMove(char board[ROW][COL], int row, int col) {
	int x = 0;
	int y = 0;
	printf("玩家下棋:>\n");
	while (1) {
		printf("请输入坐标: ");
		scanf("%d %d", &x, &y);
		//玩家不懂数组下标从0开始,所以他认为的2 2就是第二行第二个元素,按玩家认知来
		if (x >= 1 && x <= row && y >= 1 && y <= col) {
			if (board[x - 1][y - 1] == ' ') {//但在表格中要将玩家输入的横纵坐标各减一
				board[x - 1][y - 1] = '*';
				break;//下棋是回合制游戏,你一下,我一下的,所以输入一步后就停止继续下棋。
			}
			else {
				printf("格子已被占用,请重新输入!\n");
			}
		}

		//若玩家输入的坐标不符合数组内容,例如输入:2 5(数组越界),就会弹出警告,需要重新输入
		else {
			printf("非法输入坐标\n");
		}
	}
}

//电脑下棋函数--电脑肯定是知道数组下标为0开始,所以横纵坐标不需要-1
void ComputerMove(char board[ROW][COL], int row, int col) {
	int x = 0;
	int y = 0;
	printf("电脑下棋:>\n");
	while (1) {
		//给电脑下棋做一个随机性,随便下棋
		x = rand() % row;//rand产生0-32767的随机一个数,但%row(3)后随机数的范围在0-2三个数之间
		y = rand() % col;//同理
		if (board[x][y] == ' ') {
			board[x][y] = '#';
			break;
		}
	}
}

//判断棋盘是否满了
int Is_fall(char board[ROW][COL], int row, int col) {
	int i = 0;
	for (i = 0; i < row; i++) {
		int j = 0;
		for (j = 0; j < col; j++) {
			if (board[i][j] == ' ') {//说明棋盘没满了
				return 0;
			}
		}
	}
	return 1;//说明满了,平局
}


//判断输赢
char Is_Wins(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][1] != ' ') {
			return board[i][1];
		}
		//列三子连城
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ') {
			return board[1][i];
		}
	}
	//正对角线三子连成
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') {
		return board[1][1];
	}
	//副对角线三子连成
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') {
		return board[1][1];
	}
	if (1 == Is_fall(board, ROW, COL)) {
		return 'Q';
	}
	else
		return 'C';
}

????????对于井字棋游戏,我们并不陌生,小时候经常与同学,朋友之间玩的一种游戏,它是在一个3*3大小的正方形棋盘中进行,好比五子棋一般,执行回合制,一人走一步,若谁先把下好的棋连成一条线,谁就赢得比赛的胜利。注:这里的一条线指的是某一行,某一列,或者两条对角线上的任意一种达成即可。

????????1.首先,我们可以在主函数中创建一个游戏的基础写法,利用do..while语句可以先执行一次循环体,再进行判断条件,若判断条件一直为真,那么我们便可以一直玩这个游戏。这种写法应该是所有游戏都会用到的写法了。之后我们设计菜单界面,进行游戏界面的美化,输入相应的文字功能,教给用户如何玩这个游戏。

? ? ? ? 2.在game游戏中,根据游戏的核心,创建出一个宏定义的行列矩阵数组,这样做方便我们以后改成5*5,10*10大小的界面时,不需要大费周章改各种数据,只需要修改头文件中define的行列数字即可!然后就该给数组界面建立边界,例:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???空格 ?| ?空格 ? | 空格
? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?空格 ?| ?空格 ? | 空格
? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?空格 ?| ?空格 ? | 空格 ?

其次,还需要行与行之间建立分割的符合“---”与“|”两种符合

????????????????????????????????????????????????---|---|---

? ? ? ? ? ? ? ????????????????????????????????? ---|---|---? ??

最终形成数组打印后如下:?

????????3. 井字棋作为两方博弈游戏,自然是要创立双方的函数,在这里我使用了玩家(主动操控下棋处的)函数和电脑(计算机下棋)函数,若想玩双人小游戏,则需要将我的电脑函数代码改为玩家函数即可。我设立的规则是玩家使用‘ * '号下棋,电脑使用'#'号下棋,考虑到玩家并不懂数组的下标位置从0开始,所以正常输入,代码中是将玩家输入的坐标行列都减1就行。若是玩家输入的坐标不符合条件,就提示警告;对于电脑函数,就没有那么多的限制,电脑函数的核心在于输入坐标的随机性,函数中用到了rand函数:在0—32767之间产生一个随机数;

?

????????rand函数调用
rand()函数每次调用前都会查询是否调用过srand,是否给srand设定了一个值,如果有那么它会自动调用srand一次来初始化它的起始值.
若之前没有调用srand,那么系统会自动给srand赋初始值,即srand(1)自动调用它一次。

????????想要使rand随机的生成一个随机数就要用到srand函数。

?

?strand函数:设置随机数的起点,让rand()产生的随机数随机化,用时间作种子 srand(time(NULL)),这样每次运行程序的时间肯定是不相同的,产生的随机数肯定就不一样了。代码如下:

srand((unsigned int) time(NULL));//time--时间戳(与系统从1970-0-0 0时0分至今的时间,时时刻刻在变化),增强随机数的随机性(使系统在输出随机数的时候能保持随机性)

? ? ? ?

????????4.接下来就是需要创建判断输赢的函数了。在井字棋中,我设立游戏的输赢方案是在于一方优先达到行三连、列三连、正副对角线三连成线,若是‘ * ’先连成则表明玩家赢,若是‘ # ’号先连成,则是电脑赢,若是棋盘都下满,双方没有分出胜负则表明是平局‘Q’。

1.玩家赢图片展示? ? ? ??

2.电脑赢图片展示

3.平局展示

?

感谢观看,点个关注再走吧谢谢!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:19:47  更:2022-07-21 21:22:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 20:04:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码