I implemented a card game using pygame, the game is a game of war and using png files that I made in Microsoft paint. I tried to keep the object classes as separated from the pygame module as possible. The idea of this is so I can use the CardClasses module with other graphical interfaces, and to reuse it on different games whose displays will be different. When I go to rewrite this, or something similar the idea is to plan on using a Game class as opposed to the more function paradigm I wrote here. I learned that I cant upload the card image files here so I will upload the code in hopes that some brave soul will comb through the lines and give me some feedback. Looking at how to rewrite the doc strings, I feel as though they are weak and only give the idea of the functions or classes they represent.
"""Created: 3/30/2019 Objects to represent a playing Card, playing Deck, and Player """ from enum import Enum from itertools import product from random import shuffle class ranks(Enum): TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE = range(2, 15) class suits(Enum): CLUBS,DIAMONDS,HEARTS,SPADES = range(1, 5) class Card(object): """Card object represents a standard playing card. The object attributes, suit and rank, are implemented as enums whose values determine the weight of the card """ def __init__(self, suit, rank, in_deck = False, image = None): if rank in ranks and suit in suits: self.rank = rank self.suit = suit else: self.rank = None self.suit = None self.in_deck = in_deck self.image = image self.position_x, self.position_y = 0,0 self.horizontal_demension = None self.vertical_demension = None def __str__(self): return str(self.rank.name) + " " + str(self.suit.name) def __eq__(self, other): return True if self.rank == other.rank and self.suit == other.suit else False def __gt__(self, other): """Tests suit precedence, if suits are equal then checks ranks precedence""" if self.suit == other.suit: if self.rank.value > other.rank.value: return True if self.suit.value > other.suit.value: return True return False class Deck(object): """A deck is a collection of 52 Card objects Object attributes: cards, removed methods: draw(range = 1), deck_shuffle() """ def __init__(self): self.cards = [Card(suit, rank, in_deck = True) for suit, rank in product(suits, ranks)] self.removed =  def __str__(self): return str([str(card) for card in self.cards]) def draw(self, range = 1): """Draw card(s) by removing them from deck""" drawn_cards = self.cards[:range] for card in drawn_cards: card.in_deck = False del self.cards[:range] self.removed.append(drawn_cards) return drawn_cards def deck_shuffle(self): """Shuffles deck object in place""" shuffle(self.cards) class Player(object): """Implementation of a player object Object attributes: name, hand, score, turn, card_selected methods: remove_from_hand(card) """ def __init__(self, name, hand = None, score = 0, turn = False): self.name = name self.hand = hand self.score = score self.turn = turn self.selected_card = None def __str__(self): return str(self.name) def remove_from_hand(self, card): """Removes a card object from the players hand""" if card and card in self.hand: position = self.hand.index(card) del self.hand[position] return card return None
"""3/31/2019 Implementation of game of war using pygame and CardClasses """ from CardClasses import * import pygame green = (0, 200, 50) def show_hand(screen, player): """Displays all cards in hand of player on pygame display object""" x, y, space_between_cards = 5, 462, 5 for card in player.hand: card.position_x, card.position_y = x, y screen.blit(card.image, (x, y)) x += card.horizontal_demension + space_between_cards def select_card(player, mouse_x, mouse_y): """Player selects a card to play""" if mouse_x: for card in player.hand: lower_x, upper_x = (card.position_x, card.position_x + card.horizontal_demension) lower_y, upper_y = (card.position_y, card.position_y + card.vertical_demension) if mouse_x > lower_x and mouse_x < upper_x: if mouse_y > lower_y and mouse_y < upper_y: player.selected_card = card def load_card_images(player): "Loads image, and demensions to card objects" for card in player.hand: card.image = pygame.image.load("Cards/" + str(card) + ".png") width, hieght = card.image.get_size() card.horizontal_demension = width card.vertical_demension = hieght def play_selected_card(screen, player): """Display card that is selected on pygame display object""" x = player.selected_card.position_x = 220 y = player.selected_card.position_y screen.blit(player.selected_card.image, (x,y)) def show_winner(screen, player1, player2, my_font): """Display text stating game winner at end of game""" screen.fill(green) winner = str(player1) if player1.score > player2.score else str(player2) textsurface = my_font.render("The winner is: " + winner, False, (0, 0, 0)) screen.blit(textsurface, (100, 270)) def update_selected_card_position(player, new_y_position): """Change the Y position of selected card to move card to played position""" if player.selected_card: player.selected_card.position_y = new_y_position def evaluate(player1, player2): """determines who won round and updates their score""" round_winner = None if player1.selected_card and player2.selected_card: pygame.time.delay(1000) round_winner = player1 if player1.selected_card > player2.selected_card else player2 round_winner.score += 1 player1.selected_card, player2.selected_card = None, None return round_winner def show_player_scores(screen, player1, player2): """Left corner is player 1 score, right corner is player 2 score""" font_size = 12 my_font = pygame.font.SysFont('Times New Roman', font_size) textsurface1 = my_font.render("Player 1 score: " + str(player1.score), False, (0, 0, 0)) textsurface2 = my_font.render("Player 2 score: " + str(player2.score), False, (0, 0, 0)) screen.blit(textsurface1, (0,0)) screen.blit(textsurface2, (470,0)) def flip_turns(player1, player2): """Negates Turn attributes of player1 and player2""" player1.turn = not player1.turn player2.turn = not player2.turn def turn(player, mouse_x, mouse_y, new_y_position): """Player will select card using mouse_x, and mouse_y, card will be removed from hand and played""" select_card(player, mouse_x, mouse_y) player.remove_from_hand(player.selected_card) update_selected_card_position(player, new_y_position) def winner_goes_first(winner, loser): """Sets the winner to the starter of the next round""" winner.turn = True loser.turn = False def main(): """GAME of war, each player is given a hand of 10 cards, on each turn a player will select a card to play, players cards will be compared and the player with the greater in value card will be assigned a point for round victory. When all cards in hand have been played game ends and winner is displayed """ sc_width, sc_height = 555, 555 selected_card_y_pos_player_1 = 330 selected_card_y_pos_player_2 = 230 font_size = 30 delay_time_ms = 1000 number_of_cards = 10 turn_count = 1 deck = Deck() deck.deck_shuffle() player1 = Player(input("Player 1 name: "), hand = deck.draw(number_of_cards), turn = True) player2 = Player(input("Player 2 name: "), hand = deck.draw(number_of_cards)) pygame.init() screen = pygame.display.set_mode((sc_width, sc_height)) load_card_images(player1) load_card_images(player2) pygame.font.init() my_font = pygame.font.SysFont('Times New Roman', font_size) """Main Game Loop""" game_is_running = True while game_is_running: screen.fill(green) mouse_x, mouse_y = None, None events = pygame.event.get() for event in events: if event.type == pygame.QUIT: game_is_running = False quit() if event.type == pygame.MOUSEBUTTONUP: mouse_x, mouse_y = pygame.mouse.get_pos() if player1.turn: show_hand(screen, player1) turn(player1, mouse_x, mouse_y, selected_card_y_pos_player_1) if player1.selected_card: flip_turns(player1, player2) else: show_hand(screen, player2) turn(player2, mouse_x, mouse_y, selected_card_y_pos_player_2) if player2.selected_card: flip_turns(player1, player2) if player1.selected_card: play_selected_card(screen, player1) if player2.selected_card: play_selected_card(screen, player2) show_player_scores(screen, player1, player2) pygame.display.update() winner = evaluate(player1,player2) if winner: if winner == player1: winner_goes_first(player1, player2) else: winner_goes_first(player2, player1) if not player1.hand and not player2.hand: show_winner(screen, player1, player2, my_font) pygame.display.update() pygame.time.delay(delay_time_ms) game_is_running = False if __name__ == '__main__': main()