Next Python question...
So I have a student who is working on a self playing game of Go Fish game in Python 3 and is having an issue with the card draw. The problem is that the program deals the same card to each player, in order, ie: Player 1 gets 4 of Spades, 2 of Diamonds, 8 of Hearts, etc, Player 2 gets same, Player 3 gets same, etc).
We're not sure how to get it to re-loop through the randomizing portion of the code for each draw, for each player.
Thanks!
First here is the deck module and posted second is the game code.
import random
def MakeDeck():
deck = []
c = 0
values = ["Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"]
suits = ["Hearts", "Spades", "Diamonds", "Clubs"]
for v in values:
for s in suits:
deck.append([v,s])
random.shuffle(deck)
return deck
Now, the game code...
import deck, random, time
fish_deck = deck.MakeDeck()
#for i in fish_deck:
# print(i[0]+" of "+i[1])
class fisherman():
name = ""
hand = []
sets = []
def ask(player1, player2):
pause = random.randint(2,5)
has = []
choose = randint(0,len(player1.hand)-1)
value = player1.hand[choose][0]
for card in player2.hand:
if card[0] == value:
has.append(card)
for card in has:
player2.hand.remove(card)
for card in has:
player1.hand.append(card)
return_string = player1.name+" asked "+player2.name+" for "+value+"s. "
print(return_string)
return_string = player2.name+" had "+str(len(has))+". "
print(return_string)
if len(has) == 0:
draw(player1)
return_string = player1.name+" had to go fish."
print(return_string)
def draw(player):
card = fish_deck.pop()
player.hand.append(card)
def set_check(player):
amount = {}
for card in player.hand:
if card[0] not in amount.keys():
amount[card[0]] = 1
if card[0] in amount.keys():
amount[card[0]] += 1
for count in amount.keys():
if amount[count] == 4:
print(player.name+" got a set of "+count+"s.")
player.sets.append(count)
player.hand[:] = [card for card in player.hand if card[0] == count]
john = fisherman()
john.name = "John"
tim = fisherman()
tim.name = "Tim"
sara = fisherman()
sara.name = "Sara"
kris = fisherman()
kris.name = "Kris"
def play(player1, player2, player3, player4, deck):
turn = 0
size = 7
dealt = 0
order = [player1, player2, player3, player4]
random.shuffle(order)
while dealt < size:
draw(order[0])
draw(order[1])
draw(order[2])
draw(order[3])
dealt += 1
while len(deck) != 0:
for player in order:
count = 0
hand = player.name+"'s hand: "
for card in player.hand:
if count < len(player.hand)-1:
hand += card[0]+" of "+card[1]+", "
count += 1
elif count == len(player.hand)-1:
hand += card[0]+" of "+card[1]+"."
print(hand)
count = 0
sets = player.name+"'s sets: "
for set in player.sets:
if count < len(player.sets)-1:
sets += set+"s, "
elif count == len(player.sets)-1:
sets += set+"s."
print(sets)
other_player = turn
while other_player == turn:
other_player = random.randint(0,3)
ask(order[turn], order[other_player])
set_check(order[turn])
if turn >= 3:
turn = 0
else:
turn += 1
time.sleep(10)
print("=========================================")
play(john, tim, sara, kris, fish_deck)
class fisherman():
name = ""
hand = []
sets = []
All of your fisherman instances will share identical hand references, because these variables are class variables. If you want them to be individual instance variables, create them inside an __init__ method.
class fisherman():
def __init__(self):
self.name = ""
self.hand = []
self.sets = []
Related
there a problem with add AI + r.radint(0, 99).
i want a user to input who to attack and if a user type in the wrong input then prompt invalid input and try again using while loop, if a user type in AI99 (for example) that in the list on a ai unit then it will break and continue the program.
i want to use this statement under the input ("who do you want attack?")
# Prompts the user who he/she wants to attack.
opponent_name_to_attack = input("Who do you want attack? ").upper()
Main:
import gameplayerteam
import gamechar
import random as r
import gamelogger
player_units = None # A GamePlayerTeam object which comprises of 3 Human players
ai_units = None # A GamePlayerTeam object which comprises of 3 AI players
ai_units_player_id = []
ai_character_class_list = ['warrior', 'tanker']
def main():
gamelogger.prepares_log_folder()
gamelogger.print_and_log_game_message("Welcome to battle game!")
setup_human_unit()
setup_ai()
game_is_over = False
player_turn_of_attack = 'human' # Possible values: 'human', 'ai'
previous_player = None
curr_player = None
opponent_player_team = None
while not game_is_over:
gamelogger.print_and_log_game_message("============= Human Unit =============")
for i in range(len(player_units.players)):
gamelogger.print_and_log_game_message(player_units.players[i])
gamelogger.print_and_log_game_message("======================================\n")
gamelogger.print_and_log_game_message("============= AI Unit ================")
for i in range(len(ai_units.players)):
gamelogger.print_and_log_game_message(ai_units.players[i])
gamelogger.print_and_log_game_message("======================================\n")
#print("Is Game Over? : " + str(game_is_over))
if player_turn_of_attack == 'human':
#Gets the current human player's GameCharacter object
curr_player = player_units.get_current_player()
gamelogger.print_and_log_game_message("Now the {0} is playing".format(curr_player.name))
# Prompts the user who he/she wants to attack.
opponent_name_to_attack = input("Who do you want attack? ").upper()
# Sets the current_player_id of the matching AI Player's name that the user input
ai_units.set_player_id(opponent_name_to_attack)
# Sets the predicted next (name of) AI player after current AI player's turn ends
ai_units.predict_next_player()
# Assigns the AI Team (GamePlayerTeam object) as the opponent_player_team
opponent_player_team = ai_units
# Let's search for the GameCharacter object with the same name as opponent_to_attack
opponent_to_attack = ai_units.get_player_by_name(opponent_name_to_attack)
# Update the player_turn_of_attack value to ai so that the next turn will be AI
player_turn_of_attack = 'ai'
else:
gamelogger.print_and_log_game_message("Now the AI is playing")
# Sets the predicted next (name of) human player after current human player's turn ends
player_units.predict_next_player()
# Update the opponent_name_to_attack with previous_player
opponent_name_to_attack = previous_player.name
# Assigns the Human Team (GamePlayerTeam object) as the opponent_player_team
opponent_player_team = player_units
# Let's search for the GameCharacter object with the same name as opponent_to_attack
opponent_to_attack = previous_player
# Update the player_turn_of_attack value to human so that the next turn will be human
player_turn_of_attack = 'human'
# Update the curr_player_id to the next human player id
#player_units.set_next_player_id()
gamelogger.print_and_log_game_message("Attacking " + opponent_name_to_attack)
curr_player.attack_target(opponent_to_attack)
curr_player.check_rank()
#opponent_player_team.set_next_player_id()
#Checks the opponent player's HP
if opponent_to_attack.hp <= 0:
#Removes this opponent_to_attack from the team
opponent_player_team.remove_player(opponent_to_attack)
opponent_player_team.set_next_player_id()
# The next player in the opponent team will be switched over as the
# opponent_to_attack as our previous opponent player has been disqualified
opponent_to_attack = opponent_player_team.get_current_player()
else:
# We will simply set the curr_player_id to the next (predicted) player
opponent_player_team.set_next_player_id()
# Update the value of curr_player and the previous_player
previous_player = curr_player
curr_player = opponent_to_attack
game_is_over = check_has_game_over()
gamelogger.print_and_log_game_message("===========================")
gamelogger.print_and_log_game_message("Game is over")
def setup_human_unit():
global player_units
player_units = gameplayerteam.GamePlayerTeam('human')
for i in range(3):
char_type = input("Enter Character class [warrior/tanker]: ")
char_name = input("Enter character name: ")
player_units.add_player(char_type, char_name)
def setup_ai():
global ai_units
#Creates a GamePlayerTeam object (with no players first)
ai_units = gameplayerteam.GamePlayerTeam('ai')
for ai_player_count in range(3):
ai_character_class_list.reverse()
random_num = r.choice(ai_character_class_list)
ai_units.add_player(random_num, 'AI'+ str(ai_player_count+r.randint(0, 99)))
#ai_units.append(gamechar.GameCharacter(random_num, 'AI'+ str(ai_player_count+1) ))
def check_has_game_over():
is_game_over = False
# In the entire game, there's only 1 player left (whether it is an AI or human)
if ai_units.check_are_all_players_defeated():
is_game_over = True
elif player_units.check_are_all_players_defeated():
is_game_over = True
else:
is_game_over = False
return is_game_over
main()
gameplayerteam:
import gamechar
class GamePlayerTeam:
def __init__(self, player_type):
self.players = []
self.type_of_player = player_type #Possible value: 'ai', 'human'
self.all_players_defeated = False #Keeping track whether all units in this team are defeated
self.curr_player_id = 0 # Up to the last index of the players list
self.next_player_name = ''
def add_player(self, char_type, char_name):
#Adding a particular unit / player to the team
self.players.append(gamechar.GameCharacter(char_type, char_name))
def remove_player(self, player_to_remove):
# Removes a particular GameCharacter object from the players list
self.players.remove(player_to_remove)
def remove_player_by_id(self, player_id_to_remove):
# Remarks: This method will only likely be used by a Human GameCharacter
# Removes a particular GameCharacter object from the players list with a matching
# player_id_to_remove value
self.players.pop(player_id_to_remove)
def get_player_by_id(self, input_player_id):
# Remarks: This method will only likely be used by a Human GameCharacter
# Returns a particular GameCharacter object from the players list using the provided
# input_player_id value
return self.players[input_player_id]
def set_player_id(self, player_name):
#Sets the id of the player with the matching name from the players list
index = 0
while index < len(self.players):
if self.players[index].name == player_name.upper():
# Targeted Player found, stops executing the loop immediately
break
# Increments index by 1 as target not yet found
index += 1
# Update the curr_player_id to the index that we found
self.curr_player_id = index
def get_player_by_name(self, input_player_name):
# Returns a particular GameCharacter object by searching the matching GameCharacter object
# with the same name as input_player_name through the players list
player = None
for i in range(len(self.players)):
if input_player_name.upper() == self.players[i].name:
player = self.players[i]
break
return player
def get_current_player(self):
# Let's first validate whether if our players list is empty or not
if len(self.players) == 0:
# Because our players list is empty, this function will just simply
# return an empty object
return None
else:
# Returns a particular GameCharacter object from the players list
return self.players[self.curr_player_id]
def predict_next_player(self):
# Looks for the next player, and then update the curr_player_id to the matching next player's id
if self.curr_player_id == len(self.players) - 1:
# Reset the human player id as 0 to be the next human player id
self.next_player_name = self.players[0].name
else:
self.next_player_name = self.players[self.curr_player_id + 1].name
def set_next_player_id(self):
index = 0
while index < len(self.players):
if self.players[index].name == self.next_player_name:
# Targeted Player found, stops executing the loop immediately
break
#Increments index by 1 as target not yet found
index += 1
#Update the curr_player_id to the index that we found
self.curr_player_id = index
def check_are_all_players_defeated(self):
if len(self.players) == 0:
self.all_players_defeated = True
else:
self.all_players_defeated = False
return self.all_players_defeated
gamechar:
import random as r
import gamelogger
class GameCharacter:
def __init__(self, char_type, char_name):
self.type = ""
self.name = char_name
self.hp = 100
self.attack = 0
self.defence = 0
self.xp = 0
self.rank = 1
self.coin = 0
if char_type == 'warrior':
self.setup_warrior()
elif char_type == 'tanker':
self.setup_tanker()
def setup_warrior(self):
self.type = 'warrior'
self.attack = r.randint(5, 20)
self.defence = r.randint(1, 10)
def setup_tanker(self):
self.type = 'tanker'
self.attack = r.randint(1, 10)
self.defence = r.randint(5, 15)
def attack_target(self, target):
damage = self.attack - target.defence + r.randint(-5, 10)
target.hp -= abs(damage)
self.xp += abs(damage)
target.xp += target.defence
target.xp = round(target.xp, 1)
self.coin += target.xp
if damage > 10:
target.xp *= 1.2
# Rounds off (up/down) target.xp to 1 decimal point if it has a value with 2
# or more decimal points
target.xp = round(target.xp, 1)
elif damage <= 0:
target.xp *= 1.5
# Rounds off (up/down) target.xp to 1 decimal point if it has a value with 2
# or more decimal points
target.xp = round(target.xp, 1)
gamelogger.print_and_log_game_message("******************************************")
gamelogger.print_and_log_game_message("[Game Message] {0} attacked {1} with damage {2}: +{2}EXP".format(self.name, target.name, round(abs(damage),1) ) )
# print("Damage to target: {0}".format(damage))
gamelogger.print_and_log_game_message("******************************************")
def check_rank(self):
if self.xp >= 100:
self.rank += 1 # Promote rank by 1
self.xp -= 100 # Reduce the xp by 100
gamelogger.print_and_log_game_message("{0} have been promoted to Rank {1} ".format(self.name, self.rank) )
def __str__(self):
text = "{} {}: HP:{}, ATK:{}, DEF:{}, EXP:{}, RANK: {}".format(self.type, self.name, self.hp, self.attack, self.defence, self.xp, self.rank)
return text
So I am creating a card game in python using classes. I got it all set up to the point where it should work. But when I ran it it just simply never stops running. I am not really sure how to make this code minimal and reproduceable, because I do not know where the issue is at.
Here is the code i have written.
It has to be in the play_uno() class object.
""" UNO Simulator """
import random
class card():
def __init__(self, value, color, wild):
'''
An UNO deck consists of 108 cards, of which there are 76 Number cards,
24 Action cards and 8 Wild cards. UNO cards have four color "suits",
which are red, yellow, blue and green.
'''
self.card_nums = ['0','1','2','3','4','5','6','7','8','9']
self.card_colors = ['red','blue','green','yellow']
self.spec_cards = ['draw2','reverse','skip']
self.wild_cards = ['wild','wild_draw_4']
if wild == False:
self.value = self.card_nums[value]
self.color = self.card_colors[color]
elif wild == 'special':
self.value = self.spec_cards[value]
self.color = self.card_colors[color]
elif wild == True:
self.value = self.wild_cards[value]
self.color = None
class generate_deck():
def __init__(self):
self.number_cards = self.get_num_cards()
self.special_cards = self.get_special_cards()
self.wild_cards = self.get_wild_cards()
self.cards = self.number_cards + self.special_cards + self.wild_cards
random.shuffle(self.cards)
def get_num_cards(self):
# only one zero per color
with_zeroes = [card(i,j,False) for i in range(10) for j in range(4)]
no_zeroes = [card(i,j,False) for i in range(1,10) for j in range(4)]
return no_zeroes + with_zeroes
def get_wild_cards(self):
wild_draw4s = [card(i,None,True) for i in range(2) for x in range(2)]
wilds = [card(i,None,True) for i in range(2) for x in range(2)]
return wilds + wild_draw4s
def get_special_cards(self):
return [card(i,j,'special') for i in range(3) for j in range(4) for x in range(2)]
class player():
def __init__(self, name):
self.wins = 0
self.name = name
self.cheater = False
self.cards = ''
self.turn = 0
self.uno = 0
class play_uno():
def __init__(self, num_players = 3, num_cheaters = 0, cards_per_player = 5):
# get started
self.rules = 'default'
self.status = 'ongoing'
self.deck = generate_deck().cards
self.played_cards = []
self.dro = 0
self.direction = 0
self.top_card = self.deck.pop() # random card as first card to play on
self.tot_turns = 0
# generate players, make cheaters later
self.players = [player('player' + str(i)) for i in range(num_players + num_cheaters)]
# give each player 7 cards to start
for _player_ in self.players:
_player_.cards = [self.draw_card() for i in range(cards_per_player)]
# start playing turns in order
# do not know how to reverse yet
"""
Right now it is endless for some reason.
"""
while self.status == 'ongoing':
for _player in self.players:
self.turn(_player)
def draw_card(self):
# draws random card from deck instead of card on top
if len(self.deck) == 0:
self.re_shuffle()
self.dro += 1
return self.deck.pop()
def re_shuffle(self):
self.deck = self.played_cards
random.shuffle(self.deck)
self.played_cards = []
return self.deck, self.played_cards
def play_card(self, player_cards, _card):
self.top_card = _card
return player_cards.remove(_card), self.played_cards.append(_card), self.top_card
def game_over(self, winner):
winner.wins += 1
self.game_status = 'over'
def turn(self, _player):
played = False
# check if someone played wild card last turn
if self.top_card.value in card(1,2,None).wild_cards:
self.top_card.color = random.choice(card.card_colors)
if self.top_card.value == 'wild_draw_4':
_player.cards += [self.draw_card() for i in range(4)]
self.tot_turns += 1
return _player
# check for special cards
elif self.top_card.value in card(1,2,None).spec_cards:
if self.top_card.value == 'draw2':
_player.cards += [self.draw_card() for i in range(4)]
self.tot_turns += 1
return _player
# for now we are treating reverse cards like skips
elif self.top_card.value == 'reverse' or self.top_card.value == 'skip':
played = True
self.tot_turns += 1
return _player
# If its a normal card, or regular wild
if played == False:
for _card in _player.cards:
if _card.color == self.top_card.color:
self.play_card(_player.cards, _card)
played = True
break
elif _card.value == self.top_card.value:
self.play_card(_player.cards, _card)
played = True
break
# if the player cannot play at all
# rn they just move on if they have to draw,
# cant play the card they just drew.
if played == False:
_player.cards += [self.draw_card()]
played = True
self.tot_turns += 1
# check if the player won or not
if len(_player.cards) == 0:
self.game_over(_player)
elif len(_player.cards) == 1:
_player.uno += 1
return _player.cards
In the function turn in the play_uno class you are checking for certain wild/special cards. If the value is reverse, for example, the function hits a return _player line which ends the execution of the function and the player is unable to play another card.
Move the return statements to the end of the function if you want to ensure the rest of the code is run.
I did not run the code, but I think you should test a player's number of cards before drawing again. Like this:
if len(_player.cards) == 0:
self.game_over(_player)
elif len(_player.cards) == 1:
_player.uno += 1
if played == False:
_player.cards += [self.draw_card()]
played = True
self.tot_turns += 1
Or are the rules of this game different? I sincerely don't remember them anymore.
The while loop at the end of play_uno's __init__ checks for status, which never changes.
The loop calls turn on each of players every iteration. You must change status somewhere or you must put an if ...: break in the while loop (e.g. if not _player.cards).
EDIT: It appears that you meant self.status instead of self.game_status, in game_over. Try changing game_status to status there.
Im making a card game for a project for my high school class. I'm making black jack but with changed rules and new features. I am using the random plugin to randomize the numbers. I am not using suits but am using face cards. How do I make it so if a user gets a face card like 'King' the program knows the value of the face card and able to calculate the total.
For example if one user gets a 3 card and a King card their total will be 13 as King = 10. How will I make the face cards have values and put it into a list with the normal cards
Here is my code so far, I know how to deal more cards later, just want to know how to add face cards and their value to shuffle. Thanks
while len(dealer_cards) != 2:
dealer_cards.append(random.randint(2, 10))
if len(dealer_cards) == 2:
print("The Dealer has:", dealer_cards)
# Players cards
while len(player_cards) != 2:
player_cards.append(random.randint(2, 10))
if len(player_cards) == 2:
print("You have:", player_cards)
One way is to define the card as an object (dictionary)
Note that this is just a way to build your logic: This doesn't take into effect other rules (like how many total cards and if the same card gets dealt out twice. You need more rules and house-keeping for that
card = {
"face": "K", # This indicates what is printed on the face
"value": 10, # This indicates the value (used internally)
"suite": "spade", # will be one of ["spade", "jack", "clubs", "hearts"]
}
define a function to get a random card:
def getRandomCard():
# list of possible cards with their values
cards = [("1", 1), ("2", 2).. ("J", <value>), ("Q", <value>), ("K", <value>), ("A", <value>)]
randIdx = <Get random number>
randomCard, randomCardValue = cards[randIdx % len(cards)] #
suits = ["spade", "jack", "clubs", "hearts"]
randomSuite = <similarly pick a random suite>
return {
"face": randomCard,
"value": randomCardValue,
"suite": randomSuite
}
Now rest of your code deals with the card object.
you get the idea..
I quickly wrote this bare bones blackjack game. It doesn't have betting, splitting, or even the logic to say if who wins but it does the basic game play. I hope you can look at this example of Object Oriented programming and maybe learn something.
import random
class Card:
suits = {0:"Spades",
1:"Heaarts",
2:"Clubs",
3:"Dimods"}
names = {1:"Ace",
2:"Duce",
3:"Three",
4:"Four",
5:"Five",
6:"Six",
7:"Seven",
8:"Eight",
9:"Nine",
10:"Ten",
11:"Jack",
12:"Queen",
0:"King"}
def __init__(self,id):
self.id = id
self.name = id%13
self.suit = int((id-1)/13)
def announce(self):
return Card.names[self.name]+" of "+Card.suits[self.suit]
def value(self):
if self.name > 10:
return 10
if self.name == 1:
return 0
else:
return self.name
class Deck:
def __init__(self):
self.cards=[int(k) for k in range(1,53)]
def restock(self):
self.cards = range(1,53)
def deal(self):
cardIndex = random.choice(range(len(self.cards)))
cardId = self.cards[cardIndex]
del self.cards[cardIndex]
return Card(cardId)
def evaluate(hand):
total = 0
aces = 0
for c in hand:
v = c.value()
if v:
total+= v
else:
aces+=1
while aces > 0:
aces-=1
if total<11-aces:
total+=11
else:
total+=1
return 0 if total>21 else total
class Player:
deck = Deck()
def __init__(self):
self.hand = []
def getCard(self):
self.hand.append(self.deck.deal())
def discard(self):
self.hand = []
def play(self):
print("Player has:")
print(self.hand[0].announce())
print(self.hand[1].announce())
hitOrStand="hit"
v = evaluate(self.hand)
while hitOrStand != "stand" and v:
hitOrStand = input("hit or stand:")
if hitOrStand not in ["hit","stand"]:
print("please enter `hit` or `stand`.")
continue
if hitOrStand == "hit":
self.getCard()
print(self.hand[-1].announce())
v = evaluate(self.hand)
print(v if v else "bust")
class Dealer(Player):
def hits(self):
v = evaluate(self.hand)
return True if v<17 and v else False
def play(self):
print("Dealer has:")
print(self.hand[0].announce())
print(self.hand[1].announce())
while self.hits():
print("And gets:")
self.getCard()
print(self.hand[-1].announce())
v = evaluate(self.hand)
v = evaluate(self.hand)
print(v if v else "bust")
def restock(self):
Player.deck.restock()
class Game:
def __init__(self):
self.player = Player()
self.dealer = Dealer()
def playRound(self):
self.player.getCard()
self.dealer.getCard()
self.player.getCard()
self.dealer.getCard()
self.player.play()
self.dealer.play()
self.player.discard()
self.dealer.discard()
self.dealer.restock()
g = Game()
g.playRound()
I am trying to create the war card game where 2 players draw a card each on the table, and the player whose card has max value gets both the cards, if the card values are equal(called war condition) each player draws 5 cards, and the value of the last card among these 5 cards are compared and works similarly as above. A player wins when either the other player runs out of cards or if in war condition the other player has less than 5 cards.
My questions:
When I am running the game logic sometimes it runs but sometimes it gets stuck in an infinite loop. Why?
I can notice that when the total number of cards for both players at all times should be 52, but here it is decreasing. Why? (I can see that the cards are getting lost every time the game goes into war condition, but I am not able to understand why that is happening, since I am adding all the 10 cards to the player whose card has a greater value.)
I have tried another method where I assume that players are always at war and then approach it, which works. But I want to understand why, if I break it into steps which I am trying to do here, is it not working?
Code:
import random
suits = ['Hearts','Clubs','Spades','Diamonds']
ranks = ['Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Jack','Queen','King','Ace']
values = {'Two': 2, 'Three': 3, 'Four': 4, 'Five': 5, 'Six' : 6 , 'Seven' :7, 'Eight': 8,'Nine':9,
'Ten':10,'Jack':11, 'Queen': 12,'King': 13,'Ace':14 }
classes:
class Card():
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
self.value = values[rank]
#string method
def __str__(self):
return self.rank + ' of ' + self.suit
class Deck():
def __init__(self):
self.all_cards = [] #list of objects
for suit in suits:
for rank in ranks:
#create card object
created_card = Card(suit,rank)
self.all_cards.append(created_card)
def shuffle(self): #method to shuffle the card
random.shuffle(self.all_cards)
def deal_one(self):
return self.all_cards.pop() #we want the last card from deck
class Player():
def __init__(self,name):
self.name = name
self.all_cards = []
def remove_one(self):
return self.all_cards.pop(0) #to remove card from beginning of the list
def add_cards(self,new_cards):
if type(new_cards) == type([]):
self.all_cards.extend(new_cards)
else:
self.all_cards.append(new_cards)
def __str__(self):
return f'Player {self.name} has {len(self.all_cards)} cards.'
And below is the final game logic:
#create 2 new instances of the player class
player1_name = input('Enter the name of Player1: ')
player2_name = input('Enter the name of Player2: ')
player1 = Player(player1_name)
player2 = Player(player2_name)
newdeck = Deck()
newdeck.shuffle()
#splitting the deck among the two players - alternate card from deck goes to each player respectively
for i in range(0,len(newdeck.all_cards)-1,2):
player1.add_cards(newdeck.all_cards[i])
player2.add_cards(newdeck.all_cards[i+1])
#for x in range(26):
# player1.add_cards(newdeck.deal_one())
#player2.add_cards(newdeck.deal_one())
print(player1)
print(player2)
game_status = True
round_num = 0
while game_status == True:
round_num +=1
print(f"Round {round_num}")
if len(player1.all_cards) == 0:
print('Player 1 out of cards'+ player2.name + 'Wins!')
game_status = False
break
if len(player2.all_cards) == 0:
print('Player 2 out of cards' + player1.name + 'Wins!')
game_status = False
break
else:
player_cards = []
player1_card = player1.remove_one()
player2_card = player2.remove_one()
player_cards.append(player1_card)
player_cards.append(player2_card)
print('player1_card_value: ',player1_card.value)
print('')
print('player2_card_value: ',player2_card.value)
print('')
print(player1)
print('')
print(player2)
at_war = True
if player1_card.value == player2_card.value:
while at_war == True:
player1_list = []
player2_list = []
card_list = []
if len(player1.all_cards) < 5:
print('Player 2 won')
game_status = False
at_war = False
break
elif len(player2.all_cards) <5:
print('Player 1 won')
game_status = False
at_war = False
break
if len(player1.all_cards) >= 5 and len(player2.all_cards) >= 5:
for i in range(5):
player1_list.append(player1.remove_one())
player2_list.append(player2.remove_one())
card_list.extend(player1_list)
card_list.extend(player2_list)
print("CARD LIST LEN", len(card_list))
if player1_list[0].value > player2_list[0].value:
player1.add_cards(card_list)
at_war = False
break
elif player1_list[0].value < player2_list[0].value:
player2.add_cards(card_list)
#player2.add_cards(player1_list)
at_war = False
break
else:
at_war = True
elif player1_card.value > player2_card.value:
player1.add_cards(player_cards)
#player1.add_cards(player2_cards)
#print('p1>p2', player1)
elif player2_card.value > player1_card.value:
player2.add_cards(player_cards)
print(player1)
print(player2)
if len(player1.all_cards) == 0:
print('Player 2 won')
elif len(player2.all_cards) == 0:
print('Player 1 won')
Output: When it was stuck in an infinite loop:(You can see the total number of cards is now 34 instead of 52.)
(Cards numbered 2-10 should be valued from 2-10, respectively. J,Q, and K should be 10, and A should be either 1 or 11, depending on the value of the hand).
How do I assign the deck these values? Also, the game needs to be 3 rounds. The way I did it is only one round. How do I make the game go three times, while keeping track of the players wins/losses?
Could someone please explain how I can do this a simple way?
here is a complete implementation for you
look at hand.Score
import random
class Card:
def __init__(self,rank,suite):
self.rank = rank
self.suite = suite
def Rank(self):
return "Ace Two Three Four Five Six Seven Eight Nine Ten Jack Queen King".split()[self.rank]
def Suite(self):
return "Hearts Spades Clubs Diamonds".split()[self.suite]
def __str__(self):
#print "Get Self:",type(self)
#print "Dir:",dir(self)
#return "OF"
return self.Rank()+" of "+ self.Suite()
class Hand:
def __init__(self):
self.cards = []
def Score(self):
aces_ct = 0
score = 0
for c in self.cards:
if c.rank == 0:
aces_ct += 1
score += 11
if 0 < c.rank < 9:
score += c.rank+1
else:
score += 10
while score > 21 and aces_ct > 0:
score -= 10
aces_ct -= 1
return score
def add(self,card):
self.cards.append(card)
def Show(self,show_only=None):
if not show_only:
for k in self.cards:
print "%s"%k
else:
if isinstance(show_only,int):
print "%s"%self.cards[show_only]
elif isinstance(show_only,(list,tuple)):
for idx in show_only:
print "%s"%self.cards[idx]
class deck:
def __init__(self):
self.cards = []
for i in range(4):
for j in range(13):
self.cards.append(Card(j,i))
random.shuffle(self.cards)
def shuffle(self):
random.shuffle(self.cards)
def pop(self):
return self.cards.pop()
if __name__ == "__main__":
d = deck()
player_hand = Hand()
dealer_hand = Hand()
player_hand.add(d.pop())
dealer_hand.add(d.pop())
player_hand.add(d.pop())
dealer_hand.add(d.pop())
print "Player Score :",player_hand.Score()
player_hand.Show()
print "\n\nDealer Score :",dealer_hand.Score()
dealer_hand.Show()
You can represent cars as tuples: a character indicating suit, and a number indicating value. I would also add a third value to the tuple, its blackjack value (e.g. a king and a queen both count as a 10).
card = ('D', 11, 10) # card is queen of diamonds
You could also make your own class to represent cards.
class Card(object):
def __init__(self, suit, number):
self.suit = suit
self.number = number
self.value = (number if 2 <= number <= 9 else 10)
You will have to special-case the value of the ace, of course.
You should probably calculate the total dynamically. Also, you need some kind of way to store the money of each individual player. Right now, there is no way of knowing the distribution of money since you only have one total.