Conway's game of life - derived from another project, turned into a c++ class, and scaled to support up to a 480x272 display, or a lower resolution color display.
LifeRules.h
- Committer:
- WiredHome
- Date:
- 2014-04-23
- Revision:
- 3:860ae49fedb7
- Parent:
- 2:c11005ab38db
File content as of revision 3:860ae49fedb7:
#include "mbed.h" // Defined and Derived values to check if it exceeds available memory #define FRAMES_PER_BIT 2 /* current and next life cycle */ //#if (LIFE_W * LIFE_H * BITS_PER_LIFE * FRAMES_PER_BIT / 8) > (BYTE_RSVD_RAM) //#error Bummer, can't make the lifemap that big //#endif /// Conway's game of life /// /// http://en.wikipedia.org/wiki/Conway's_Game_of_Life /// /// A simple cellular automation where pixels are born, live, and die /// following a simple set of rules. The oddest of the rules is that /// it takes 3 to create birth of a new life... /// /// Early on (back in the 70's), computers were not accessible to /// most, and yet somehow this simulation flourished. I was one of /// many that used pencil and graph paper, chalk on a board and /// even pennies on paper to simulate each cell. It was so much /// more animated when I had access to an 8008 micro and a "TV /// typewriter" interface. /// class Life { public: typedef enum { monochrome, ///< life cycle is dead or living color ///< life cycle is dying to dead and birthing to living } Animation; typedef enum { dead, living, dying, birthing } ValueOfLife; /// constructor for the life /// /// Constructor for the life object. The most important thing /// when constructing life, is to have room for the occupants, /// so take care that memory is actually available for the /// life map on your system. /// /// The required memory in bits is: /// /// w * h * 2 * (animate == color) ? 2 : 1 /// /// The '2' is because it keeps a current generation map and /// a next generation map. /// /// As an example: /// 480 * 272 * 2 * 1 => 261120 bits => 32640 bytes /// /// Fragments from a sample application you might find in main.cpp /// are shown here, this one for the RA8875 display graphics /// library. (see http://mbed.org/components/RA8875-Based-Display/) /// /// @code /// #define SCREEN_W 480 /// #define SCREEN_H 272 /// Life life(LIFE_W, LIFE_H, Life::monochrome); /// RA8875 lcd(p5, p6, p7, p12, NC, "tft"); /// /// // Where on screen do we locate it? /// #define LIFE_OFFSET_X (SCREEN_W - LIFE_W) /// #define LIFE_OFFSET_Y (SCREEN_H - LIFE_H) /// /// int main() /// { /// life.setbit(1,1, Life::living); /// life.setbit(1,2, Life::living); /// life.setbit(1,3, Life::living); /// while(1) { /// static uint16_t toggle = 0; /// if ((++toggle & 1) == 0) { /// life.GenerationStep(); /// } else { /// life.UpdateLifeCycle(); /// } /// ScreenUpdate(); /// } /// } /// /// void ScreenUpdate() /// { /// lcd.window(LIFE_OFFSET_X, LIFE_OFFSET_Y, LIFE_W, LIFE_H); /// lcd._StartGraphicsStream(); /// for (int j = 0; j < LIFE_H; j++) { /// for (int i = 0; i < LIFE_W; i++) { /// Life::ValueOfLife lifeState = life.getbit(i,j); /// switch (lifeState) { /// case Life::dead: /// lcd._putp(Black); /// break; /// case Life::dying: /// lcd._putp(RGB(64,0,0)); /// break; /// case Life::living: /// lcd._putp(Charcoal); /// break; /// case Life::birthing: /// lcd._putp(Blue); /// break; /// default: /// lcd._putp(Orange); /// ERR(" lifeState = %d\r\n", lifeState); /// break; /// } /// } /// } /// lcd._EndGraphicsStream(); /// lcd.WindowMax(); /// } /// @endcode /// /// @param[in] w is the width of the life map in pixels, commonly /// chosen to match the display device capability. /// @param[in] h is the height of the life map in pixels, commonly /// chosen to match the display device capability. /// @param[in] animate is an optional parameter that can be either /// 'monochrome' or 'color' (the default), which determines /// if each life cycle has one step (e.g. from life directly /// to death) or two steps (e.g. life to dying to death). /// @param[in] pMap is an optional pointer to a block of memory to /// host the life map. If not specified, it will assume /// the memory space of an LPC1768 where the 32K Ethernet /// buffers are not being used (and take that space for the /// life map). /// Life(int w, int h, Animation animate = color, uint8_t * pMap = (uint8_t *)(0x2007C000)); /// sets a life value in the frame at location x,y. /// /// @param[in] x is the x location in the life-map /// @param[in] y is the y location in the life-map /// @param[in] otherframe selects the next life-cycle of interest /// @param[in] b is the value of life to assign to that location /// void setbit(int x, int y, ValueOfLife b, int otherframe = 0); /// gets the life value from the specified location. /// /// @param[in] x is the x location in the life-map /// @param[in] y is the y location in the life-map /// @param[in] otherframe selects the next life-cycle of interest /// @returns the value of life at that location. /// ValueOfLife getbit(int x, int y, int otherframe = 0); /// Count and return the number of living neighbors. /// /// @param[in] x is the x location in the life-map /// @param[in] y is the y location in the life-map /// @returns the number of neighbors /// int CountNeighbors(int x, int y); /// Destroy all life - typically at startup. /// void DestroyAllLife(void); /// Step life forward by one generation /// void GenerationStep(void); /// Update the life-cycle. /// /// This method applies partial step to a life cycle. /// It does this when the Life is set up for color mode /// where you can then see birthing and dying cells as /// a result of this method. /// void UpdateLifeCycle(void); /// Apply the cycle of life to a cell. /// /// Based on the number of neighbors, and the current /// state of a cell, this determines whether the cell /// is born, lives, or dies. /// /// @param[in] x is the x offset into the life map. /// @param[in] y is the y offset into the life map. /// @param[in] neighbors is the count of neighbors. /// void CycleOfLife(int x, int y, int neighbors); private: int LIFE_W; // dimensions of the life map int LIFE_H; int maxX; // set max element for ease of iterations int maxY; int frame; // the current life cycle int animation; // mode - color or b&w uint8_t * pLifeMap; };