C++实战:实现生命游戏

这篇具有很好参考价值的文章主要介绍了C++实战:实现生命游戏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


一、实战概述

  • 在C++中实现康威生命游戏是一项结合了算法设计、数据结构和用户交互的实战编程任务。首先,定义一个名为Life的类来存储游戏状态,其中包含一个二维数组用于表示细胞网格,并实现初始化(initialize)、打印当前状态(print)以及根据规则更新状态到下一代(update)的方法。neighbor_count函数用于计算每个细胞周围活细胞的数量。

  • 此外,还创建了两个辅助函数:instructions用于输出游戏使用说明;user_says_yes则处理用户的交互输入,判断是否继续执行游戏迭代。

  • 主程序main.cpp中,实例化Life对象,按照流程初始化游戏状态、打印初始布局并持续询问用户是否查看下一个世代。通过调用update方法和print方法循环展示生命游戏的演化过程。

  • 此C++实现不仅展示了如何将数学概念转化为实际代码,也体现了计算机科学中的模拟与自动化思想,通过简单的规则模拟出复杂的生命现象,为学习者提供了一个理解和实践元胞自动机理论的良好平台。

二、实战步骤

  • 创建一个名为"GameOfLife"的项目,并编写头文件life.h和源文件life.cpp。通过这些文件,可以定义游戏的基本结构、初始化游戏、打印当前状态以及更新游戏状态。

(一)编写生命头文件

  • 这个头文件定义了生命游戏类(Life)的基本结构,包括成员函数和私有变量。其中的常量 maxrow 和 maxcol 分别表示网格的最大行数和最大列数。包含的成员函数有 initialize()、print() 和 update()。
    C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏
// 定义游戏区域最大尺寸,这里是行数和列数
const int maxrow = 20, maxcol = 60; // 游戏格子的维度

// 定义生命游戏(Conway's Game of Life)类
class Life {
public:
    // 初始化方法,用于设置初始细胞状态
    void initialize();

    // 打印当前游戏状态的方法,显示整个网格
    void print();

    // 更新方法,根据游戏规则计算下一代细胞的状态
    void update();    

    // 使用二维数组存储游戏网格,并额外增加两行两列以简化边界条件处理
    int grid[maxrow + 2][maxcol + 2]; 

    // 计算给定位置 (row, col) 的邻居细胞存活数量的方法
    int neighbor_count(int row, int col);
};

// 结束某些预处理器条件或标志着某个阶段完成的宏定义
#define DONE

// 包含实现上述接口的具体代码
#include "life.cpp"
  • 该C++代码定义康威生命游戏类Life,含初始化、打印状态、更新规则方法及计算邻居存活数量函数。利用二维数组存储格子状态,其中边界额外扩充以简化处理,并通过包含"life.cpp"实现具体逻辑。

(二)创建生命实现文件

  • 这个源文件实现了生命游戏类中的各个成员函数。initialize()函数用于初始化游戏状态,用户可以指定活细胞的位置;print()函数负责打印当前的游戏状态;update()函数根据邻居计数规则更新游戏状态到下一代。
    C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏
#include <iostream>
#include <istream>
using namespace std;

#ifdef DONE

// 初始化方法:清零整个游戏区域,并让用户输入活细胞坐标,构建初始生命配置
void Life::initialize()
/*Pre: 无预条件
  Post: Life对象包含用户指定的生命配置*/
{
	int row, col;
	for (row = 0; row <= maxrow + 1; row++)
		for (col = 0; col <= maxcol + 1; col++)
			grid[row][col] = 0; // 将所有格子初始化为死状态

	cout << "List the coordinates for living cells." << endl;
	cout << "Terminate the list with the special pair -1 -1" << endl;
	cin >> row >> col;
	while (row != -1 || col != -1)
	{
		if (row >= 1 && row <= maxrow)
			if (col >= 1 && col <= maxcol)
				grid[row][col] = 1; // 根据有效坐标设置活细胞
			else
				cout << "Column " << col << " is out of range." << endl;
		else
			cout << "Row " << row << " is out of range." << endl;
		cin >> row >> col; // 继续读取下一个坐标对
	}
}

// 打印当前生命游戏配置的方法
void Life::print()
/*Pre: Life对象已包含一个生命配置
  Post: 用户可以看到该配置信息*/
{
	int row, col;
	cout << "\nThe current Life configuration is:" << endl;
	for (row = 1; row <= maxrow; row++)
	{
		for (col = 1; col <= maxcol; col++)
			if (grid[row][col] == 1)
				cout << '*'; // 输出活细胞用星号表示
			else
				cout << ' '; // 死细胞用空格表示
		cout << endl;		 // 换行准备输出下一行
	}
	cout << endl; // 输出结束后的额外换行
}

// 更新方法:根据康威生命游戏规则计算并生成下一世代的生命配置
void Life::update()
/*Pre: Life对象已包含一个生命配置
  Post: Life对象现在包含基于原有配置计算出的新一代生命配置*/
{
	int row, col;
	int new_grid[maxrow + 2][maxcol + 2]; // 创建一个新的临时网格用于存放下一代状态

	// 遍历每一个细胞,根据邻居数量决定新状态
	for (row = 1; row <= maxrow; row++)
		for (col = 1; col <= maxcol; col++)
			switch (neighbor_count(row, col))
			{
			case 2:
				new_grid[row][col] = grid[row][col]; // 当前状态保持不变
				break;
			case 3:
				new_grid[row][col] = 1; // 符合“生死准则”的细胞变为活细胞
				break;
			default:
				new_grid[row][col] = 0; // 其他情况,细胞变为死细胞
			}

	// 将临时网格中的新状态复制回原网格中,完成更新过程
	for (row = 1; row <= maxrow; row++)
		for (col = 1; col <= maxcol; col++)
			grid[row][col] = new_grid[row][col];
}

// 生命游戏类 Life 的成员函数,计算给定位置周围活细胞数量的方法
int Life::neighbor_count(int row, int col)
{
	// 检查输入坐标是否在有效范围内(假设网格从1开始计数)
	if (row < 1 || row > maxrow || col < 1 || col > maxcol)
		return 0; // 如果坐标无效,则返回0表示没有活细胞邻居

	int count = 0;							 // 初始化活细胞计数器为0
	for (int i = row - 1; i <= row + 1; ++i) // 遍历以给定行为中心的3行
	{
		for (int j = col - 1; j <= col + 1; ++j) // 遍历以给定列为中心的3列
		{
			// 跳过当前格子自身(不计入邻居)
			if (i == row && j == col)
				continue;

			// 检查所考虑的单元格是否在有效范围内并存活
			if (i >= 1 && i <= maxrow && j >= 1 && j <= maxcol && grid[i][j] == 1)
				++count; // 若存活,则增加计数器
		}
	}

	return count; // 返回活细胞邻居的数量
}

#endif
  • 这段代码为康威生命游戏实现了一个简单的类Life,包含了初始化、打印当前配置以及根据游戏规则更新配置的方法。同时,还有一个辅助函数用来计算每个细胞周围活细胞的数量。注释详细解释了各个函数的前置条件、后置条件以及功能。

(三)编写工具头文件

  • 这个头文件包含了两个辅助函数声明:instructions()用于打印使用生命游戏的说明信息;user_says_yes()用于获取用户的输入,并判断是否为肯定回答。
    C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏
void instructions();
bool user_says_yes();

#define DONE
#include "utility.cpp"

(四)编写工具实现文件

  • 这个源文件实现了utility.h中声明的两个辅助函数。instructions()函数打印关于如何使用生命游戏的详细说明;user_says_yes()函数接收用户输入并返回一个布尔值,表示用户是否给出了肯定回答。
    C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏
#include <iostream>
#include <istream>
using namespace std;

#ifdef DONE

// 函数:打印游戏使用说明
void instructions()
/*Pre: 无预条件.
  Post: 已经打印了使用生命游戏的说明。*/
{
	cout << "Welcome to Conway's game of Life." << endl;
	cout << "This game uses a grid of size " << maxrow << " by " << maxcol << " in which " << endl;
	cout << "each cell can either be occupied by an organism or not." << endl;
	cout << "The occupied cells change from generation to generation" << endl;
	cout << "according to the number of neighboring cells which are alive." << endl;
}

