hello everyone.
I have this code here that i have been working on using stackoverflow for support. i have yet come into another problem. I need to call on a player for there turn. How do i do this. if it helps the players have a number assigned to them corrosponding to the time they where created.
thanks in advance, Josh
class Player:
def __init__(self, name, tank_name, number):
self.name = name
self.tank_name = tank_name
self.number = number
players = input('Please type player amount >>> ')
try:
players = int(players)
except ValueError:
print('Whoops... ' + players + ' is not a valid number. The auto amount is two players.')
players = int(2)
number = 0
def new_player(number):
name = input('What is your name >>> ')
tank_name = input('What is your tanks name >>> ')
return Player(name, tank_name, number)
for i in range(0, players):
number = int(number)
number = number + 1
new_player(number)
print()
print('Next player or end of player creation.')
print()
This is entirely dependent on what the player turn entails. Here is your code with a basic player turn functionality.
class Player:
def __init__(self, name, tank_name, number):
self.name = name
self.tank_name = tank_name
self.number = number
def player_turn_method(self):
pass
players = input('Please type player amount >>> ')
try:
players = int(players)
except ValueError:
print('Whoops... ' + players + ' is not a valid number. The auto amount is two players.')
players = int(2)
number = 0
def new_player(number):
name = input('What is your name >>> ')
tank_name = input('What is your tanks name >>> ')
return Player(name, tank_name, number)
def player_turn(player):
pass
for i in range(0, players):
playerList = []
number = int(number)
number = number + 1
playerList.append(new_player(number))
print()
print('Next player or end of player creation.')
print()
# this cycles through the players and plays their turn
for i in range(players):
player_turn(playerList[i])
# alternatively you could use a class method:
# playerList[i].player_turn_method()
Note this will only allow each player to play one turn. I will let you implement further logic for playing more than 1 turn.
Related
Instead of printing the player variables from the list it prints:
[<__main__.Player object at 0x7f95614f4ee0>, <__main__.Player object at 0x7f95614f4f70>,
<__main__.Player object at 0x7f9561520400>]
Code:
class Player:
def __init__(self, name, swaps, points):
self.player_name = name
self.player_swaps = swaps
self.player_points = points
def add_player(players):
name = input('Enter the new players Name : ')
swaps = 3
points = 0
players.append(Player(name, swaps, points))
print('Player Added \n')
def playerselector():
'''Input for players to choose how many players they want.
Will tell them if not sensible and get them to do it again.
'''
valid = False
while valid is False:
try:
num_players = int(input("How many players do you want? (2-5)\n"))
if num_players >= 2 and num_players <= 5:
valid = True
else:
print("Please choose a number between 2 and 5")
except ValueError:
print("Sorry that isn't a number")
return num_players
num_players = playerselector()
players=[]
for x in range(num_players):
add_player(players)
print(players)
Any tips/solutions?
Add player_return function in class:
def player_return(self):
return [self.player_name,self.player_swaps, self.player_points]
and call it in add_player()
A=Player(name, swaps, points)
players.append(A.player_return())
Ouput
How many players do you want? (2-5)
2
Enter the new players Name : tim
[['tim', 3, 0]]
Player Added
Enter the new players Name : Jerry
[['tim', 3, 0], ['Jerry', 3, 0]]
Player Added
[['tim', 3, 0], ['Jerry', 3, 0]]
This should work:
class Player:
def __init__(self, name, swaps, points):
self.player_name = name
self.player_swaps = swaps
self.player_points = points
def __repr__(self):
rep = f'Player({self.player_name}, {self.player_swaps}, {self.player_points})'
return rep
def add_player(players):
name = input('Enter the new players Name : ')
swaps = 3
points = 0
players.append(Player(name, swaps, points))
print('Player Added \n')
def playerselector():
valid = False
while valid is False:
try:
num_players = int(input("How many players do you want? (2-5)\n"))
if num_players >= 2 and num_players <= 5:
valid = True
else:
print("Please choose a number between 2 and 5")
except ValueError:
print("Sorry that isn't a number")
return num_players
num_players = playerselector()
players=[]
for x in range(num_players):
add_player(players)
print(players)
Output:
How many players do you want? (2-5)
3
Enter the new players Name : bob
Player Added
Enter the new players Name : joe
Player Added
Enter the new players Name : tom
Player Added
[Player(bob, 3, 0), Player(joe, 3, 0), Player(tom, 3, 0)]
You can change the rep variable in the __repr__ method to modify the output. You can find out more about __repr__ and its uses here
I'm making a multi-player game of blackjack and having been encountering issues getting the code (in python) to deal unique cards to multiple players. The code below has been dealing the same set of cards to all players.
An example of the results for 2 players is as follow:
Player1's first card is Four of Hearts.
Player1's second card is Nine of Clubs.
Player2's first card is Four of Hearts.
Player2's second card is Nine of Clubs.
I have been reviewing the code and making amendments to the function of dealingcards, e.g. by using a while loop to go through each player and appending two cards to their hand. However, the result is no different.
Will anyone be able to advise where the error in the code lies? Thank you.
Code as shown below:
"""This is a game of Blackjack."""
import random
"""Defining the attributes of the cards"""
suits = ('Hearts', 'Diamonds', 'Spades', 'Clubs')
ranks = ('Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace')
"""Class class must be able to understand the Suit and Rank of a card"""
class Card:
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
def __str__(self):
return self.rank + " of " + self.suit
"""Deck class must be able to:
Instantiate a new deck and hold as a list of card objects;
Shuffle a deck through a method call; and
Deal cards from the deck."""
class Deck:
def __init__(self):
self.all_cards = []
for suit in suits:
for rank in ranks:
created_card = Card(suit,rank)
self.all_cards.append(created_card)
def shuffle(self):
random.shuffle(self.all_cards)
def deal_one(self):
return self.all_cards.pop()
def __str__(self):
statement = ""
for card in self.all_cards:
statement = statement + card.rank + " of " + card.suit + "\n"
return statement
"""Hand class must be able to:
Store the hands of the player;
Compute the value of each hand"""
class Playerhand:
def __init__(self,name,hands=[[],[],[],[]]):
self.name = name
self.hands = hands
def num_of_hands(self):
num_of_hands = 0
for hand in self.hands:
if hand != []:
num_of_hands += 1
else:
pass
return num_of_hands
def show_first_card(self):
print("{}'s first card is {}".format(self.name,self.hands[0][0]))
print("{}'s second card is {}".format(self.name,self.hands[0][1]))
def value_of_hands(self):
value_of_hands = []
for hand in self.hands:
total_value = 0
values = {'Two':2, 'Three':3, 'Four':4, 'Five':5, 'Six':6, 'Seven':7, 'Eight':8, 'Nine':9, 'Ten':10, 'Jack':10, 'Queen':10, 'King':10, 'Ace':11}
check_for_aces = []
for card in hand:
if card.suit == 'Ace':
check_for_aces.append('Ace')
else:
pass
for card in hand:
total_value = total_value + values[card.rank]
for item in range(0,len(check_for_aces)):
if total_value > 21:
total_value = total_value - 10
else:
pass
value_of_hands.append(total_value)
return value_of_hands
"""Pre-game:
Asking for the number of players to CREATE A LIST OF PLAYERS ['Dealer', 'P1', 'P2', etc.] and a DICTIONARY OF WAGERS {"P1": $X, "P2": $Y, etc.}"""
def number_of_players():
number_of_players = input("How many players are we expecting? Please enter 1 to 7: ")
while number_of_players.isdigit() == False or int(number_of_players) not in range(1,8):
number_of_players = input("Only accepting integer values between 1 to 7. Please enter 1 to 7: ")
return int(number_of_players)
def check_float(potential_float):
try:
float(potential_float)
return True
except:
return False
def playername(no_of_players):
print("We are expecting {} player(s). We are going to start collecting information on player names and wager!".format(no_of_players))
player_list = ['Dealer']
for number in range(1,no_of_players+1):
name = input("Player {}, what is your name? ".format(number))
while name in player_list:
name = input("Player {}, your chosen name has been taken. Please give us an alternative: ")
player_list.append(name)
return player_list
def playerwager(player_list):
player_wager = {}
for number in range(1, len(player_list)):
wager = input("{}, how much are you betting? Please input number: $ ".format(player_list[number]))
while check_float(wager) is False:
wager = input("{}, please input a valid wager in number: $ ".format(player_list[number]))
wager = float(wager)
player_wager[player_list[number]] = wager
player_wager["Dealer"] = 0
return player_wager
def dealingcards(player_list):
newdeck = Deck()
newdeck.shuffle()
print(newdeck) # Remove in due course.
for player in player_list:
for item in range(0,2):
Playerhand(player).hands[0].append(newdeck.deal_one())
Playerhand(player).show_first_card()
#GAME ON
x = number_of_players()
playerlist = playername(x)
playerwager(playerlist)
dealingcards(playerlist)
This part of the code is wrong:
for player in player_list:
for item in range(0,2):
Playerhand(player).hands[0].append(newdeck.deal_one())
Playerhand(player).show_first_card()
You have to store the playerhand and not redefine it when showing the first card:
playerhands = []
for player in player_list:
playerhands.append(Playerhand(player,hands=[[],[],[],[]]))
for item in range(0,2):
playerhands[-1].hands[0].append(newdeck.deal_one())
playerhands[-1].show_first_card()
EDIT: This is the true source of the problem
"Least Astonishment" and the Mutable Default Argument
While Heiner is on the right track, I went through with a debugger and found that doing:
ph = Playerhand(player)
Mysteriously wasn't clearing the hand. The data seems to almost be static. However, a simple bandaid fix is as follows:
for player in player_list:
ph = Playerhand(player)
ph.hands[0] = []
for item in range(0, 2):
card = newdeck.deal_one()
ph.hands[0].append(card)
ph.show_first_card()
The hands were never clearing and that's why they kept outputting the same hand.
I have made this simple program all ut does so far is create tanks however i have come to a problem. I would like it to assign a number corrosponding to if its the first second third or fourth etc... could someone help me with this thanks in advance.
class Player:
def __init__(self, name, tank_name):
self.name = name
self.tank_name = tank_name
self.number = number
players = input('Please type player amount >>> ')
try:
players = int(players)
except ValueError:
print('Whoops... ' + players + ' is not a valid number. The auto amount is two players.')
players = int(2)
number = 0
def new_player():
name = input('What is your name >>> ')
tank_name = input('What is your tanks name >>> ')
number = str(number)
number = Player(name, tank_name)
for i in range(0, players):
number = int(number)
number = number + 1
new_player()
print()
print('Next player or end of player creation.')
print()
You can pass the number to new_player by changing it to this:
def new_player(number):
name = input('What is your name >>> ')
tank_name = input('What is your tanks name >>> ')
return Player(name, tank_name, number)
Note that I made it now return the created Player which you forgot to do.
We now give number to Player, so we need to change __init__ to this:
def __init__(self, name, tank_name, number):
self.name = name
self.tank_name = tank_name
self.number = number
Now you actually already have a variable called number that you increase by 1 each time (using number = number + 1), but you can instead use i directly like this. since the range will take care of increasing i by one each time for you:
for i in range(0, players):
player = new_player(i)
print()
print('Next player or end of player creation.')
print()
Note how I got rid of the int use, as i here is already an integer.
If you want to start the players at 1 instead of 0, you would change new_player(i) to new_player(i + 1).
I would recommend passing through a number variable to the class, and every time you are creating an instance of the Player class, you add one to the number. Also, it can be useful to store the instances of the class in list, and then you can access a specific player with the generator: [player for player in players if player.number == 1]
class Player:
def __init__(self, name, tank_name, number):
self.name = name
self.tank_name = tank_name
self.number = number
players = input('Please type player amount >>> ')
try:
players = int(players)
except ValueError:
print('Whoops... ' + players + ' is not a valid number. The auto amount is two players.')
players = int(2)
number = 0
players = []
def new_player():
name = input('What is your name >>> ')
tank_name = input('What is your tanks name >>> ')
number += 1
players.append(Player(name, tank_name, number))
for i in range(0, players):
new_player()
print()
print('Next player or end of player creation.')
print()
You can also just add a class level counter so every new player gets a unique number.
class Player:
playerctr = 0 # increment for each new player
def __init__(self, name, tank_name):
self.name = name
self.tank_name = tank_name
Player.playerctr += 1
self.number = Player.playerctr # set current counter to this player
I am in need of help with an assignment I have been given.
I have been asked to modify the section below from a blackjack game so that a dealer deals a card to each player and the highest card wins unless there is a draw.
I am unable to get the code right for this.
This is what i have in place:
for player in self.still_playing:
if player.total > self.players.total:
player.win()
elif player.total < self.players.total:
player.lose()
else:
player.push()
here is the rest of the code:
import Cards, Games
class BJ_Card(Cards.Card):
# Defines a Blackjack card
ACE_VALUE = 1
#property
def value(self):
if self.is_face_up:
val = BJ_Card.CARDS.index(self.card) + 1
if val > 10:
val = 10
else:
val = None
return val
# This object returns a number between 1 and 10,
# representing the value of a Blackjack card
class BJ_Deck(Cards.Deck):
# Defines a Blackjack deck
def populate(self):
for suit in BJ_Card.SUITS:
for card in BJ_Card.CARDS:
self.cards.append(BJ_Card(card, suit))
class BJ_Hand(Cards.Hand):
# Defines 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 has the value None, then total is None
for card in self.cards:
if not card.value:
return None
# Add card values
t = 0
for card in self.cards:
t += card.value
# Check if hand contains an Ace
contains_ace = False
for card in self.cards:
if card.value == BJ_Card.ACE_VALUE:
contains_ace = True
# treat Ace as 1
contains_ace = 1
return t
def is_busted(self):
return self.total > 21
class BJ_Player(BJ_Hand):
# Defines a Blackjack player
def is_hitting(self):
response = Games.askYesNo("\n" + self.name + ", do you want another
card? (Y/N): ")
return response == "y"
def bust(self):
print(self.name, "busts.")
self.lose()
def lose(self):
print(self.name, "loses.")
def win(self):
print(self.name, "wins.")
def push(self):
print(self.name, "draws.")
class BJ_Dealer(BJ_Hand):
# Defines 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):
# Defines 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 1 card to all players
self.deck.deal(self.players, per_hand = 1)
for player in self.players:
print(player)
for player in self.still_playing:
if player.total > self.players.total:
player.win()
elif player.total < self.players.total:
player.lose()
else:
player.push()
# Remove everyone's cards
for player in self.players:
player.clear()
def main():
print("\nWelcome to the Python Blackjack game.\n")
names = []
number = Games.askForNumber("How many players? (2-7): ", low = 2, high =
8)
print()
i = 1
for i in range(number):
name = input("Enter player name: ")
if name == "":
names.append("Anon")
print()
i += 1
else:
names.append(name)
print()
i += 1
game = BJ_Game(names)
again = "Y"
while again == "y" or again == "Y":
game.play()
again = Games.askYesNo("\nDo you want to play again?: ")
main()
self.players
is a list of BJ_Player classes / objects. You're calling self.players.total i.e trying to get the property total of a python list which does not exist as this is not a property of a list. I assume you're trying to do something more like;
for player in self.players:
print(player.total)
this way you would be accessing each players total. However, the class BJ_Player does not appear to have a total property either, so you will need to add this to the class and then use a loop like the one given above.
When I define the __init__ of ProductionWorker, I also need to set the attributes of EmployeeClass. I entered "Bob" and "001121" as a test and it works but I need to be able to change it in my main from the input of the user.
class ProductionWorker(EmployeeClass):
SHIFT = {1: "day shift", 2: "night shift"}
def __init__(self, shift=None, hourly_pay=None):
EmployeeClass.__init__(self, "Bob", "001121")
self.__shift = shift
self.set_shift = shift
self.__hourly_pay = hourly_pay
self.set_hourly_pay = hourly_pay
# setters
def set_shift(self, shift):
if shift in ProductionWorker.SHIFT:
self.__shift = shift
else:
self.__shift = None
def set_hourly_pay(self, hourly_pay):
self.__hourly_pay = hourly_pay
# getters
def get_shift(self):
return self.__shift
def get_hourly_pay(self):
return self.__hourly_pay
def __str__(self):
summary = EmployeeClass.__str__(self)
return summary + "They work on the " + ProductionWorker.SHIFT[self.__shift] + " and make " + "$" \
+ str(format(self.__hourly_pay, "0.2f")) + " an hour."
My main:
from Employee import EmployeeClass
from Employee import ProductionWorker
e_name = input("Enter the name of the employee: ")
e_number = input("Enter the ID number of the employee: ")
e_shift = int(input("Enter 1 if they work day shift or 2 if they work night shift: "))
e_hourly_pay = float(input("Enter how much they make hourly (numerical): "))
x = EmployeeClass(e_name, e_number)
z = ProductionWorker(e_shift, e_hourly_pay)
print(z)
This is the result I get:
Enter the name of the employee: Joe
Enter the ID number of the employee: 5555
Enter 1 if they work day shift or 2 if they work night shift: 2
Enter how much they make hourly (numerical): 30
The employee's name is Bob. Bob's ID number is: 001121. They work on the night shift and make $30.00 an hour.
You have to use arguments as any with any other parameters:
class ProductionWorker(EmployeeClass):
SHIFT = {1: "day shift", 2: "night shift"}
def __init__(self, name, number, shift=None, hourly_pay=None):
EmployeeClass.__init__(self, name, number)
self._shift = shift
self.hourly_pay = hourly_pay
#property
def shift(self):
return self._shift
#shift.setter
def shift(self, shift):
if shift in ProductionWorker.SHIFT:
self._shift = shift
else:
self._shift = None
def __str__(self):
summary = EmployeeClass.__str__(self)
return summary + "They work on the {} and make ${:.2f} an hour.".format(
ProductionWorker.SHIFT[self.shift], self.hourly_pay)
name = input("Enter the name of the employee: ")
number = input("Enter the ID number of the employee: ")
shift = int(input("Enter 1 if they work day shift or 2 if they work night shift: "))
hourly_pay = float(input("Enter how much they make hourly (numerical): "))
z = ProductionWorker(name, number, shift, hourly_pay)
print(z)
I would include the parameters of the EmployeeClass in the init method parameters of the ProductionWorker to pass along to the superclass.
For python 3 you can do super().__init___() rather than EmployeeClass.__init__().
Additionally you should consider using descriptors rather than implementing getters and setters as that is the pythonic way to do that.
class ProductionWorker(EmployeeClass):
def __init__(self, name, number, shift=None, hourly_pay=None):
super().__init__(name, number)
self.__shift = shift
self.__hourly_pay = hourly_pay