Задание № 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