Thread Kartenspielgolf (11 answers)
Opened by Matze at 2017-01-13 03:57

Gast Matze
 2017-01-13 03:57
#185839 #185839
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)

View full thread Kartenspielgolf