@@ -591,125 +591,80 @@ def run_interactive_simulation(
591
591
# -------------------------------------------------------------------------
592
592
593
593
594
- def demo_game_of_life () -> None :
595
- """
596
- Demonstrate Conway's Game of Life cellular automaton.
597
-
598
- This will open a matplotlib animation window.
599
-
600
- Examples
601
- --------
602
- >>> demo_game_of_life() # doctest: +SKIP
603
- """
604
- try :
605
- visualize_cellular_automaton (
606
- rule_b = [3 ],
607
- rule_s = [2 , 3 ],
608
- size = 50 ,
609
- steps = 100 ,
610
- title = "Game of Life (B3/S23)" ,
611
- )
612
- except (ValueError , RuntimeError ) as e :
613
- print (f"Error in Game of Life demo: { e } " )
614
-
615
-
616
- def demo_highlife () -> None :
617
- """
618
- Demonstrate the HighLife cellular automaton (B36/S23).
619
-
620
- This will open a matplotlib animation window.
621
-
622
- Examples
623
- --------
624
- >>> demo_highlife() # doctest: +SKIP
625
- """
626
- try :
627
- visualize_cellular_automaton (
628
- rule_b = [3 , 6 ],
629
- rule_s = [2 , 3 ],
630
- size = 50 ,
631
- steps = 100 ,
632
- title = "HighLife (B36/S23)" ,
633
- )
634
- except (ValueError , RuntimeError ) as e :
635
- print (f"Error in HighLife demo: { e } " )
636
-
637
-
638
- def demo_oscillator () -> None :
639
- """
640
- Demonstrate a simple oscillator pattern.
641
-
642
- This will open a matplotlib animation window.
643
-
644
- Examples
645
- --------
646
- >>> demo_oscillator() # doctest: +SKIP
647
- """
648
- try :
649
- initial_state = np .zeros ((10 , 10 ), dtype = int )
650
- initial_state [4 :7 , 5 ] = 1 # vertical line
651
- visualize_cellular_automaton (
652
- rule_b = [3 ],
653
- rule_s = [2 , 3 ],
654
- initial_state = initial_state ,
655
- steps = 10 ,
656
- title = "Oscillator: Blinker" ,
657
- )
658
- except (ValueError , RuntimeError ) as e :
659
- print (f"Error in Oscillator demo: { e } " )
594
+ def demo_game_of_life (size : int = 50 , steps : int = 100 ):
595
+ """Demo using Game of Life rules on a Von Neumann grid."""
596
+ initial_state = np .random .Generator (0 , 2 , size = (size , size ))
597
+ history = simulate_von_neumann_cellular_automaton (
598
+ initial_state , generations = steps ,
599
+ birth_rules = {3 }, survival_rules = {2 , 3 }
600
+ )
601
+ visualize_cellular_automaton (history )
660
602
661
603
662
- def demo_randomized () -> None :
663
- """
664
- Demonstrate a cellular automaton with randomized initial state.
604
+ def demo_highlife (size : int = 50 , steps : int = 100 ):
605
+ """Demo using HighLife rules (B36/S23)."""
606
+ initial_state = np .random .Generator (0 , 2 , size = (size , size ))
607
+ history = simulate_von_neumann_cellular_automaton (
608
+ initial_state , generations = steps ,
609
+ birth_rules = {3 , 6 }, survival_rules = {2 , 3 }
610
+ )
611
+ visualize_cellular_automaton (history )
665
612
666
- This will open a matplotlib animation window.
667
613
668
- Examples
669
- --------
670
- >>> demo_randomized() # doctest: +SKIP
671
- """
672
- try :
673
- visualize_cellular_automaton (
674
- rule_b = [2 ],
675
- rule_s = [2 , 3 ],
676
- size = 50 ,
677
- steps = 50 ,
678
- title = "Randomized Automaton (B2/S23)" ,
679
- )
680
- except (ValueError , RuntimeError ) as e :
681
- print (f"Error in Randomized demo: { e } " )
614
+ def demo_oscillator (steps : int = 20 ):
615
+ """Demo with a simple 3-cell Von Neumann oscillator pattern."""
616
+ size = 10
617
+ initial_state = np .zeros ((size , size ), dtype = int )
682
618
619
+ # A vertical 3-cell oscillator in the center
620
+ center = size // 2
621
+ initial_state [center - 1 , center ] = 1
622
+ initial_state [center , center ] = 1
623
+ initial_state [center + 1 , center ] = 1
683
624
684
- def demo_statistics () -> None :
685
- """
686
- Demonstrate cellular automaton population statistics.
625
+ history = simulate_von_neumann_cellular_automaton (
626
+ initial_state ,
627
+ generations = steps ,
628
+ birth_rules = {3 }, # Standard Game of Life birth rule
629
+ survival_rules = {2 , 3 } # Standard Game of Life survival rule
630
+ )
631
+ visualize_cellular_automaton (history )
687
632
688
- Prints population and density statistics to the console.
689
633
690
- Examples
691
- --------
692
- >>> demo_statistics() # doctest: +SKIP
693
- """
694
- try :
695
- final_state = visualize_cellular_automaton (
696
- rule_b = [3 ],
697
- rule_s = [2 , 3 ],
698
- size = 50 ,
699
- steps = 50 ,
700
- return_states = True ,
701
- )
702
- alive_counts = [np .sum (state ) for state in final_state ]
703
- density = [count / (50 * 50 ) * 100 for count in alive_counts ]
704
- average_population = f"{ np .mean (alive_counts ):.1f} cells"
705
-
706
- print ("Statistics Example:" )
707
- print (f"-Average population: { average_population } " )
708
- print (f"-Average density: { np .mean (density ):.1f} %" )
709
- print (f"-Max population: { np .max (alive_counts )} " )
710
- print (f"-Min population: { np .min (alive_counts )} " )
711
- except (ValueError , RuntimeError ) as e :
712
- print (f"Error in Statistics demo: { e } " )
634
+ def demo_random_rules (size : int = 50 , steps : int = 100 ):
635
+ """Demo with random birth/survival rules."""
636
+ birth_rules = set (
637
+ np .random .Generator (range (5 ),
638
+ size = np .random .Generator (1 , 5 ),
639
+ replace = False )
640
+ )
641
+ survival_rules = set (
642
+ np .random .Generator (range (5 ),
643
+ size = np .random .Generator (1 , 5 ),
644
+ replace = False )
645
+ )
646
+ initial_state = np .random .Generator (0 , 2 , size = (size , size ))
647
+ history = simulate_von_neumann_cellular_automaton (
648
+ initial_state , generations = steps ,
649
+ birth_rules = birth_rules , survival_rules = survival_rules
650
+ )
651
+ visualize_cellular_automaton (history )
652
+
653
+
654
+ def demo_statistics (size : int = 50 , steps : int = 100 ):
655
+ """Demo that plots live cell counts over time."""
656
+ initial_state = np .random .Generator (0 , 2 , size = (size , size ))
657
+ history = simulate_von_neumann_cellular_automaton (initial_state , generations = steps )
658
+
659
+ # collect statistics
660
+ live_counts = [np .sum (state > 0 ) for state in history ]
661
+ plt .figure (figsize = (6 , 4 ))
662
+ plt .plot (range (steps + 1 ), live_counts , label = 'Live Cells' )
663
+ plt .xlabel ("Generation" )
664
+ plt .ylabel ("Number of live cells" )
665
+ plt .title ("Cell Count Over Time" )
666
+ plt .legend ()
667
+ plt .show ()
713
668
714
669
715
670
# -------------------------------------------------------------------------
@@ -734,7 +689,7 @@ def demonstrate_cellular_automaton_features() -> None:
734
689
demo_game_of_life ()
735
690
demo_highlife ()
736
691
demo_oscillator ()
737
- demo_randomized ()
692
+ demo_random_rules ()
738
693
demo_statistics ()
739
694
740
695
print ("=" * 80 )
0 commit comments