This is an automated email from the ASF dual-hosted git repository. simbit18 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 058c7a8353bc960cc9c9ed5cd95d3b9d148c1775 Author: Matteo Golin <[email protected]> AuthorDate: Tue Nov 11 22:48:09 2025 -0500 docs/applications/games/cgol: Documentation for CGOL game Added documentation for the new Conway's Game of Life application. Signed-off-by: Matteo Golin <[email protected]> --- Documentation/applications/games/cgol/cgol.jpg | Bin 0 -> 102297 bytes Documentation/applications/games/cgol/index.rst | 150 ++++++++++++++++++++++++ 2 files changed, 150 insertions(+) diff --git a/Documentation/applications/games/cgol/cgol.jpg b/Documentation/applications/games/cgol/cgol.jpg new file mode 100644 index 00000000000..a6b9e6c59f9 Binary files /dev/null and b/Documentation/applications/games/cgol/cgol.jpg differ diff --git a/Documentation/applications/games/cgol/index.rst b/Documentation/applications/games/cgol/index.rst new file mode 100644 index 00000000000..517b283f80b --- /dev/null +++ b/Documentation/applications/games/cgol/index.rst @@ -0,0 +1,150 @@ +===================== +Conway's Game of Life +===================== + +A classic "game" is Conway's Game of Life (CGOL). It is not a game in the +playable sense, but is an entertaining curiosity. CGOL is a type of cellular +automata: complex behaviour arising from a simplistic set of rules. It has been +widely studied, especially by mathematicians. Conway himself was a +mathematician. + +.. figure:: cgol.jpg + :figwidth: 80% + :align: center + :alt: An example of rendered output from the CGOL game. + + An example of rendered output from the CGOL game. + +Requirements +------------ + +The CGOL implementation for NuttX relies on a frame buffer driver, that is: +:doc:`/components/nxgraphics/framebuffer_char_driver`. If you have +``VIDEO_FB`` enabled, you should be able to use the app. The visuals for the +game are rendered to a display through the provided frame buffer. + +.. note:: + + CGOL currently only supports devices with 32, 24, 16 or 8 bpp rendering. + Since the game is only two colours, 1 bpp rendering can be supported as well, + I just didn't want to bother playing with individual bit operations any more + by the time I got to the end of writing the application. By all means, please + send patches! + + The implementation was only tested on a 32bpp frame buffer device. + +This game works for frame buffers that require ``FB_UPDATE`` as well. It does +nothing special with overlays. + +Usage +----- + +The game can be played by simply running it in the NSH console: + +.. code:: console + + nsh> cgol + +The game will use the frame buffer device specified by +``CONFIG_GAMES_CGOL_FBDEV`` to render the image. By default, that is +``/dev/fb0``. If you wish to use a different device at run-time, you can pass +the frame buffer device path as the first argument: + +.. code:: console + + nsh> cgol /dev/fb1 + +Note that the game will loop forever and render the output to the screen. After +a certain point, CGOL reaches a "stable" configuration and there is not really +anything interesting to watch. At this point, you can terminate the application +with ``CTRL + C``. You can also run the app in the background by adding the +``&`` character after the command in NSH, which is recommended if you want to do +things in the console after running it. + +.. warning:: + + This program has not been tested with ``bpp`` values other than 32. It may + have unknown bugs. + + It has also not been tested with devices that have a word size + (``sizeof(unsigned int)``) other than 32 bits. + +Configuration options +--------------------- + +There are a few options you can customize in order to modify the game. The first +two are very obvious: the map width and map height. + +* ``CONFIG_GAMES_CGOL_MAPWIDTH`` +* ``CONFIG_GAMES_CGOL_MAPHEIGHT`` + +These options select the width and height of the game map in cells. You must +pick a width which is a multiple of ``sizeof(unsigned int) * 8``. This is a +necessary evil in order to implement CGOL efficiently on embedded device. Often +times, this value is your device's natural word size in bits. So, if you're +using a 32 bit machine, pick a map width that is a multiple of 32. There is no +such restriction for the map height. + +To change the amount of cells used to populate the map initially, you can modify +the density: ``CONFIG_GAMES_CGOL_DENSITY``. The number of cells that are +generated at start is then ``TOTAL_CELLS * (1 / density)``, where total cells +is the map area. + +The next thing you can change is the delay between frames in microseconds, using +the option: ``CONFIG_GAMES_CGOL_FRAMEDELAY``. By default this value is 0 (no +delay). Use this if the rendering is too fast for you to appreciate each frame. + +Purely for rendering reasons, the last option you can change is +``CONFIG_GAMES_CGOL_DBLBUF``. This enables double buffering for rendering, which +allocates a RAM buffer of equal size to the actual framebuffer. All rendering is +performed directly on the RAM buffer, and then copied to the framebuffer once +done. This is only necessary on some devices. For instance, the :doc:`Raspberry +Pi 4b </platforms/arm64/bcm2711/boards/raspberrypi-4b/index>` experiences +significant artifacts and completely incorrect rendering if double buffering is +not used. + +Implementation +-------------- + +The game itself is implemented using bit-fields to represent living and dead +cells. A ``1`` bit is alive, and a ``0`` is dead. I used the natural word size +of the machine to store the bits, which is why I impose the restriction that the +map width must be a multiple of the number of bits in an ``unsigned int``. + +More bits in a word equates to more parallelism. When rendering living cells, I +can skip over 32 cells at once on a 32-bit machine if the word evaluates to 0. +This saves 32 iterations. The bit-fields themselves are also a space saver, as +opposed to using 1 byte per cell, for instance. Even representing living cells +as (x, y) pairs consumes more memory, and also takes significantly more CPU +power to advance the game state at each step. + +The main loop consists of the following steps: + +1. Render living cells +2. Sleep if user configured frame delay +3. Display render +4. Advance the state of the game +5. Clear the render + +The map is randomly initialized with living cells using ``rand()``, which is a +uniform distribution. This isn't always the best for CGOL; a certain density +needs to be achieved for interesting evolutions. I have settled on a density of +1/6 of the map. + +The game is auto-scaled to fill as much of the frame buffer as possible. The +minimum resolution is one pixel per cell. If the configuration has a map size +larger than the frame buffer, the program will exit with an error. + +Finally, the map wraps around from right to left. It does not wrap from top to +bottom to allow a more memory efficient method of buffering the next state as it +is calculated. + +.. todo:: + + This program could be improved with: + + * 1 bit support + * Optional input device support for re-initializing the game, maybe drawing + cells + * Optional ability to load seeds + * Runtime speed controls