// 函数:获取用户确认(yes/no)的回答,并返回布尔值表示结果
bool user_says_yes()
{
	int c;
	bool initial_response = true; // 标记是否是首次提示

	do
	{ // 循环直到获得有效输入为止
		if (initial_response)
			cout << " (y,n)? " << flush; // 首次提示信息
		else
			cout << "Respond with either y or n: " << flush; // 非首次提示信息
		do
		{ // 忽略空白字符并等待用户输入
			c = cin.get();
		} while (c == '\n' || c == ' ' || c == '\t'); // 检查换行符、空格和制表符
		initial_response = false;
	} while (c != 'y' && c != 'Y' && c != 'n' && c != 'N'); // 循环直至用户输入 y, Y, n 或 N
	return (c == 'y' || c == 'Y');							// 如果用户输入的是 y 或 Y,则返回 true,否则返回 false
}
#endif
  • instructions()函数用于输出康威生命游戏的基本介绍和运行原理,而user_says_yes()函数负责从用户那里获取“是/否”形式的回答,并在接收到有效的 y/n 输入后返回布尔值,以确定用户是否同意或希望继续进行某个操作。这个函数通过循环确保用户只能输入预期的有效字符。

(五)编写主程序文件

  • 编写主程序文件main.cpp,以运行我们的生命游戏并查看结果。在这个过程中,我们可以尝试不同的初始布局,观察它们如何按照生命游戏的规则演变。
    C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏
#include "life.h"
#include "utility.h"

int main() // 主程序:运行康威生命游戏
/*Pre: 用户提供一个初始的生命细胞配置。
  Post: 程序按照生命游戏规则打印出一系列显示生命细胞配置变化的图像。
  使用:Life 类及其方法 initialize(), 2 print(), 和 update()。
		函数 instructio1ns(); user_says_yes()。*/
{
	Life configuration;			// 创建一个 Life 类的对象,用于存储和更新生命游戏状态
	instructions();				// 输出游戏使用说明
	configuration.initialize();		// 初始化生命游戏的起始状态
	cout << "count = " << configuration.neighbor_count(2, 3) << endl; // 示例性调用 neighbor_count 方法,并打印某个位置周围活细胞的数量
	configuration.print();		// 打印当前生命游戏状态
	cout << "Continue viewing new generations? " << endl;
	while (user_says_yes()) // 当用户希望继续查看时,循环执行以下操作
	{
		configuration.update(); // 根据生命游戏规则计算并更新到下一个世代
		configuration.print();	// 打印更新后的新一代生命游戏状态
		cout << "Continue viewing new generations? " << endl;
	}

	return 0; // 主程序正常结束,返回值为0
}
  • 这段代码定义了主函数main(),它创建了一个Life对象来处理生命游戏的所有状态变化。首先输出游戏说明,然后初始化生命游戏状态,接着通过neighbor_count()方法演示如何计算某个格子周围的活细胞数量,并打印当前状态。

  • 接下来,程序进入一个循环,询问用户是否继续观察新的生命游戏世代。如果用户选择继续(由user_says_yes()函数获取),则通过调用configuration.update()更新到下一世代,并再次打印新的状态,循环反复直到用户不再希望继续观看。最后,主函数返回0,表示程序成功执行完毕。

(六)运行程序,查看结果

  • 运行生命游戏程序后,我们可以看到一个由星号(*)表示的生命单元组成的初始布局。随着每个世代的更新,生命的数量和分布会发生变化,根据生命游戏的规则(B3/S23),只有在有2个或3个邻居时生命才能存活。通过观察这些动态变化,我们可以感受到生命游戏中的简单规则如何产生复杂且意想不到的行为模式。
  • 尝试初始布局
    C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏
  • 运行程序,输入
2 2
2 3
2 4
2 5
-1 -1

C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏

  • 输入y,继续游戏
    C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏

  • 输入y,继续游戏
    C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏

  • 输入n,结束游戏
    C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏文章来源地址https://www.toymoban.com/news/detail-810912.html

(七)尝试生命游戏其它初始布局

  • 在生命游戏中,尝试不同的初始布局可以产生千变万化的结果。例如,你可以从简单的点状布局开始,观察它们如何相互作用和演变;也可以设计复杂的图案,如滑翔机、飞船等,看它们如何在网格上移动和繁殖。通过探索各种初始布局,我们可以更深入地理解生命游戏的规则和复杂性。
    C++实战:实现生命游戏,C++学习园地,c++,康威生命游戏

三、实战总结

  • 在C++中实现康威生命游戏的实战项目通过设计Life类及其成员函数,将数学理论转化为实际代码。该项目涵盖了从初始化、打印到更新游戏状态的关键环节,并通过计算邻居数量的方法遵循生命游戏规则进行迭代。此外,项目还包括了辅助工具函数以增强用户体验,如输出游戏说明和处理用户交互。主程序实现了整个生命游戏的流程控制,允许用户观察不同初始布局下的演化过程。此实现不仅展示了如何构造元胞自动机模型,也通过实践帮助学习者深入理解简单规则如何产生复杂行为这一深刻概念。

