{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "name": "General Simulation Framework", "provenance": [], "collapsed_sections": [], "toc_visible": true }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "LL3GCoe6EfnC" }, "source": [ "# Creating a Conway's Game of Life\n", "\n", "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.\n", "\n", "![aca3.png](data:image/png;base64,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)\n" ] }, { "cell_type": "markdown", "metadata": { "id": "ZdOGrmIgGL6J" }, "source": [ "## Rules\n", "\n", "The universe of the Game of Life is an infinite, two-dimensional orthogonal grid of square cells, each of which is in one of two possible states, live or dead, (or populated and unpopulated, respectively). Every cell interacts with its eight neighbours, which are the cells that are horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions occur:\n", "\n", "\n", "1. Any live cell with two or three live neighbours survives.\n", "2. Any dead cell with three live neighbours becomes a live cell.\n", "3. All other live cells die in the next generation. Similarly, all other dead cells stay dead." ] }, { "cell_type": "markdown", "metadata": { "id": "-BiEkCxsLRRC" }, "source": [ "## Implementing cells\n", "\n", "To implement cells, you don't need to apply many changes from the previous example." ] }, { "cell_type": "code", "metadata": { "id": "6ag63xbJLj-4" }, "source": [ "from typing import Dict\n", "from gsf.dynamic_system.dynamic_systems import DiscreteEventDynamicSystem\n", "from gsf.models.models import DiscreteTimeModel\n", "\n", "\n", "class Cell(DiscreteTimeModel):\n", " \"\"\"Cell of the Conway's Game of life\n", "\n", " It has an state alive or dead. When receives an input, changes its by the defined rules.\n", " Its output is the state.\n", "\n", " Attributes:\n", " _symbol (str): Symbol that represents the cell when it is printed in console.\n", " \"\"\"\n", " _symbol: str\n", "\n", " def __init__(self, dynamic_system: DiscreteEventDynamicSystem, state: bool, symbol: str = None):\n", " \"\"\"\n", " Args:\n", " dynamic_system (DiscreteEventDynamicSystem): Automaton Grid where the cell belongs.\n", " state (bool); State that indicates whether the cell is alive (True) or dead (False).\n", " symbol (str): Symbol that represents the cell when it is printed in console.\n", " \"\"\"\n", " super().__init__(dynamic_system, state=state)\n", " self._symbol = symbol or \"\\u2665\"\n", "\n", " def _state_transition(self, state: bool, inputs: Dict[str, bool]) -> bool:\n", " \"\"\"\n", " Receives an input and changes the state of the cell.\n", " Args:\n", " state (bool); Current state of the cell.\n", " inputs: A dictionary where the key is the input source cell and the value the output of that cell.\n", "\n", " Returns:\n", " The new state of the cell.\n", " \"\"\"\n", " neighbors_states = inputs.values()\n", " count_alive = 0\n", " for is_alive in neighbors_states:\n", " if is_alive:\n", " count_alive = count_alive + 1\n", " return (not state and count_alive == 3) or (state and 2 <= count_alive <= 3)\n", "\n", " def _output_function(self, state: bool) -> bool:\n", " \"\"\"\n", " Returns the state of the cell.\n", " \"\"\"\n", " return state\n", "\n", " def __str__(self):\n", " \"\"\"Prints the cell with the defined symbol\"\"\"\n", " is_alive = self.get_state()\n", " if is_alive:\n", " return self._symbol\n", " else:\n", " return \"-\"" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "gPCixTBxLk1P" }, "source": [ "The difference is in the state transition, where instead of having only one input, it can have up to eight neighbors.\n", "\n", "![neighbors.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHoAAAB6CAYAAABwWUfkAAAAAXNSR0IArs4c6QAABHN0RVh0bXhmaWxlACUzQ214ZmlsZSUyMGhvc3QlM0QlMjJhcHAuZGlhZ3JhbXMubmV0JTIyJTIwbW9kaWZpZWQlM0QlMjIyMDIxLTA5LTI0VDE0JTNBMTYlM0ExOS4yMjlaJTIyJTIwYWdlbnQlM0QlMjI1LjAlMjAoWDExJTNCJTIwTGludXglMjB4ODZfNjQpJTIwQXBwbGVXZWJLaXQlMkY1MzcuMzYlMjAoS0hUTUwlMkMlMjBsaWtlJTIwR2Vja28pJTIwQ2hyb21lJTJGOTQuMC40NjA2LjU0JTIwU2FmYXJpJTJGNTM3LjM2JTIyJTIwdmVyc2lvbiUzRCUyMjE1LjMuMCUyMiUyMGV0YWclM0QlMjJHa1luNzdqZkJ3UWNTTUM1UkRrNSUyMiUyMHR5cGUlM0QlMjJnb29nbGUlMjIlM0UlM0NkaWFncmFtJTIwaWQlM0QlMjJPLWdkZjdsQ2xsTV91YUFTdS0xVSUyMiUzRTNaak5qcHN3RklXZmhtMEVHSk93N0tUVG1VMmxTbGwwYmNFZHNHUmlaSnlCOU9ucjFEWiUyRlRqck1xR1ZRV0VUMmlibm1mc2ZYTW5ob1g3WlBnbFRGZDU0QjgwSSUyRmF6MzAxUXREakJQMWV4SE9Xa0JCcUlWYzBFeExRUzhjNkM4d29tJTJGVUU4MmdIZzJVbkROSnE3R1k4dU1SVWpuU2lCQzhHUTk3NFd3OGEwVnljSVJEU3BpciUyRnFTWkxMUzZDN2U5JTJGZ3cwTCUyQnpNUVd3U0xva2RiREtwQzVMeFppQ2hSdyUyRnRCZWRTdDhwMkQlMkJ6Q3puTFI5MzI3OFclMkYzWUFLT2NzNE5odnNyWVNlVG0za3VlYmJKTmdXVmNLaElldWszeWs4UFBSU3laS29YcUNhcEs0MzRoYmFnb2o2WWlDQWt0RGVmS3VoeVZXc0VlQWxTbk5VUWN3T0tESjZ6QldqNlRVJTJGYkRpa0dvSzFHakw5NUY3bEhvQnFHd25VaWFKMUVkcDlISkZvbGtTajhQQ0o0bFVTY3FzSExFWW5YU1dSYU5Rc1MyYTZTaUZNMUN4TFpyWktJVXpYSmNrU1NkUktaVnMyQ1JPd212aklr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)\n", "\n", "For each neighbor adds one to the counter if it is alive. Then apply the suviving rules.\n", "\n", "\n" ] }, { "cell_type": "markdown", "source": [ "## Implementing the Automaton\n", "\n", "The model is also similar to the previous one, changing the way in which neighbors are assigned." ], "metadata": { "collapsed": false } }, { "cell_type": "code", "metadata": { "id": "7KzIZQFwMKkF" }, "source": [ "from __future__ import annotations\n", "from random import random, seed\n", "from typing import List, TYPE_CHECKING\n", "\n", "from gsf.dynamic_system.dynamic_systems import DiscreteEventDynamicSystem\n", "\n", "if TYPE_CHECKING:\n", " from gsf.dynamic_system.core.base_dynamic_sytem import DynamicSystemOutput\n", "\n", "\n", "class Board(DiscreteEventDynamicSystem):\n", " \"\"\"Game of life\n", "\n", " It has a group of cells, connected between them. The output of each cell is its right neighbor.\n", " Attributes:\n", " _cells (List[List[Cell]]): Group of cells of the board Automaton.\n", " \"\"\"\n", " _cells: List[List[Cell]]\n", "\n", " def __init__(self, width: int, height: int, random_seed: int = 42):\n", " super().__init__()\n", " seed(random_seed)\n", " self._create_cells(width, height)\n", " self._define_relations(width, height)\n", "\n", " def _create_cells(self, width: int, height: int):\n", " \"\"\"Appends the cells to the automaton.\n", " Args:\n", " width (int): Number of column cells of the automaton.\n", " height (int): Number of row cells of the automaton.\n", " \"\"\"\n", " self._cells = []\n", " for i in range(height):\n", " row = []\n", " for j in range(width):\n", " row.append(Cell(self, random() < 0.5))\n", " self._cells.append(row)\n", "\n", " def _define_relations(self, width: int, height: int):\n", " \"\"\"Creates the connections between the left cell and the right cell.\n", " Args:\n", " width (int): Number of column cells of the automaton.\n", " height (int): Number of row cells of the automaton.\n", " \"\"\"\n", " for i in range(height):\n", " for j in range(width):\n", " for x in range(max(0, i - 1), min(i + 2, height)):\n", " for y in range(max(0, j - 1), min(j + 2, width)):\n", " if x != i or y != j:\n", " self._cells[i][j].add(self._cells[x][y])\n", "\n", " def __str__(self):\n", " \"\"\"Changes the format to show the board automaton when is printed\"\"\"\n", " s = \"\"\n", " for row in self._cells:\n", " for cell in row:\n", " s += str(cell)\n", " s += \"\\n\"\n", " return s\n", "\n", " def get_output(self) -> DynamicSystemOutput:\n", " \"\"\"Prints the model every generation\"\"\"\n", " print(self)\n", " return super().get_output()" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "5m1n3S7fM6JA" }, "source": [ "We overwrite the `get_output` member, because we want to print the board every generation." ] }, { "cell_type": "markdown", "metadata": { "id": "pI2v16jgNKcO" }, "source": [ "## Running the simulation\n", "\n", "Create the experiment and assign the dynamic system." ] }, { "cell_type": "code", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "2RfMdOGPNQlF", "outputId": "d1c8189e-3d9f-4897-871b-aa7229d48c10", "pycharm": { "name": "#%%\n" } }, "source": [ "from gsf.experiments.experiment_builders import DiscreteEventExperiment\n", "\n", "board = Board(10, 10)\n", "experiment = DiscreteEventExperiment(board)\n", "print(board)\n", "experiment.simulation_control.start(stop_time=10)\n", "experiment.simulation_control.wait()\n", "print(board)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "-♥♥♥---♥♥♥\n", "♥-♥♥--♥--♥\n", "--♥♥-♥♥♥--\n", "----♥-----\n", "-♥♥♥♥♥♥♥-♥\n", "♥♥♥---♥-♥♥\n", "------♥♥♥♥\n", "♥--♥-♥-♥♥♥\n", "-♥--♥♥--♥♥\n", "♥--♥♥♥----\n", "\n", "-♥♥♥---♥♥♥\n", "♥-♥♥--♥--♥\n", "--♥♥-♥♥♥--\n", "----♥-----\n", "-♥♥♥♥♥♥♥-♥\n", "♥♥♥---♥-♥♥\n", "------♥♥♥♥\n", "♥--♥-♥-♥♥♥\n", "-♥--♥♥--♥♥\n", "♥--♥♥♥----\n", "\n", "-♥-♥---♥♥♥\n", "-----♥---♥\n", "-♥♥--♥♥♥--\n", "-♥------♥-\n", "♥---♥-♥♥-♥\n", "♥---♥-----\n", "♥-♥--♥----\n", "-----♥----\n", "♥♥♥----♥-♥\n", "---♥-♥----\n", "\n", "--------♥♥\n", "-♥--♥♥---♥\n", "-♥♥--♥♥♥♥-\n", "♥♥♥-----♥-\n", "♥♥---♥-♥♥-\n", "♥--♥♥-♥---\n", "-♥--♥♥----\n", "♥-♥---♥---\n", "-♥♥-♥-♥---\n", "-♥♥-------\n", "\n", "--------♥♥\n", "-♥♥-♥♥---♥\n", "---♥♥♥♥♥♥♥\n", "-----♥---♥\n", "---♥♥♥♥♥♥-\n", "♥-♥♥--♥♥--\n", "♥♥♥-♥-♥---\n", "♥-♥-♥-♥---\n", "♥----♥----\n", "-♥♥♥------\n", "\n", "--------♥♥\n", "--♥-------\n", "--♥♥---♥-♥\n", "---------♥\n", "--♥♥----♥-\n", "♥-------♥-\n", "♥---♥-♥---\n", "♥-♥-♥-♥---\n", "♥---♥♥----\n", "-♥♥-------\n", "\n", "----------\n", "--♥♥-----♥\n", "--♥♥----♥-\n", "---------♥\n", "--------♥♥\n", "-♥-♥---♥--\n", "♥--♥---♥--\n", "♥---♥-♥---\n", "♥-♥-♥♥----\n", "-♥--------\n", "\n", "----------\n", "--♥♥------\n", "--♥♥----♥♥\n", "---------♥\n", "--------♥♥\n", "--♥----♥--\n", "♥♥♥♥♥-♥♥--\n", "♥---♥-♥---\n", "♥--♥♥♥----\n", "-♥--------\n", "\n", "----------\n", "--♥♥------\n", "--♥♥----♥♥\n", "----------\n", "--------♥♥\n", "--♥---♥♥--\n", "♥-♥-♥-♥♥--\n", "♥-----♥♥--\n", "♥♥-♥♥♥----\n", "----♥-----\n", "\n", "----------\n", "--♥♥------\n", "--♥♥------\n", "----------\n", "-------♥♥-\n", "-♥-♥-♥♥---\n", "---♥----♥-\n", "♥-♥----♥--\n", "♥♥-♥♥♥♥---\n", "---♥♥♥----\n", "\n", "----------\n", "--♥♥------\n", "--♥♥------\n", "----------\n", "------♥♥--\n", "--♥-♥-♥-♥-\n", "-♥-♥♥-♥♥--\n", "♥-♥--♥♥♥--\n", "♥♥----♥---\n", "--♥♥--♥---\n", "\n", "----------\n", "--♥♥------\n", "--♥♥------\n", "----------\n", "-----♥♥♥--\n", "--♥-♥---♥-\n", "-♥--♥---♥-\n", "♥-♥♥♥-----\n", "♥--♥------\n", "-♥♥-------\n", "\n" ] } ] } ] }