Jump to content

War card game: Difference between revisions

→‎{{header|Raku}}: Add a Raku example
(→‎{{header|Raku}}: Add a Raku example)
Line 8:
References:
 
:* Bicycle card company: War game site. [[https://bicyclecards.com/how-to-play/war/]]  War   (Thisgame site leaves a cookie.)]
 
:* Wikipedia entry.: [[httpswp://en.wikipedia.org/wiki/War_(card_game)|War (card game)]]
 
Related tasks:
Line 691:
Player 2 wins the game.
</pre>
 
=={{header|Raku}}==
The linked Bicycle cards site has slightly different rules for War! than how I used to play when I was but a lad. Implement it both ways.
 
Some rules are not nailed down very well. Here is how I interpreted it:
* The values of the cards 2-10 are face value; Jack, Queen, King and Ace may effectively be treated as: 11, 12, 13 & 14.
* Each player plays one card face up. The player whose card is the highest value takes both of the played cards and adds them to the bottom of his deck.
* When one player runs out of cards and is not able to place enough cards to finish a round, he loses.
* If both players play a card of the same value, it is then War!
** '''Bicycle rules:''' each player then plays another card face down then another face up.
** '''thundergnat rules:''' each player then plays ''three'' cards face down then another face up. (Tends to make for shorter games.)
** If the final face-up cards are different, the player playing the higher value card takes all of the played cards and adds them to the bottom of his deck
** If they are the same, continue with rounds of War! until one player plays a higher value war card or a player runs out of cards.
* When the winning player picks up his cards. the cards are randomized when added to the bottom of his deck. (Cuts a typical game from multi thousands of rounds to multi hundreds of rounds)
 
Pass in which variant you want to play 2 down (Bicycle), 4 down (thundergnat) or 3 down (????). By default, there is a short delay (.1 seconds) beween rounds so you can watch what is going on. Pass in a larger/smaller value to slow down or speed up how long the game takes.
 
In glorious ANSI color! (The output loses much when pasted in as text so show output as screenshot images.)
 
<lang perl6>unit sub MAIN (:$war where 2..4 = 4, :$sleep = .1);
 
my %c = ( # convenience hash of ANSI colors
red => "\e[38;2;255;10;0m",
blue => "\e[38;2;05;10;200m",
black => "\e[38;2;0;0;0m"
);
 
my @cards = flat (flat
<🂢 🂣 🂤 🂥 🂦 🂧 🂨 🂩 🂪 🂫 🂭 🂮 🂡
🃒 🃓 🃔 🃕 🃖 🃗 🃘 🃙 🃚 🃛 🃝 🃞 🃑>.map({ "{%c<black>}$_" }),
<🂲 🂳 🂴 🂵 🂶 🂷 🂸 🂹 🂺 🂻 🂽 🂾 🂱
🃂 🃃 🃄 🃅 🃆 🃇 🃈 🃉 🃊 🃋 🃍 🃎 🃁>.map({ "{%c<red>}$_" })
).batch(13).map({ .flat Z 2..14 })».map: { .[1] but .[0] };
 
my $back = "{%c<blue>}🂠";
my @won = <👈 👉>;
 
sub shuffle (@cards) { @cards.pick: * }
sub deal (@cards) { [@cards[0,*+2 … *], @cards[1,*+2 … *]] }
 
my ($rows, $cols) = qx/stty size/.words».Int; # get the terminal size
note "Terminal is only $cols characters wide, needs to be at least 80, 120 or more recommended."
and exit if $cols < 80;
 
sub clean-up {
reset-scroll-region;
show-cursor;
print-at $rows, 1, '';
print "\e[0m";
exit(0)
}
 
signal(SIGINT).tap: { clean-up() }
 
my @index = ($cols div 2 - 5, $cols div 2 + 4);
my @player = (deal shuffle @cards)».Array;
my $lose = False;
 
sub take (@player, Int $cards) {
if +@player >= $cards {
return @player.splice(0, $cards);
}
else {
$lose = True;
return @player.splice(0, +@player);
}
}
 
use Terminal::ANSI;
 
clear-screen;
hide-cursor;
# Set background color
print "\e[H\e[J\e[48;2;245;245;245m", ' ' xx $rows * $cols + 1;
 
# Add header
print-at 1, $cols div 2 - 1, "{%c<red>}WAR!";
print-at 2, 1, '━' x $cols;
 
my $row = 3;
my $height = $rows - $row - 2;
set-scroll-region($row, $height);
 
# footer
print-at $height + 1, 1, '━' x $cols;
 
my $round = 0;
my @round;
 
loop {
@round = [@player[0].&take(1)], [@player[1].&take(1)] unless +@round;
print-at $row, $cols div 2, "{%c<red>}┃";
print-at $row, @index[0], @round[0;0] // ' ';
print-at $row, @index[1], @round[1;0] // ' ';
if $lose {
if @player[0] < @player[1] {
print-at $row, $cols div 2 + 1, @won[1] unless +@round[1] == 1;
print-at $height + 3, $cols div 2 - 10, "{%c<red>} Player 1 is out of cards "
} else {
print-at $row, $cols div 2 - 2, @won[0] unless +@round[0] == 1;
print-at $height + 3, $cols div 2 - 10, "{%c<red>} Player 2 is out of cards "
}
 
}
if (@round[0].tail // 0) > (@round[1].tail // 0) {
print-at $row, $cols div 2 - 2, @won[0];
@player[0].append: flat (|@round[0],|@round[1]).pick: *;
@round = ();
}
elsif (@round[0].tail // 0) < (@round[1].tail // 0) {
print-at $row, $cols div 2 + 1, @won[1];
@player[1].append: flat (|@round[0],|@round[1]).pick: *;
@round = ();
}
else {
@round[0].append: @player[0].&take($war);
@round[1].append: @player[1].&take($war);
print-at $row, @index[0] - $_ * 2, ($_ %% $war) ?? @round[0; $_] !! $back for ^@round[0];
print-at $row, @index[1] + $_ * 2, ($_ %% $war) ?? @round[1; $_] !! $back for ^@round[1];
next
}
last if $lose;
print-at $height + 2, $cols div 2 - 4, "{%c<blue>} Round {++$round} ";
print-at $height + 2, $cols div 2 - 40, "{%c<blue>} Player 1: {+@player[0]} cards ";
print-at $height + 2, $cols div 2 + 21, "{%c<blue>} Player 2: {+@player[1]} cards ";
sleep $sleep if +$sleep;
if $row >= $height { scroll-up } else { ++$row }
}
 
# game over
print-at $height + 2, $cols div 2 - 40, "{%c<blue>} Player 1: {+@player[0] ?? '52' !! "{%c<red>}0"}{%c<blue>} cards ";
print-at $height + 2, $cols div 2 + 20, "{%c<blue>} Player 2: {+@player[1] ?? '52' !! "{%c<red>}0"}{%c<blue>} cards ";
clean-up;</lang>
 
{{out|Sample outout Bicycle}}
Pass in <code>:war=2</code> on the command line.
See [https://github.com/thundergnat/rc/blob/master/img/war-2.png Bicycle variation] (offsite png image)
 
{{out|Sample outout using defaults}}
See [https://github.com/thundergnat/rc/blob/master/img/war-4.png thundergnat variation] (offsite png image)
 
=={{header|Wren}}==
Line 712 ⟶ 852:
for (i in 0..51) deck[i] = i
rand.shuffle(deck)
var hand1 = Deque.new()unit sub MAIN (:$war where 2..4 = 4, :$sleep = .1);
 
my %c = ( # convenience hash of ANSI colors
red => "\e[38;2;255;10;0m",
blue => "\e[38;2;05;10;200m",
black => "\e[38;2;0;0;0m"
);
 
my @cards = flat (flat
<🂢 🂣 🂤 🂥 🂦 🂧 🂨 🂩 🂪 🂫 🂭 🂮 🂡
🃒 🃓 🃔 🃕 🃖 🃗 🃘 🃙 🃚 🃛 🃝 🃞 🃑>.map({ "{%c<black>}$_" }),
<🂲 🂳 🂴 🂵 🂶 🂷 🂸 🂹 🂺 🂻 🂽 🂾 🂱
🃂 🃃 🃄 🃅 🃆 🃇 🃈 🃉 🃊 🃋 🃍 🃎 🃁>.map({ "{%c<red>}$_" })
).batch(13).map({ .flat Z 2..14 })».map: { .[1] but .[0] };
 
my $back = "{%c<blue>}🂠";
my @won = <👈 👉>;
 
sub shuffle (@cards) { @cards.pick: * }
sub deal (@cards) { [@cards[0,*+2 … *], @cards[1,*+2 … *]] }
 
my ($rows, $cols) = qx/stty size/.words».Int; # get the terminal size
note "Terminal is only $cols characters wide, needs to be at least 80, 120 or more recommended."
and exit if $cols < 80;
 
sub clean-up {
reset-scroll-region;
show-cursor;
print-at $rows, 1, '';
print "\e[0m";
exit(0)
}
 
signal(SIGINT).tap: { clean-up() }
 
my @index = ($cols div 2 - 5, $cols div 2 + 4);
my @player = (deal shuffle @cards)».Array;
my $lose = False;
 
sub take (@player, Int $cards) {
if +@player >= $cards {
return @player.splice(0, $cards);
}
else {
$lose = True;
return @player.splice(0, +@player);
}
}
 
use Terminal::ANSI;
 
clear-screen;
hide-cursor;
# Set background color
print "\e[H\e[J\e[48;2;245;245;245m", ' ' xx $rows * $cols + 1;
 
# Add header
print-at 1, $cols div 2 - 1, "{%c<red>}WAR!";
print-at 2, 1, '━' x $cols;
 
my $row = 3;
my $height = $rows - $row - 2;
set-scroll-region($row, $height);
 
# footer
print-at $height + 1, 1, '━' x $cols;
 
my $round = 0;
my @round;
 
loop {
@round = [@player[0].&take(1)], [@player[1].&take(1)] unless +@round;
print-at $row, $cols div 2, "{%c<red>}┃";
print-at $row, @index[0], @round[0;0] // ' ';
print-at $row, @index[1], @round[1;0] // ' ';
if $lose {
if @player[0] < @player[1] {
print-at $row, $cols div 2 + 1, @won[1] unless +@round[1] == 1;
print-at $height + 3, $cols div 2 - 10, "{%c<red>} Player 1 is out of cards "
} else {
print-at $row, $cols div 2 - 2, @won[0] unless +@round[0] == 1;
print-at $height + 3, $cols div 2 - 10, "{%c<red>} Player 2 is out of cards "
}
 
}
if (@round[0].tail // 0) > (@round[1].tail // 0) {
print-at $row, $cols div 2 - 2, @won[0];
@player[0].append: flat (|@round[0],|@round[1]).pick: *;
@round = ();
}
elsif (@round[0].tail // 0) < (@round[1].tail // 0) {
print-at $row, $cols div 2 + 1, @won[1];
@player[1].append: flat (|@round[0],|@round[1]).pick: *;
@round = ();
}
else {
@round[0].append: @player[0].&take($war);
@round[1].append: @player[1].&take($war);
print-at $row, @index[0] - $_ * 2, ($_ %% $war) ?? @round[0; $_] !! $back for ^@round[0];
print-at $row, @index[1] + $_ * 2, ($_ %% $war) ?? @round[1; $_] !! $back for ^@round[1];
next
}
last if $lose;
print-at $height + 2, $cols div 2 - 4, "{%c<blue>} Round {++$round} ";
print-at $height + 2, $cols div 2 - 40, "{%c<blue>} Player 1: {+@player[0]} cards ";
print-at $height + 2, $cols div 2 + 21, "{%c<blue>} Player 2: {+@player[1]} cards ";
sleep $sleep if +$sleep;
if $row >= $height { scroll-up } else { ++$row }
}
 
# game over
print-at $height + 2, $cols div 2 - 40, "{%c<blue>} Player 1: {+@player[0] ?? '52' !! "{%c<red>}0"}{%c<blue>} cards ";
print-at $height + 2, $cols div 2 + 20, "{%c<blue>} Player 2: {+@player[1] ?? '52' !! "{%c<red>}0"}{%c<blue>} cards ";
clean-up;
 
var hand2 = Deque.new()
for (i in 0..25) {
10,333

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.