Skip to content

Instantly share code, notes, and snippets.

@ysakasin
Last active August 29, 2015 14:03
Show Gist options
  • Save ysakasin/d9c4dec29aa17ab957a1 to your computer and use it in GitHub Desktop.
Save ysakasin/d9c4dec29aa17ab957a1 to your computer and use it in GitHub Desktop.
C++の練習用に書いたライフゲームです。トーラス上の盤面でエミュレートしています。C++11仕様のコンパイルをしなければならないこと、ひたすら端末に出力し続けることに注意が必要です。
/* 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