Skip to content

Instantly share code, notes, and snippets.

@eisterman
Created November 4, 2017 14:46
Show Gist options
  • Save eisterman/500e6d914ece0e7f7095f59ec156bc27 to your computer and use it in GitHub Desktop.
Save eisterman/500e6d914ece0e7f7095f59ec156bc27 to your computer and use it in GitHub Desktop.
NewGameOfLifeXL - Versione C++ - BUG Row0/Col0
#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;
}
//
// 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
//
// 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