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 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 自写小游戏-三子棋 -> 正文阅读

[游戏开发]自写小游戏-三子棋

1.三子棋分析

三子棋顾名思义就是五子棋的缩小版,棋手和电脑进行博弈,当某一方棋子三子连珠,该方即为获胜方,可用符号‘#’来表示玩家棋子,‘*’代表电脑棋子,便于对弈双方的区分,该自写程序电脑执行下棋步骤还不具备识别赢棋规则,后期需要改进。
三子棋游戏需要有以下几个功能:
1.游戏菜单
2.初始化棋盘
3.当前棋盘状态界面显示
3.下棋模式
4.检测三子连珠模块
5.检测平局模块

2.建立三子棋盘模型

                                     |     |   
                                -----|-----|-----
                                     |     |      
                                -----|-----|-----
                                     |     |      

3.功能分析和设计

3.1游戏菜单

游戏菜单至少包含以下两个功能(待补充):

  1. 游戏名称展示;
  2. 游戏进入退出选择模式;

3.1.1设计流程图

游戏菜单设计流程图如下:

Created with Rapha?l 2.3.0 start 输入模式 模式输入正确与否 是否进入游戏 进入游戏 end yes no yes no

3.1.2源码

 ```c源码
//利用goto语句********************************
  int Intput()
{
	int intput;
	scanf("%d", &intput);
	return intput;
}
int menu()
{
	int intput;
	printf("************************欢迎进入三子棋*******************\n");
	printf("************************请输入以下选项*******************\n");
	printf("****************0:退出游戏    1:进入游戏***************\n");
	printf("***********请输入->");
loop:
	intput = Intput(); //模式输入
	if (intput == 0)
	{
		printf("****************退出游戏,再见***************\n");
	}
	else if (intput == 1)
	{
		printf("****************进入游戏*********************\n");
	}
	else
	{
		printf("***********输入错误,请重新输入**************\n");
		printf("***********请输入->");
		goto loop;

	}
	return intput;
}
//或者***************************************************
int menu()
{
	int intput;
	printf("************************欢迎进入三子棋*******************\n");
	printf("************************请输入以下选项*******************\n");
	printf("****************0:退出游戏    1:进入游戏***************\n");
	printf("***********请输入->");
	while (1)
	{
		scanf("%d", &intput);
		if (intput == 0)
		{
			printf("****************退出游戏,再见***************\n");
			break;
		}
		else if (intput == 1)
		{
			printf("****************进入游戏*********************\n");
			break;
		}
		else
		{
			printf("***********输入错误,请重新输入**************\n");
			printf("***********请输入->");
		}
	}
	return intput;
}

3.2游戏功能

3.2.1游戏函数功能

游戏函数需包含显示棋盘函数,下棋函数和下棋结果判断等功能.

3.2.1.1分析

3.2.1.2源码

void game()
{
	//int rows, columns;
	//int not_draw;//平局
	//char sign;
	//存放棋盘信息
	char board[ROWS][COLUMNS] = { 'a','a','a','a','a','a','a','a','a' };//全部为空格
	//初始化棋盘
	Initi_board(board,ROWS,COLUMNS);
	//打印棋盘
	display_board(board, ROWS, COLUMNS);
	printf("\n");
	while (1)
	{
		//玩家走棋
		playermove(board, ROWS, COLUMNS);
		display_board(board, ROWS, COLUMNS);
		printf("\n");
		int ret = winner(board, ROWS, COLUMNS, '#');
		if (ret)
		{
			printf("玩家获胜,结束比赛");
			break;
		}
		else
		{
			if (judge_draw(board, ROWS, COLUMNS))
			{
				printf("双方平局,结束游戏");
				break;
			}
		}
		//电脑走棋
		computermove(board, ROWS, COLUMNS);
		display_board(board, ROWS, COLUMNS);
		printf("\n");
		ret = winner(board, ROWS, COLUMNS, '*');
		if (ret)
		{
			printf("电脑获胜,结束比赛");
			break;
		}
		else
		{
			if (judge_draw(board, ROWS, COLUMNS))
			{
				printf("双方平局,结束游戏");
				break;
		   }
		}
	}
}

3.2.2初始化棋盘

3.2.2.1分析

根据棋盘架构得知棋盘的棋子字符构成3 * 3的数组,创建二维3 * 3数组并赋空字符初值,初始化棋盘。主函数创建二维数组后,需将二维数组传入棋盘初始化函数进行数组初始化,二维数组的行列值可由全局变量进行创建,便于以后进行多子棋设计。

3.2.2.2源码

//利用传址调用,将二维数组地址传入初始化棋盘函数,因利用函数参数1类型为数组指针,所以需利用其它参数将数组的行列值传入函数
void Initi_board(char(*board)[COLUMNS], int rows, int colunms)
{
	int i,j;
	for (i = 0;i < rows; i++)
	{
		for (j = 0; j <colunms; j++)
		{
			//*(*(board+i)+j) = ' ';
			board[i][j] = ' ';
		}
	}
}

3.2.3棋盘显示函数

3.2.3.1分析

根据棋盘架构得知棋盘的棋子字符构成3 * 3的数组。
其中每一行都是由以下模型创建:

                                     |     |   
                                -----|-----|-----

其中每一列都是由以下模型创建:

                                     |      
                                -----|
                                     |        
                                -----|
                                     |                

当在最后一行没有-----|-----|-----模型,当在最后一列时,没有‘|’模型,需进行不显示处理

3.2.3.2源码

void display_board(char(*board)[COLUMNS], int rows, int colunms)
{
	int i,j;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < colunms; j++)
		{
			printf(" %c ",board[i][j]);
			if (j<colunms-1)
			printf("|");
		}
		printf("\n");
		if (i<rows-1)
			for (j = 0; j < colunms; j++)
			{
				printf("---");
				if(j < colunms - 1)
					printf("|");
			}
		printf("\n");
	}
}

3.2.4下棋模块

3.2.4.1 玩家下棋模块

3.2.4.1.1 分析

将棋子放在相应的横纵坐标即可,横纵坐标对应着相应的二维数组,对二维数组成员进行赋值

3.2.4.1.2 源码
void playermove(char(*board)[COLUMNS], int rows, int colunms)
{
	int x, y;
	while (1)
	{
		printf("玩家请在合法坐标处填入#\n");
		printf("请输入x,y坐标:");
		scanf("%d%d", &x,&y);
		//printf("请输入y坐标:");
		//scanf("%d", &y);
		if (x >= 1 && x <= rows && y >= 1 && y <= colunms)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '#';
				break;
			}
			else
			{
				printf("该位置已有棋子请重新输入");
			}
		}
		else
		{
			printf("输入错误请重新输入");
		}
	}
}

3.2.4.2 电脑下棋模块

3.2.4.2.1 分析

电脑模式下用随机数模式,产生随机坐标(当前电脑下棋函数没有按照赢棋规则下棋逻辑)

3.3.4.2.2 源码
void computermove(char(*board)[COLUMNS], int rows, int colunms)
{
	int x, y;
	time_t* timer1 = NULL;
	time_t* timer2 = NULL;
	printf("请电脑执行下棋填入*\n");
	while (1)
	{
		srand((unsigned int)time(timer1));//利用时间戳播种
		Sleep(500);
		srand((unsigned int)time(timer2));
		x = rand() % rows + 1;//产生随机x坐标
		y = rand() % colunms + 1;
		if (x >= 1 && x <= rows && y >= 1 && y <= colunms)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
		}
	}
}

3.2.5结果判断

3.2.5.1 分析

利用循环判断某一坐标下横向三子连珠,纵向三子连珠和,左下,右下三子连珠情况.
若未产生取胜一方,需判断当前二维数组已经填满,若填满则为平局结果.

3.2.5.2 源码

//赢家判断模式
int winner(char(*board)[COLUMNS], int rows, int colunms,char ch)
{
	int x = 0, y = 0, z = 0;
	signed char z1=0,z2=0;
	int ret=0,cycle_num=0;
	//检测行连子情况
	for (x = 0; x < rows; x++)
	{
		for (y = 0; y + 2 < colunms;)
		{
			z = y;
			while (1)
			{
				cycle_num++;
				if (board[x][z] != ch)
				{
					y = y + cycle_num;
					cycle_num = 0;
					z = 0;
					break;
				}
				else if (cycle_num == 3)
				{
					cycle_num = 0;
					ret = 1;
					return ret;
				} 
				z++;
			}
		}
	}
	//检测列连子情况
	for (y = 0; y < colunms; y++)
	{
		for (x = 0; x + 2 < rows;)
		{
			z = x;
			while (1)
			{
				cycle_num++;
				if (board[z][y] != ch)
				{
					x = x + cycle_num;
					cycle_num = 0;
					z = 0;
					break;
				}
				else if (cycle_num == 3)
				{
					cycle_num = 0;
					ret = 1;
					return ret;
				}
				z++;
			}
		}
	}
	//检测左下右下方向连子情况
	for (x = 0; x < rows; x++)
	{
		for (y = 0; y < colunms;y++)
		{
			for (z1 = x, z2 = y, cycle_num = 0; z1 < rows && z2 < colunms;)
			{
				cycle_num++;
				if (board[z1][z2] != ch)
				{
					break;
				}
				else if (cycle_num == 3)
				{
					ret = 1;
					return ret;
				}
				z1++;
				z2++;
			}
			for (z1 = x, z2 = y, cycle_num = 0; z1 < rows && z2 >= 0;)
			{
				cycle_num++;
				if (board[z1][z2] != ch)
				{
					break;
				}
				else if (cycle_num == 3)
				{
					ret = 1;
					return ret;
				}
				z1++;
				z2--;
			}
		}
	}
		return 0;
}
//平局判断模式
int judge_draw(char(*board)[COLUMNS], int rows, int colunms)
{
	int x, y;
	for (x = 0; x < rows; x++)
	{
		for (y = 0; y < colunms; y++)
		{
			if (board[x][y] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}

3.3头文件声明函数

#pragma once
#define ROWS 3
#define COLUMNS 3
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<windows.h>
#ifndef __HEAD_H__
#define __HEAD_H__
//声明函数
void Initi_board(char(*board)[COLUMNS], int rows, int colunms);
void display_board(char(*board)[COLUMNS], int rows, int colunms);
void playermove(char(*board)[COLUMNS], int rows, int colunms);
void computermove(char(*board)[COLUMNS], int rows, int colunms);
int winner(char(*board)[COLUMNS], int rows, int colunms, char ch);
int judge_draw(char(*board)[COLUMNS], int rows, int colunms);
#endif

3.4主函数调用

int main()
{
	while (1)
	{
		if (menu() == 1)
		{
			game();
			break;
		}
		else
		{
			break;
		}
	}
	return 0;
}
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-24 15:52:55  更:2021-08-24 15:53: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年5日历 -2024/5/4 18:42:22-

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