到了这里,关于C++实战:实现生命游戏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 面试经典150题——生命游戏

    2.1 思路一——暴力求解 之所以先暴力求解,是因为我开始也没什么更好的思路,所以就先写一种解决方案,没准写着写着就来新的灵感了。暴力求解思路还是很简单的,就是尝试遍历面板的每个格子,判断其周围八个位置的状态(对于边角需要特殊处理),根据边角种存在

    2024年02月21日
    浏览(41)
  • 【面试经典150 | 矩阵】生命游戏

    本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删: Tag:介绍本题牵涉到的知识点、数据结构; 题目来源:

    2024年02月07日
    浏览(39)
  • leetcode 289. 生命游戏

    题目链接:leetcode 289 根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态: 1 即为 活细胞 (live),或 0 即为 死细胞

    2024年02月09日
    浏览(27)
  • 力扣289. 生命游戏

    思路: 可以复制一个表格,然后根据规则两层循环模拟出结果,但是空间复杂度太高; 可以复用原有数组,对其进行染色标记; 最终状态是活的标记值 1, 还原标记值时可以使用规则 val 0 ; 之前是活的现在是死的,标记成 -1, 统计活细胞时可以使用规则 abs(val) = 1 ; 根据

    2024年02月02日
    浏览(20)
  • (16-3)多智能体强化学习实战:Predator-Prey游戏(3)

    创建一个名为PredatorPreyEnv2的自定义强化学习环境类,用于模拟实现“捕食者-猎物”(Predator-Prey)的环境。这是一个多智能体环境,其中捕食者追逐猎物,而猎物尽量躲避被捕食。与传统的Predator-Prey环境不同,这个版本中的猎物不会永久消失,并且捕食者只能在一次行动中捕

    2024年04月28日
    浏览(34)
  • 强化学习Agent系列(一)——PyGame游戏编程,Python 贪吃蛇制作实战教学

    大家好,未来的开发者们请上座 随着人工智能的发展,强化学习基本会再次来到人们眼前,遂想制作一下相关的教程。强化学习第一步基本离不开虚拟环境的搭建,下面用大家耳熟能详的贪吃蛇游戏为基础,制作一个Agent,完成对这个游戏的绝杀。 万里长城第一步:用pytho

    2024年01月21日
    浏览(65)
  • 【Unity实战】实现一款简单的FPS游戏

    实现一款FPS游戏需要以下步骤: 1.创建场景:在Unity中创建3D场景,设定地形、灯光、天气等环境,新增角色、武器等道具。 2.角色控制:创建角色,并添加Unity内置的角色控制器或自定义控制器脚本,处理角色的移动、射击、跳跃、动作等。 3.武器系统:创建武器模型,添加

    2024年02月06日
    浏览(45)
  • 用C++实现简单的小游戏

    采用面向对象的编程思想 在头文件中引入acllic图形库,实现c++控制图片以及生成可视化窗口 所需工具: acllib图形库下载地址:acl图形库下载地址  win32位项目的创建: 通过visual studio创建win32项目 三张图片:tom.bmp,jerry.bmp,heart.bmp 1.猫和老鼠游戏,其中包含可以加分的红心

    2024年02月05日
    浏览(32)
  • C++ 实现游戏(例如MC)键位显示

    效果: 是不是有那味儿了? 显示AWSD,空格,Shift和左右键的按键情况以及左右键的CPS。 彩虹色轮廓,黑白填充。 具有任务栏图标,可以随时关闭 字体是Minecraft AE Pixel,如果你没有装(大概率),你可以换用其他好看的字体(在代码中修改即可) 由于是从一个更大的项目中

    2024年01月16日
    浏览(40)
  • 用c++实现五子棋小游戏

    五子棋是一款经典小游戏,今天我们就用c++实现简单的五子棋小游戏 目录 用到的算法: 思路分析 定义变量  开始写代码   完整代码  结果图: 合法移动的判断: isValidMove 函数通过检查指定位置是否在棋盘范围内,并且该位置是否为空位来确定是否为合法的移动。 获胜条

    2024年02月07日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包