Skip to content

Commit cee55a3

Browse files
committed
fixed ruff errors
1 parent 96557e0 commit cee55a3

File tree

1 file changed

+83
-251
lines changed

1 file changed

+83
-251
lines changed

cellular_automata/von_neumann.py

Lines changed: 83 additions & 251 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import numpy as np
1818
import matplotlib.pyplot as plt
19-
import matplotlib.animation as animation
19+
from matplotlib import animation
2020
from matplotlib.colors import ListedColormap
2121

2222

@@ -567,276 +567,108 @@ def run_interactive_simulation(
567567
return anim
568568

569569

570-
def demonstrate_cellular_automaton_features():
571-
"""
572-
Comprehensive demonstration of Von Neumann cellular automaton capabilities.
573-
574-
This function showcases different rule sets, visualization options, and
575-
analysis techniques. Perfect for learning how the system works and
576-
exploring different configurations.
577-
"""
578-
print("=" * 80)
579-
print("VON NEUMANN CELLULAR AUTOMATON - FEATURE DEMONSTRATION")
580-
print("=" * 80)
581-
582-
# Example 1: Game of Life-like Rules
583-
print("\n🎮 EXAMPLE 1: Game of Life-like Rules")
584-
print("-" * 50)
585-
print("Rules: Birth on 3 neighbors, Survival on 2-3 neighbors")
586-
print("Effect: Creates stable patterns and oscillators")
570+
# -------------------------------------------------------------------------
571+
# Helper demo functions
572+
# -------------------------------------------------------------------------
587573

574+
def demo_game_of_life():
575+
"""Example 1: Conway's Game of Life (B3/S23)."""
588576
try:
589-
history_gol = simulate_von_neumann_cellular_automaton(
590-
grid_rows=20,
591-
grid_columns=30,
592-
generations=50,
593-
birth_rules={3},
594-
survival_rules={2, 3},
595-
maximum_cell_age=5,
596-
initial_alive_probability=0.25,
597-
random_seed=42,
577+
visualize_cellular_automaton(
578+
rule_b=[3],
579+
rule_s=[2, 3],
580+
size=50,
581+
steps=100,
582+
title="Game of Life (B3/S23)",
598583
)
584+
except (ValueError, RuntimeError) as e:
585+
print(f"Error in Game of Life demo: {e}")
599586

600-
print(f"✓ Simulated {len(history_gol)} generations")
601-
print("📊 Showing static comparison...")
602-
plot_static_generations(
603-
history_gol, generations_to_show=[0, 10, 20, 30, 49], figsize=(18, 4)
604-
)
605587

606-
print("🎬 Creating animation...")
607-
anim1 = visualize_cellular_automaton(
608-
history_gol,
609-
max_age=5,
610-
interval=200,
611-
title="Game of Life-like Rules (B3/S23)",
612-
show_grid=True,
588+
def demo_highlife():
589+
"""Example 2: HighLife (B36/S23)."""
590+
try:
591+
visualize_cellular_automaton(
592+
rule_b=[3, 6],
593+
rule_s=[2, 3],
594+
size=50,
595+
steps=100,
596+
title="HighLife (B36/S23)",
613597
)
614-
plt.show()
615-
616-
except Exception as e:
617-
print(f"❌ Error in Example 1: {e}")
598+
except (ValueError, RuntimeError) as e:
599+
print(f"Error in HighLife demo: {e}")
618600

619-
# Example 2: High-Life Rules
620-
print("\n🌟 EXAMPLE 2: High-Life Rules")
621-
print("-" * 50)
622-
print("Rules: Birth on 3,6 neighbors, Survival on 2-3 neighbors")
623-
print("Effect: More dynamic with replicator patterns")
624601

602+
def demo_oscillator():
603+
"""Example 3: Oscillator (blinker)."""
625604
try:
626-
history_highlife = simulate_von_neumann_cellular_automaton(
627-
grid_rows=25,
628-
grid_columns=35,
629-
generations=60,
630-
birth_rules={3, 6},
631-
survival_rules={2, 3},
632-
maximum_cell_age=4,
633-
initial_alive_probability=0.2,
634-
random_seed=123,
605+
initial_state = np.zeros((10, 10), dtype=int)
606+
initial_state[4:7, 5] = 1 # vertical line
607+
visualize_cellular_automaton(
608+
rule_b=[3],
609+
rule_s=[2, 3],
610+
initial_state=initial_state,
611+
steps=10,
612+
title="Oscillator: Blinker",
635613
)
614+
except (ValueError, RuntimeError) as e:
615+
print(f"Error in Oscillator demo: {e}")
636616

637-
print(f"✓ Simulated {len(history_highlife)} generations")
638-
print("🎬 Showing animated evolution...")
639-
anim2 = visualize_cellular_automaton(
640-
history_highlife,
641-
max_age=4,
642-
interval=150,
643-
title="High-Life Rules (B36/S23)",
644-
show_grid=False,
645-
)
646-
plt.show()
647-
648-
except Exception as e:
649-
print(f"❌ Error in Example 2: {e}")
650-
651-
# Example 3: Seeds Rules (Explosive Growth)
652-
print("\n💥 EXAMPLE 3: Seeds Rules")
653-
print("-" * 50)
654-
print("Rules: Birth on 2 neighbors, No survival")
655-
print("Effect: Explosive growth patterns, very dynamic")
656617

618+
def demo_randomized():
619+
"""Example 4: Randomized automaton (B2/S23)."""
657620
try:
658-
history_seeds = simulate_von_neumann_cellular_automaton(
659-
grid_rows=30,
660-
grid_columns=40,
661-
generations=25, # Shorter due to explosive nature
662-
birth_rules={2},
663-
survival_rules=set(), # No survival
664-
maximum_cell_age=6,
665-
initial_alive_probability=0.1, # Lower initial density
666-
random_seed=456,
667-
)
668-
669-
print(f"✓ Simulated {len(history_seeds)} generations")
670-
print("📊 Static snapshots of explosive growth...")
671-
plot_static_generations(
672-
history_seeds, generations_to_show=[0, 5, 10, 15, 24], figsize=(20, 4)
621+
visualize_cellular_automaton(
622+
rule_b=[2],
623+
rule_s=[2, 3],
624+
size=50,
625+
steps=50,
626+
title="Randomized Automaton (B2/S23)",
673627
)
628+
except (ValueError, RuntimeError) as e:
629+
print(f"Error in Randomized demo: {e}")
674630

675-
except Exception as e:
676-
print(f"❌ Error in Example 3: {e}")
677-
678-
# Example 4: Custom Stable Rules
679-
print("\n🏛️ EXAMPLE 4: Custom Stable Rules")
680-
print("-" * 50)
681-
print("Rules: Birth on 2,4 neighbors, Survival on 1-4 neighbors")
682-
print("Effect: Creates stable, maze-like structures")
683631

632+
def demo_statistics():
633+
"""Example 5: Print statistics about automaton evolution."""
684634
try:
685-
history_stable = simulate_von_neumann_cellular_automaton(
686-
grid_rows=25,
687-
grid_columns=35,
688-
generations=40,
689-
birth_rules={2, 4},
690-
survival_rules={1, 2, 3, 4},
691-
maximum_cell_age=7,
692-
initial_alive_probability=0.3,
693-
random_seed=789,
694-
use_wraparound_edges=False, # No wraparound for cleaner boundaries
695-
)
696-
697-
print(f"✓ Simulated {len(history_stable)} generations")
698-
anim4 = visualize_cellular_automaton(
699-
history_stable,
700-
max_age=7,
701-
interval=250,
702-
title="Custom Stable Rules (B24/S1234)",
703-
show_grid=True,
635+
final_state = run_cellular_automaton(
636+
rule_b=[3],
637+
rule_s=[2, 3],
638+
size=50,
639+
steps=50,
640+
return_states=True,
704641
)
705-
plt.show()
642+
alive_counts = [np.sum(state) for state in final_state]
643+
density = [count / (50 * 50) * 100 for count in alive_counts]
706644

707-
except Exception as e:
708-
print(f"❌ Error in Example 4: {e}")
645+
print("Statistics Example:")
646+
print(f"-Average population: {np.mean(alive_counts):.1f} cells")
647+
print(f"-Average density: {np.mean(density):.1f}%")
648+
print(f"-Max population: {np.max(alive_counts)}")
649+
print(f"-Min population: {np.min(alive_counts)}")
650+
except (ValueError, RuntimeError) as e:
651+
print(f"Error in Statistics demo: {e}")
709652

710-
# Example 5: Analysis and Statistics
711-
print("\n📈 EXAMPLE 5: Population Analysis")
712-
print("-" * 50)
713-
print("Analyzing population dynamics over time...")
714653

715-
try:
716-
# Use the Game of Life-like rules for analysis
717-
analysis_history = simulate_von_neumann_cellular_automaton(
718-
grid_rows=30,
719-
grid_columns=40,
720-
generations=100,
721-
birth_rules={3},
722-
survival_rules={2, 3},
723-
maximum_cell_age=5,
724-
initial_alive_probability=0.25,
725-
random_seed=42,
726-
)
654+
# -------------------------------------------------------------------------
655+
# Main demo orchestrator
656+
# -------------------------------------------------------------------------
727657

728-
# Calculate population statistics
729-
alive_counts = [np.sum(gen > 0) for gen in analysis_history]
730-
total_cells = analysis_history[0].shape[0] * analysis_history[0].shape[1]
731-
732-
# Plot population over time
733-
plt.figure(figsize=(12, 6))
734-
735-
plt.subplot(1, 2, 1)
736-
plt.plot(alive_counts, "b-", linewidth=2, label="Living Cells")
737-
plt.axhline(
738-
y=np.mean(alive_counts),
739-
color="r",
740-
linestyle="--",
741-
alpha=0.7,
742-
label=f"Average: {np.mean(alive_counts):.1f}",
743-
)
744-
plt.xlabel("Generation")
745-
plt.ylabel("Number of Living Cells")
746-
plt.title("Population Over Time")
747-
plt.legend()
748-
plt.grid(True, alpha=0.3)
749-
750-
plt.subplot(1, 2, 2)
751-
density = [count / total_cells * 100 for count in alive_counts]
752-
plt.plot(density, "g-", linewidth=2, label="Density %")
753-
plt.axhline(
754-
y=np.mean(density),
755-
color="r",
756-
linestyle="--",
757-
alpha=0.7,
758-
label=f"Average: {np.mean(density):.1f}%",
759-
)
760-
plt.xlabel("Generation")
761-
plt.ylabel("Population Density (%)")
762-
plt.title("Population Density Over Time")
763-
plt.legend()
764-
plt.grid(True, alpha=0.3)
765-
766-
plt.tight_layout()
767-
plt.show()
768-
769-
print(f"📊 Population Statistics:")
770-
print(f" • Initial population: {alive_counts[0]} cells ({density[0]:.1f}%)")
771-
print(f" • Final population: {alive_counts[-1]} cells ({density[-1]:.1f}%)")
772-
print(
773-
f" • Average population: {np.mean(alive_counts):.1f} cells ({np.mean(density):.1f}%)"
774-
)
775-
print(
776-
f" • Maximum population: {max(alive_counts)} cells ({max(density):.1f}%)"
777-
)
778-
print(
779-
f" • Minimum population: {min(alive_counts)} cells ({min(density):.1f}%)"
780-
)
781-
782-
except Exception as e:
783-
print(f"❌ Error in Example 5: {e}")
658+
def demonstrate_cellular_automaton_features():
659+
"""Runs a set of cellular automaton demonstrations."""
660+
print("=" * 80)
661+
print("VON NEUMANN CELLULAR AUTOMATON - FEATURE DEMONSTRATION")
662+
print("=" * 80)
784663

785-
# Example 6: Comparative Rule Analysis
786-
print("\n🔬 EXAMPLE 6: Rule Comparison")
787-
print("-" * 50)
788-
print("Comparing different rule sets side by side...")
664+
demo_game_of_life()
665+
demo_highlife()
666+
demo_oscillator()
667+
demo_randomized()
668+
demo_statistics()
789669

790-
try:
791-
rule_sets = [
792-
({"birth": {3}, "survival": {2, 3}, "name": "Conway B3/S23"}),
793-
({"birth": {2, 3}, "survival": {1, 2}, "name": "Dynamic B23/S12"}),
794-
({"birth": {1}, "survival": {1, 2}, "name": "Minimal B1/S12"}),
795-
]
796-
797-
fig, axes = plt.subplots(len(rule_sets), 4, figsize=(16, 3 * len(rule_sets)))
798-
if len(rule_sets) == 1:
799-
axes = axes.reshape(1, -1)
800-
801-
for i, rule_set in enumerate(rule_sets):
802-
print(f" Analyzing: {rule_set['name']}")
803-
804-
history = simulate_von_neumann_cellular_automaton(
805-
grid_rows=20,
806-
grid_columns=25,
807-
generations=30,
808-
birth_rules=rule_set["birth"],
809-
survival_rules=rule_set["survival"],
810-
maximum_cell_age=4,
811-
initial_alive_probability=0.25,
812-
random_seed=42,
813-
)
814-
815-
# Show generations 0, 10, 20, 29
816-
for j, gen_idx in enumerate([0, 10, 20, 29]):
817-
if gen_idx < len(history):
818-
im = axes[i, j].imshow(
819-
history[gen_idx],
820-
cmap=create_heatmap_colormap(4),
821-
vmin=0,
822-
vmax=4,
823-
)
824-
axes[i, j].set_title(f"Gen {gen_idx}")
825-
axes[i, j].set_xticks([])
826-
axes[i, j].set_yticks([])
827-
828-
# Label the row
829-
axes[i, 0].set_ylabel(rule_set["name"], rotation=90, va="center")
830-
831-
plt.suptitle("Rule Set Comparison", fontsize=16)
832-
plt.tight_layout()
833-
plt.show()
834-
835-
except Exception as e:
836-
print(f"❌ Error in Example 6: {e}")
837-
838-
print("\n" + "=" * 80)
839-
print("🎉 DEMONSTRATION COMPLETE!")
670+
print("=" * 80)
671+
print("Demonstration complete.")
840672
print("=" * 80)
841673

842674

@@ -879,12 +711,12 @@ def quick_demo(rule_name: str = "conway"):
879711
}
880712

881713
if rule_name not in rule_configs:
882-
print(f"Unknown rule set: {rule_name}")
714+
print(f"Unknown rule set: {rule_name}")
883715
print(f"Available: {', '.join(rule_configs.keys())}")
884716
return
885717

886718
config = rule_configs[rule_name]
887-
print(f"🎮 Running quick demo: {config['title']}")
719+
print(f"Running quick demo: {config['title']}")
888720

889721
try:
890722
run_interactive_simulation(
@@ -897,8 +729,8 @@ def quick_demo(rule_name: str = "conway"):
897729
animation_speed=150,
898730
show_static=True,
899731
)
900-
except Exception as e:
901-
print(f"Error running demo: {e}")
732+
except (ValueError, RuntimeError) as e:
733+
print(f"Error running demo: {e}")
902734

903735

904736
if __name__ == "__main__":

0 commit comments

Comments
 (0)