ライフゲーム

提供:kuhalaboWiki
2016年11月15日 (火) 07:10時点におけるKuha (トーク | 投稿記録)による版

移動: 案内, 検索

Cellクラスを作る

Cell.h
#pragma once
#include "ofMain.h"

class Cell {
public:
	int currState; //現在の状態
	int nextState; //次回の状態
	int activeNeighbors; //近傍の生命の数
	ofColor color; //生きているセルの色
	ofColor gcolor; //グリッドの色

	Cell();
	void update();
	void draw(float x, float y, float w, float h);
	void clear();
};
Cell.cpp
#include "Cell.h"

//初期状態の設定
Cell::Cell(){
	currState = 0;
	nextState = 0;	
	color = ofColor::black; // cell color
	gcolor = ofColor(150, 150, 150); // grid color
}
//セルの状態変異測
void Cell::update(){
	if (currState) {
		switch(activeNeighbors){
		case 0:
		case 1:
			nextState = 0;
			break;
		case 2:
		case 3:
			nextState = 1;
			color = ofColor::black; // live cell color
			break;
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
			nextState = 0;
			break;
		}
	}
	else{
		switch(activeNeighbors){
		case 3:
			nextState = 1;
			color = ofColor::green; // born cell color
			break;
		default:
			nextState = false;
			break;
		}
	}
}
//セルを描画
void Cell::draw(float x, float y, float w, float h){
	ofSetColor(gcolor);
	ofNoFill();
	ofRect(x, y, w, h);
	if (currState) {
		ofSetColor(color);
		ofFill();				
		ofRect(x, y, w, h);
		ofNoFill();
	}
}

void Cell::clear() {
	currState = 0;
	nextState = 0;	
	color = ofColor::black;
}

主プログラム

ofApp.h
#pragma once

#include "ofMain.h"
#include "Cell.h"

class ofApp : public ofBaseApp {

public:
	void setup();
	void update();
	void draw();

	void keyPressed(int key);
	void mousePressed(int x, int y, int button);

	void keyReleased(int key);
	void mouseMoved(int x, int y );
	void mouseDragged(int x, int y, int button);
	void mouseReleased(int x, int y, int button);
	void windowResized(int w, int h);
	void dragEvent(ofDragInfo dragInfo);
	void gotMessage(ofMessage msg);

//ライフゲームのセルに関する定義
	Cell **grid;
	int rows, cols;
	float cellWidth, cellHeight;
	bool fullScreen, highlight;
	bool active;

	void init(int width, int height, int cellsize);
	void pause();
	int getNumActiveNeighbors(int colIndex, int rowIndex);
	void RandomCell();
	void ClearCell();
	void goFullScreen();
};
ofApp.cpp
#include "ofApp.h"

const int WIDTH = 800;
const int HEIGHT = 600;
const int CELLSIZE = 6;
const int FULLSCREEN_CELLSIZE = 8;
const int FRAMERATE = 30;

void ofApp::setup() {
	fullScreen = false;
	active = false;

	ofSetFullscreen(false);
	ofSetWindowShape(WIDTH, HEIGHT);
	ofBackground(ofColor::white);
	ofSetBackgroundAuto(true);
	ofSetWindowTitle("Conway's Game of Life");
	ofSetFrameRate(FRAMERATE);

	init(WIDTH, HEIGHT, CELLSIZE);
}

void ofApp::init(int width, int height, int cellSize) {
	cols = width/cellSize;
	rows = height/cellSize;

	grid = new Cell *[cols];
	for (int i=0; i<cols; i++) {
		grid[i] = new Cell[rows];
		for (int j=0; j<rows; j++) {
			Cell *thisCell = &grid[i][j];
		}
	}

	if (width % cellSize != 0 || (height & cellSize) != 0) {
		float ratio = width/height;
		cellWidth = cellSize * ratio;
		cellHeight = cellSize;
	} else {
		cellWidth = cellSize;
		cellHeight = cellSize;
	}
}

void ofApp::update() {
	if(active){
		// get active neighbors for each cell
		for (int i=0; i<cols; i++) {
			for (int j=0; j<rows; j++) {
				grid[i][j].activeNeighbors = getNumActiveNeighbors(i, j);
				grid[i][j].update();
			}
		}
		for (int i=0; i<cols; i++) {
			for (int j=0; j<rows; j++) {
				grid[i][j].currState = grid[i][j].nextState;		
			}
		}
	}
}

void ofApp::draw() {
	for (int i=0; i<cols; i++) {
		for (int j=0; j<rows; j++) {
			grid[i][j].draw(i*cellWidth, j*cellHeight, cellWidth, cellHeight);
		}
	}
}

void ofApp::RandomCell() {
	for (int i=0; i<cols; i++) {
		for (int j=0; j<rows; j++) {
			grid[i][j].clear();
			grid[i][j].currState = ofRandom(2);
		}
	}
}

void ofApp::ClearCell() {
	for (int i=0; i<cols; i++) {
		for (int j=0; j<rows; j++) {
			grid[i][j].clear();
		}
	}
}

int ofApp::getNumActiveNeighbors(int colIndex, int rowIndex) {
	int ret = 0;

	int prevCol = (colIndex - 1 + cols) % cols;
	int nextCol = (colIndex + 1 + cols) % cols;
	int prevRow = (rowIndex - 1 + rows) % rows;
	int nextRow = (rowIndex + 1 + rows) % rows;

	ret += grid[prevCol][prevRow].currState;
	ret += grid[prevCol][rowIndex].currState;
	ret += grid[prevCol][nextRow].currState;

	ret += grid[colIndex][prevRow].currState;
	ret += grid[colIndex][nextRow].currState;

	ret += grid[nextCol][prevRow].currState;
	ret += grid[nextCol][rowIndex].currState;
	ret += grid[nextCol][nextRow].currState;

	return ret;
}

void ofApp::goFullScreen() {
	active = false;
	ofToggleFullscreen();
	fullScreen = !fullScreen;
	if (fullScreen) {
		init(ofGetScreenWidth(), ofGetScreenHeight(), FULLSCREEN_CELLSIZE);
	} else {
		init(WIDTH, HEIGHT, CELLSIZE);
	}
}

void ofApp::pause() {
	active = false;
}

void ofApp::mousePressed(int x, int y, int button) {
	int xcell = x/cellWidth;
	int ycell = y/cellHeight;
	grid[xcell][ycell].currState = !grid[xcell][ycell].currState;
}

void ofApp::keyPressed(int key) {
	switch (key) {
	case ' ':
		active = !active;
		break;
	case 'R':
		RandomCell();
		break;
	case 'c':
		ClearCell();
		break;
	case 'f':
		goFullScreen();
		break;
	case 'g':
//		pause();
		patterns::gliderGun(grid, 2, 2);
		break;
	case 'p':
//		pause();
		patterns::pufferTrain(grid, cols/2 - 10, rows - 30);
		break;
	default:
		break;
	}
}







個人用ツール
名前空間

変種
操作
案内
ツールボックス