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


Messages In This Thread
War with deck of cards - by menator01 - Sep-24-2022, 03:34 AM

Forum Jump:

User Panel Messages

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