StyleInCode

RSS

 

Card Game - War

6 February 2025

A solution to the War Card Game Kata described at Awesome Katas.

Solution

""" card_game_war.py """

# usage: python3 card_game_war.py

import random


random.seed()


def new(size=52):
    """ deck of cards """
    return [(i, None) for i in range(size)]


def shuffle(cards):
    """ shuffle """
    return random.sample(cards, len(cards))


def deal(cards):
    """ assign to player """
    return [(c, i % 2) for i, (c, _) in enumerate(cards)]


def endgame(cards):
    """ has a player won """
    return sum(i for _, i in cards) in (0, len(cards))


def top(hand, cards):
    """ top card for hand """
    for c, i in cards:
        if i == hand:
            return c
    raise ValueError


def add(hand, extra, cards):
    """ add extra to bottom of hand """
    return cards + [(i, hand) for i in shuffle(extra)], []


def process(card0, card1, extras, cards):
    """ remove cards and add to extras """
    return ([(c, i) for c, i in cards if c not in [card0, card1]],
            extras + [player0, player1])


def score(cards):
    """ who won? """
    i = sum(j for _, j in cards)
    return 'player 0' if i == 0 else 'player 1'


deck = deal(shuffle(new()))

carry = []
while not endgame(deck):
    player0, player1 = top(0, deck), top(1, deck)
    deck, carry = process(player0, player1, carry, deck)
    difference = player0 % 13 - player1 % 13
    if difference > 0:
        deck, carry = add(0, carry, deck)
    elif difference < 0:
        deck, carry = add(1, carry, deck)
    else:
        count = 0
        while not endgame(deck) and count < 3:
            player0, player1 = top(0, deck), top(1, deck)
            deck, carry = process(player0, player1, carry, deck)
            count += 1

print(score(deck))

Categories

Links