Last active
August 29, 2015 14:03
-
-
Save ysakasin/d9c4dec29aa17ab957a1 to your computer and use it in GitHub Desktop.
C++の練習用に書いたライフゲームです。トーラス上の盤面でエミュレートしています。C++11仕様のコンパイルをしなければならないこと、ひたすら端末に出力し続けることに注意が必要です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* License | |
The MIT License (MIT) | |
Copyright (c) 2014 SAKATA Sinji | |
*/ | |
/* Attention | |
This program should be compiled by C++11. | |
Example:$ g++ -std=c++11 lifegame.cpp | |
*/ | |
#include <iostream> | |
#include <random> | |
#include <unistd.h> | |
using namespace std; | |
class Cell{ | |
private: | |
int x, y; | |
bool state, beforeState; | |
static Cell* headCell; | |
public: | |
static int CELL_WIDTH; | |
static int CELL_HEIGHT; | |
static int INITIAL_ALIVE; | |
Cell(); | |
void updateState(); | |
void setPosition(int y, int x){ this->y = y; this->x = x;} | |
bool getState(){ return state; } | |
void setState(bool state){ this->state = state; } | |
bool getBeforeState(){ return beforeState; } | |
bool setBeforeState(bool state){ beforeState = state; } | |
static Cell* getCell(int y, int x); | |
static void setHeadCell(Cell* head){ headCell = head; } | |
}; | |
Cell* Cell::headCell; | |
int Cell::CELL_WIDTH; | |
int Cell::CELL_HEIGHT; | |
int Cell::INITIAL_ALIVE; | |
Cell::Cell() | |
{ | |
state = false; | |
beforeState = false; | |
} | |
void Cell::updateState() | |
{ | |
int aliveCell = 0; | |
for(int i = -1; i <= 1; i++){ | |
for(int j = -1; j <= 1; j++){ | |
if(i == 0 && j == 0){ | |
continue; | |
} | |
if(getCell(y+i, x+j)->getBeforeState()){ | |
aliveCell++; | |
} | |
} | |
} | |
if(aliveCell == 3){ | |
setState(true); | |
} else if(aliveCell == 2 && getBeforeState()){ | |
setState(true); | |
} else{ | |
setState(false); | |
} | |
} | |
Cell* Cell::getCell(int y, int x) | |
{ | |
int diff_height = Cell::CELL_WIDTH * ((Cell::CELL_HEIGHT + y) % Cell::CELL_HEIGHT); | |
int diff_width = (Cell::CELL_WIDTH + x) % Cell::CELL_WIDTH; | |
return headCell + diff_height + diff_width; | |
} | |
int main() | |
{ | |
cout << "CELL_WIDTH:"; | |
cin >> Cell::CELL_WIDTH; | |
cout << "CELL_HEIGHT:"; | |
cin >> Cell::CELL_HEIGHT; | |
cout << "INITIAL_ALIVE:"; | |
cin >> Cell::INITIAL_ALIVE; | |
Cell field[Cell::CELL_HEIGHT][Cell::CELL_WIDTH]; | |
Cell::setHeadCell( (Cell*)field ); | |
for(int y = 0; y < Cell::CELL_HEIGHT; y++){ | |
for(int x = 0; x < Cell::CELL_WIDTH; x++){ | |
Cell::getCell(y, x)->setPosition(y, x); | |
} | |
} | |
// set initial alive sell | |
std::random_device rd; | |
mt19937 rndm(rd()); | |
const int MAX_INITIAL_ALIVE = (Cell::CELL_HEIGHT / 3) * (Cell::CELL_WIDTH / 3); | |
for(int i = 0; i < Cell::INITIAL_ALIVE && i < MAX_INITIAL_ALIVE;){ | |
int y = rndm() % (Cell::CELL_HEIGHT / 3) + (Cell::CELL_HEIGHT / 3); | |
int x = rndm() % (Cell::CELL_WIDTH / 3) + (Cell::CELL_WIDTH / 3); | |
Cell* cell = Cell::getCell(y, x); | |
if( !(cell->getState()) ){ | |
cell->setState(true); | |
i++; | |
} | |
} | |
while(true){ | |
// print field | |
for(int y = 0; y < Cell::CELL_HEIGHT; y++){ | |
for(int x = 0; x < Cell::CELL_WIDTH; x++){ | |
Cell* cell = Cell::getCell(y, x); | |
if(cell->getState()){ | |
cout << "0"; | |
} else{ | |
cout << "."; | |
} | |
cell->setBeforeState( cell->getState() ); | |
} | |
cout << endl; | |
} | |
cout << "-----" << endl; | |
// update field | |
for(int y = 0; y < Cell::CELL_HEIGHT; y++){ | |
for(int x = 0; x < Cell::CELL_WIDTH; x++){ | |
Cell::getCell(y, x)->updateState(); | |
} | |
} | |
usleep(600000); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment