Задание № 2: Играем в жизнь

В ходе разработки я написал программу, которая играет сама с собой в жизнь Конвея (http://ru.wikipedia.org/wiki/Жизнь_(игра)). К моему глубочайшему сожалению, часть файлов затёрлась, а именно ключевая часть программы, где реализованы 3 важные функции. Я не помню, что это за функции, и как они работали.

Ваша задача: восстановить утерянные куски кода.

Пример работы программы

Программа меняет своё состояние по правилам, описанным по ссылке. Дальше я привожу пример того, как выглядело поле после смены трёх эпох:

Эпоха 1         Эпоха 2         Эпоха 3

|          |    |       *  |    |       * *|
|          |    |          |    |          |
|       *  | => |          | => |          |
|         *|    |     *   *|    |         *|
|     * * *|    |       * *|    |     *   *|
--------------------------------------------
|          |    |       *  |    |       * *| <- Дополнительная строка для наглядности, вообще, она сверху ;-)

Исходный код

Обратите внимание, что в некоторых случаях код может отличаться в зависимости от вашей платформы и используемого компилятора. Так, например, вместо time.h необходимо использовать unistd.h, если вы работаете под OS X Maverics с компилятором clang.

main.cpp

#include "game.h"
#include "console.h"
#include <time.h>

// Start program
int main()
{
	// Set rows and cols of the future field
	size_t rows = 20, cols = 40;
	// Get a blank field
	matrix *field = Game::getBlankField(rows, cols);
	// Some magic things for getting random numbers
	srand(time(NULL));
	// Set randomly alive or dead cell
	for (uint i = 0; i < rows; i++) {
		for (uint j = 0; j < cols; j++) {
			field->at(i).at(j) = rand() % 2;
		}
	}

	// 1000 times will be shown
	for (uint i = 0; i < 1000; i++) {
		// Clear console
		Console::clearUnix();
		// Draw the field into console
		Console::drawField(*field);
		// Save the current field...
		matrix *oldField = Game::getBlankField(rows, cols);
		Game::copy(*oldField, *field);
		// ...and update field
		Game::step(*field);
		// Check if life is frozen. If so break the loop
		if (Game::isEqual(*oldField, *field))
			break;
		// Sleep time
		usleep(250 * 1000);
	}
	return 0;
}

console.h

#include <iostream>
#include <cstdlib>
#include <vector>
typedef std::vector<std::vector<bool> > matrix;
typedef unsigned int uint;

/* Utils for working with console */
namespace Console {

	// Clear console in *nix
	void clearUnix() {
		system("clear");
	}

	// Clear console in Windows™
	void clearWin() {
		system("cls");
	}

	// Let's draw the field into console space!
	void drawField(matrix &field) {
		// For each row...
		for (uint i = 0; i < field.size(); i++) {
			// ...draw first '|'...
			std::cout << '|';
			// ...then for each value in row...
			for (uint j = 0; j < field[0].size(); j++) {
				// ...draw '*' if the cell is alive, ' ' otherwise...
				std::cout << (field[i][j] ? '*' : ' ') << ' ';
			}
			// ...close row with '|'
			std::cout << "|\n";
		}
	}
}

game.h

#include <vector>
typedef std::vector<std::vector<bool> > matrix;
typedef unsigned int uint;

/* Functions implement game logic */
namespace Game {

	// Returns blaaaank field where nobody is alive
	matrix *getBlankField(size_t rows, size_t cols) {
		matrix *field = new matrix();
		// Add rows...
		for (uint i = 0; i < rows; i++) {
			field->push_back(std::vector<bool>());
			// ... and values into the row
			for (uint j = 0; j < cols; j++) {
				(field->at(i)).push_back(false);
			}
		}
		return field;
	}

	// Returns rows number
	size_t getRows(const matrix &field) {
		return field.size();
	}

	// Returns cols number
	size_t getCols(const matrix &field) {
		if (getRows(field) != 0) {
			return field[0].size();
		}
		return -1;
	}

// ======================= YOUR CODE HERE =======================

// ==============================================================
}

Makefile

all:
	g++ main.cpp -o ./life

Результат выглядит примерно так

Дополнительный материал

Написание Makefile: http://habrahabr.ru/post/155201

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: