Advertisement
Guest User

GameOfLife

a guest
Apr 21st, 2019
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.85 KB | None | 0 0
  1. #include <Adafruit_NeoPixel.h>
  2.  
  3. // ===============================
  4. // ========== Constants ==========
  5. // ===============================
  6.  
  7. #define IO_PIN      10
  8. #define NUM_PIXEL   100
  9. #define BRIGHTNESS  255
  10. #define TIME_DELAY  1500
  11.  
  12. #define MATRIX_SIZE   10
  13. #define MATRIX_EMPTY  0
  14. #define MATRIX_SET    1
  15.  
  16. #define RED   0x00FF0000
  17. #define GREEN 0x0000FF00
  18. #define BLUE  0x000000FF
  19.  
  20. // =============================
  21. // ========== CLASSES ==========
  22. // =============================
  23.  
  24. class Map {
  25.   private:
  26.     bool matrix[MATRIX_SIZE][MATRIX_SIZE];
  27.    
  28.   public:
  29.     Map(){
  30.       doEmpty();
  31.     }
  32.    
  33.     ~Map(){
  34.      
  35.     }
  36.  
  37.     bool get(uint8_t x, uint8_t y){
  38.       return matrix[y][x];
  39.     }
  40.  
  41.     void set(uint8_t x, uint8_t y, bool value){
  42.       matrix[y][x] = value;
  43.     }
  44.  
  45.     bool isEmpty(){
  46.       for (uint8_t i = 0; i < MATRIX_SIZE; i++){
  47.         for (uint8_t j = 0; j < MATRIX_SIZE; j++){
  48.           if (matrix[i][j] == true){
  49.             return false;
  50.           }
  51.         }
  52.       }
  53.      
  54.       return true;
  55.     }
  56.  
  57.     void doEmpty(){
  58.       for (uint8_t i = 0; i < MATRIX_SIZE; i++){
  59.         for (uint8_t j = 0; j < MATRIX_SIZE; j++){
  60.           matrix[i][j] = false;
  61.         }
  62.       }
  63.     }
  64.  
  65.   bool coordsInRange(int8_t x, int8_t y){
  66.       if ((x < 0) || (y < 0)){
  67.         return false;
  68.       }
  69.  
  70.       if ((x >= MATRIX_SIZE) || (y >= MATRIX_SIZE)){
  71.         return false;
  72.       }
  73.  
  74.       return true;
  75.     }
  76.  
  77.     uint8_t countNeighbors(uint8_t x, uint8_t y){
  78.       uint8_t count = 0;
  79.      
  80.       for (int8_t i = x - 1; i < x + 2; i++){
  81.         for (int8_t j = y - 1; j < y + 2; j++){
  82.           if (coordsInRange(i, j) && (get(i, j) == true)){
  83.             count++;
  84.           } else {
  85.           }
  86.         }
  87.       }
  88.  
  89.       if (get(x, y) == true){
  90.         count--;
  91.       }
  92.  
  93.       return count;
  94.     }
  95. };
  96.  
  97. // ==========
  98.  
  99. class GameOfLife {
  100.   private:
  101.     Map map_a;
  102.     Map map_b;
  103.     Map history_1;
  104.     Map history_2;
  105.     Map *currentMap;
  106.     Map *otherMap;
  107.  
  108.   public:
  109.     GameOfLife(){
  110.       map_a = Map();
  111.       map_b = Map();
  112.       history_1 = Map();
  113.       history_2 = Map();
  114.      
  115.       currentMap = &map_a;
  116.       otherMap = &map_b;
  117.     }
  118.  
  119.     ~GameOfLife(){
  120.      
  121.     }
  122.  
  123.     void switchMaps(){
  124.       if (currentMap == &map_a){
  125.         currentMap = &map_b;
  126.         otherMap = &map_a;
  127.       } else {
  128.         currentMap = &map_a;
  129.         otherMap = &map_b;
  130.       }
  131.     }
  132.  
  133.     void setHistory(Map &map){
  134.       copy(history_1, history_2);
  135.       copy(map, history_1);
  136.     }
  137.  
  138.     void copy(Map &map_1, Map &map_2){
  139.       for (uint8_t i = 0; i < MATRIX_SIZE; i++){
  140.         for (uint8_t j = 0; j < MATRIX_SIZE; j++){
  141.           map_2.set(i, j, map_1.get(i, j));
  142.         }
  143.       }
  144.     }
  145.  
  146.     void rnd(){
  147.       for (uint8_t i = 0; i < MATRIX_SIZE; i++){
  148.         for (uint8_t j = 0; j < MATRIX_SIZE; j++){
  149.           if (random(4) == 0){
  150.             currentMap->set(i, j, true);
  151.           } else {
  152.             currentMap->set(i, j, false);
  153.           }
  154.         }
  155.       }
  156.     }
  157.  
  158.     bool isEmpty(){
  159.       return currentMap->isEmpty();
  160.     }
  161.  
  162.     void doEmpty(){
  163.       currentMap->doEmpty();
  164.     }
  165.  
  166.     bool get(uint8_t x, uint8_t y){
  167.       return currentMap->get(x, y);
  168.     }
  169.  
  170.     void iterate(){
  171.       setHistory(*otherMap);
  172.       otherMap->doEmpty();
  173.  
  174.       uint8_t count;
  175.  
  176.       for (uint8_t i = 0; i < MATRIX_SIZE; i++){
  177.         for (uint8_t j = 0; j < MATRIX_SIZE; j++){
  178.           count = currentMap->countNeighbors(i, j);
  179.  
  180.           if (count == 3){
  181.             otherMap->set(i, j, true);
  182.           }
  183.  
  184.           if ((count == 2) && (currentMap->get(i, j) == true)){
  185.             otherMap->set(i, j, true);
  186.           }
  187.         }
  188.       }
  189.  
  190.       switchMaps();
  191.     }
  192.  
  193.     bool bothEqual(Map &map_1, Map &map_2){
  194.       for (uint8_t i = 0; i < MATRIX_SIZE; i++){
  195.         for (uint8_t j = 0; j < MATRIX_SIZE; j++){
  196.           if (map_1.get(i, j) != map_2.get(i, j)){
  197.             return false;
  198.           }
  199.         }
  200.       }
  201.  
  202.       return true;
  203.     }
  204.  
  205.     bool isLoop(){
  206.       bool isLoop_bool = false;
  207.      
  208.       isLoop_bool |= bothEqual(*currentMap, *otherMap);
  209.       isLoop_bool |= bothEqual(*currentMap, history_1);
  210.       isLoop_bool |= bothEqual(*currentMap, history_2);
  211.  
  212.       return isLoop_bool;
  213.     }
  214. };
  215.  
  216. // =============================
  217. // ========== GLOBALS ==========
  218. // =============================
  219.  
  220. long periodEnd;
  221. GameOfLife game = GameOfLife();
  222.  
  223. Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXEL, IO_PIN, NEO_GRBW + NEO_KHZ800);
  224.  
  225. // ====================================
  226. // ========== Main-Functions ==========
  227. // ====================================
  228.  
  229. void setup() {
  230.   randomSeed(analogRead(0));
  231.  
  232.   Serial.begin(9600);
  233.   while (!Serial) {
  234.     ;
  235.   }
  236.  
  237.   strip.begin(); // This initializes the NeoPixel library.
  238.   strip.setBrightness(BRIGHTNESS); // set brightness
  239.   strip.show(); // Initialize all pixels to 'off'
  240. }
  241.  
  242.  
  243.  
  244. void loop() {
  245.   if (game.isEmpty()){
  246.     game.rnd();
  247.   }
  248.  
  249.   if (game.isLoop()){
  250.     game.doEmpty();
  251.   }
  252.  
  253.   game.iterate();
  254.  
  255.   while (periodEnd > millis()) {
  256.       ; // Wait
  257.   }
  258.   periodEnd = millis() + TIME_DELAY;
  259.  
  260.   renderToScreen();
  261. }
  262.  
  263.  
  264. void renderToScreen(){
  265.   uint8_t pos = 0;
  266.   uint32_t pointColor = strip.Color(0, 0, 255);
  267.  
  268.   for (uint8_t i = 0; i < MATRIX_SIZE; i++){
  269.     for (uint8_t j = 0; j < MATRIX_SIZE; j++){
  270.       pos = calcLedPos(i, j);
  271.      
  272.       if (game.get(i, j) == true){
  273.         strip.setPixelColor(pos, BLUE);
  274.       } else {
  275.         strip.setPixelColor(pos, 0);
  276.       }
  277.     }
  278.   }
  279.  
  280.   strip.show();
  281. }
  282.  
  283. /**
  284.    Calculates the position of a coordinate on the led strip
  285. */
  286. uint8_t calcLedPos(uint8_t x, uint8_t y) {
  287.   uint8_t pos = y * MATRIX_SIZE;
  288.  
  289.   if ((y % 2) == 0) {
  290.     return pos + x;
  291.   } else {
  292.     return pos + MATRIX_SIZE - x - 1;
  293.   }
  294. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement