#!/usr/bin/perl use 5.012; use warnings; use List::Util qw(shuffle); # initialize board my @cards = shuffle(2..99); my @hand = splice @cards, 0, 7; my @stacks = ([1], [1], [100], [100]); while () { # play two cards (if possible) for (0,1) { # show the stacks and the hand say "\n\n\tA\tB\tC\tD\t\t", ~~@cards, " cards"; for my $i (0..99) { my @row = map { $stacks[$_][$i] || " " } 0..3; (~~grep $_ ne " ", @row) ? say "\t", join "\t", @row : (say "\nhand: ", join ", ", sort {$a<=>$b} @hand) && last } # check if the game is lost exit say "=== YOU LOSE ===\n", "# Todo: ", @cards + @hand if sub { for my $c (@hand) { can_play($_, $c) && return 0 for @stacks } return 1 }->(); # read in the stack and the card to play my ($stack, $card); do { print "> "; ($stack, $card) = ~~ =~ /([AaBbCcDd])\s*(\d\d?)/; $stack = $stacks[ord(uc $stack) - ord "A"] if $card; } until $card && can_play($stack, $card) && grep $_ eq $card, @hand; # play the card push @$stack, $card; @hand = grep $_ ne $card, @hand; # check if the game is won exit !say "=== YOU WIN ===\n" if !(@cards + @hand); } # draw new cards push @hand, pop @cards while $#hand < 6 && @cards; } # respect the rules sub can_play { my ($stack, $card) = @_; my $top = $stack->[-1]; return $stack->[0] == 1 ? $top < $card || $card == $top - 10 : $top > $card || $card == $top + 10; } __END__ =pod =head1 The Game 100 =head2 Equipment Four stacks: A, B, C, and D. 102 cards: 1, 1, 100, 100, 2 .. 99. The back face of all cards is the same so that you cannot know the value if they are placed face-down on the table. =head2 Rules 1) Stacks A and B start with 1 and count up. 2) Stacks C and D start with 100 and count down. 3) The rest of the cards (2 .. 99) forms the deck and is shuffled and placed face-down on the table. 4) You start playing with seven cards. 5) Every round you need to play two cards (if possible). A card must increase/decrease the stack's value, or it must be exactly 10 off in the opposite direction. Example: A B C D 1 1 100 100 9 2 79 86 31 22 65 71 In this situation, you can play cards above 31 or the card 21 at A, cards above 22 or the card 12 at B, cards below 65 or the card 75 at C, and cards below 71 or the card 81 at D. 6) After playing two cards, you draw two cards from the deck. =head2 Winning the game You win when there are no more cards in the deck and when you hold no more cards in your hand. You lose if you cannot play any card. =head2 Instructions The stacks and your hand cards are displayed. You need to input the stack and the card from your hand that you want to play. A B C D 1 1 100 100 9 2 79 86 31 22 65 71 hand: 21, 23, 24, 57, 67, 88, 94 > Example inputs: > a 21 > a 57 > b 23 > c 57 > c 67 > d 24 =head1 Recovery If you want to pick up a prior game, here you are a snippet that you can execute before the game loop: chomp(my @lines = split "\n", < 1 } @hand; for my $stack (@stacks) { $out{$_} = 1 for @$stack; } @cards = grep { !$out{$_} } shuffle(2..99); =cut