💾 Archived View for thrig.me › blog › 2024 › 02 › 04 › state.pl captured on 2024-07-09 at 02:10:57.
⬅️ Previous capture (2024-02-05)
-=-=-=-=-=-=-
#!/usr/bin/env perl # state.pl - a silly game state example use 5.36.0; use constant { UPDATE => 0, RENDER => 1, ENTER => 2, EXIT => 3, }; my ( $Player_HP, $Troll_HP ); my $Is_Running = 1; my @Game_State; state_push( make_state( \&menu_update, \&menu_render ) ); while ($Is_Running) { $Game_State[-1][RENDER]->(); $Game_State[-1][UPDATE]->(); # no sleep because this blocks } exit(1); sub make_state ( $up, $rend, $enter = undef, $exit = undef ) { my $s; $s->@[ UPDATE, RENDER, ENTER, EXIT ] = ( $up, $rend, $enter, $exit ); return $s; } sub state_push ($new) { $new->[ENTER]->() if defined $new->[ENTER]; push @Game_State, $new; } sub state_pop { $Game_State[-1][EXIT]->() if defined $Game_State[-1][EXIT]; pop @Game_State; } sub menu_render { say qq{enter "play" or "quit"}; } sub menu_update { my $choice = readline; if ( $choice =~ m/(?i)p/ ) { state_push( make_state( \&game_update, \&game_render, \&game_enter ) ); } elsif ( $choice =~ m/(?i)q/ ) { $Is_Running = 0; } } sub game_enter { $Player_HP = 10; $Troll_HP = 10; } sub game_render { say qq{"attack" the troll or "flee"}; } sub game_update { my $choice = readline; if ( $choice =~ m/(?i)f/ ) { say qq{You find yourself back at the main menu...}; pop @Game_State; } elsif ( $choice =~ m/(?i)a/ ) { my $roll = int rand(5); say "You hit the troll for $roll generic damage units!"; $Troll_HP -= $roll; $roll = int rand(7); say "The troll hits you for $roll!"; $Player_HP -= $roll; if ( $Player_HP <= 0 ) { say qq{You die...}; say qq{... and so did the troll, congrats?} if $Troll_HP <= 0; state_pop(); return; } if ( $Troll_HP <= 0 ) { say qq{You win! (this time...)}; # this of course could instead go to a victory state or back # to the menu or whatever exit(0); } } }