Python Forum
War with deck of cards
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
War with deck of cards
#1
My attempt at war with a deck of cards. Not all of the Player attributes are used right now.



#! /usr/bin/env python3
# Do the imports
import random as rnd
from tabulate import tabulate
from sys import platform
import subprocess
from time import sleep

def clear():
    subprocess.call('cls' if platform == 'win32' else 'clear')


class Player:
    ''' Create the player class
        Set some class variables
        Return a string representation
    '''
    def __init__(self, player):
        self.player = player
        self.card = None
        self.cards = []
        self.win = 0
        self.loss = 0

    def __repr__(self):
        return f'{self.player}: Cards:{len(self.cards)} wins: {self.win} loss: {self.loss}'


class Card:
    ''' Card with a suit and value '''
    suits = ['❤️', '♠️', '♦️', '♣️']
    values = [("Ace",14), ("2",2), ("3",3), ("4",4), ("5",5), ("6",6), ("7",7), ("8",8), ("9",9), ("10",10), ("Jack",11), ("Queen",12), ("King",13)]

    def __init__(self, suit, value):
        self.suit = suit
        self.value = value

    def __lt__(self, other):
        return self.value[1] < other.value[1]

    def __gt__(self, other):
        return self.value[1] > other.value[1]

    def __eq__(self, other):
        return self.value[1] == other.value[1]

    # Return a string representation
    def __repr__(self):
        return f'{self.value[0]} of {self.suit}'


class Deck:
    ''' Card list that can shuffle '''
    def __init__(self, shuffle=False):
        self.cards = [Card(suit, value) for suit in Card.suits for value in Card.values]
        if shuffle:
            rnd.shuffle(self.cards)

    # For getting how many cards are in the deck
    def __len__(self):
        return len(self.cards)

    # Deal cards Default is one
    def deal(self, count=1):
        cards = self.cards[:count]
        self.cards = self.cards[count:]
        return cards


class Game:
    '''
        Class for setting up gameplay
    '''
    def __init__(self, player):
        self.player1 = Player(player)
        self.player2 = Player('computer')
        self.last_winner = None
        self.deck = Deck(True)

    # Method for getting winner
    def check(self):
        '''
            If cards are equal print out words list
            Using sleep so all words do not print out all at once
            self.last_winner will be None as will need to draw again
            call self.check() so cards can be compared again
        '''
        if self.player1.card == self.player2.card:
            self.last_winner = None
            words = ['I', 'declare', 'war', 'on', 'you!']
            speak = []
            for i in range(5):
                speak.append(words[i])
                clear()
                print(' ' .join(speak))
                sleep(0.75)
            self.player1.card = self.deck.deal()
            self.player2.card = self.deck.deal()
            self.check()
        # If player has high card set player 1 winner
        # Add 1 to player 2 loss score
        elif self.player1.card > self.player2.card:
            self.last_winner = self.player1
            self.player2.loss += 1
        else:
            # Same as above but, for player 2
            self.last_winner = self.player2
            self.player1.loss += 1
        if self.last_winner:
            self.last_winner.win += 1

    # Method for displaing results
    def show(self):
        clear()
        headers = ['Player', 'Card']
        data = [[self.player1.player, self.player1.card[0]], [self.player2.player, self.player2.card[0]]]
        print(tabulate(data, headers=headers), '\n')
        if self.last_winner:
            print(f'{self.last_winner.player} wins the round')
        else:
            pass
        print('\nCurrent Stats:')
        print(tabulate([[self.player1, self.player2]],tablefmt='pretty'))


    # Method for gameplay
    # If the deck get down to only four cards
    # generate a new deck
    def play(self):
        self.player1.card = self.deck.deal()
        self.player2.card = self.deck.deal()
        self.check()
        self.show()
        if len(self.deck) <= 0:
            self.deck = Deck(True)

    # The main game loop
    def mainloop(self):
        while True:
            self.play()
            play_again = input('Play Again, Enter \'y\' ').upper()
            if play_again != 'Y':
                clear()
                print('Thanks for playing Cards of War.')
                print(f'Final Score:\n{tabulate([[self.player1, self.player2]], tablefmt="pretty")}')
                break

if __name__ == '__main__':
    ''' Start title loop '''
    while True:
        # List of letters to display for title
        war = ['W', 'A', 'R']

        # Empty title list / will append a letter through each iteration and print
        title = []
        for i in range(3):
            title.append(war[i])
            sleep(0.75)
            clear()
            print(''.join(title))

        # If i == 2 insert text into list at index 0 and print. Break out of while loop
        if i == 2:
            sleep(0.75)
            title.insert(0, 'Cards of ')
            clear()
            print(''.join(title))
            sleep(1.0)
            break

        
    '''
        Get player name
    '''
    clear()
    while True:
        print('Welcome to Cards of War!')
        print('Enter your name')
        name = input('>> ')
        if not name:
            print('You must enter a name')
        else:
            break
    Game(name).mainloop()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020