Card Game using pygame module
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
$begingroup$
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.
CardClasses.py
"""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
Game.py
"""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()
python object-oriented game pygame
$endgroup$
add a comment |
$begingroup$
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.
CardClasses.py
"""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
Game.py
"""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()
python object-oriented game pygame
$endgroup$
add a comment |
$begingroup$
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.
CardClasses.py
"""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
Game.py
"""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()
python object-oriented game pygame
$endgroup$
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.
CardClasses.py
"""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
Game.py
"""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()
python object-oriented game pygame
python object-oriented game pygame
asked 3 hours ago
CE3601CE3601
355
355
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217109%2fcard-game-using-pygame-module%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217109%2fcard-game-using-pygame-module%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown