{"id":13570728,"url":"https://github.com/perama-v/GoL2","last_synced_at":"2025-04-04T07:32:00.529Z","repository":{"id":40686402,"uuid":"408330903","full_name":"perama-v/GoL2","owner":"perama-v","description":"Cellular automata on replicated state machine","archived":false,"fork":false,"pushed_at":"2022-06-27T14:34:14.000Z","size":435,"stargazers_count":25,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-14T02:42:04.711Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/perama-v.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-20T06:16:23.000Z","updated_at":"2023-11-21T12:58:33.000Z","dependencies_parsed_at":"2022-08-26T13:10:20.553Z","dependency_job_id":null,"html_url":"https://github.com/perama-v/GoL2","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perama-v%2FGoL2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perama-v%2FGoL2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perama-v%2FGoL2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perama-v%2FGoL2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/perama-v","download_url":"https://codeload.github.com/perama-v/GoL2/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247138876,"owners_count":20890116,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T14:00:54.547Z","updated_at":"2025-04-04T07:31:55.517Z","avatar_url":"https://github.com/perama-v.png","language":"Python","funding_links":[],"categories":["Applications"],"sub_categories":["Games"],"readme":"# GoL2\n\nGame of L2\n\nCellular automata on replicated state machine.\nAn implementation of Conway's Game of Life as a contract on StarkNet, written\nin Cairo, with an interactive element.\n\nPlayers can alter the state of the game, affecting the future of the simulation.\nPeople may create interesting states or coordinate with others to achieve some\noutcome of interest.\n\nThis implementation is novel in that the game state shared (agreed by all) and permissionless\n(anyone may participate). The game rules are enforced by a validity proof, which means that\nno one can evolve the game using different rules.\n\nThe main rules of the game are:\n\n- The normal rules of Conways' Game of Life (3 to revive, 2 or 3 to stay alive).\n- The boundaries wrap - a glider may travel infinitely within the confines of the grid.\n\n|Acorn generation 0|Acorn generation 1|\n|:--: | :--:|\n| ![acorn-0](img/acorn_0.png)| ![acorn-0](img/acorn_1.png) |\n\n## Game modes\n\nThere are two modes: Inifinite and Creator\n\n- Usage and Mechanics\n    - [Infinite](descriptions/usage_infinite.md)\n    - [Creator](descriptions/usage_creator.md)\n- Frontend Considerations\n    - [General notes](descriptions/frontend_spec_general_notes.md)\n    - [Infinite](descriptions/frontend_spec_infinite.md)\n    - [Creator](descriptions/frontend_spec_creator.md)\n- Example deployments\n    - [Infinite](https://voyager.online/contract/0x06dd56f17fba09c62d9a1f3542f184de7b157eb178b13661d7d9ed44f977d1db#readContract)\n    - [Creator](https://voyager.online/contract/0x01fff3f1807f873ddeaa61bbea8910bd8d1e04399d9fa5db29b80c25aa1121db#readContract)\n    - Note that calling these functions in the explorer will originate\ntransactions from the zero-address. Calling from the Account directly will follow\nas wallet/SDK infrastructure is connected.\n\n\n### Infinite\n\nA single game with an ability for participants to evolve the game to its next state.\nBy doing so they also gain a special power - to revive a single cell at their discretion.\n\nThe game may flourish and produce a myriad of diverse game states, or it may fall to ruin and\nbecome a barren wasteland. It will be up to the participants to decide if and when to use\ntheir life-giving power.\n\nThe purpose of this game mode is to encourage collaboration.\n\n### Creator\n\nAn open-ended collection of starting states that anyone can create. A player\ncan specify the alive/dead state for all the cells in the game they spawn. The\ngame can be evolved from that point, but individual cells cannot be altered.\n\nAnyone can progress a game, and in return they get creator credits. Ten creator\ncredits can be redeemed to spawn their own game.\n\nThe purpose of this game is to allow players to explore interesting starting\npatterns in the the game. E.g., inventing new starting positions that last a\nmany generations before dying out or create a unique pattern.\n\n# Architecture\n\nEach game mode is a separate contract and holds the state of Conway's Game of Life.\n\n- The game board is a square with side length `dim`, (E.g., dim = 16) containing `dim**2` cells.\nCells wrap around edges.\n- Every cell is in storage as alive or dead.\n    - A row of cells will be stored as a binary number of length `dim` (max `dim` is\n    limited to 250 bit due to field size).\n    - Each row is stored as a felt in storage. (`dim` storage updates per interaction)\n- When the contract is called by a player to progress a game it:\n    1. Runs the simulation for one generation..\n    2. Saves the new state to storage.\n    3. Saves the generation.\n    4. Issues a credit.\n- Anyone can call the contract to view the game which returns a set of 32 integers\nrepresenting rows of the game board. The columns are binary encoded with 0 or 1 for\ndead/alive states in each row.\n- Anyone with a `Warden` token may call `give_life_to_cell` once per token to\nrevive a chosen cell.\n\n## Inner Contract Operations\n\n- A player calls the external function to have a turn.\n- Initialization: A `cell_states` array is created to hold the state of all the cells\n(length `dim**2`):\n    1. Iterate over `dim` to access rows by index indices)\n    2. Call `saved_cells.read(row)` to get binary representation of state (for each row).\n    3. For each bit, save it as a felt to the array.\n        - Use a mask for each column: `state[dim*row + column] = bitwise_and(row, 2**column)`)\n        - At the end of the contract call the state will be converted back to binary\n        representation for storage.\n- Simulation: A `next_state` array is made to hold the values during evaluation.\n    1. Iterate over all cells (``dim**2``).\n    2. For each cell check and sum all 8 neighbours, apply life rule and save alive/dead (`0/1`).\n    3. Save result to `next_state` array.\n    4. After final cell is read, change the array to point at the new neighbour array\n    `cell_states=next_state`.\n- Repeat simulation for `number_of_generations`.\n- Recreate the binary representation of each row and save with `saved_cells.write(row)`.\n\nIn `Infinite` mode, a give life action is processed as follows:\n\n- A player calls `give_life(row_index, col_index)`.\n- The current row is read from storage.\n- The column is applied with a bitwise AND mask to the row.\n- The row is saved to storage.\n- The player loses one give life credit.\n\nIn `Creator` mode, a player submits an array of 32 integers, representing the rows\nof the game. The game then stores these, ensuring that no two starting points are the same.\nAnyone can then evolve that game to earn a creator credit.\n\n## Token contract ownership model\n\nThe games currently have tokens as an internal representation. There is no ERC20/ERC721\nconnected to the game at the moment. Given that each game state is stored\non chain, another contract could be written to interact with this\ngame (e.g. to score games by some metric).\n\n## Example storage\n\nStorage: store `DIM` rows as binary alive/dead\n```\nrow[0] = 01001100101001010100110010100101   (as a felt: 1285901477).\nrow[1]\n...\nrow[dim] = 10001100010101001001010100110010   (as a felt: 2354353458).\n```\nCalling `view_game()` will produce `dim` numbers in decimal representation, which\ncan be rendered as binary (e.g., in the console).\n\n## Parameters\n\n```\ndim = 32 (max 250)\ncell_count = dim**2 (e.g., 1024 cells if DIM=32)\n```\n\n## Dev\n\nActivate virtual environment with python \u003e=3.7. Install\ncairo-lang either with nile or directly.\n\nNile:\n\n    pip install cairo-nile\n    https://github.com/OpenZeppelin/nile\n\nDirectly:\n\n    pip install cairo-lang\n\n### Data structure\n\nBoth game modes use a binary encoded game state. Calling for a\ngame state will return 32 numbers, the starting state for the Infinite\ngame is the Acorn (as shown in the image above),\nsituated mid-right.\n\n```\n0 0 0 0 0 0 0 0 0 0 0 0 32 8 103 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n\nWhich decoded as bin(32), bin(8) and bin(103) take the acorn form:\n\n   100000\n     1000\n  1100111\n```\nAfter evolving one generation, and calling for the state again, the\nreturned state is:\n\n```\n0 0 0 0 0 0 0 0 0 0 0 0 0 118 6 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n\nOr:\n  1110110\n      110\n       10\n```\n\nIf for example a user gave life to a particular cell\n(row index `9` and column index `9`). The state would then be:\n\n```\n0 0 0 0 0 0 0 0 0 4194304 0 0 0 118 6 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n\nWhere 4194304 is the binary number: 00000000010000000000000000000000\n\nColumn index 9 is '1', or 'alive' now.\n```\nThis single cell would die out in the next generation, and so would not be a\nwise placement, unless other cells are placed in adjacent locations.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperama-v%2FGoL2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fperama-v%2FGoL2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperama-v%2FGoL2/lists"}