I am trying to code a card game in python using OOP.
the user should select either red( hearts and diamonds)
or black( clubs and spades)
the user then goes on with the game.
here is the code:
import random
class Card:
def __init__(self, name, suit):
self.name = name
self.suit = suit
def print_card(self):
print(self.name + ' of ' + self.suit)
def show(self):
print('{} of {}'.format(self.suit, self.name))
class Deck:
def __init__(self):
self.cards = []
self.build()
def build(self):
for s in ['Hearts', 'diamonds', 'Clubs', 'Spades']:
for v in range(1, 14):
self.cards.append(Card(s, v))
def shuffle(self):
random.shuffle(self.cards)
def show(self):
for c in self.cards:
c.show()
class Game:
def __init__(self, player, score):
self.player = player
self.score = score
self.cards = []
self.hand = []
def shuffle(self):
random.shuffle(self.cards)
def drawCard(self):
return self.cards.pop()
def draw(self, deck):
self.hand.append(deck.drawCard())
return self
def showHand(self):
for card in self.hand:
card.show()
def reset(self):
pass
print('Welcome message')
user = input("Please enter your name: ")
print('While you start your score is 1000')
team = input((' RED or BLACK \n Your team : '))
while True:
if team == 'red':
print('Great, You have chosen Team Red, hearts and diamonds will fetch you points, clubs and sp')
print("")
playGame = input(('Press ENTER to play'))
print('Game starts')
shuffleCard = input(('Press ENTER to shuffle and Pick your card'))
deck = Deck()
deck.shuffle()
print('That was a good mix')
showCard = input(('Press ENTER to reveal your card'))
user = Game(user, 1000)
user.showHand --> here i am expecting the final card to show up but its not happening
the terminal gives this error:
Traceback (most recent call last):
File "/Users/yoshithkotla/PycharmProjects/pythonFinalProject001/main.py", line 71, in <module>
player = player()
TypeError: 'str' object is not callable
Details of the problem : Using the OOP topics and programs we examined in our Lecture Notes 8 and 9 develop a Python
program to implement a card game.
You select the card game.
o You can invent your own simple card game; just provide the instructions for your card
game as comments in your Python program.
In our Lecture Notes 9, we will be developing OOP Python code for the fundamentals of a card
game. Use this code in your implementation of your card game. Add additional OOP code for your
specific card game.
Changes made:-
player=player() -> player=game()
Code:-
class game:
def __init__(self, player, score):
self.player = player
self.score = score
def start_game(self, player, score, team):
self.score = score
self.player = player
self.team = team
print("Welcome")
player = input("Please enter your name: ")
print('While you start your score is 1000')
team = input((' RED or BLACK \n Your team : '))
while team == 'red':
print('Great, You have chosen Team Red, hearts and diamonds will fetch you points, clubs and sp')
print("")
playGame = input(('Press ENTER to play'))
print('game starts')
shuffleCard = input(('Press ENTER to shuffle and Pick your card'))
deck = Deck()
deck.shuffle()
print(' that was a good mix')
showCard = input(('Press ENTER to reveal your card'))
player = game()
player.draw(deck)
player.showHand
break
Output:-
Welcome
Please enter your name: Yash
While you start your score is 1000
RED or BLACK
Your team : red
Great, You have chosen Team Red, hearts and diamonds will fetch you points, clubs and sp
Press ENTER to play
Updated query:-
I think you should go with the process to learn all the conditions for the game than start your code.. for reference you should follow this -> click here to know all the conditions for the game and then try to code..!
In the line player = player() you are trying to call a function named 'player' by adding brackets. Player is not a function but a string variable where you store the entered name of a player, so you cannot call it.
Try to erase the brackets or delete line completely (since you've already assigned the variable in line player = input("Please enter your name: ")).
Related
I am trying to write my first python project blackjack. I was advised to write the program with each class and its methods in a different file so that the code would be more manageable. I divided my code up into smaller files and used import statements.
When I run my code I get the following error message:
Chips.place_bet() missing 1 required positional argument. self.
I thought self was, pardon the pun, self explanatory. I do not need to put a value for self. I am wondering if this is an import issue.
I am trying to get my place_bet function to activate so that I can ask the user to input the number of chips for a bet. Can anyone advise me on how to do this?
My code is spread over these files:
blackjack.py
import random
from player import Player
from hand import Hand
from chips import Chips
from deck import Deck
from card import Card
# import helper_functions
# Blackjack/
# ├── app/
# │ ├── card.py
# │ ├── chips.py
# │ ├── deck.py
# │ ├── hand.py
# │ ├── player.py
# │ ├── main.py
# │ ├── helper_functions.py
# Gameplay and Outline of Project
# Welcome message and rules
print("Welcome to Blackjack! The rules for blackjack can be found here. https://www.youtube.com/watch?v=PljDuynF-j0")
print("The object of this blackjack game is to make it to 100 chips. You will start with 25 chips.")
# Establish player name
print("Please insert your player name: ")
player_name = input()
print('Please insert your player name ' + player_name)
print("Lets get started" + player_name + "please place your bet!")
# Place the bets BEFORE the cards are dealt. Pure risk.
place_bet()
# . Deal 2 cards to user and dealer
# . print a message explaining the total hand value of the user. ask player to hit/stay?
# . If the player busts print player busts. if the player is under 21 ask them again to hit or stay.
# . If stay, move on to dealers turn.
# . If the hand is less than 17 have him hit, if it is over 17 have the dealer stay.
# . If the dealer stays print the dealers hand total. IF the dealers hand total is greater than the player the dealer wins.
# . if the dealer busts print the message he busts and the player wins and the player gets the chips.
# 1. Ask dealer to hit/stay?
# 2. If hit, deal 2 cards
# 3. If broke or blackjack deliver message
# 4. If stay, compare hands
# 5. If users hand is closer to 21, (user wins)
# 6. If dealers hand is closer to 21, (user loses)
def main():
player = Player('strikeouts27', 500,)
dealer = Player()
player_chips = Chips()
dealer_chips = Chips()
cards = Card()
deck = Deck()
if __name__ == '__main__':
main()
card.py
class Card:
"""Card class"""
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __repr__(self):
return f'{self.__class__.__name__}(rank={self.rank}, suit={self.suit})'
class Chips:
"""Chip class manages chip balance"""
def __init__(self, balance):
self.balance = balance
self.bet = 0
def place_bet(self):
while True:
total = input(f'How much do you bet? (1-{self.balance}):\n> ')
# return True if a digit string. false otherwise. hover over the method for visual studio code to show you.
if not total.isdigit():
continue
total = int(total)
if total > self.balance:
print('You do not have enough')
continue
return total
def add_value(self, value):
"""Add value to chip total"""
self.balance += value
def deduct_value(self, value):
"""Deduct value from chip total"""
self.balance -= value
def display_chips(player, dealer):
print(f'player chips: ${player.chips.balance}')
print(f'dealer chips: ${dealer.chips.balance}')
# Displays player and dealer chip count
class.py
class Card:
#"""Card class"""
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __repr__(self):
return f'{self.__class__.__name__}(rank={self.rank}, suit={self.suit})'
deck.py
class Deck:
"""Deck class, represents 52 cards"""
def __init__(self):
self.ranks = [str(n) for n in range(2, 11)] + list('jqka')
self.suits = ["hearts", "diamonds", "clubs", "spades"]
self.cards = [Card(rank, suit)
for suit in self.suits for rank in self.ranks]
random.shuffle(self.cards)
# dunder method rewrites what pythons default method to show better information about itself.
def __repr__(self):
return f'{self.__class__.__name__}({self.cards})'
def __len__(self):
return len(self.cards)
def __getitem__(self, item):
return self.cards[item]
def shuffle(self):
"""shuffles deck of cards"""
random.shuffle(self.cards)
hand.py
class Hand:
"""Hand class to hold the cards for the player and the dealer"""
def __init__(self, cards=None):
self.cards = [] if cards is None else cards
self.value = 0
self.aces = 0
def add_to_hand(self, card):
"""Adds a cards to self.cards."""
self.cards.append(card)
def display_hand(self):
hashtable = {'hearts': 9829, 'diamonds': 9830,
'spades': 9824, 'clubs': 9827}
return [[i.rank, chr(hashtable.get(i.suit))] for i in self.cards]
def display_hand_two(player, dealer):
# Displays player and dealer hand
print(
f'players Hand: {player.hand.display_hand()} --> total {player.total}')
print(
f'dealer Hand: {dealer.hand.display_hand()} --> total {dealer.total}')
player.py
class Player:
"""Player class"""
def __init__(self, name, chips, hand):
self.name = name
self.chips = chips
self.hand = hand
#property
def total(self):
"""Returns the value of the cards. Face cards equal 10, aces can equal
11 or 1, this function picks best case"""
value = 0
aces_count = 0
# Each card is a tuple in a list:
cards = [card for card in self.hand.cards]
for card in cards:
if card.rank == 'a':
aces_count += 1
elif card.rank in 'kqj':
# Face cards are worth 10 points
value += 10
else:
# Numbered cards are worth their value.
value += int(card.rank)
# Add value of aces - 1 per ace
value += aces_count
for i in range(aces_count):
# If another 10 can be added,then do it!
if value + 10 <= 21:
value += 10
return value
#staticmethod
def get_move():
"""returns player choice to hit or stand"""
move = input('>>> (H)it, (S)tand ?:\n> ').lower()
return move
def main():
# Instantiate Deck
deck = Deck()
# shuffle deck
deck.shuffle()
# Instantiate player and dealer chips
player_chips = Chips(500)
dealer_chips = Chips(500)
while True:
# Instantiate player and dealer hand
player_hand = Hand()
dealer_hand = Hand()
# Instantiate player and dealer
player = Player('seraph', player_chips, player_hand)
dealer = Player('codecademy', dealer_chips, dealer_hand)
# Check if player has enough money
if player_chips.balance <= 0:
print('need more money')
# Then place bet
bet = player_chips.place_bet()
# player draws 2 cards
player.hand.add_to_hand(deck.cards.pop())
player.hand.add_to_hand(deck.cards.pop())
# Dealer draws cards
dealer.hand.add_to_hand(deck.cards.pop())
dealer.hand.add_to_hand(deck.cards.pop())
# display player ann dealers hand
display_hand(player, dealer)
# Begin game
while True:
if player.total > 21:
break
# Get the player's moves
player_move = player.get_move()
if player_move == 'h':
new_card = deck.cards.pop()
rank, suit = new_card.rank, new_card.suit
player.hand.add_to_hand(new_card)
print(f'You drew a {rank} of {suit}')
display_hand(player, dealer)
if player.total > 21:
print('You busted...')
# Busted
continue
if player_move == 's':
break
# Get the dealer's moves
if dealer.total <= 21 and not player.total > 21:
while dealer.total <= 17:
print('Dealer hits...')
new_card = deck.cards.pop()
dealer.hand.add_to_hand(new_card)
if dealer.total > 21:
break
if dealer.total > 21:
print('Dealer Busted - You win!')
display_hand(player, dealer)
player.chips.add_value(bet)
dealer.chips.deduct_value(bet)
display_chips(player, dealer)
elif player.total > 21 or player.total < dealer.total:
print('You lost!')
display_hand(player, dealer)
player.chips.deduct_value(bet)
dealer.chips.add_value(bet)
display_chips(player, dealer)
elif player.total == dealer.total:
print("It's a tie! Money is returned")
if __name__ == '__main__':
main()
Does anyone have advice for a rookie?
I have tried calling the function and have gotten an error. Nothing else to be honest.
A few issues:
The file class.py is redundant. It is not imported, and only defines a class that is already defined in card.py.
There are two main function definitions. One in blackjack.py and one in player.py. The first one defines a player 'strikeouts27', while the other defines 'seraph', 'codecademy'. The second one seems the more developed one, and uses more than what is in player.py, and so it should actually be moved into blackjack.py.
Related to the previous point: blackjack.py has code that executes outside of any function. This counters the pattern where you put the driver code in a function main. It is better to move all relevant driver code inside one main function that is placed in blackjack.py. But still, that code looks unfinished, and the code already present in main is much more developed. I think you only need the code in main (the larger one).
Related to the previous point: that code in blackhack.py calls a function place_bet which is not defined. There is a method with that name, but not a standalone function with that name. For calling the method you first need an instance of Chips, so like I mentioned in the previous bullet, I would suggest to just remove this code, including also the input that is made there. Maybe you just want to keep the introductory print statements that are made there, and move those into main.
random is used in deck.py, but it is imported in blackjack.py. It would make deck.py more self-contained, if you would move that import statement to the deck.py file.
display_hand_two should not be a method of the Hand class. It doesn't even expect a self argument of the type Hand. Instead this should be a standalone function in blackjack.py.
In main you have several calls like display_hand(player, dealer), but display_hand is not a standalone function, but a method. What you really wanted to do here, is call display_hand_two(player, dealer), and for that to work you must make display_hand_two a standalone function as mentioned in the previous bullet point.
If you implement all those changes, your code will run.
I'm playing with Python 3 and putting together an RPG-style system, but am struggling with OOP as I've not really used it in python before.
I'm specifically struggling with the following function:
def choosestat(statname, max, min):
# Takes the name of the stat
# as mentioned in the Player/Character class and
# a min/max value for the length. Allows the player
# to set their stats for the char.
print("Your stat choices are: " + str(stats))
choice = int(input("Please select a strength score ("+min+":"+max+")\n"))
if type(choice) == int and choice < (max+1) and choice > (min-1):
self.statname = stats[choice-1]
stats.pop(choice-1)
else:
print("Please select a valid option.\n")
This should be pulling from the below, to set playerchar.strength to the selected amount:
class Character(object):
# A Class for ALL characters - player, enemy etc.
def __init__(self, name, hp, armor, damage, strength,
intelligence, wisdom, dexterity, constitution, charisma,
inventory, profession):
self.name = name
self.hp = hp
self.armor = armor
self.damage = damage
self.strength = strength
self.intelligence = intelligence
self.wisdom = wisdom
self.dexterity = dexterity
self.constitution = constitution
self.charisma = charisma
self.inventory = inventory
self.profession = profession
class Player(Character):
# A class for the Player character only.
# We will use a few parameters to set initial variables
def __init__(self):
super().__init__(name="", hp=10, armor=10, damage=10, strength=7,
intelligence=7, wisdom=7, dexterity=7, constitution=7,
charisma=7, inventory=[], profession="")
maxhp = 10
level = 1
exp = 0
However, when I run the code, I simply get:
Traceback (most recent call last):
File "main.py", line 122, in <module>
menu()
File "main.py", line 53, in menu
gameloop()
File "main.py", line 73, in gameloop
statchoice()
File "main.py", line 108, in statchoice
choosestat(strength, 6, 1)
NameError: name 'strength' is not defined
The full code is here:
import os
import random
import time
from utilities import roll
class Character(object):
# A Class for ALL characters - player, enemy etc.
def __init__(self, name, hp, armor, damage, strength,
intelligence, wisdom, dexterity, constitution, charisma,
inventory, profession):
self.name = name
self.hp = hp
self.armor = armor
self.damage = damage
self.strength = strength
self.intelligence = intelligence
self.wisdom = wisdom
self.dexterity = dexterity
self.constitution = constitution
self.charisma = charisma
self.inventory = inventory
self.profession = profession
class Player(Character):
# A class for the Player character only.
# We will use a few parameters to set initial variables
def __init__(self):
super().__init__(name="", hp=10, armor=10, damage=10, strength=7,
intelligence=7, wisdom=7, dexterity=7, constitution=7,
charisma=7, inventory=[], profession="")
maxhp = 10
level = 1
exp = 0
class Enemy(Character):
# a class for any enemy.
def __init__(self):
super().__init__(name=enemyname, hp=10, armor=10, damage=10,
strength=7, intelligence=7, wisdom=7, dexterity=7,
constitution=7, charisma=7, inventory=[],
profession="")
playerchar = Player()
# simply call playerchar rather than calling the Class each time
def menu():
# Running the Main Menu under a single Function.
# This is the simplest method of running the menu
while True:
print("|==================|")
print("Welcome to Py RPG!")
print("Please select an option!")
print("1. Start a Game\n")
print("2. Settings\n")
print("3. Quit")
choice = input("\n>")
if choice == 1 or choice == "start":
gameloop()
elif choice == 2 or choice == "settings":
settings()
elif choice == 3 or choice == "quit":
break
else:
print("Please select an option from the menu.")
def settings():
# Settings page for all amendments
# TODO - create a 'settings' file and have this read/amend it?
print("Nothing exists here at the moment!")
menu()
def gameloop():
# the main game loop, contains all calls to relevant functions
while True:
print("This is the main game")
print("Let's begin. What is your name?")
playerchar.name = input(">")
print("Well then, " + playerchar.name + ", let us begin.")
statchoice()
def choosestat(statname, max, min):
# Takes the name of the stat
# as mentioned in the Player/Character class and
# a min/max value for the length. Allows the player
# to set their stats for the char.
print("Your stat choices are: " + str(stats))
choice = int(input("Please select a strength score ("+min+":"+max+")\n"))
if type(choice) == int and choice < (max+1) and choice > (min-1):
self.statname = stats[choice-1]
stats.pop(choice-1)
else:
print("Please select a valid option.\n")
def displaystats(entity):
# quick function to display all relevant stats in-line.
print("Are you happy with your choices?\n")
print("Strength: " + str(entity.strength))
print("Intelligence: " + str(entity.intelligence))
print("Wisdom: " + str(entity.wisdom))
print("Dexterity: " + str(entity.dexterity))
print("Constitution: " + str(entity.constitution))
print("Charisma: " + str(entity.charisma))
def statchoice():
# Using the roll function, we get 6 ability scores, append them to 'stats',
# and run the choosestat function for each to set stats.
stats = []
stats.append(roll(4, 6))
stats.append(roll(4, 6))
stats.append(roll(4, 6))
stats.append(roll(4, 6))
stats.append(roll(4, 6))
stats.append(roll(4, 6))
choosestat(strength, 6, 1)
choosestat(intelligence, 5, 1)
choosestat(wisdom, 4, 1)
choosestat(dexterity, 3, 1)
choosestat(constitution, 2, 1)
choosestat(charisma, 1, 1)
displaystats(playerchar)
reroll = input("Do you wish to re-roll?")
if reroll == "yes" or reroll == "y":
statchoice()
menu()
You can use setattr().
choosestat('strength', 6, 1)
def choosestat(statname, max, min):
print("Your stat choices are: " + str(stats))
choice = int(input("Please select a strength score ("+min+":"+max+")\n"))
if type(choice) == int and choice < (max+1) and choice > (min-1):
setattr(self, statname, stats[choice-1]
stats.pop(choice-1)
else:
print("Please select a valid option.\n")
It's important to pass a string of the field name you want to change to setattr() or in this case through choosestat().
You want your choosestat function inside your class if you are calling self.*something*. Right now it's not. If you move that inside your Character class and add the self argument to it. Then you can access members of that class. Right now in statchoice, strength is not defined. You could try passing in a string "strength" and having a dict inside of choosestat (a member of Character) that maps the strings to their member counter parts:
{"strength" : self.strength, "intelligence" : self.intelligence} and so forth. Also, I don't think that your stats array is global, so you'll either have to make it global or somehow a member of the class and rework some of your other functions, too.
Through some educational materials I've been tasked to use the below structure (the classes) for a text adventure game and am required to add a simple combat system for battle between a hero and an enemy.
Currently I am able to have an enemy created in each room and move between the start room(corridor) to the bathroom and back, but at this point I'm stuck. I can't determine where I should be creating my 'hero' or how I'd communicate the changes I'd need to make to the health attributes etc.
If I could structure the code in another way, I would be able to complete the game, but as it is there is a gap in my understanding of how to enable various sections of code communicate with each other.
Thanks,
Dave
# text based adventure game
import random
import time
from sys import exit
class Game(object):
def __init__(self, room_map):
self.room_map = room_map
def play(self):
current_room = self.room_map.opening_room()
while True:
next_room_name = current_room.enter()
current_room = self.room_map.next_room(next_room_name)
class Character(object):
def __init__(self, name, health, attack):
self.name = name
self.health = health
self.attack = attack
class Hero(Character):
def __init__(self, name):
super(Hero, self).__init__(name, 10, 2)
def __str__(self):
rep = "You, " + self.name + ", have " + str(self.health) + " health and " + \
str(self.attack) + " attack."
return rep
class Enemy(Character):
ENEMIES = ["Troll", "Witch", "Ogre", "Jeremy Corbyn"]
def __init__(self):
super(Enemy, self).__init__(random.choice(self.ENEMIES),
random.randint(4, 6), random.randint(2, 4))
def __str__(self):
rep = "The " + self.name + " has " + str(self.health) + \
" health, and " + str(self.attack) + " attack."
return rep
class Room(object):
def __init__(self):
self.commands = ["yes", "no"]
self.rooms = ["\'corridor\'", "\'bathroom\'", "\'bedroom\'"]
self.enemy = Enemy()
def command_list(self):
print("Commands: ", ", ".join(self.commands))
def enter_room_question(self):
print("Which room would you like to enter?")
print("Rooms:", ", ".join(self.rooms))
def leave_room_question(self):
print("Do you want to leave this room?")
print("Commands:", ", ".join(self.commands))
class Bathroom(Room):
def enter(self):
print("You enter the bathroom. But, wait! There is an", \
self.enemy.name, "!")
print(self.enemy)
print("You are in the bathroom. Need to take a dump? ")
self.command_list()
response = input("> ")
while response not in self.commands:
print("Sorry I didn't recognise that answer")
print("You are in the bathroom. Need to take a dump?")
self.command_list()
response = input("> ")
if response == "yes":
print("Not while I'm here!")
return "death"
elif response == "no":
print("Good.")
self.leave_room_question()
response = input("> ")
if response == "yes":
return "corridor"
else:
return "death"
class Bedroom(Room):
def enter(self):
pass
class Landing(Room):
def enter(self):
pass
class Corridor(Room):
def enter(self):
print("You are standing in the corridor. There are two rooms available to enter.")
self.enter_room_question()
response = input("> ")
if response == "corridor":
print("You're already here silly.")
else:
return response
class Death(Room):
QUIPS = ["Off to the man in sky. You are dead",
"You died, no-one cried.",
"Lolz. You're dead!"]
def enter(self):
time.sleep(1)
print(random.choice(Death.QUIPS))
exit()
class Map(object):
ROOMS = {"corridor": Corridor(),
"bathroom": Bathroom(),
"death": Death(),
"landing": Landing(),
"bedroom": Bedroom()}
def __init__(self, start_room):
self.start_room = start_room
self.hero = hero
def next_room(self, room_name):
return Map.ROOMS.get(room_name)
def opening_room(self):
return self.next_room(self.start_room)
a_hero = Hero("Dave")
a_map = Map("corridor")
a_game = Game(a_map, a_hero)
a_game.play()
If I were you, I would set out a game schema. You could find out asking yourself questions like this:
What are the really important entities?
In your case, as you have done, I would consider Character, Enemy, Room and Map, inheriting when it would be appropiate, like Character-> Hero and Enemy, and several types of room from Room as Bathroom, Corridor, ...
If I were you a consider using a data structure to represent the Map. For example, if you are considering do a text game adventure, you could think in different rooms as different states in your game. If you are in the bathroom, you could be attacked by an enemy and if you are in the bedroom, you can retrieve your hitpoints (life) so these places can be thought as different states.
As an example, you would an array for group all your different rooms (states)
rooms = ["bedroom", "bathroom", "corridor", "kitchen", "living_room"]
and other rooms that you can think about.
(there is probably a better example, more efficient and so on, so this example is to help you about not giving up when you gets stuck about an problem.
According to this example, if you use an array, you can assign a value to each room (equal to each position in the array)
Moreover, you will need to know the hero's position, so you could assign a random value to it using rand(). You can read links below for more information:
random docs python
stackoverflow answer
At last, you also would find useful to compare the hero's position, which would have a random assigned value previously with every position of your array or rooms
In this cases, you could use a if... elif.. elif... to compare those values and do something according to the room where your hero would be.
I hope this answer will be useful for you.
Let me know if you have any doubt about my answer.
Cheers
I have windows 8 running on my computer and I think I downloaded python 2 and 3 simultaneously or I think my computer has built in python 2 and I downloaded python 3. And now when I ran my code in IDLE, the code works fine but when I save my program and double click the save file, it will run but it doesn't worked like it used to work in IDLE.
Can someone explain the possible problem I'm currently facing?
I just want my program to run perfectly in both IDLE and when I double click the saved file.
I tried what Anand S. Kumar suggested but I'm not sure I know what I'm doing.
So here is what I inputted in the CMD adminstrator but the output is still the same as the first picture above.
so here is the code
the games module:
# Games
# Demonstrates module creation
class Player(object):
""" A player for a game. """
def __init__(self, name, score = 0):
self.name = name
self.score = score
def __str__(self):
rep = self.name + ":\t" + str(self.score)
return rep
def ask_yes_no(question):
"""Ask a yes or no question."""
response = None
while response not in("y", "n"):
response = input(question).lower()
return response
def ask_number(question, low, high):
"""Ask for a number within a range."""
response = None
while response not in range(low, high):
response = int(input(question))
return response
if __name__ == "__main__":
print("You ran this module directly (and did not 'import' it).")
input("\n\nPress the enter key to exit.")
the cards module:
# Cards Module
# Basic classes for a game with playing cards
class Card(object):
""" A playing card. """
RANKS = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
SUITS = ["c", "d", "h", "s"]
def __init__(self, rank, suit, face_up = True):
self.rank = rank
self.suit = suit
self.is_face_up = face_up
def __str__(self):
if self.is_face_up:
rep = self.rank + self.suit
else:
rep = "XX"
return rep
def flip(self):
self.is_face_up = not self.is_face_up
class Hand(object):
"""A hand of playing cards."""
def __init__(self):
self.cards = []
def __str__(self):
if self.cards:
rep = ""
for card in self.cards:
rep += str(card) + "\t"
else:
rep = "<empty>"
return rep
def clear(self):
self.cards = []
def add(self, card):
self.cards.append(card)
def give(self, card, other_hand):
self.cards.remove(card)
other_hand.add(card)
class Deck(Hand):
""" A deck of playing card. """
def populate(self):
for suit in Card.SUITS:
for rank in Card.RANKS:
self.add(Card(rank, suit))
def shuffle(self):
import random
random.shuffle(self.cards)
def deal(self, hands, per_hand = 1):
for rounds in range(per_hand):
for hand in hands:
if self.cards:
top_card = self.cards[0]
self.give(top_card, hand)
else:
print("Can't continue deal. Out of cards!")
if __name__ == "__main__":
print("This is a module with classes for playing cards.")
input("\n\nPress the enter key to exit.")
and then the main code:
# Blackjack
# From 1 to 7 players compete against a dealer
# Daghan pakog wa nasabtan ani so balikan pa nako ni!
import cards, games
class BJ_Card(cards.Card):
""" A Blackjack Card. """
ACE_VALUE = 1
#property
def value(self):
if self.is_face_up:
v = BJ_Card.RANKS.index(self.rank) + 1 # unsaon pag kabalo sa self.rank xia.
if v > 10:
v = 10
else:
v = None
return v
class BJ_Deck(cards.Deck):
""" A Blackjack Deck. """
def populate(self):
for suit in BJ_Card.SUITS:
for rank in BJ_Card.RANKS:
self.cards.append(BJ_Card(rank, suit)) # kay naa may __init__ sa BJ_Card
class BJ_Hand(cards.Hand):
""" A Blackjack Hand. """
def __init__(self, name):
super(BJ_Hand, self).__init__()
self.name = name
def __str__(self):
rep = self.name + ":\t" + super(BJ_Hand, self).__str__()
if self.total:
rep += "(" + str(self.total) + ")"
return rep
#property
def total(self):
# if a card in the hand has value of None, then total is None
for card in self.cards:
if not card.value:
return None
# add up card values, treat each ACE as 1
t= 0
for card in self.cards:
t += card.value #-->? tungod sa # property pwede na xa .value ra
#--> Libog ning diri dapita, unsaon pag kabalo nga self.rank xia
# determine if hand contains an ACE
contains_ace = False
for card in self.cards:
if card.value == BJ_Card.ACE_VALUE:
contains_ace = True
# if hand contains Ace and total is low enough, treat Ace as 11
if contains_ace and t <= 11:
# add only 10 since we've already added 1 for the Ace
t += 10
return t
def is_busted(self):
return self.total > 21
class BJ_Player(BJ_Hand):
""" A Blackjack Player. """
def is_hitting(self):
response = games.ask_yes_no("\n" + self.name + ", do you want a hit? (Y/N): ")
return response == "y"
def bust(self):
print(self.name, "busts.")
self.lose()
def lose(self):
print(self.name, "losses.")
def win(self):
print(self.name, "wins.")
def push(self):
print(self.name, "pushes.")
class BJ_Dealer(BJ_Hand):
""" A Blackjack Dealer. """
def is_hitting(self):
return self.total < 17
def bust(self):
print(self.name, "busts.")
def flip_first_card(self):
first_card = self.cards[0]
first_card.flip()
class BJ_Game(object):
""" A Blackjack Game. """
def __init__(self, names):
self.players = []
for name in names:
player = BJ_Player(name)
self.players.append(player)
self.dealer = BJ_Dealer("Dealer")
self.deck = BJ_Deck()
self.deck.populate()
self.deck.shuffle()
#property
def still_playing(self):
sp = []
for player in self.players:
if not player.is_busted():
sp.append(player)
return sp
def __additional_cards(self, player):
while not player.is_busted() and player.is_hitting():
self.deck.deal([player])
print(player)
if player.is_busted():
player.bust()
def play(self):
# deal initial 2 cards to everyone
self.deck.deal(self.players + [self.dealer], per_hand =2)
self.dealer.flip_first_card() # hide dealer's first card
for player in self.players:
print(player)
print(self.dealer)
# deal additional cards to playeres
for player in self.players:
self.__additional_cards(player)
self.dealer.flip_first_card() # reveal dealer's first
if not self.still_playing:
# since all players have busted, just show the dealer's hand
print(self.dealer)
else:
# deal additional cards to dealer
print(self.dealer)
self.__additional_cards(self.dealer)
if self.dealer.is_busted():
# everyone still playing wins
for player in self.still_playing:
player.win()
else:
# compare each player still playing to dealer
for player in self.still_playing:
if player.total > self.dealer.total:
player.win()
elif player.total < self.dealer.total:
player.lose()
else:
player.push()
# remove everyone's cards
for player in self.players: # dapat inside ra xia sa class kay kung dili. self is not defined.
player.clear()
self.dealer.clear()
def main():
print("\t\tWelcome to Blackjack!\n")
names = []
number = games.ask_number("How many players? (1 - 7): ", low = 1, high = 8)
for i in range(number):
name = input("Enter player name: ")
names.append(name)
print()
game = BJ_Game(names)
again = None
while again != "n":
game.play()
again = games.ask_yes_no("\nDo you want to play again?: ")
main()
input("\n\nPress the enter key to exit.")
Please don't mind the comments if you don't understand. That is my first language by the way.
Most probably, the default program associated with .py files is the Python 2.x's executable . That could be the reason it is not running correctly, when you double-click the python file.
Because when you double click a file (or run it in command prompt without giving an executable ) , windows picks up the default program that is associated with .py files and runs the file using that executable.
In your case, even though you installed Python 3, this may still be pointing to Python 2.
From python installation doc, to change the default executable for Python files , use -
You can also make all .py scripts execute with pythonw.exe, setting
this through the usual facilities, for example (might require
administrative rights):
Launch a command prompt.
Associate the correct file group with .py scripts:
assoc .py=Python.File
Redirect all Python files to the new executable:
ftype Python.File=C:\Path\to\python3.exe "%1" %*
Use the above to redirect .py files to Python 3.
I have never tried to run a Python program by double clicking the save file, but I can point you in the direction that tells you how to run a program in the Command Line or Python Shell.
First off, Windows does not come with Python 2 or 3. You can check which version you have by simply going to wherever the Python files were installed. By default, they will be in the C drive. Once you have your enviornment path set up, you can also check which version of Python you have via the Python shell.
Here is where you can find the steps to set up your environment to run Python from the Command Line. This also will help you set up your enviornment. Essentially what you are doing is telling Windows where to find the Python libraries when you type 'python' into the Command Line. Once you have your environment set up, you can run your files in the Command Line or in the Python Shell. Look at Escualo's answer for how to do this.
You could try to to change the assosiation to:
python.file="C:\Windows\py.exe" "%L" %*
or set the "C:\Windows" part to where-ever Python3.exe is.
The Python installer (for Python3 at least) seems to specify that the filename should be on the wide-character form; Hence the %L modifier.
BTW. You can use ftype in your cmd-shell too (instead of poking around
in Explorer). Untested, so beware:
ftype python.file=="C:\Windows\py.exe" "%L" %*
I'm trying to program the card game Euchre in Python and I'm running into some errors with it. I'll post my code below and then explain my current problem:
import random
class Card(object):
'''defines card class'''
RANK=['9','10','J','Q','K','A'] #list of ranks & suits to make cards
SUIT=['c','s','d','h']
def __init__(self,rank,suit):
self.rank=rank
self.suit=suit
def __str__(self):
rep=self.rank+self.suit
return rep
#Next four definitions haven't been used yet. Goal was to use these
#to define a numerical vaule to each card to determine which one wins the trick
def getSuit(self):
return self.suit
def value(self):
v=Card.RANK.index(self.rank)
return v
def getValue(self):
print(self.value)
def changeValue(self,newValue):
self.value=newValue
return self.value
class Hand(object):
def __init__(self):
self.cards=[]
def __str__(self):
if self.cards:
rep=''
for card in self.cards:
rep+=str(card)+'\t'
else:
rep="EMPTY"
return rep
def clear(self):
self.cards=[]
def add(self,card):
self.cards.append(card)
def give(self,card,other_hand):
self.cards.remove(card)
other_hand.add(card)
def remove(self,card):
self.cards.remove(card)
class Deck(Hand):
def populate(self):
for suit in Card.SUIT:
for rank in Card.RANK:
self.add(Card(rank,suit))
def shuffle(self):
random.shuffle(self.cards)
def reshuffle(self):
self.clear()
self.populate()
self.shuffle()
def deal(self,hands,hand_size=1):
for rounds in range(hand_size):
for hand in hands:
if self.cards:
top_card=self.cards[0]
self.give(top_card,hand)
else:
print("Out of cards.")
#These two are the total scores of each team, they haven't been used yet
player_score=0
opponent_score=0
#These keep track of the number of tricks each team has won in a round
player_tricks=0
opponent_tricks=0
deck1=Deck()
#defines the hands of each player to have cards dealt to
player_hand=Hand()
partner_hand=Hand()
opp1_hand=Hand()
opp2_hand=Hand()
trump_card=Hand() #This is displayed as the current trump that players bid on
played_cards=Hand() #Not used yet. Was trying to have played cards removed from
#their current hand and placed into this one in an attempt to
#prevent playing the same card more than once. Haven't had
#success with this yet
hands=[player_hand,opp1_hand,partner_hand,opp2_hand]
deck1.populate()
deck1.shuffle()
print("\nPrinting the deck: ")
print(deck1)
deck1.deal(hands,hand_size=5)
deck1.give(deck1.cards[0],trump_card)
def redeal(): #just to make redealing cards easier after each round
player_hand.clear()
partner_hand.clear()
opp1_hand.clear()
opp2_hand.clear()
trump_card.clear()
deck1.reshuffle()
deck1.deal(hands,hand_size=5)
deck1.give(deck1.cards[0],trump_card)
print("\nPrinting the current trump card: ")
print(trump_card)
while player_tricks+opponent_tricks<5:
#Converts players hand into a list that can have its elements removed
Player_hand=[str(player_hand.cards[0]),str(player_hand.cards[1]),str(player_hand.cards[2]),\
str(player_hand.cards[3]),str(player_hand.cards[4])]
print("\nYour hand: ")
print(Player_hand)
played_card=str(raw_input("What card will you play?: "))#converts input into a string
if played_card==Player_hand[0]: #crudely trying to remove the selected card
Player_hand.remove(Player_hand[0]) #from player's hand
if played_card==Player_hand[1]:
Player_hand.remove(Player_hand[1])
if played_card==Player_hand[2]:
Player_hand.remove(Player_hand[2])
if played_card==Player_hand[3]:
Player_hand.remove(Player_hand[3])
if played_card==Player_hand[4]: #received the 'list index out of range' error
Player_hand.remove(Player_hand[4]) #here. Don't know why this is an error since
#Player_hand has 5 elements in it.
opp1_card=opp1_hand.cards[0] #just having a card chosen to see if the game works
#will fix later so that they select the best card
#to play
partner_card=partner_hand.cards[0]
opp2_card=opp2_hand.cards[0]
print("First opponent plays: ")
print(opp1_card)
print("Your partner plays: ")
print(partner_card)
print("Second opponent plays: ")
print(opp2_card)
trick_won=[0,1] #Just used to randomly decide who wins trick to make sure score is
#kept correctly
Trick_won=random.choice(trick_won)
if Trick_won==0:
print("\nYou win the trick!")
player_tricks+=1
if Trick_won==1:
print("\nOpponent wins the trick!")
opponent_tricks+=1
if player_tricks>opponent_tricks:
print("\nYou win the round!")
if opponent_tricks>player_tricks:
print("\nOpponont wins the round!")
print("\nGOOD GAME") #Just to check that game breaks loop once someone wins the round
So far what I'm able to accomplish is have a deck created and each of the four players be dealt a five card hand and then have the player asked what card they would like to play. Once they play a card, the other three players (two opponents and a partner) play their cards and then I randomly decide who wins the "trick" just to see if the score is being kept correctly.
The current problem I'm trying to tackle is that once a player plays a card and the trick is played out, on the next trick they should have one less card in their hand when it's displayed but I'm not able to remove the card that was previously played so the player will still have five cards in their hand.
Do any of you know what I'm doing wrong and how I can have the selected card removed? Thanks for any help.
The IndexError you're getting is because you're using multiple ifs instead of elif.
if played_card==Player_hand[0]:
Player_hand.remove(Player_hand[0])
# The next if is still evaluated, with the shortened Player_hand
if played_card==Player_hand[1]:
Player_hand.remove(Player_hand[1])
use:
if played_card==Player_hand[0]:
Player_hand.remove(Player_hand[0])
elif played_card==Player_hand[1]:
Player_hand.remove(Player_hand[1])
But yeah, use those classes you made, and use __eq__ to compare.