Created
November 4, 2017 14:46
-
-
Save eisterman/500e6d914ece0e7f7095f59ec156bc27 to your computer and use it in GitHub Desktop.
NewGameOfLifeXL - Versione C++ - BUG Row0/Col0
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
#include "Rule.hpp" | |
#include "GoLEngine.hpp" | |
#include <random> | |
#include <iostream> | |
#include <unistd.h> | |
using namespace std; | |
using namespace GoL; | |
void print(GoLEngine<bool> & Game) | |
{ | |
system("clear"); | |
cout << "Simulazione Random - Gen: " << Game.getGen() << endl; | |
for(auto y = 0; y < 20; y++) | |
{ | |
for(auto x = 0; x < 60; x++) | |
{ | |
if(Game.get(x,y)) cout << "#"; | |
else cout << "."; | |
} | |
cout << endl; | |
} | |
} | |
int main() | |
{ | |
GoLEngine<bool> Game(60,20,CONWAY); | |
int seme = 5; | |
std::mt19937 gen(seme); | |
std::uniform_int_distribution<> dis(0, 1); | |
auto RANDNUM = [dis, gen]() mutable { return dis(gen); }; | |
for(size_t i = 0; i < 20; i++) | |
for(size_t j = 0; j < 60; j++) | |
{ | |
Game.set(j, i, RANDNUM() > 0.5); | |
} | |
float delay=0.2; | |
while(1) | |
{ | |
usleep(delay*1000000); | |
print(Game); | |
Game.run(); | |
} | |
return 0; | |
} |
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
// | |
// Created by fpasqua on 02/11/17. | |
// | |
#ifndef NEWGAMEOFLIFEXL_GAMEOFLIFE_H | |
#define NEWGAMEOFLIFEXL_GAMEOFLIFE_H | |
#include <cstddef> | |
#include <vector> | |
#include <algorithm> | |
#include "Rule.hpp" | |
namespace GoL { | |
template <typename T> | |
using table_t = std::vector<std::vector<T>>; | |
template<typename T = bool> | |
class GoLEngine { | |
public: | |
GoLEngine() : m_rule(CONWAY), max_x(1), max_y(1) { } | |
GoLEngine(std::size_t max_x, std::size_t max_y, const Rule<T> & rule = CONWAY) : | |
m_rule{rule} , max_x{max_x}, max_y{max_y} , m_table(max_x, std::vector<T>(max_y, T() )) { } | |
void setRule(const Rule<T> & rule) { m_rule = rule; } | |
virtual void run(size_t iter); | |
void run() { run(1); } | |
Rule<T> getRule() const { return m_rule; } | |
T get(int x, int y) const { return m_table.at((x+max_x)%max_x).at((y+max_y)%max_y); } | |
void set(size_t x, size_t y, T state) { m_table.at(x).at(y) = state; } | |
void reset(); | |
unsigned long long int getGen() const { return m_gen; } | |
size_t getXMax() const { return max_x; } | |
size_t getYMax() const { return max_y; } | |
protected: | |
// Useful Function | |
virtual void run_once(table_t<T> & tmp_table); | |
size_t counting_full(size_t x, size_t y) const; | |
inline bool is_confine(size_t x, size_t y) const { | |
return ( x == 0 || x == max_x -1 || y == 0 || y == max_y -1); | |
} | |
// Attributes | |
Rule<T> m_rule; | |
unsigned long long int m_gen = 0; // Generazione | |
size_t max_x, max_y; | |
table_t<T> m_table; | |
}; | |
template<typename T> | |
void GoLEngine<T>::reset() { | |
for (auto & ax : m_table) | |
std::fill(ax.begin(), ax.end(), T() ); | |
m_gen = 0; | |
} | |
template<typename T> | |
size_t GoLEngine<T>::counting_full(size_t x, size_t y) const { | |
size_t full = 0; | |
for(auto i = x-1; i <= x+1; i++) | |
for(auto j = y-1; j <= y+1; j++) { | |
if(i == x && j == y) continue; | |
if(this->get(i,j)) full++; | |
} | |
return full; | |
} | |
template<typename T> | |
void GoLEngine<T>::run(size_t iter) { | |
table_t<T> tmp_table = m_table; | |
for(size_t i = 0; i < iter; i++) { | |
run_once(tmp_table); | |
m_table = tmp_table; | |
m_gen++; | |
} | |
} | |
template<typename T> | |
void GoLEngine<T>::run_once(table_t<T> & tmp_table) { | |
for(size_t i = 0; i < max_x; i++) | |
for(size_t j = 0; j < max_y; j++) { | |
size_t full = counting_full(i, j); | |
tmp_table.at(i).at(j) = m_rule.apply(full, m_table.at(i).at(j)); | |
} | |
} | |
} | |
#endif //NEWGAMEOFLIFEXL_GAMEOFLIFE_H |
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
// | |
// Created by fpasqua on 02/11/17. | |
// | |
#ifndef NEWGAMEOFLIFEXL_RULE_H | |
#define NEWGAMEOFLIFEXL_RULE_H | |
#include <cstddef> | |
#include <vector> | |
#include <algorithm> | |
#include <stdexcept> | |
namespace GoL { | |
template <typename T = bool> | |
class Rule { | |
public: | |
Rule() = default; | |
Rule(const std::vector<size_t> & B, const std::vector<size_t> & S); | |
Rule(const Rule & old) = default; | |
~Rule() = default; | |
T apply(size_t full, T state) const; | |
std::vector<size_t> getBirth() const { return m_Birth; } | |
std::vector<size_t> getStay() const { return m_Stay; } | |
protected: | |
std::vector<size_t> m_Birth; | |
std::vector<size_t> m_Stay; | |
}; | |
template <typename T> | |
Rule<T>::Rule(const std::vector<size_t> & B, const std::vector<size_t> & S) { | |
if (std::any_of(B.begin(), B.end(), [](size_t n){ return (n < 0 || n > 8); })) | |
throw std::range_error("Birth Rule must be between 0 and 8."); | |
if (std::any_of(S.begin(), S.end(), [](size_t n){ return (n < 0 || n > 8); })) | |
throw std::range_error("Birth Rule must be between 0 and 8."); | |
// TODO: Check repeating | |
m_Birth = B; | |
m_Stay = S; | |
} | |
template <typename T> | |
T Rule<T>::apply(size_t full, T state) const { | |
if(state) { | |
return std::find(m_Stay.begin(), m_Stay.end(), full) != m_Stay.end(); | |
} else { | |
return std::find(m_Birth.begin(), m_Birth.end(), full) != m_Birth.end(); | |
} | |
} | |
const Rule<bool> CONWAY({3}, {3,2}); | |
} | |
#endif //NEWGAMEOFLIFEXL_RULE_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment