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. 首先是自己最先创建,包含主函数的.c文件,例如在此游戏中是test.c。
  2. 我们通常会新建一个头文件,例如此游戏新建game.h,此头文件通常用来完成函数声明、头文件的引用、宏定义变量。
  3. 新建一个.c文件,例如在此游戏新建game.c,编写涉及到的功能函数实现。

二、思路

  1. 我们可以先编写让玩家进行输入(决定是否进行游戏,例如:进行输入1,不进行输入0,(这里运用switch语句进行判断选择))。
  2. 如果用户输入1,则我们进入游戏。
  3. 我们都知道三子棋游戏是需要玩家输入(下棋),接着是电脑自动输入(下棋),(或者电脑先下,玩家后下,这里我们设置的是玩家先下)那么我们下棋之前每一个格子里面肯定都是空的。
  4. 所以,进入游戏之后的第一步,我们要初始化棋盘,并且将其打印出来,这样我们可以清楚的看到棋盘的样子。
  5. 接着我们定义函数让玩家进行输入。
  6. 打印棋盘(这样可以清楚地看到玩家输入之后棋盘的样子)。
  7. 接着定义函数让电脑进行输入。
  8. 打印棋盘(这样可以清楚地看到电脑输入之后棋盘的样子)
  9. 如果这样打印,那么我们会发现一个问题,那就是当棋盘下满之后,还是继续的状态。这个时候我们就知道我们需要判断是电脑赢还是玩家赢或者是平局。
  10. 然后在玩家输入并且打印棋盘之后我们就需要定义一个判断输赢的函数去判断(因为一直处于玩家输完电脑输入的状态,随时有可能玩家赢)。
  11. 同理,在电脑输入并且打印棋盘之后,我们需要用定义输赢的那个函数去判断。

简单来说,步骤如下:

  1. 棋盘的初始化;
  2. 打印棋盘;
  3. 玩家下棋;
  4. 打印玩家下了之后的棋盘;
  5. 判断输赢;
  6. 电脑下棋;
  7. 打印电脑下了之后的棋盘;
  8. 判断输赢。

三、详细步骤

1、菜单界面

定义一个菜单函数,放到main()函数中。其中 1 表示 游戏开始(进入游戏),0表示不玩游戏(退出游戏)。(其中srand()是随机数发生器的初始化函数,在电脑自动输入时候会用到;并且御用switch语句来判断)

void menu()
{
	printf("------------------------------\n");
	printf("-----------请输入:-----------\n");
	printf("------游戏开始(输入1):-----\n");
	printf("------不玩游戏(输入0):-----\n");
	printf("------------------------------\n");
}
int main()
{
	int a;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请输入:\n");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	}while (a);
	return 0;
}

2、创建棋盘

定义函数game(),在其中创建棋盘。使用3行3列的二维数组来表示,元素类型是char。

?接着新建game.h,此头文件通常用来完成函数声明、头文件的引用、宏定义变量。在其中定义行和列的大小(这个例子是三行三列):

?【注意】#pragma once是保证无论头文件被引用多少次,都只读取一次。

3、棋盘初始化

void Initboard(char board[ROW][COL], int row, int col)
{
	int i,j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

?4、打印棋盘

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

5、玩家下棋

【注意】
1.玩家落子需要在棋盘范围内。
2.玩家要在棋盘上空的地方落子。
3.如果输入的坐标不满足要重新输入。

void Playmove(char board[ROW][COL], int row, int col)
{
	printf("玩家走\n");
	int x, y;
	while (1)
	{
		scanf("%d %d", &x, &y);//输入要走的坐标
		if (x >= 1 && x <= row && y >= 1 && y <= row)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐标被占用\n");
			}
		}
		else
		{
			printf("非法坐标\n");
		}
	}

}

6、电脑下棋

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

void Computermove(char board[ROW][COL], int row, int col)
{
	printf("电脑走\n");
	int x, y;
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

7、判断输赢

调用Iswin()函数,此处约定返回结果的含义:

  1. ‘*’ 表示玩家获胜
  2. ‘#’ 表示电脑获胜
  3. ’ p’ 表示平局
  4. ?'c'表示对局继续

我们要判断的方面:

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

第一种:

【注意】:

箭头指向的代码不要放在判断在 一行/列 电脑或者玩家是否赢?的else if后面(如下):

?因为如果放在此处,只要打印的棋盘里面有一处是空,那么即使一行/列都是*或#,也不会显示玩家/电脑赢。

char Iswin(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)//行
	{
		if ((board[i][0] == '*') && (board[i][1] == '*') && (board[i][2] == '*'))
		{
			return '*';//玩家获胜
		}
		else if ((board[i][0] == '#') && (board[i][1] == '#') && (board[i][2] == '#'))
		{
			return '#';//电脑获胜
		}
	}
	for (i = 0; i < col; i++)//列
	{
		if ((board[0][i] == '*') && (board[1][i] == '*') && (board[2][i] == '*'))
		{
			return '*';
		}
		else if ((board[0][i] == '#') && (board[1][i] == '#') && (board[2][i] == '#'))
		{
			return '#';
		}
	}
	//对角线
	if (((board[0][0] == '*') && (board[1][1] == '*') && (board[2][2] == '*')) || ((board[0][2] == '*') && (board[1][1] == '*') && (board[2][0] == '*')))
		return '*';
	else if (((board[0][0] == '#') && (board[1][1] == '#') && (board[2][2] == '#')) || ((board[0][2] == '#') && (board[1][1] == '#') && (board[2][0] == '#')))
		return '#';
	else
	{
		for (i = 0; i < row; i++)
		{
			for (j = 0; j < col; j++)
			{
				if (board[i][j] == ' ')
					return 'c';
			}
		}
		return 'p';
	}
}

第二种:

int IsFull(char board[ROW][COL], int row, int col)
{
	int i,j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}
char Iswin(char board[ROW][COL], int row, int col)
{
	//行
	int i;
	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 < col; 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] != ' ')
		return board[1][1];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
		return board[1][1];
	//判断平局
	if (IsFull(board, row, col))
	{
		return 'p';
	}
	return 'c';
}

四、代码

game.h头文件:

#pragma once

#define ROW 3
#define COL 3
#include <stdio.h>
#include "game.h"
#include <time.h>
#include <stdlib.h>

void Initboard(char board[ROW][COL],int row ,int col);//初始化空格
void Playboard(char board[ROW][COL],int row, int col);//打印棋盘
void Playmove(char board[ROW][COL], int row, int col);
void Computermove(char board[ROW][COL], int row, int col);
char Iswin(char board[ROW][COL], int row, int col);//假设玩家赢了 返回* 电脑赢了 返回# 平局 返回 p 都没赢 c

game.c源文件:

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void Initboard(char board[ROW][COL], int row, int col)
{
	int i,j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void Playboard(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		}
		printf("\n");
		if (i < row-1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
		}
		printf("\n");
	}
}
void Playmove(char board[ROW][COL], int row, int col)
{
	printf("玩家走\n");
	int x, y;
	while (1)
	{
		scanf("%d %d", &x, &y);//输入要走的坐标
		if (x >= 1 && x <= row && y >= 1 && y <= row)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐标被占用\n");
			}
		}
		else
		{
			printf("非法坐标\n");
		}
	}

}
void Computermove(char board[ROW][COL], int row, int col)
{
	printf("电脑走\n");
	int x, y;
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}
char Iswin(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)//行
	{
		if ((board[i][0] == '*') && (board[i][1] == '*') && (board[i][2] == '*'))
		{
			return '*';//玩家获胜
		}
		else if ((board[i][0] == '#') && (board[i][1] == '#') && (board[i][2] == '#'))
		{
			return '#';//电脑获胜
		}
	}
	for (i = 0; i < col; i++)//列
	{
		if ((board[0][i] == '*') && (board[1][i] == '*') && (board[2][i] == '*'))
		{
			return '*';
		}
		else if ((board[0][i] == '#') && (board[1][i] == '#') && (board[2][i] == '#'))
		{
			return '#';
		}
	}
	//对角线
	if (((board[0][0] == '*') && (board[1][1] == '*') && (board[2][2] == '*')) || ((board[0][2] == '*') && (board[1][1] == '*') && (board[2][0] == '*')))
		return '*';
	else if (((board[0][0] == '#') && (board[1][1] == '#') && (board[2][2] == '#')) || ((board[0][2] == '#') && (board[1][1] == '#') && (board[2][0] == '#')))
		return '#';
	else
	{
		for (i = 0; i < row; i++)
		{
			for (j = 0; j < col; j++)
			{
				if (board[i][j] == ' ')
					return 'c';
			}
		}
		return 'p';
	}
}

test.c源文件:

//三子棋游戏
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void menu()
{
	printf("------------------------------\n");
	printf("-----------请输入:-----------\n");
	printf("------游戏开始(输入1):-----\n");
	printf("------不玩游戏(输入0):-----\n");
	printf("------------------------------\n");
}
void game()
{
	//三子棋
	char board[ROW][COL];//棋盘数组
	Initboard(board, ROW, COL);	//初始化棋盘
	Playboard(board, ROW, COL);//打印棋盘
	char ret;
	while (1)
	{
		Playmove(board, ROW, COL);//人走
		Playboard(board, ROW, COL);//打印棋盘
		ret = Iswin(board, ROW, COL);
		if (ret != 'c')
		{
			break;
		}
		Computermove(board, ROW, COL);//电脑走
		Playboard(board, ROW, COL);//打印棋盘
		ret = Iswin(board, ROW, COL);
		if (ret != 'c')
		{
			break;
		}
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
		printf("平局\n");
}

int main()
{
	int a;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请输入:\n");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	}while (a);
	return 0;
}

四、实现结果

玩家赢:

电脑赢:

?平局:

?退出游戏:

五、源代码链接?

https://gitee.com/ltianyuu/c-language/tree/master/test-7-27-3

最后:创作不易,希望大家给博主能点个赞啦!谢谢!!!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 16:31:45  更:2021-07-28 16:31:47 
 
开发: 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年4日历 -2024/4/18 11:24:30-

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