Replace given/when and smartmatch with LUTs and ifs
[mafia.git] / lib / Mafia.pm
index ada67d210e7278ce4ee11500ae04243fa19bc857..40eeaba1989f1932d71db666af4c0ccf79f324b2 100644 (file)
@@ -3,7 +3,6 @@ package Mafia;
 use 5.014000;
 use strict;
 use warnings;
-no if $] > 5.017011, warnings => 'experimental::smartmatch';
 use parent qw/Exporter/;
 
 use constant;
@@ -40,6 +39,12 @@ use constant +{
        GUNROLES => [vigilante, gunsmith],
 };
 
+my %ROLE_HASH = map { $_ => 1 } @{ROLE()};
+my %FACTION_HASH = map { $_ => 1 } @{FACTION()};
+my %FLAG_HASH = map { $_ => 1 } @{FLAG()};
+my %INVESTIGATIVE_ACTIONS_HASH = map { $_ => 1 } @{INVESTIGATIVE_ACTIONS()};
+my %GUNROLES_HASH = map { $_ => 1 } @{GUNROLES()};
+
 our @EXPORT = do {
        no strict 'refs';
        grep { $_ !~ [qw/import/] and exists &$_ } keys %{__PACKAGE__ . '::'};
@@ -96,78 +101,80 @@ sub rolename {
 
 sub msg {
        my ($type, @args) = @_;
-       given ($type){
-               when (MSG_NIGHT) {
+       my %msg_lut = (
+               MSG_NIGHT => sub {
                        my ($night) = @args;
                        say '' unless $first;
                        $first = 0;
                        say "It is Night $night";
-               }
+               },
 
-               when (MSG_DAY) {
+               MSG_DAY => sub {
                        my ($day) = @args;
                        say '' unless $first;
                        $first = 0;
                        say "It is Day $day";
-               }
+               },
 
-               when (MSG_PLAYERS_ALIVE) {
+               MSG_PLAYERS_ALIVE => sub {
                        @args = sort @args;
                        say "Players alive: ", join ', ', @args
-               }
+               },
 
-               when (MSG_DEATH) {
+               MSG_DEATH => sub {
                        my %args = @args;
                        my ($who, $reason) = @args{'target', 'reason'};
                        my $phase = phase;
                        my $rolename = rolename $who;
                        say "$who ($rolename) — $reason $phase";
-               }
+               },
 
-               when (MSG_GUNCHECK) {
+               MSG_GUNCHECK => sub {
                        my %args = @args;
                        my ($gunsmith, $who, $hasgun) = @args{'source', 'target', 'result'};
                        say "$gunsmith: $who has a gun" if $hasgun;
                        say "$gunsmith: $who does not have a gun" unless $hasgun;
-               }
+               },
 
-               when (MSG_NORESULT) {
+               MSG_NORESULT => sub {
                        my %args = @args;
                        my ($who) = $args{'source'};
                        say "$who: No result"
-               }
+               },
 
-               when (MSG_TRACK) {
+               MSG_TRACK => sub {
                        my %args = @args;
                        my ($tracker, $who, $result) = @args{'source', 'target', 'result'};
                        my @result = @{$result};
                        local $, = ', ';
                        say "$tracker: $who did not visit anyone" unless scalar @result;
                        say "$tracker: $who visited: @result" if scalar @result;
-               }
+               },
 
-               when (MSG_WATCH) {
+               MSG_WATCH => sub {
                        my %args = @args;
                        my ($watcher, $who, $result) = @args{'source', 'target', 'result'};
                        my @result = @{$result};
                        local $, = ', ';
                        say "$watcher: $who was not visited by anyone" unless scalar @result;
                        say "$watcher: $who was visited by: @result" if scalar @result;
-               }
+               },
 
-               when (MSG_ROLECOP) {
+               MSG_ROLECOP => sub {
                        my %args = @args;
                        my ($rolecop, $who, $role) = @args{'source', 'target', 'result'};
                        say "$rolecop: $who\'s role is: $role"
-               }
+               },
 
-               when (MSG_COP) {
+               MSG_COP => sub {
                        my %args = @args;
                        my ($cop, $who, $ismafia) = @args{'source', 'target', 'result'};
                        say "$cop: $who is mafia" if $ismafia;
                        say "$cop: $who is not mafia" unless $ismafia;
-               }
-       }
+               },
+       );
+
+       $msg_lut{$type}->();
 }
 
 sub putaction {
@@ -207,14 +214,13 @@ sub doaction {
                my $hidden = $tplayers{$target}{hidden};
                my $hidepierce = $args{hidepierce};
                if ($source && (( $roleblocked && !$strongkill ) || ($hidden && !$hidepierce) )) {
-                       msg MSG_NORESULT, %args if $type ~~ INVESTIGATIVE_ACTIONS;
+                       msg MSG_NORESULT, %args if $INVESTIGATIVE_ACTIONS_HASH{$type};
                        return
                }
        }
 
-
-       given ($type) {
-               when(ACT_KILL) {
+       my %act_lut = (
+               ACT_KILL => sub {
                        break if $tplayers{$target}{bulletproof} && defined $source;
                        if ($tplayers{$target}{guard_count} && defined $source) {
                                $tplayers{$target}{guard_count}--;
@@ -229,9 +235,9 @@ sub doaction {
                        }
                        msg MSG_DEATH, %args;
                        delete $players{$target}
-               }
+               },
 
-               when(ACT_LYNCH){
+               ACT_LYNCH => sub {
                        if ($tplayers{$target}{guard_count}) {
                                $tplayers{$target}{guard_count}--;
                                $args{target} = shift @{$tplayers{$target}{guards}};
@@ -243,56 +249,58 @@ sub doaction {
                        }
                        msg MSG_DEATH, %args, reason => 'lynched';
                        delete $players{$target}
-               }
+               },
 
-               when(ACT_PROTECT){
+               ACT_PROTECT => sub {
                        my $count = $args{count} // 1;
                        $tplayers{$target}{protection} += $count unless $tplayers{$target}{macho}
-               }
+               },
 
-               when(ACT_ROLEBLOCK){
+               ACT_ROLEBLOCK => sub {
                        $tplayers{$target}{roleblocked} = 1
-               }
+               },
 
-               when(ACT_GUNCHECK){
+               ACT_GUNCHECK => sub {
                        my $role = $players{$target}{role};
-                       my $hasgun = $role ~~ GUNROLES || ($players{$target}{faction} eq mafia && $role ne doctor);
+                       my $hasgun = $GUNROLES_HASH{$role} || ($players{$target}{faction} eq mafia && $role ne doctor);
                        msg MSG_GUNCHECK, %args, result => $hasgun
-               }
+               },
 
-               when(ACT_TRACK_RESULT){
+               ACT_TRACK_RESULT => sub {
                        msg MSG_TRACK, %args, result => [ uniq @{$tplayers{$target}{targets} // []} ];
-               }
+               },
 
-               when(ACT_WATCH_RESULT){
+               ACT_WATCH_RESULT => sub {
                        msg MSG_WATCH, %args, result => [ uniq @{$tplayers{$target}{sources} // []} ];
-               }
+               },
 
-               when(ACT_GUARD){
+               ACT_GUARD => sub {
                        $tplayers{$target}{guard_count}++;
                        $tplayers{$target}{guards} //= [];
                        push @{$tplayers{$target}{guards}}, $source;
-               }
+               },
 
-               when(ACT_ROLECOP){
+               ACT_ROLECOP => sub {
                        my $result = $players{$target}{role};
                        $result = vanilla if $result eq goon;
                        msg MSG_ROLECOP, %args, result => ucfirst $result
-               }
+               },
 
-               when(ACT_COP){
+               ACT_COP => sub {
                        my $result = $players{$target}{faction} eq mafia;
                        $result = 1 if $players{$target}{miller};
                        $result = 0 if $players{$target}{godfather};
                        msg MSG_COP, %args, result => $result
-               }
+               },
 
-               when(ACT_HIDE){
+               ACT_HIDE => sub {
                        $tplayers{$source}{hidden} = 1;
                        $tplayers{$target}{hiders} //= [];
                        push @{$tplayers{$target}{hiders}}, $source
-               }
-       }
+               },
+       );
+
+       $act_lut{$type}->();
 }
 
 sub process_phase_change {
@@ -309,11 +317,9 @@ sub player {
        my ($name, @args) = @_;
        my %player;
        for my $trait (@args) {
-               given ($trait) {
-                       $player{role} = $trait when ROLE;
-                       $player{faction} = $trait when FACTION;
-                       $player{$trait} = 1 when FLAG;
-               }
+               $player{role} = $trait    if $ROLE_HASH{$trait};
+               $player{faction} = $trait if $FACTION_HASH{$trait};
+               $player{$trait} = 1       if $FLAG_HASH{$trait};
        }
 
        $players{$name} = \%player;
This page took 0.01607 seconds and 4 git commands to generate.