康威生命游戏

简介看这里
为保证通用性,逻辑层使用C语言的标准库去做

#ifndef __H__CELLULAR_AUTOMATA__
#define __H__CELLULAR_AUTOMATA__
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
	int startGame(int grid, unsigned int seed, int initCount, int initSize, double initDensity);
	void stopGame();
	void evolution();
	int getValue(int i, int j);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __H__CELLULAR_AUTOMATA__

#include "CellularAutomata.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int *g_world;
static int *g_mirror;
static int g_grid;

#define setValue(i, j, value)	(*(g_world + g_grid * (i) + (j)) = (value))

int getValue(int i, int j)
{
	return *(g_world + g_grid * i + j);
}

static int surroundingLivingCells(int i, int j)
{
	int ii, jj;
	int sum = 0;

	ii = i - 1; 
	jj = j - 1;
	if (ii > 0 && jj > 0)
		if (getValue(ii, jj) == 1)
			++sum;

	ii = i - 1;
	jj = j;
	if (ii > 0 && jj > 0)
		if (getValue(ii, jj) == 1)
			++sum;

	ii = i - 1;
	jj = j + 1;
	if (ii > 0 && jj > 0)
		if (getValue(ii, jj) == 1)
			++sum;

	ii = i;
	jj = j - 1;
	if (ii > 0 && jj > 0)
		if (getValue(ii, jj) == 1)
			++sum;

	ii = i;
	jj = j + 1;
	if (ii > 0 && jj > 0)
		if (getValue(ii, jj) == 1)
			++sum;

	ii = i + 1;
	jj = j - 1;
	if (ii > 0 && jj > 0)
		if (getValue(ii, jj) == 1)
			++sum;

	ii = i + 1;
	jj = j;
	if (ii > 0 && jj > 0)
		if (getValue(ii, jj) == 1)
			++sum;

	ii = i + 1;
	jj = j + 1;
	if (ii > 0 && jj > 0)
		if (getValue(ii, jj) == 1)
			++sum;

	return sum;
}

int startGame(int grid, unsigned int seed, int initCount, int initSize, double initDensity)
{
	int i, j, k, value;
	g_grid = grid;
	g_world = (int *)malloc(grid * grid * sizeof(int));
	if (!g_world)
		return -1;
	g_mirror = (int *)malloc(grid * grid * sizeof(int));
	if (!g_mirror)
	{
		delete g_world;
		g_world = NULL;
		return -1;
	}

	memset(g_world, 0, grid * grid * sizeof(int));
	memset(g_mirror, 0, grid * grid * sizeof(int));

	srand(seed);

	for (k = 0; k < initCount; ++k)
	{
		int startx = rand() % grid - initSize;
		int endx = startx + initSize;
		int starty = rand() % grid - initSize;
		int endy = starty + initSize;

		for (i = startx; i < endx; ++i)
		{
			for (j = starty; j < endy; ++j)
			{
				int density = 100 / (initDensity * 100);
				value = rand() % density;
				if (value == 0)
					setValue(i, j, 1);
			}
		}
	}

	memcpy(g_mirror, g_world, grid * grid * sizeof(int));

	return 0;
}

void stopGame()
{
	g_grid = 0;
	free(g_world);
	free(g_mirror);
	g_world = NULL;
	g_mirror = NULL;
}

void evolution()
{
	int i, j;
	for (i = 0; i < g_grid; ++i)
	{
		for (j = 0; j < g_grid; ++j)
		{
			int count = surroundingLivingCells(i, j);
			if (getValue(i, j) > 0)
			{
				if (count == 2 || count == 3)
					continue;

				if (count < 2 || count > 3)
				{
					*(g_mirror + g_grid * i + j) = 0;
				}
			}
			else
			{
				if (count == 3)
				{
					*(g_mirror + g_grid * i + j) = 1;
				}
			}
		}
	}

	memcpy(g_world, g_mirror, g_grid * g_grid * sizeof(int));
}

接下来是界面,这部分就随意了,把逻辑层的数据用界面表现出来就行,这里随便用qt来画一画

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_GameOfLife.h"

class QColorDialog;
class GameOfLife : public QMainWindow
{
	Q_OBJECT

public:
	GameOfLife(QWidget *parent = Q_NULLPTR);

protected:
	void paintEvent(QPaintEvent *event) override;


private:
	Ui::GameOfLifeClass ui;
	int m_grid;
	bool m_isStart;
	QTimer *m_timer;
	QColor m_colorGrid;
	QColor m_colorLife;
	QColor m_colorDeath;

private slots:
	void onTimerTimeout();
	void onPushButtonClicked(bool checked = false);
	void onPushButtonGridClicked(bool checked = false);
	void onPushButtonLifeClicked(bool checked = false);
	void onPushButtonDeathClicked(bool checked = false);
};


#include "GameOfLife.h"
#include "CellularAutomata.h"
#include <QTimer>
#include <QDateTime>
#include <QPainter>
#include <QResizeEvent>
#include <QColorDialog>

GameOfLife::GameOfLife(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	m_grid = 0;
	m_isStart = false;
	m_colorGrid = Qt::red;
	m_colorLife = Qt::black;
	m_colorDeath = Qt::white;
	m_timer = new QTimer(this);
	ui.pushButton->setText("start");
	connect(m_timer, &QTimer::timeout, this, &GameOfLife::onTimerTimeout);
	connect(ui.pushButton, &QPushButton::clicked, this, &GameOfLife::onPushButtonClicked);
	connect(ui.pushButton_grid, &QPushButton::clicked, this, &GameOfLife::onPushButtonGridClicked);
	connect(ui.pushButton_life, &QPushButton::clicked, this, &GameOfLife::onPushButtonLifeClicked);
	connect(ui.pushButton_death, &QPushButton::clicked, this, &GameOfLife::onPushButtonDeathClicked);
}

void GameOfLife::onTimerTimeout()
{
	if (!m_isStart)
		return;
	evolution();
	update();
}

void GameOfLife::onPushButtonClicked(bool checked)
{
	if (m_isStart)
	{
		m_isStart = false;
		m_timer->stop();
		m_grid = 0;
		stopGame();
		ui.pushButton->setText("start");
	}
	else
	{
		m_grid = ui.spinBox->value();
		if (startGame(m_grid, QDateTime::currentDateTime().toTime_t(), 
			ui.spinBox_2->value(), ui.spinBox_3->value(), 
			ui.doubleSpinBox_2->value()) < 0)
			return;
		m_isStart = true;
		m_timer->setInterval(ui.doubleSpinBox->value() * 1000);
		m_timer->start();
		ui.pushButton->setText("stop");
	}
}

void GameOfLife::onPushButtonGridClicked(bool checked)
{
	QColor c = QColorDialog::getColor(m_colorGrid, this);
	if (c.isValid())
		m_colorGrid = c;
}

void GameOfLife::onPushButtonLifeClicked(bool checked)
{
	QColor c = QColorDialog::getColor(m_colorLife, this);
	if (c.isValid())
		m_colorLife = c;
}

void GameOfLife::onPushButtonDeathClicked(bool checked)
{
	QColor c = QColorDialog::getColor(m_colorDeath, this);
	if (c.isValid())
		m_colorDeath = c;
}

void GameOfLife::paintEvent(QPaintEvent *event)
{
	int i, j, value;
	QPainter painter(this);
	QVector<int>::iterator it;
	int w = width();
	int h = height();
	painter.setPen(m_colorGrid);

	if (m_grid > 0)
	{
		w = w / m_grid;
		h = h / m_grid;
		for (i = 0; i < m_grid; ++i)
		{
			for (j = 0; j < m_grid; ++j)
			{
				value = getValue(i, j);
				if (value)
					painter.setBrush(m_colorLife);
				else
					painter.setBrush(m_colorDeath);

				painter.drawRect(i * w, j * h, w, h);
			}
		}
	}
	QMainWindow::paintEvent(event);
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python康威生命游戏是一个基于细胞自动机的游戏,它由约翰·康威发明。在这个游戏中,有一个二维的网格世界,每个网格上的细胞可以存在或死亡,它们的生死状态取决于周围八个格子中存活细胞的数量。 要实现这个游戏,你可以使用Python语言。首先,你需要定义一个二维数组来表示网格世界,其中每个元素表示一个细胞的状态(存活或死亡)。然后,你可以编写一个函数来计算每个细胞的下一次状态,根据周围细胞的存活情况进行判断。最后,你可以使用循环来不断更新网格中每个细胞的状态,从而模拟游戏的演化过程。 在你的代码中,你可以使用引用提供的主函数作为入口点,并将网格的大小和迭代次数作为参数传递给主函数。接下来,你可以在主函数中调用你编写的函数来更新网格的状态,并在每次迭代后打印出网格的当前状态,以便观察游戏的演化过程。 需要注意的是,康威生命游戏是一个零玩家游戏,也就是说它的演化是由初始状态决定的,不需要进一步的输入。因此,在运行程序之前,你需要定义一个初始的网格状态,可以手动设置一些细胞的存活状态,或者使用一些随机生成的初始状态。 通过以上步骤,你就可以编写一个简单的Python程序来实现康威生命游戏了。这个程序将模拟细胞的生命周期,并展示出不同存活规则下细胞群体的演化情况。你可以根据自己的需求来调整网格的大小和迭代次数,以及定义不同的初始状态,来观察不同情况下游戏的演化效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木千

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值