From 6e4a35b0c2710d12ea85ed6283d0515448b96bf7 Mon Sep 17 00:00:00 2001 From: Ryan Reed <git@ryanreed.net> Date: Fri, 11 Aug 2023 15:13:20 -0400 Subject: [PATCH] Fixing processing which was not properly following Conway's rules --- world.gd | 54 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/world.gd b/world.gd index 7d7981d..3a86102 100644 --- a/world.gd +++ b/world.gd @@ -17,9 +17,9 @@ enum CellStates { @onready var world_seed_label: Label = $CanvasLayer/Debug/VBoxContainer/WorldSeed @export var world_seed: int -@export var cell_size: Vector2 = Vector2(64, 64) +@export var cell_size: Vector2 = Vector2(16, 16) @export var cell_texture: Texture2D -@export var world_size: Vector2 = Vector2(8, 8) +@export var world_size: Vector2 = Vector2(32, 32) var cell_instance var generation: int = 1 @@ -37,29 +37,26 @@ func _ready() -> void: generate_world() -## Check a cell against the Conway rules -func check_cell_rules(pos: Vector2) -> void: +## Check a cell against the Conway rules and return True if cell shoudl be alive +func cell_is_alive(pos: Vector2) -> bool: var neighbors := count_living_neighbors(pos) var currently_alive = world[pos.x][pos.y] is RID # Rule 1 - Any live cell with fewer than two live neighbours dies (underpopulation) if currently_alive and neighbors < 2: - kill_cell(pos) - return + return false # Rule 2 - Any live cell with two or three live neighbours lives elif currently_alive and (neighbors == 2 or neighbors == 3): - total_living += 1 - return + return true # Rule 3 - Any live cell with more than three live neighbours dies (overpopulation) - elif currently_alive and neighbors > 3: - kill_cell(pos) - return + return false # Rule 4 - Any dead cell with epos.xactly three live neighbours becomes a live cell (reproduction) elif not currently_alive and neighbors == 3: - total_living += 1 - world[pos.x][pos.y] = create_cell(pos) - return + return true + return false + +## Count all neighbors surrounding a cell func count_living_neighbors(pos: Vector2) -> int: var count := 0 @@ -75,18 +72,31 @@ func count_living_neighbors(pos: Vector2) -> int: count += 1 return count +## Loop through the world and create or kill cells depending on rules func process_generation() -> void: generation += 1 total_living = 0 + var new_world: Array= [] for x in range(world_size.x): + new_world.append([]) + new_world[x].resize(world_size.x) for y in range(world_size.y): - check_cell_rules(Vector2(x, y)) + var pos = Vector2(x, y) + if cell_is_alive(pos): + total_living += 1 + new_world[x][y] = create_cell(pos) + else: + new_world[x][y] = kill_cell(pos) + world = new_world ## Create the cell using the rendering server func create_cell(pos: Vector2) -> RID: + var world_size = world.size() + if world[pos.x][pos.y] is RID: return world[pos.x][pos.y] + var rs = RenderingServer cell_instance = rs.canvas_item_create() @@ -101,23 +111,23 @@ func create_cell(pos: Vector2) -> RID: return cell_instance -func kill_cell(pos: Vector2) -> void: - if not world[pos.x][pos.y] is RID: return - - RenderingServer.free_rid(world[pos.x][pos.y]) - world[pos.x][pos.y] = CellStates.DEAD +func kill_cell(pos: Vector2) -> CellStates: + if world[pos.x][pos.y] is RID: + RenderingServer.free_rid(world[pos.x][pos.y]) + return CellStates.DEAD ## Generate the world with the initial cells func generate_world() -> void: for x in range(world_size.x): world.append([]) + world[x].resize(world_size.x) for y in range(world_size.y): if randi_range(0, 1): total_living += 1 - world[x].append(create_cell(Vector2(x, y))) + world[x][y] = create_cell(Vector2(x, y)) else: - world[x].append(CellStates.DEAD) + world[x][y] = CellStates.DEAD func _on_generation_timer_timeout() -> void: