Thread Kartenspielgolf
(11 answers)
Opened by Matze at 2017-01-13 03:57
Nabend, ich hatte gerade Lust zu Golfen, möchte das Ergebnis gerne teilen, und erwarte mit einer kürzeren Version konfrontiert zu werden ;-)
Hier das Kartenspiel "The Game 100" für einen Spieler auf der Konsole (730B): Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 #!/usr/bin/perl use 5.012;use warnings;use List::Util qw(shuffle);my@c=shuffle(2..99);my@h= splice@c,0,7;my@s=([1],[1],[100],[100]);while(){for(0,1){say "\n\n\tA\tB\tC\tD\t\t",~~@c," cards";for my$i(0..99){my@s=map{$s[$_][$i]||" " }0..3;(~~grep$_ ne" ",@s)?say"\t",join"\t",@s:(say"\nhand: ",join", ",sort{$a <=>$b}@h)&&last}exit say"=== YOU LOSE ===\n","# Todo: ",@c+@h if sub{for my$c (@h){p($_,$c)&&return 0for@s}1}->();my($s,$c);do{print"> ";($s,$c)= ~~<STDIN> =~/([AaBbCcDd])\s*(\d\d?)/;$s=$s[ord(uc$s)-ord"A"]if$c}until$c&&p($s,$c)&& grep$_ eq$c,@h;push@$s,$c;@h=grep$_ ne$c,@h;exit!say"=== YOU WIN ===\n"if!( @c+@h)}push@h,pop@c while$#h<6&&@c}sub p{my($s,$c)=@_;my$t=$s->[-1];$s->[0]== 1?$t<$c||$c==$t-10:$t>$c||$c==$t+10} Und eine lesbare Variante mit Erklärung zum Spiel (pod): Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 #!/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) = ~~<STDIN> =~ /([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", <<OUTPUT); A B C D 85 cards 1 1 100 100 17 87 47 50 94 48 95 hand: 55, 61, 67, 74, 79, 82 OUTPUT for my $line (@lines) { if ($line =~ /\A {8}(\d{1,3}| ) {5,7}(\d{1,3}| ) {5,7}(\d{1,3}| ) {5,7}(\d{1,3}| )\z/) { my ($A, $B, $C, $D) = ($1, $2, $3, $4); next if grep { $_ eq 1 or $_ eq 100 } $A, $B, $C, $D; push @{ $stacks[0] }, $A if $A !~ /\s/; push @{ $stacks[1] }, $B if $B !~ /\s/; push @{ $stacks[2] }, $C if $C !~ /\s/; push @{ $stacks[3] }, $D if $D !~ /\s/; } elsif ($line =~ /hand: (\d\d?(?:, \d\d?)*)/) { my ($hand) = ($1); @hand = $hand =~ /(\d\d?)/g; } } my %out = map { $_ => 1 } @hand; for my $stack (@stacks) { $out{$_} = 1 for @$stack; } @cards = grep { !$out{$_} } shuffle(2..99); =cut Es ist noch ganz frisch, daher muss ich eventuell noch ein paar Fehler finden. In meinen Tests hat bislang aber alles funktioniert wie erwartet. Falls jemand noch andere Kartenspiele kennt -- z.B. auch für Zweispieler (an der selben Tastatur) --, die sich gut zum Golfen eignen, würde ich mich über Vorschläge freuen :-) best regards, Matze Last edited: 2017-01-13 08:17:04 +0100 (CET) |