Created
November 2, 2017 20:13
-
-
Save eisterman/f991bf5eac517efd5847d3d5261ee0f7 to your computer and use it in GitHub Desktop.
Demotest NewGameOfLifeXL
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 <array> | |
#include "Rule.hpp" | |
namespace GoL { | |
template <class T, std::size_t x, std::size_t y> | |
using table_t = std::array<std::array<T,y>,x>; | |
template<std::size_t max_x, std::size_t max_y, typename T = bool> | |
class GoLEngine { | |
public: | |
explicit GoLEngine(const Rule<T> & rule = CONWAY) : m_rule{rule} {} | |
void setRule(const Rule<T> & rule) { m_rule = rule; } | |
void run(size_t iter = 1); | |
Rule<T> getRule() const { return m_rule; } | |
T get(size_t x, size_t y) const { return m_table.at(x%max_x).at(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, max_x, max_y> & 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 | |
table_t<T, max_x, max_y> m_table; | |
}; | |
void GoLEngine::reset() { | |
for (auto ax : m_table) | |
ax.fill(0); | |
m_gen = 0; | |
} | |
size_t GoLEngine::counting_full(size_t x, size_t y) const { | |
size_t empty = 0; | |
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)) | |
this->get(i,j) ? full++ : empty++; | |
} | |
return full; | |
} | |
template<std::size_t max_x, std::size_t max_y, typename T = bool> | |
void GoLEngine::run(size_t iter) { | |
table_t<T, max_x, max_y> tmp_table = m_table; | |
for(int i = 0; i < iter; i++) { | |
run_once(tmp_table); | |
m_table = tmp_table; | |
m_gen++; | |
} | |
} | |
template<std::size_t max_x, std::size_t max_y, typename T = bool> | |
void GoLEngine::run_once(table_t<T, max_x, max_y> & 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, tmp_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(Rule &&) noexcept = 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; | |
}; | |
Rule::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 = bool> | |
T Rule::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 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