War card game: Difference between revisions

From Rosetta Code
Content added Content deleted
mNo edit summary
No edit summary
Line 175: Line 175:
Player 1 wins the game.
Player 1 wins the game.
</pre>
</pre>

=={{header|Python}}==
{{trans|Julia}}
<lang python>""" https://bicyclecards.com/how-to-play/war/ """

from numpy.random import shuffle

SUITS = ['♣', '♦', '♥', '♠']
FACES = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
DECK = [f + s for f in FACES for s in SUITS]
CARD_TO_RANK = dict((DECK[i], (i + 3) // 4) for i in range(len(DECK)))


class WarCardGame:
""" card game War """
def __init__(self):
deck = DECK.copy()
shuffle(deck)
self.deck1, self.deck2 = deck[:26], deck[26:]
self.pending = []

def turn(self):
""" one turn, may recurse on tie """
if len(self.deck1) == 0 or len(self.deck2) == 0:
return self.gameover()

card1, card2 = self.deck1.pop(0), self.deck2.pop(0)
rank1, rank2 = CARD_TO_RANK[card1], CARD_TO_RANK[card2]
print("{:10}{:10}".format(card1, card2), end='')
if rank1 > rank2:
print('Player 1 takes the cards.')
self.deck1.extend([card1, card2])
self.deck1.extend(self.pending)
self.pending = []
elif rank1 < rank2:
print('Player 2 takes the cards.')
self.deck2.extend([card2, card1])
self.deck2.extend(self.pending)
self.pending = []
else: # rank1 == rank2
print('Tie!')
if len(self.deck1) == 0 or len(self.deck2) == 0:
return self.gameover()

card3, card4 = self.deck1.pop(0), self.deck2.pop(0)
self.pending = [card1, card2, card3, card4]
print("{:10}{:10}".format("?", "?"), 'Cards are face down.', sep='')
self.turn()

return True

def gameover(self):
""" game over who won message """
if len(self.deck2) == 0:
if len(self.deck1) == 0:
print('\nGame ends as a tie.')
else:
print('\nPlayer 1 wins the game.')
else:
print('\nPlayer 2 wins the game.')

return False


if __name__ == '__main__':
WG = WarCardGame()
while WG.turn():
continue
</lang>{{out}}
<pre>
8♠ K♠ Player 2 takes the cards.
3♠ 8♥ Player 2 takes the cards.
K♣ 4♠ Player 1 takes the cards.
Q♦ J♣ Player 1 takes the cards.
5♦ 6♦ Player 2 takes the cards.
A♥ Q♣ Player 1 takes the cards.
10♣ 5♥ Player 1 takes the cards.
J♦ 7♣ Player 1 takes the cards.
K♥ Q♠ Player 1 takes the cards.
2♦ 2♣ Player 1 takes the cards.
10♠ 9♥ Player 1 takes the cards.
9♠ 3♦ Player 1 takes the cards.
A♠ A♦ Tie!
? ? Cards are face down.
3♥ 8♦ Player 2 takes the cards.
5♣ 2♠ Player 1 takes the cards.
J♠ 4♦ Player 1 takes the cards.
2♥ 7♦ Player 2 takes the cards.

... et cetera ...

A♣ 4♣ Player 1 takes the cards.
7♣ 3♣ Player 1 takes the cards.
9♠ A♦ Player 2 takes the cards.
6♦ Q♠ Player 2 takes the cards.
7♦ 3♦ Player 1 takes the cards.
5♥ 2♥ Player 1 takes the cards.
A♣ A♥ Player 2 takes the cards.
4♣ 10♣ Player 2 takes the cards.
7♣ 10♥ Player 2 takes the cards.
3♣ 5♦ Player 2 takes the cards.
7♦ K♦ Player 2 takes the cards.
3♦ 8♣ Player 2 takes the cards.
5♥ J♦ Player 2 takes the cards.
2♥ 6♥ Player 2 takes the cards.

Player 2 wins the game.
</pre>



=={{header|Wren}}==
=={{header|Wren}}==

Revision as of 23:54, 26 December 2020


War card game is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

War Card Game

Simulate the card game War. Use the Bicycle playing card manufacturer's rules. Show a game as played. User input is optional.

References:

  • Bicycle card company War game site. [[1]]     (This site leaves a cookie.)
  • Wikipedia entry. [[2]]

Related tasks:


Julia

<lang julia># https://bicyclecards.com/how-to-play/war/

using Random

const SUITS = ["♣", "♦", "♥", "♠"] const FACES = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" ] const DECK = vec([f * s for s in SUITS, f in FACES]) const rdict = Dict(DECK[i] => div(i + 3, 4) for i in eachindex(DECK))

deal2(deck) = begin d = shuffle(deck); d[1:2:51], d[2:2:52] end

function turn!(d1, d2, pending)

   (isempty(d1) || isempty(d2)) && return false
   c1, c2 = popfirst!(d1), popfirst!(d2)
   r1, r2 = rdict[c1], rdict[c2]
   print(rpad(c1, 10), rpad(c2, 10))
   if r1 > r2
       println("Player 1 takes the cards.")
       push!(d1, c1, c2, pending...)
       empty!(pending)
   elseif r1 < r2
       println("Player 2 takes the cards.")
       push!(d2, c2, c1, pending...)
       empty!(pending)
   else # r1 == r2
       println("Tie!")
       (isempty(d1) || isempty(d2)) && return false
       c3, c4 = popfirst!(d1), popfirst!(d2)
       println(rpad("?", 10), rpad("?", 10), "Cards are face down.")
       turn!(d1, d2, push!(pending, c1, c2, c3, c4))
   end
   return true

end

function warcardgame()

   deck1, deck2 = deal2(DECK)
   while turn!(deck1, deck2, []) end
   if isempty(deck2)
       if isempty(deck1)
           println("Game ends as a tie.")
       else
           println("Player 1 wins the game.")
       end
   else
       println("Player 2 wins the game.")
   end

end

warcardgame()

</lang>

Output:
5♦        3♥        Player 1 takes the cards.
8♥        K♥        Player 2 takes the cards.
5♠        K♦        Player 2 takes the cards.
3♦        6♥        Player 2 takes the cards.
9♣        J♠        Player 2 takes the cards.
8♦        2♦        Player 1 takes the cards.
J♣        5♥        Player 1 takes the cards.
3♠        4♥        Player 2 takes the cards.
9♥        A♣        Player 2 takes the cards.
9♠        9♦        Tie!
?         ?         Cards are face down.     
A♠        4♦        Player 1 takes the cards.
5♣        Q♠        Player 2 takes the cards.
6♦        8♠        Player 2 takes the cards.
4♣        10♦       Player 2 takes the cards.
4♠        2♥        Player 1 takes the cards.
Q♦        K♣        Player 2 takes the cards.
A♥        2♣        Player 1 takes the cards.
Q♣        2♠        Player 1 takes the cards.
10♥       6♣        Player 1 takes the cards.

... many other lines ...

10♥       Q♣        Player 2 takes the cards.
4♣        5♦        Player 2 takes the cards.
A♣        8♦        Player 1 takes the cards.
9♣        2♣        Player 1 takes the cards.
Q♥        Q♣        Tie!
?         ?         Cards are face down.
Q♠        5♦        Player 1 takes the cards.
8♥        4♣        Player 1 takes the cards.
Player 1 wins the game.

Phix

Shuffles on pickup to significantly shorten the games <lang Phix>sequence deck = shuffle(tagset(52)),

        hands = {deck[1..26],deck[27..52]},
        pending = {}

function pop(integer hand)

   integer res
   {res, hands[hand]} = {hands[hand][1],hands[hand][2..$]}
   return res

end function

function show(integer c)

   integer r = remainder(c-1,13)+1,
           s = floor((c-1)/13)+1
   printf(1,"%s    ",{"23456789TJQKA"[r]&"SHDC"[s]})
   return r

end function

while true do

   if length(hands[1])=0 then
       if length(hands[2])=0 then
           printf(1,"Game ends as a tie.\n")
           exit
       end if
       printf(1,"Player 2 wins the game.\n")
       exit
   elsif length(hands[2])=0 then
       printf(1,"Player 1 wins the game.\n")
       exit
   end if
   integer c1 = pop(1),
           c2 = pop(2),
           r1 = show(c1),
           r2 = show(c2)
   if r1>r2 then
       printf(1,"Player 1 takes the cards.\n")
       hands[1] &= shuffle(c1&c2&pending)
       pending = {}
   elsif r1<r2 then
       printf(1,"Player 2 takes the cards.\n")
       hands[2] &= shuffle(c1&c2&pending)
       pending = {}
   else -- r1==r2
       printf(1,"Tie!\n")
       if length(hands[1])!=0 and length(hands[2])!=0 then
           pending &= shuffle(c1&c2&pop(1)&pop(2))
           printf(1,"??    ??    Cards are face down.\n")
       end if
   end if

end while</lang>

Output:
9H    3C    Player 1 takes the cards.
AD    KD    Player 1 takes the cards.
3D    KS    Player 2 takes the cards.
...
2H    9S    Player 2 takes the cards.
KC    7H    Player 1 takes the cards.
5C    JS    Player 2 takes the cards.
3S    3D    Tie!
??    ??    Cards are face down.
8D    2H    Player 1 takes the cards.
2C    JS    Player 2 takes the cards.
JD    5C    Player 1 takes the cards.
6D    2C    Player 1 takes the cards.
QD    JS    Player 1 takes the cards.
Player 1 wins the game.

Python

Translation of: Julia

<lang python>""" https://bicyclecards.com/how-to-play/war/ """

from numpy.random import shuffle

SUITS = ['♣', '♦', '♥', '♠'] FACES = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] DECK = [f + s for f in FACES for s in SUITS] CARD_TO_RANK = dict((DECK[i], (i + 3) // 4) for i in range(len(DECK)))


class WarCardGame:

   """ card game War """
   def __init__(self):
       deck = DECK.copy()
       shuffle(deck)
       self.deck1, self.deck2 = deck[:26], deck[26:]
       self.pending = []
   def turn(self):
       """ one turn, may recurse on tie """
       if len(self.deck1) == 0 or len(self.deck2) == 0:
           return self.gameover()
       card1, card2 = self.deck1.pop(0), self.deck2.pop(0)
       rank1, rank2 = CARD_TO_RANK[card1], CARD_TO_RANK[card2]
       print("{:10}{:10}".format(card1, card2), end=)
       if rank1 > rank2:
           print('Player 1 takes the cards.')
           self.deck1.extend([card1, card2])
           self.deck1.extend(self.pending)
           self.pending = []
       elif rank1 < rank2:
           print('Player 2 takes the cards.')
           self.deck2.extend([card2, card1])
           self.deck2.extend(self.pending)
           self.pending = []
       else:  #  rank1 == rank2
           print('Tie!')
           if len(self.deck1) == 0 or len(self.deck2) == 0:
               return self.gameover()
           card3, card4 = self.deck1.pop(0), self.deck2.pop(0)
           self.pending = [card1, card2, card3, card4]
           print("{:10}{:10}".format("?", "?"), 'Cards are face down.', sep=)
           self.turn()
       return True
   def gameover(self):
       """ game over who won message """
       if len(self.deck2) == 0:
           if len(self.deck1) == 0:
               print('\nGame ends as a tie.')
           else:
               print('\nPlayer 1 wins the game.')
       else:
           print('\nPlayer 2 wins the game.')
       return False


if __name__ == '__main__':

   WG = WarCardGame()
   while WG.turn():
       continue

</lang>

Output:
8♠        K♠        Player 2 takes the cards.
3♠        8♥        Player 2 takes the cards.
K♣        4♠        Player 1 takes the cards.
Q♦        J♣        Player 1 takes the cards.
5♦        6♦        Player 2 takes the cards.
A♥        Q♣        Player 1 takes the cards.
10♣       5♥        Player 1 takes the cards.
J♦        7♣        Player 1 takes the cards.
K♥        Q♠        Player 1 takes the cards.
2♦        2♣        Player 1 takes the cards.
10♠       9♥        Player 1 takes the cards.
9♠        3♦        Player 1 takes the cards.
A♠        A♦        Tie!
?         ?         Cards are face down.
3♥        8♦        Player 2 takes the cards.
5♣        2♠        Player 1 takes the cards.
J♠        4♦        Player 1 takes the cards.
2♥        7♦        Player 2 takes the cards.

... et cetera ...

A♣        4♣        Player 1 takes the cards.
7♣        3♣        Player 1 takes the cards.
9♠        A♦        Player 2 takes the cards.
6♦        Q♠        Player 2 takes the cards.
7♦        3♦        Player 1 takes the cards.
5♥        2♥        Player 1 takes the cards.
A♣        A♥        Player 2 takes the cards.
4♣        10♣       Player 2 takes the cards.
7♣        10♥       Player 2 takes the cards.
3♣        5♦        Player 2 takes the cards.
7♦        K♦        Player 2 takes the cards.
3♦        8♣        Player 2 takes the cards.
5♥        J♦        Player 2 takes the cards.
2♥        6♥        Player 2 takes the cards.

Player 2 wins the game.


Wren

Library: Wren-queue

I've assumed that if a player runs out of cards during a 'war', then the other player automatically wins the game. The Bicycle card company's rules don't appear to cover this eventuality

I've also assumed that if a player wins a round, his/her own cards (in the order played) are added back to the bottom of his/her hand before the other player's cards. <lang ecmascript>import "random" for Random import "/queue" for Deque

var rand = Random.new() var suits = ["♣", "♦", "♥", "♠"] var faces = ["2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A" ] var cards = List.filled(52, null) for (i in 0..51) cards[i] = "%(faces[i%13])%(suits[(i/13).floor])" var ranks = List.filled(52, 0) for (i in 0..51) ranks[i] = i % 13

var war = Fn.new {

   var deck = List.filled(52, 0)
   for (i in 0..51) deck[i] = i
   rand.shuffle(deck)
   var hand1 = Deque.new()
   var hand2 = Deque.new()
   for (i in 0..25) {
       hand1.pushFront(deck[2*i])
       hand2.pushFront(deck[2*i+1])
   }
   while (hand1.count > 0 && hand2.count > 0) {
       var card1 = hand1.popFront()
       var card2 = hand2.popFront()
       var played1 = [card1]
       var played2 = [card2]
       var numPlayed = 2
       while (true) {
           System.write("%(cards[card1])\t%(cards[card2])\t")
           if (ranks[card1] > ranks[card2]) {
               hand1.pushAllBack(played1)
               hand1.pushAllBack(played2)
               System.print("Player 1 takes the %(numPlayed) cards. Now has %(hand1.count).")
               break
           } else if (ranks[card1] < ranks[card2]) {
               hand2.pushAllBack(played2)
               hand2.pushAllBack(played1)
               System.print("Player 2 takes the %(numPlayed) cards. Now has %(hand2.count).")
               break
           } else {
               System.print("War!")
               if (hand1.count < 2) {
                   System.print("Player 1 has insufficient cards left.")
                   hand2.pushAllBack(played2)
                   hand2.pushAllBack(played1)
                   hand2.pushAllBack(hand1)
                   hand1.clear()
                   break
               }
               if (hand2.count < 2) {
                   System.print("Player 2 has insufficient cards left.")
                   hand1.pushAllBack(played1)
                   hand1.pushAllBack(played2)
                   hand1.pushAllBack(hand2)
                   hand2.clear()
                   break
               }
               played1.add(hand1.popFront()) // face down card
               card1 = hand1.popFront()      // face up card
               played1.add(card1)
               played2.add(hand2.popFront()) // face down card
               card2 = hand2.popFront()      // face up card
               played2.add(card2)
               numPlayed = numPlayed + 4
               System.print("%("? ")\t%("? ")\tFace down cards.")
           }
       }
   }
   if (hand1.count == 52) {
       System.print("Player 1 wins the game!")
   } else {
       System.print("Player 2 wins the game!")
   }

}

war.call()</lang>

Output:

Sample game (abridged):

Q♥	9♠	Player 1 takes the 2 cards. Now has 27.
3♦	T♦	Player 2 takes the 2 cards. Now has 26.
8♣	A♥	Player 2 takes the 2 cards. Now has 27.
3♠	Q♠	Player 2 takes the 2 cards. Now has 28.
J♠	4♥	Player 1 takes the 2 cards. Now has 25.
3♣	7♣	Player 2 takes the 2 cards. Now has 28.
9♦	2♠	Player 1 takes the 2 cards. Now has 25.
7♥	K♦	Player 2 takes the 2 cards. Now has 28.
5♥	A♠	Player 2 takes the 2 cards. Now has 29.
2♦	K♠	Player 2 takes the 2 cards. Now has 30.
5♠	5♣	War!
? 	? 	Face down cards.
4♣	T♣	Player 2 takes the 6 cards. Now has 33.
A♦	9♥	Player 1 takes the 2 cards. Now has 20.
T♥	9♣	Player 1 takes the 2 cards. Now has 21.
K♣	Q♣	Player 1 takes the 2 cards. Now has 22.
4♦	A♣	Player 2 takes the 2 cards. Now has 31.
7♠	7♦	War!
? 	? 	Face down cards.
8♦	J♣	Player 2 takes the 6 cards. Now has 34.

.....

T♠	7♦	Player 1 takes the 2 cards. Now has 10.
7♠	J♣	Player 2 takes the 2 cards. Now has 43.
4♣	4♥	War!
? 	? 	Face down cards.
2♠	2♣	War!
? 	? 	Face down cards.
3♦	9♠	Player 2 takes the 10 cards. Now has 48.
5♠	5♣	War!
? 	? 	Face down cards.
T♠	T♥	War!
Player 1 has insufficient cards left.
Player 2 wins the game!