| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Game::Cribbage; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = "0.12"; |
|
4
|
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
130082
|
use Rope; |
|
|
1
|
|
|
|
|
15334
|
|
|
|
1
|
|
|
|
|
8
|
|
|
6
|
1
|
|
|
1
|
|
1019
|
use Rope::Autoload; |
|
|
1
|
|
|
|
|
4192
|
|
|
|
1
|
|
|
|
|
8
|
|
|
7
|
1
|
|
|
1
|
|
759
|
use Game::Cribbage::Board; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
3789
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
prototyped 'board' => undef, dealer => undef, crib_set => 0, starter_card => undef; |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
sub start { |
|
12
|
0
|
|
|
0
|
1
|
|
my ($self, %params) = @_; |
|
13
|
|
|
|
|
|
|
|
|
14
|
0
|
|
|
|
|
|
$self->clear_screen; |
|
15
|
|
|
|
|
|
|
|
|
16
|
0
|
|
|
|
|
|
$self->print_header("Welcome to terminal Cribbage"); |
|
17
|
|
|
|
|
|
|
|
|
18
|
0
|
|
|
|
|
|
$self->print_footer("Insert name: "); |
|
19
|
|
|
|
|
|
|
|
|
20
|
0
|
|
|
|
|
|
my $name = ; |
|
21
|
|
|
|
|
|
|
|
|
22
|
0
|
|
|
|
|
|
chomp($name); |
|
23
|
|
|
|
|
|
|
|
|
24
|
0
|
|
|
|
|
|
my $board = Game::Cribbage::Board->new(); |
|
25
|
|
|
|
|
|
|
|
|
26
|
0
|
|
|
|
|
|
$board->add_player(name => 'Bot'); |
|
27
|
0
|
|
|
|
|
|
$board->add_player(name => $name); |
|
28
|
|
|
|
|
|
|
|
|
29
|
0
|
|
|
|
|
|
$board->start_game(); |
|
30
|
|
|
|
|
|
|
|
|
31
|
0
|
|
|
|
|
|
$self->board = $board; |
|
32
|
|
|
|
|
|
|
|
|
33
|
0
|
|
|
|
|
|
$self->init_game(); |
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub init_game { |
|
37
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
38
|
|
|
|
|
|
|
|
|
39
|
0
|
|
|
|
|
|
$self->clear_screen; |
|
40
|
|
|
|
|
|
|
|
|
41
|
0
|
|
|
|
|
|
$self->reset_cursor(); |
|
42
|
|
|
|
|
|
|
|
|
43
|
0
|
|
|
|
|
|
$self->split_cards(); |
|
44
|
|
|
|
|
|
|
|
|
45
|
0
|
|
|
|
|
|
$self->init_draw(); |
|
46
|
|
|
|
|
|
|
} |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub init_draw { |
|
49
|
0
|
|
|
0
|
1
|
|
my ($self, $switch) = @_; |
|
50
|
|
|
|
|
|
|
|
|
51
|
0
|
|
|
|
|
|
$self->crib_set = 0; |
|
52
|
0
|
|
|
|
|
|
$self->starter_card = undef; |
|
53
|
0
|
0
|
|
|
|
|
$self->dealer = !$self->dealer if $switch; |
|
54
|
|
|
|
|
|
|
|
|
55
|
0
|
|
|
|
|
|
my $winner; |
|
56
|
0
|
0
|
|
|
|
|
if ($self->board->score->player1->{current} > 120) { |
|
|
|
0
|
|
|
|
|
|
|
57
|
0
|
|
|
|
|
|
$winner = 'player1'; |
|
58
|
|
|
|
|
|
|
} elsif ($self->board->score->player2->{current} > 120) { |
|
59
|
0
|
|
|
|
|
|
$winner = 'player2'; |
|
60
|
|
|
|
|
|
|
} |
|
61
|
0
|
0
|
|
|
|
|
return $self->winner($winner) if $winner; |
|
62
|
|
|
|
|
|
|
|
|
63
|
0
|
|
|
|
|
|
$self->draw_cards(); |
|
64
|
|
|
|
|
|
|
|
|
65
|
0
|
|
|
|
|
|
$self->discard_cards(); |
|
66
|
|
|
|
|
|
|
|
|
67
|
0
|
|
|
|
|
|
$self->starter(); |
|
68
|
|
|
|
|
|
|
|
|
69
|
0
|
|
|
|
|
|
while (!$winner) { |
|
70
|
0
|
|
|
|
|
|
$self->clear_screen(); |
|
71
|
|
|
|
|
|
|
|
|
72
|
0
|
|
|
|
|
|
$self->print_header(q|It is your turn to play a card, type go if you're unable to play.|); |
|
73
|
|
|
|
|
|
|
|
|
74
|
0
|
|
|
|
|
|
my $ok = eval { $self->play_hand(); }; |
|
|
0
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
|
|
76
|
0
|
0
|
|
|
|
|
unless ($@) { |
|
77
|
0
|
0
|
|
|
|
|
if ($self->board->score->player1->{current} > 120) { |
|
|
|
0
|
|
|
|
|
|
|
78
|
0
|
|
|
|
|
|
$winner = 'player1'; |
|
79
|
0
|
|
|
|
|
|
next; |
|
80
|
|
|
|
|
|
|
} elsif ($self->board->score->player2->{current} > 120) { |
|
81
|
0
|
|
|
|
|
|
$winner = 'player2'; |
|
82
|
0
|
|
|
|
|
|
next; |
|
83
|
|
|
|
|
|
|
} |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
|
|
86
|
0
|
|
|
|
|
|
my $hands = $self->board->get_hands; |
|
87
|
0
|
0
|
|
|
|
|
unless (grep { !$_->{used} } @{$hands->player2->cards}, @{$hands->player1->cards}) { |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
88
|
0
|
|
|
|
|
|
eval { |
|
89
|
0
|
|
|
|
|
|
$self->end_hands(); |
|
90
|
|
|
|
|
|
|
}; |
|
91
|
0
|
0
|
|
|
|
|
if ($@) { |
|
92
|
0
|
|
|
|
|
|
while (1) { |
|
93
|
0
|
|
|
|
|
|
print $@; |
|
94
|
|
|
|
|
|
|
} |
|
95
|
|
|
|
|
|
|
} |
|
96
|
0
|
|
|
|
|
|
return $self->init_draw(1); |
|
97
|
|
|
|
|
|
|
} |
|
98
|
|
|
|
|
|
|
|
|
99
|
0
|
0
|
|
|
|
|
if ($self->board->no_player_can_play) { |
|
100
|
0
|
|
|
|
|
|
eval { $self->board->next_play(); }; |
|
|
0
|
|
|
|
|
|
|
|
101
|
0
|
0
|
|
|
|
|
if ($@) { |
|
102
|
0
|
|
|
|
|
|
while (1) { |
|
103
|
0
|
|
|
|
|
|
print $@; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
} |
|
109
|
0
|
|
|
|
|
|
$self->winner($winner); |
|
110
|
|
|
|
|
|
|
} |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub end_hands { |
|
113
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
114
|
|
|
|
|
|
|
|
|
115
|
0
|
|
|
|
|
|
$self->board->end_play(); |
|
116
|
|
|
|
|
|
|
|
|
117
|
0
|
|
|
|
|
|
my $hands = $self->board->get_hands; |
|
118
|
|
|
|
|
|
|
|
|
119
|
0
|
|
|
|
|
|
$self->board->end_hands(); |
|
120
|
|
|
|
|
|
|
|
|
121
|
0
|
|
|
|
|
|
$self->crib_set = 0; |
|
122
|
|
|
|
|
|
|
|
|
123
|
0
|
|
|
|
|
|
$self->clear_screen(); |
|
124
|
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
|
my $last = $self->board->last_round_hands(); |
|
126
|
0
|
|
|
|
|
|
my $player1_score = $last->player1->score->total_score; |
|
127
|
0
|
|
|
|
|
|
my $player2_score = $last->player2->score->total_score; |
|
128
|
0
|
0
|
|
|
|
|
my $crib_player = $self->dealer ? $self->board->players->[-1]->name : 'Bot'; |
|
129
|
0
|
0
|
|
|
|
|
my $crib_score = $last->{$self->dealer ? 'player2' : 'player1'}->crib_score->total_score; |
|
130
|
|
|
|
|
|
|
|
|
131
|
0
|
|
|
|
|
|
$self->print_header(sprintf "Bot scored: %s - %s scored: %s - %s crib scored: %s", |
|
132
|
|
|
|
|
|
|
$player1_score, |
|
133
|
|
|
|
|
|
|
$self->board->players->[-1]->name, |
|
134
|
|
|
|
|
|
|
$player2_score, |
|
135
|
|
|
|
|
|
|
$crib_player, |
|
136
|
|
|
|
|
|
|
$crib_score |
|
137
|
|
|
|
|
|
|
); |
|
138
|
|
|
|
|
|
|
|
|
139
|
0
|
|
|
|
|
|
$self->draw_scores(); |
|
140
|
|
|
|
|
|
|
|
|
141
|
0
|
|
|
|
|
|
$self->render_player_cards($hands->player1->cards, 3, 20, 1); |
|
142
|
|
|
|
|
|
|
|
|
143
|
0
|
|
|
|
|
|
$self->render_player_cards($hands->{$hands->crib_player}->crib, 15, 20, 1); |
|
144
|
|
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
|
$self->render_player_cards($hands->player2->cards, 26, 20, 1); |
|
146
|
|
|
|
|
|
|
|
|
147
|
0
|
|
|
|
|
|
$self->print_footer(q|Press enter to continue|); |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
|
|
150
|
0
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
sub play_hand { |
|
153
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
154
|
|
|
|
|
|
|
|
|
155
|
0
|
|
|
|
|
|
my $hands = $self->board->get_hands; |
|
156
|
|
|
|
|
|
|
|
|
157
|
0
|
0
|
|
|
|
|
if ($self->board->next_to_play->player eq 'player1') { |
|
158
|
0
|
|
|
|
|
|
my $card = $self->board->best_run_play('player1'); |
|
159
|
0
|
0
|
|
|
|
|
if ($card->go) { |
|
160
|
0
|
|
|
|
|
|
$self->board->cannot_play('player1'); |
|
161
|
0
|
|
|
|
|
|
$self->draw_go(6, 2); |
|
162
|
|
|
|
|
|
|
} else { |
|
163
|
0
|
|
|
|
|
|
$self->board->play_card('player1', $card); |
|
164
|
0
|
0
|
|
|
|
|
if ($self->board->current_play_score == 31) { |
|
165
|
0
|
|
|
|
|
|
$self->board->next_play(); |
|
166
|
0
|
|
|
|
|
|
return; |
|
167
|
|
|
|
|
|
|
} |
|
168
|
|
|
|
|
|
|
|
|
169
|
0
|
0
|
|
|
|
|
if ($self->board->score->player1->{current} > 120) { |
|
170
|
0
|
|
|
|
|
|
return; |
|
171
|
|
|
|
|
|
|
} |
|
172
|
|
|
|
|
|
|
} |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
|
|
175
|
0
|
0
|
|
|
|
|
if ($self->board->player_cannot_play('player2')) { |
|
176
|
0
|
0
|
|
|
|
|
if (!$self->board->player_cannot_play('player1')) { |
|
177
|
0
|
|
|
|
|
|
$self->board->set_next_to_play('player1'); |
|
178
|
|
|
|
|
|
|
} |
|
179
|
0
|
|
|
|
|
|
return; |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
|
|
182
|
0
|
|
|
|
|
|
$_[0]->draw_scores(); |
|
183
|
|
|
|
|
|
|
|
|
184
|
0
|
|
|
|
|
|
$self->render_opponent_cards(scalar grep { !$_->{used} } @{$hands->player1->cards}); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
|
|
186
|
0
|
|
|
|
|
|
$self->render_run_play(); |
|
187
|
|
|
|
|
|
|
|
|
188
|
0
|
|
|
|
|
|
$self->render_player_cards($hands->player2->cards, 26, 20); |
|
189
|
|
|
|
|
|
|
|
|
190
|
0
|
|
|
|
|
|
$self->print_footer(q|Pick a card: |); |
|
191
|
|
|
|
|
|
|
|
|
192
|
0
|
|
|
|
|
|
my $number = ; |
|
193
|
|
|
|
|
|
|
|
|
194
|
0
|
|
|
|
|
|
chomp($number); |
|
195
|
|
|
|
|
|
|
|
|
196
|
0
|
0
|
|
|
|
|
if ($number =~ m/go/i) { |
|
197
|
0
|
|
|
|
|
|
my @can = $self->board->cannot_play('player2'); |
|
198
|
0
|
0
|
0
|
|
|
|
if (scalar @can && ref $can[0]) { |
|
199
|
0
|
|
|
|
|
|
return; |
|
200
|
|
|
|
|
|
|
} |
|
201
|
0
|
|
|
|
|
|
$self->draw_go(30); |
|
202
|
0
|
|
|
|
|
|
return; |
|
203
|
|
|
|
|
|
|
} |
|
204
|
|
|
|
|
|
|
|
|
205
|
0
|
0
|
|
|
|
|
if ($number eq 'b') { |
|
206
|
0
|
|
|
|
|
|
my $card = $self->board->best_run_play('player2'); |
|
207
|
0
|
0
|
|
|
|
|
if ($card->go) { |
|
208
|
0
|
|
|
|
|
|
$self->board->cannot_play('player2'); |
|
209
|
0
|
|
|
|
|
|
$self->draw_go(6, 2); |
|
210
|
|
|
|
|
|
|
} else { |
|
211
|
0
|
|
|
|
|
|
$self->board->play_card('player2', $card); |
|
212
|
0
|
0
|
|
|
|
|
if ($self->board->current_play_score == 31) { |
|
213
|
0
|
|
|
|
|
|
$self->board->next_play(); |
|
214
|
|
|
|
|
|
|
} |
|
215
|
|
|
|
|
|
|
} |
|
216
|
0
|
|
|
|
|
|
return; |
|
217
|
|
|
|
|
|
|
} |
|
218
|
|
|
|
|
|
|
|
|
219
|
0
|
0
|
0
|
|
|
|
if ($number !~ m/^\d+$/ || $number > scalar @{$hands->player2->cards}) { |
|
|
0
|
|
|
|
|
|
|
|
220
|
0
|
|
|
|
|
|
return; |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
|
|
223
|
0
|
|
|
|
|
|
my $card = $self->board->get_card('player2', $number - 1); |
|
224
|
0
|
|
|
|
|
|
$self->board->play_card('player2', $card); |
|
225
|
|
|
|
|
|
|
|
|
226
|
0
|
0
|
|
|
|
|
if ($self->board->current_play_score == 31) { |
|
227
|
0
|
|
|
|
|
|
$self->board->next_play(); |
|
228
|
|
|
|
|
|
|
} |
|
229
|
|
|
|
|
|
|
|
|
230
|
0
|
|
|
|
|
|
return 1; |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
sub split_cards { |
|
234
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
235
|
|
|
|
|
|
|
|
|
236
|
0
|
|
|
|
|
|
$self->print_header(q|Split cards lowest goes first|); |
|
237
|
|
|
|
|
|
|
|
|
238
|
0
|
|
|
|
|
|
$self->show_face_down_split(52); |
|
239
|
|
|
|
|
|
|
|
|
240
|
0
|
|
|
|
|
|
$self->print_footer(q|Pick a number: |); |
|
241
|
|
|
|
|
|
|
|
|
242
|
0
|
|
|
|
|
|
my $number = ; |
|
243
|
|
|
|
|
|
|
|
|
244
|
0
|
0
|
0
|
|
|
|
if ($number !~ m/^\d+$/ || $number > 52) { |
|
245
|
0
|
|
|
|
|
|
$self->clear_screen(); |
|
246
|
0
|
|
|
|
|
|
$self->split_cards(); |
|
247
|
0
|
|
|
|
|
|
return; |
|
248
|
|
|
|
|
|
|
} |
|
249
|
|
|
|
|
|
|
|
|
250
|
0
|
|
|
|
|
|
my $low = $self->board->deck->get($number - 1); |
|
251
|
|
|
|
|
|
|
|
|
252
|
0
|
|
|
|
|
|
my $rand = int(rand(52)); |
|
253
|
|
|
|
|
|
|
|
|
254
|
0
|
|
|
|
|
|
while ($number == $rand) { |
|
255
|
0
|
|
|
|
|
|
$rand = int(rand(52)); |
|
256
|
|
|
|
|
|
|
} |
|
257
|
|
|
|
|
|
|
|
|
258
|
0
|
|
|
|
|
|
my $bot = $self->board->deck->get($rand - 1); |
|
259
|
|
|
|
|
|
|
|
|
260
|
0
|
|
|
|
|
|
$self->clear_screen(); |
|
261
|
|
|
|
|
|
|
|
|
262
|
0
|
0
|
|
|
|
|
my $dealer = $low->value < $bot->value ? 1 : 0; |
|
263
|
|
|
|
|
|
|
|
|
264
|
0
|
0
|
|
|
|
|
$self->print_header(q|Low cards picked, | . ($dealer ? "you are the dealer" : "they are the dealer")); |
|
265
|
|
|
|
|
|
|
|
|
266
|
0
|
|
|
|
|
|
$self->render_card($bot, 2, 45); |
|
267
|
|
|
|
|
|
|
|
|
268
|
0
|
|
|
|
|
|
$self->render_card($low, 27, 45); |
|
269
|
|
|
|
|
|
|
|
|
270
|
0
|
0
|
|
|
|
|
$self->board->set_crib_player($dealer ? 'player2' : 'player1'); |
|
271
|
|
|
|
|
|
|
|
|
272
|
0
|
|
|
|
|
|
$self->print_footer(q|Press enter to continue|); |
|
273
|
|
|
|
|
|
|
|
|
274
|
0
|
|
|
|
|
|
$self->dealer = $dealer; |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
|
|
277
|
0
|
|
|
|
|
|
} |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
sub draw_cards { |
|
280
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
281
|
|
|
|
|
|
|
|
|
282
|
0
|
|
|
|
|
|
$self->board->draw_hands(); |
|
283
|
|
|
|
|
|
|
} |
|
284
|
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
sub discard_cards { |
|
286
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
287
|
|
|
|
|
|
|
|
|
288
|
0
|
|
|
|
|
|
$self->clear_screen(); |
|
289
|
|
|
|
|
|
|
|
|
290
|
0
|
|
|
|
|
|
$self->print_header(q|Discard two cards to the crib, seperate the indexes with a space.|); |
|
291
|
|
|
|
|
|
|
|
|
292
|
0
|
|
|
|
|
|
my $hands = $self->board->get_hands; |
|
293
|
|
|
|
|
|
|
|
|
294
|
0
|
|
|
|
|
|
$self->render_opponent_cards(6); |
|
295
|
|
|
|
|
|
|
|
|
296
|
0
|
|
|
|
|
|
$self->render_player_cards($hands->player2->cards, 26, 5); |
|
297
|
|
|
|
|
|
|
|
|
298
|
0
|
|
|
|
|
|
$self->print_footer(q|Discard cards: |); |
|
299
|
|
|
|
|
|
|
|
|
300
|
0
|
|
|
|
|
|
my $cards_index = ; |
|
301
|
|
|
|
|
|
|
|
|
302
|
0
|
|
|
|
|
|
chomp($cards_index); |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
my @cards = map { |
|
305
|
0
|
|
|
|
|
|
$self->board->get_card('player2', $_ - 1); |
|
306
|
0
|
0
|
|
|
|
|
} grep { $_ =~ m/^\d+$/ && $_ <= 6 } split " ", $cards_index; |
|
|
0
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
|
|
308
|
0
|
0
|
|
|
|
|
unless (scalar @cards == 2) { |
|
309
|
0
|
|
|
|
|
|
$self->discard_cards(); |
|
310
|
0
|
|
|
|
|
|
return; |
|
311
|
|
|
|
|
|
|
} |
|
312
|
|
|
|
|
|
|
|
|
313
|
0
|
|
|
|
|
|
$self->board->crib_player_cards('player2', \@cards); |
|
314
|
|
|
|
|
|
|
|
|
315
|
0
|
|
|
|
|
|
my @bot = $self->board->identify_worst_cards('player1'); |
|
316
|
|
|
|
|
|
|
|
|
317
|
0
|
|
|
|
|
|
$self->board->crib_player_cards('player1', $bot[0]); |
|
318
|
|
|
|
|
|
|
|
|
319
|
0
|
|
|
|
|
|
$self->crib_set = 1; |
|
320
|
|
|
|
|
|
|
} |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
sub starter { |
|
323
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
324
|
|
|
|
|
|
|
|
|
325
|
0
|
|
|
|
|
|
$self->clear_screen(); |
|
326
|
|
|
|
|
|
|
|
|
327
|
0
|
|
|
|
|
|
my $count = scalar @{$self->board->deck->{deck}}; |
|
|
0
|
|
|
|
|
|
|
|
328
|
0
|
0
|
|
|
|
|
if ($self->dealer) { |
|
329
|
0
|
|
|
|
|
|
my $card = $self->board->deck->get(int(rand(39))); |
|
330
|
0
|
|
|
|
|
|
$self->starter_card = $card; |
|
331
|
0
|
|
|
|
|
|
$self->board->add_starter_card('player1', $card); |
|
332
|
0
|
|
|
|
|
|
return; |
|
333
|
|
|
|
|
|
|
} |
|
334
|
|
|
|
|
|
|
|
|
335
|
0
|
|
|
|
|
|
$self->print_header(q|Split deck for starter card.|); |
|
336
|
|
|
|
|
|
|
|
|
337
|
0
|
|
|
|
|
|
$self->show_face_down_split(40, 13); |
|
338
|
|
|
|
|
|
|
|
|
339
|
0
|
|
|
|
|
|
$self->print_footer(q|Split deck: |); |
|
340
|
|
|
|
|
|
|
|
|
341
|
0
|
|
|
|
|
|
my $number = ; |
|
342
|
|
|
|
|
|
|
|
|
343
|
0
|
|
|
|
|
|
chomp($number); |
|
344
|
|
|
|
|
|
|
|
|
345
|
0
|
0
|
0
|
|
|
|
if ($number !~ m/^\d+$/ || $number > 52) { |
|
346
|
0
|
|
|
|
|
|
$self->clear_screen(); |
|
347
|
0
|
|
|
|
|
|
$self->starter(); |
|
348
|
0
|
|
|
|
|
|
return; |
|
349
|
|
|
|
|
|
|
} |
|
350
|
|
|
|
|
|
|
|
|
351
|
0
|
|
|
|
|
|
my $card = $self->board->deck->get($number); |
|
352
|
0
|
|
|
|
|
|
$self->starter_card = $card; |
|
353
|
0
|
|
|
|
|
|
my $scored = $self->board->add_starter_card('player2', $card); |
|
354
|
0
|
|
|
|
|
|
return; |
|
355
|
|
|
|
|
|
|
} |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub render_card { |
|
358
|
0
|
|
|
0
|
1
|
|
my ($self, $card, $row, $col) = @_; |
|
359
|
|
|
|
|
|
|
|
|
360
|
0
|
|
|
|
|
|
$self->set_cursor_vertical($row); |
|
361
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal($col); |
|
362
|
0
|
0
|
|
|
|
|
my $color = $card->suit =~ m/H|D/ ? 91 : 90; |
|
363
|
|
|
|
|
|
|
|
|
364
|
0
|
|
|
|
|
|
my %suits = ( |
|
365
|
|
|
|
|
|
|
H => '♥', |
|
366
|
|
|
|
|
|
|
D => '♦', |
|
367
|
|
|
|
|
|
|
C => '♣', |
|
368
|
|
|
|
|
|
|
S => '♠' |
|
369
|
|
|
|
|
|
|
); |
|
370
|
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
my @card = ( |
|
372
|
|
|
|
|
|
|
"┌─────────┐", |
|
373
|
|
|
|
|
|
|
sprintf("│%s. . . .│", $card->symbol =~ m/10/ ? $card->symbol : $card->symbol . " "), |
|
374
|
|
|
|
|
|
|
"│. . . . .│", |
|
375
|
|
|
|
|
|
|
"│. . . . .│", |
|
376
|
0
|
0
|
|
|
|
|
sprintf("│. . %s . .│", $suits{$card->suit}), |
|
|
|
0
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
"│. . . . .│", |
|
378
|
|
|
|
|
|
|
"│. . . . .│", |
|
379
|
|
|
|
|
|
|
sprintf("│. . . .%s│", $card->symbol =~ m/10/ ? $card->symbol : " " . $card->symbol), |
|
380
|
|
|
|
|
|
|
"└─────────┘" |
|
381
|
|
|
|
|
|
|
); |
|
382
|
|
|
|
|
|
|
|
|
383
|
0
|
|
|
|
|
|
for (@card) { |
|
384
|
0
|
|
|
|
|
|
$self->say($_, 1, 0, $color); |
|
385
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal($col); |
|
386
|
|
|
|
|
|
|
} |
|
387
|
|
|
|
|
|
|
} |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
sub render_opponent_cards { |
|
391
|
0
|
|
|
0
|
1
|
|
my ($self, $num) = @_; |
|
392
|
|
|
|
|
|
|
|
|
393
|
0
|
0
|
|
|
|
|
return unless $num; |
|
394
|
|
|
|
|
|
|
|
|
395
|
0
|
|
|
|
|
|
$self->set_cursor_vertical(2); |
|
396
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal((100 - ($num * 4)) / 2); |
|
397
|
|
|
|
|
|
|
|
|
398
|
0
|
|
|
|
|
|
my $string = "┌──" x ($num - 1); |
|
399
|
0
|
|
|
|
|
|
$self->say($string); |
|
400
|
0
|
|
|
|
|
|
$self->say("┌─────────┐", 1, 1); |
|
401
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal((100 - ($num * 4)) / 2); |
|
402
|
0
|
|
|
|
|
|
for (0..6) { |
|
403
|
0
|
|
|
|
|
|
$string = "│. " x ($num - 1); |
|
404
|
0
|
|
|
|
|
|
$self->say($string); |
|
405
|
0
|
|
|
|
|
|
$self->say("│. . . . .│", 1, 1); |
|
406
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal((100 - ($num * 4)) / 2); |
|
407
|
|
|
|
|
|
|
} |
|
408
|
0
|
|
|
|
|
|
$string = "└──" x ($num - 1); |
|
409
|
0
|
|
|
|
|
|
$self->say($string); |
|
410
|
0
|
|
|
|
|
|
$self->say("└─────────┘", 1, 1); |
|
411
|
|
|
|
|
|
|
} |
|
412
|
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
sub render_player_cards { |
|
414
|
0
|
|
|
0
|
1
|
|
my ($self, $cards, $top, $left, $all) = @_; |
|
415
|
0
|
|
|
|
|
|
my $i = 1; |
|
416
|
0
|
|
|
|
|
|
for (@{$cards}) { |
|
|
0
|
|
|
|
|
|
|
|
417
|
0
|
0
|
0
|
|
|
|
if (!$all && $_->{used}) { |
|
418
|
0
|
|
|
|
|
|
$i++; |
|
419
|
0
|
|
|
|
|
|
next; |
|
420
|
|
|
|
|
|
|
} |
|
421
|
0
|
|
|
|
|
|
$left += 11; |
|
422
|
0
|
|
|
|
|
|
$self->set_cursor_vertical($top); |
|
423
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal($left + 5); |
|
424
|
0
|
|
|
|
|
|
$self->say($i++); |
|
425
|
0
|
|
|
|
|
|
$self->render_card($_, $top + 1, $left); |
|
426
|
|
|
|
|
|
|
} |
|
427
|
|
|
|
|
|
|
} |
|
428
|
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
sub render_run_play { |
|
430
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
431
|
|
|
|
|
|
|
|
|
432
|
0
|
|
|
|
|
|
my $cards = $self->board->current_play->cards; |
|
433
|
|
|
|
|
|
|
|
|
434
|
0
|
0
|
|
|
|
|
return unless (scalar @{$cards}); |
|
|
0
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
|
|
436
|
0
|
|
|
|
|
|
my $left = 25; |
|
437
|
0
|
|
|
|
|
|
for (@{$cards}) { |
|
|
0
|
|
|
|
|
|
|
|
438
|
0
|
|
|
|
|
|
$self->render_card($_->card, 15, $left); |
|
439
|
0
|
|
|
|
|
|
$left += 10; |
|
440
|
|
|
|
|
|
|
} |
|
441
|
|
|
|
|
|
|
} |
|
442
|
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
sub show_face_down_split { |
|
445
|
0
|
|
|
0
|
1
|
|
my ($self, $num, $vertical) = @_; |
|
446
|
|
|
|
|
|
|
|
|
447
|
0
|
|
0
|
|
|
|
$self->set_cursor_vertical($vertical || 10); |
|
448
|
|
|
|
|
|
|
|
|
449
|
0
|
|
|
|
|
|
my $width = ($num / 2) - 1; |
|
450
|
|
|
|
|
|
|
|
|
451
|
0
|
|
|
|
|
|
for my $it (0 .. 1) { |
|
452
|
0
|
|
|
|
|
|
my $string = "┌──" x $width; |
|
453
|
0
|
|
|
|
|
|
$self->say($string); |
|
454
|
0
|
|
|
|
|
|
$self->say("┌─────────┐", 1, 1); |
|
455
|
0
|
|
|
|
|
|
$string = ""; |
|
456
|
0
|
|
|
|
|
|
for (1 .. $width) { |
|
457
|
0
|
0
|
|
|
|
|
my $v = $it ? 26 + $_ : $_; |
|
458
|
0
|
0
|
0
|
|
|
|
$string .= sprintf("│%s", (!$it && $_ < 10 ? "$v " : $v)); |
|
459
|
|
|
|
|
|
|
} |
|
460
|
0
|
|
|
|
|
|
$self->say($string); |
|
461
|
0
|
0
|
|
|
|
|
$self->say(sprintf("│%s. . . .│", $it ? ($width + 1) * 2 : $width + 1), 1, 1); |
|
462
|
0
|
|
|
|
|
|
for (0..4) { |
|
463
|
0
|
|
|
|
|
|
$string = "│. " x $width; |
|
464
|
0
|
|
|
|
|
|
$self->say($string); |
|
465
|
0
|
|
|
|
|
|
$self->say("│. . . . .│", 1, 1); |
|
466
|
|
|
|
|
|
|
} |
|
467
|
0
|
|
|
|
|
|
$string = "│. " x $width; |
|
468
|
0
|
|
|
|
|
|
$self->say($string); |
|
469
|
0
|
0
|
|
|
|
|
$self->say(sprintf("│. . . .%s│", $it ? ($width + 1) * 2 : $width + 1), 1, 1); |
|
470
|
0
|
|
|
|
|
|
my $string = "└──" x $width; |
|
471
|
0
|
|
|
|
|
|
$self->say($string); |
|
472
|
0
|
|
|
|
|
|
$self->say("└─────────┘", 1, 1); |
|
473
|
|
|
|
|
|
|
} |
|
474
|
|
|
|
|
|
|
} |
|
475
|
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
sub draw_background { |
|
477
|
0
|
|
|
0
|
1
|
|
for (0 .. 35) { |
|
478
|
0
|
|
|
|
|
|
print "\e[102;1m"; |
|
479
|
0
|
|
|
|
|
|
print pack("A100", " "); |
|
480
|
0
|
|
|
|
|
|
print "\n"; |
|
481
|
0
|
|
|
|
|
|
print "\e[0"; |
|
482
|
|
|
|
|
|
|
} |
|
483
|
0
|
|
|
|
|
|
$_[0]->draw_dealer(); |
|
484
|
|
|
|
|
|
|
#$_[0]->draw_scores(); |
|
485
|
0
|
|
|
|
|
|
$_[0]->draw_crib(); |
|
486
|
0
|
|
|
|
|
|
$_[0]->draw_starter(); |
|
487
|
0
|
|
|
|
|
|
$_[0]->reset_cursor(); |
|
488
|
|
|
|
|
|
|
} |
|
489
|
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
sub draw_starter { |
|
491
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
492
|
|
|
|
|
|
|
|
|
493
|
0
|
0
|
|
|
|
|
return unless $self->starter_card; |
|
494
|
|
|
|
|
|
|
|
|
495
|
0
|
|
|
|
|
|
$self->render_card($self->starter_card, 15, 2); |
|
496
|
|
|
|
|
|
|
} |
|
497
|
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
sub draw_crib { |
|
500
|
0
|
|
|
0
|
1
|
|
my ($self) = shift; |
|
501
|
0
|
|
|
|
|
|
my $dealer = $self->dealer; |
|
502
|
0
|
0
|
|
|
|
|
return unless defined $dealer; |
|
503
|
0
|
0
|
|
|
|
|
return unless $self->crib_set; |
|
504
|
0
|
|
|
|
|
|
my @card = ( |
|
505
|
|
|
|
|
|
|
"┌─────────┐", |
|
506
|
|
|
|
|
|
|
"│. . . . .│", |
|
507
|
|
|
|
|
|
|
"│. . . . .│", |
|
508
|
|
|
|
|
|
|
"│. . . . .│", |
|
509
|
|
|
|
|
|
|
"│. . . . .│", |
|
510
|
|
|
|
|
|
|
"│. . . . .│", |
|
511
|
|
|
|
|
|
|
"│. . . . .│", |
|
512
|
|
|
|
|
|
|
"│. . . . .│", |
|
513
|
|
|
|
|
|
|
"└─────────┘" |
|
514
|
|
|
|
|
|
|
); |
|
515
|
|
|
|
|
|
|
|
|
516
|
0
|
0
|
|
|
|
|
if ($dealer) { |
|
517
|
0
|
|
|
|
|
|
$self->set_cursor_vertical(27); |
|
518
|
|
|
|
|
|
|
} else { |
|
519
|
0
|
|
|
|
|
|
$self->set_cursor_vertical(3); |
|
520
|
|
|
|
|
|
|
} |
|
521
|
|
|
|
|
|
|
|
|
522
|
0
|
|
|
|
|
|
for (@card) { |
|
523
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal(10); |
|
524
|
0
|
|
|
|
|
|
$self->say($_, 1, 0); |
|
525
|
|
|
|
|
|
|
} |
|
526
|
|
|
|
|
|
|
} |
|
527
|
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
sub draw_go { |
|
529
|
0
|
|
|
0
|
1
|
|
my ($self, $top, $left) = @_; |
|
530
|
0
|
|
|
|
|
|
my $message = ' GO '; |
|
531
|
0
|
|
|
|
|
|
$self->set_cursor_vertical($top); |
|
532
|
0
|
|
|
|
|
|
$self->say($message, 0, 0, 31, 40); |
|
533
|
|
|
|
|
|
|
} |
|
534
|
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
sub draw_dealer { |
|
537
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
538
|
|
|
|
|
|
|
|
|
539
|
0
|
|
|
|
|
|
my $dealer = $self->dealer; |
|
540
|
|
|
|
|
|
|
|
|
541
|
0
|
0
|
|
|
|
|
return unless defined $dealer; |
|
542
|
0
|
|
|
|
|
|
my $message = ' Dealer '; |
|
543
|
0
|
0
|
|
|
|
|
if ($dealer) { |
|
544
|
0
|
|
|
|
|
|
$self->set_cursor_vertical(34); |
|
545
|
0
|
|
|
|
|
|
$self->say($message, 0, 0, 31, 40); |
|
546
|
|
|
|
|
|
|
} else { |
|
547
|
0
|
|
|
|
|
|
$self->set_cursor_vertical(3); |
|
548
|
0
|
|
|
|
|
|
$self->say($message, 0, 0, 31, 40); |
|
549
|
|
|
|
|
|
|
} |
|
550
|
|
|
|
|
|
|
} |
|
551
|
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
sub draw_scores { |
|
553
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
554
|
0
|
|
|
|
|
|
my $message; |
|
555
|
0
|
0
|
|
|
|
|
return unless $self->board; |
|
556
|
0
|
0
|
0
|
|
|
|
if ($self->board && $self->board->current_play_score) { |
|
557
|
0
|
|
|
|
|
|
$message = pack("A2", $self->board->current_play_score); |
|
558
|
0
|
|
|
|
|
|
$self->set_cursor_vertical(14); |
|
559
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal(49); |
|
560
|
0
|
|
|
|
|
|
$self->say($message, 0, 0, 31, 40); |
|
561
|
|
|
|
|
|
|
} |
|
562
|
0
|
|
|
|
|
|
$message = ' Score: ' . $self->board->score->player2->{current} . ' '; |
|
563
|
0
|
|
|
|
|
|
$self->set_cursor_vertical(34); |
|
564
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal(100 - (length($message) + 1)); |
|
565
|
0
|
|
|
|
|
|
$self->say($message, 0, 0, 31, 40); |
|
566
|
0
|
|
|
|
|
|
$message = ' Score: ' . $self->board->score->player1->{current} . ' '; |
|
567
|
0
|
|
|
|
|
|
$self->set_cursor_vertical(3); |
|
568
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal(100 - (length($message) + 1)); |
|
569
|
0
|
|
|
|
|
|
$self->say($message, 0, 0, 31, 40); |
|
570
|
|
|
|
|
|
|
} |
|
571
|
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
sub winner { |
|
573
|
0
|
|
|
0
|
1
|
|
print "\e[0m\e[2J\e[0;1H"; |
|
574
|
0
|
|
|
|
|
|
for (0 .. 35) { |
|
575
|
0
|
|
|
|
|
|
print "\e[102;1m"; |
|
576
|
0
|
|
|
|
|
|
print pack("A100", " "); |
|
577
|
0
|
|
|
|
|
|
print "\n"; |
|
578
|
0
|
|
|
|
|
|
print "\e[0"; |
|
579
|
|
|
|
|
|
|
} |
|
580
|
0
|
|
|
|
|
|
$_[0]->set_cursor_vertical(17); |
|
581
|
0
|
|
|
|
|
|
my $player = $_[0]->board->players->[1]; |
|
582
|
0
|
0
|
|
|
|
|
$_[0]->say($_[1] eq 'player2' |
|
583
|
|
|
|
|
|
|
? sprintf(q|Congratualations %s, you won the game!|, $player->name) |
|
584
|
|
|
|
|
|
|
: sprintf(q|Unlucky %s, you lost this time!|, $player->name) |
|
585
|
|
|
|
|
|
|
); |
|
586
|
|
|
|
|
|
|
|
|
587
|
0
|
|
|
|
|
|
} |
|
588
|
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
sub clear_screen { |
|
591
|
0
|
|
|
0
|
1
|
|
print "\e[0m\e[2J\e[0;1H"; |
|
592
|
0
|
|
|
|
|
|
$_[0]->draw_background(); |
|
593
|
|
|
|
|
|
|
} |
|
594
|
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
sub reset_cursor { |
|
596
|
0
|
|
|
0
|
1
|
|
print "\e[;2H"; |
|
597
|
|
|
|
|
|
|
} |
|
598
|
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
sub set_cursor_vertical { |
|
600
|
0
|
|
|
0
|
1
|
|
print "\e[$_[1];2H"; |
|
601
|
|
|
|
|
|
|
} |
|
602
|
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
sub set_cursor_horizontal { |
|
604
|
0
|
|
|
0
|
1
|
|
print "\e[$_[1]G"; |
|
605
|
|
|
|
|
|
|
} |
|
606
|
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
sub say { |
|
608
|
0
|
|
|
0
|
1
|
|
my ($self, $msg, $nl, $indent, $color, $back) = @_; |
|
609
|
0
|
|
0
|
|
|
|
$color ||= 90; |
|
610
|
0
|
|
0
|
|
|
|
$back ||= 102; |
|
611
|
0
|
|
|
|
|
|
print "\e[$color;1;1m\e[$back;1m"; |
|
612
|
0
|
|
|
|
|
|
print $msg; |
|
613
|
0
|
0
|
|
|
|
|
print "\n" if $nl; |
|
614
|
0
|
0
|
|
|
|
|
$self->set_cursor_horizontal(2) if $indent; |
|
615
|
0
|
|
|
|
|
|
print "\e[0"; |
|
616
|
0
|
|
|
|
|
|
1; |
|
617
|
|
|
|
|
|
|
} |
|
618
|
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
sub print_header { |
|
620
|
0
|
|
|
0
|
1
|
|
my ($self, $message) = @_; |
|
621
|
0
|
|
|
|
|
|
$self->set_cursor_verical(0); |
|
622
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal(0); |
|
623
|
0
|
|
|
|
|
|
print "\e[40;1m"; |
|
624
|
0
|
|
|
|
|
|
print pack("A100", " "); |
|
625
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal(2); |
|
626
|
0
|
|
|
|
|
|
$self->say($message, 0, 0, 31, 40); |
|
627
|
|
|
|
|
|
|
} |
|
628
|
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
sub print_footer { |
|
630
|
0
|
|
|
0
|
1
|
|
my ($self, $message) = @_; |
|
631
|
0
|
|
|
|
|
|
$self->set_cursor_vertical(36); |
|
632
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal(0); |
|
633
|
0
|
|
|
|
|
|
print "\e[40;1m"; |
|
634
|
0
|
|
|
|
|
|
print pack("A100", " "); |
|
635
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal(2); |
|
636
|
0
|
|
|
|
|
|
$self->say($message, 0, 0, 31, 40); |
|
637
|
0
|
|
|
|
|
|
$self->set_cursor_horizontal(length($message) + 2); |
|
638
|
|
|
|
|
|
|
} |
|
639
|
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
1; |
|
642
|
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
__END__ |