I'm trying to develop a code for the zombie dice game.
My problem is when the first player replies that he doesn't want to continue playing.
The game ends and I can't get the second player to play. Can someone help me?
import random
print("========== ZOMBIE DICE (PROTÓTIPO SEMANA 4) ==========")
print("========= WELCOME TO THE ZOMBIE DICE GAME! ========")
numeroJogadores = 0
while numeroJogadores < 2:
numeroJogadores = int(input("Enter the number of players: "))
print(numeroJogadores)
if numeroJogadores < 2:
print("NOTICE: You must have at least 2 players to continue!")
listaJogadores = []
for i in range(numeroJogadores):
nome = str(input("\nEnter player name: " + str(i+1) + ": "))
listaJogadores.append(nome)
print(listaJogadores)
dadoVerde = ("brain", "steps", "brain", "shot", "steps", "brain")
dadoAmarelo = ("shot", "steps", "brain", "shot", "steps", "brain")
dadoVermelho = ("shot", "steps", "shot", "brain", "steps", "shot")
listaDados = [dadoVerde, dadoVerde, dadoVerde, dadoVerde, dadoVerde, dadoVerde,
dadoAmarelo, dadoAmarelo, dadoAmarelo, dadoAmarelo,
dadoVerde, dadoVermelho, dadoVermelho]
print("\nSTARTING THE GAME...")
jogadorAtual = 0
dadosSorteados = []
tiros = 0
cerebros = 0
passos = 0
while True:
print("PLAYER TURN: ", listaJogadores[jogadorAtual])
for i in range (3):
numeroSorteado = random.randint(0, 12)
dadoSorteado = listaDados[numeroSorteado]
if (dadoSorteado == dadoVerde):
corDado = "Green"
elif (dadoSorteado == dadoAmarelo):
corDado = "Yellow"
else:
corDado = "Red"
print("Dice Drawn: ", corDado)
dadosSorteados.append(dadoSorteado)
print("\nThe faces drawn were: ")
for dadoSorteado in dadosSorteados:
numeroFaceDado = random.randint(0,5)
if dadoSorteado[numeroFaceDado] == "brain":
print("- brain (you ate a brain)")
cerebros = cerebros + 1
elif dadoSorteado[numeroFaceDado] == "tiro":
print("- shot (you got shot)")
tiros = tiros + 1
else:
print("- steps (a victim escaped)")
passos = passos + 1
print("\nCURRENT SCORE: ")
print("brins: ", cerebros)
print("shots: ", tiros)
if cerebros >= 13:
print("Congratulations, you've won the game!")
break
elif tiros >= 3:
print("You lost the game!")
break
else:
continuarTurno = str(input("\nNOTICE: Do you want to continue playing dice? (y=yes / n=no)")).lower()
if continuarTurno == "n":
jogadorAtual = jogadorAtual + 1
dadossorteados = 0
tiros = 0
cerebros = 0
passos = 0
if jogadorAtual > numeroJogadores:
print("Finalizing the game prototype")
else:
print("Starting another round of the current turn")
dadossorteados = []
print("======================================================")
print("===================== END OF THE GAME ====================")
print("======================================================")
Does anyone know what I'm doing wrong?
I'm new as a programmer. If anyone knows how to help me with this problem, I would be grateful.
EDIT: Well now the code just works. I can switch players just fine, but if you go through all the characters it crashes again since jogadorAtual gets too big for listaJogadores. I don't quite understand the game, but assuming you want to start back with the first player, an elegant way you can accomplish that is by doing modulus with the % operator, which divides two numbers but returns the remainder. If you divide the number of players by the size of listaJogadores, you'll always get a number inside listaJogadores's range.
# Change this...
print("PLAYER TURN: ", listaJogadores[jogadorAtual])
# ...to this
print("PLAYER TURN: ", listaJogadores[jogadorAtual % len(listaJogadores)])
If that's not what you need for your game, let me know.
Original answer: Is the game ending or is it crashing? When I run the game, it always crashes with:
File "C:\Users\me\Desktop\Untitled-1.py", line 56, in <module>
diceDrawns.append(diceDrawn)
AttributeError: 'int' object has no attribute 'append'
This is because after looping, you try to do diceDrawns.append(), but you've already replaced the diceDrawns list with an integer on line 87. I'm not sure if you meant to replace diceDrawn instead, but that's definitely the source of the problem.
An unrelated note: You can do += as a shorthand way to increment a variable by a certain amount, so you can replace a lot of instances of things like currentPlayer = currentPlayer + 1 with currentPlayer += 1, and the same can be done with any operator, so you could also do things like -= or *=
I am creating an Among Us ripoff (for fun!) and the while True & if/elif/else statements will only return false (not An Impostor) with the inputs. I had created a list for the names and 2 random elements from the list will be chosen as An Impostor. However, whenever I input a name that is The Impostor, it will only return
(player) was not An Impostor.
Here is my code;
import sys, time, random
names = ["player1", "player2", "player3", "player4", "player5", "player6", "player7", "player8", "player9", "player10"]
print("Players: ")
for x in names:
print(x)
print('—————————————————————————')
impostor1 = random.choice(names)
impostor2 = random.choice(names)
crewmates = 8
impostors = 2
tries = 6
while True:
talk = input("Guess who The Impostor(s) are. " + str(crewmates) + " Crewmates are left. " + str(impostors) + " Impostors are left. You have " + str(tries) + " tries left.")
if talk in names:
print(talk + " was voted for.")
time.sleep(0.1)
if talk != impostor1 or talk != impostor2:
notimp = talk + " was not An Impostor. "
names.remove(talk)
for y in notimp:
sys.stdout.write(y)
sys.stdout.flush()
time.sleep(0.05)
crewmates -= 1
tries -= 1
elif talk == impostor1 or talk == impostor2:
wasimp = talk + " was An Impostor. "
names.remove(talk)
for v in wasimp:
sys.stdout.write(v)
sys.stdout.flush()
time.sleep(0.1)
impostors -= 1
else:
print("That player was either ejected or is not a valid player.")
However, whenever I put the Impostor in the input, it says it isn't An Impostor?
I think this line is the source of the problem:
if talk != impostor1 or talk != impostor2:
Let's say impostor1 is player1 and impostor2 is player2 and someone input in player1, according to Python Boolean expression operator or that if statement will evaluate like this:
if player1 != impostor1 evaluated to False because player1 is indeed equals to impostor1.
So far so good, but because the first test is a False, Python simply evaluates and returns the right side operand which may be either True or False. In your case Python will evaluate if talk != impostor2 and return True, thereafter executes the nested block.
I am having an issue with calling variables to add while within a definition which is in the class 'mountain'. It runs the error:
AttributeError: 'function' object has no attribute 'picture'
Here is the code for it:
import random
class currencies:
film = 5
class pictures:
picture = {"m_goat": 0, "b_eagle": 0, "marmot": 0, "r_snake": 0, "m_lion": 0, "b_dragon": 0, "vulture": 0}
class location:
city = True
shop = False
mountains = False
desert = False
class mountain:
#Travel to mountains
def travel_m():
print("You climb to the top of a tall mountain")
location.mountains = True
animals = ["mountain goat", "bald eagle", "marmot", "rattlesnake", "mountain lion"]
animal_pics = ["m_goat", "b_eagle", "marmot", "r_snake", "m_lion"]
if 1 == 1: #for simplicity I changed this to a non random number
animal = random.randint(0, 4)
str_animal = animals[animal]
ans = input("You see a wild " + str_animal + ". Would you like to take a photo? (y/n) \n")
if ans == "y" and currencies.film == 0:
print("You cannot take a picture of this animal because you are out of film")
elif ans == "y":
currencies.film -= 1
pictures.picture[animal_pics] = pictures.picture[animal_pics] + 1 #this is the line with the error
print("You took a picture of the animal")
elif ans == "n":
print("The animal was left unbothered")
else:
print("I do not recognize that command")
def pictures():
print("You have " + str(pictures.pictures['m_goat']) + " picture(s) of mountain goats")
print("You have " + str(pictures.pictures['b_eagle']) + " picture(s) of bald eagles")
print("You have " + str(pictures.pictures['marmot']) + " picture(s) of marmots")
print("You have " + str(pictures.pictures['r_snake']) + " picture(s) of rattlesnakes")
print("You have " + str(pictures.pictures['m_lion']) + " picture(s) of mountain lions")
mountain.travel_m()
Thank you for any help at all. I'm just learning the language but neither me nor my teacher could find an answer for it online. If it's something stupid, please do say
When you do:
def pictures():
you're redefining the variable pictures. It now names the function, not the class that was defined earlier.
Give the function a name that doesn't conflict with the class, e.g.
def show_pictures():
Also, in the last function you use pictures.pictures. That should be pictures.picture.
After you fix those, this line is wrong:
pictures.picture[animal_pics] = pictures.picture[animal_pics] + 1
animal_pics is a list, you can't use it as a dictionary key. I think you meant:
pictures.picture[str_animal] += 1
My problem is that if you look at 'support' variable. (In the variable list) it doesn't apply to the Current Consumption. For EX. If I press 'S' and enter to start the game then press 'M' to display missions then press 'S' to choose the Survivors mission. And I recieve 2 survivors. That count won't add to the support for some reason and display "You are consuming 0.5 blah blah blah" not "You are consuming 0.7 blah blah blah" as it should be adding 0.1 per human? Sorry if this is hard to understand, I'm only 11 trying to program!
import random
from PIL import Image
print('\x1b[6;30;42m' + 'Zombie Survival Simulator' + '\x1b[0m')
print "Press [S] to start!"
resp = raw_input()
if 's' in resp or 'S' in resp:
foodmission = ['Convience Store','Grocery Store','Restraunt','Food Storage Area']
watermission = ['Convience Store', 'Old Gas Station', 'Water Tower','Toppled Coca-Cola truck.']
survivormission = ['Abandoned Refugee Camp','Bus','Army Camp','Train Station']
"FOOD"
#Pick Area
def pickfoodMission():
foodmis = random.choice(foodmission)
return foodmis
#Chance to get food
def chanceFood():
foodcha = random.randint(1,20)
return foodcha
#How much food you gain a mission
def foodPickup():
foodpick = random.randint(1,2)
return foodpick
"WATER"
#Pick the area
def pickwaterMission():
watermis = random.choice(watermission)
return watermis
#Chance for getting water
def chancewater():
watercha = random.randint(1,20)
return watercha
#Number of water you gain a mission
def waterPickup():
waterpick = random.randint(1,2)
return waterpick
"SURVIVORS"
#Pick the area
def picksurvivorMission():
survivormis = random.choice(survivormission)
return survivormis
#Chance for getting water
def chancehuman():
humancha = random.randint(1,20)
return humancha
#Number of water you gain a mission
def humanPickup():
humanpick = random.randint(1,2)
return humanpick
food = 3
water = 3
human = 5
healthy = 0
con = 0.1
level = 1
game = 1
new = 1
foodcon = 0
watercon = 0
support = 0.1 * human
newhuman = (human + (1 + (human / 5)) + healthy)
newwater = (water + (1 + (human / 5)) + healthy)
newfood = (water + (1 + (human / 5)) + healthy)
while game == 1:
if food <= 0 or water <= 0:
print('\x1b[7;30;41m' + 'You and your friends are dead.' + '\33[3m')
break
if food >= 3 or water >= 3:
healthy = healthy + 1
if food <= 2 or water <= 2:
healthy = healthy - 1
print "Current Resources: Food: " +str(food) + " Day(s) Water: " + str(water) + " Day(s)"
print "Current Survivors " + str(human)
if healthy <= -3 and healthy >= -1:
print "Current Survivors are " + ('\x1b[7;30;41m' + 'Nearly Dead' + '\33[3m')
if healthy == 0:
print "Current survivors " + ('\x1b[7;30;41m' + 'Are not healthy' + '\33[3m')
if healthy >= 1 and healthy <= 3:
print "Current Survivors are " + ('\x1b[7;32;43m' + 'Ok' + '\x1b[0m')
if healthy >= 3 and healthy <= 5:
print "Current Survivors are " + ('\x1b[7;32;43m' + 'Great' + '\x1b[0m')
if healthy >= 5 and healthy <= 7:
print "Current Survivors are " + ('\x1b[7;32;43m' + 'Excellent' + '\x1b[0m')
foodcon = support
watercon = support
food = food - support
water = water - support
print human
print support
print "You are consuming " + str(support) + " food and " + str(support) + " water per day"
if food - support <= 0 or water - support <= 0:
print('\x1b[7;30;41m' + 'You will not survive the next day.' + '\33[3m')
print "[M]issions [B]uilding [H]oard [E]nd Day"
resp = raw_input()
if 'M' in resp or 'm' in resp:
print "[F]ood [W]ater [S]urvivor"
resp = raw_input()
if 'F' in resp or 'f' in resp:
foodmis = pickfoodMission()
print "You go to a " + foodmis
foodcha = chanceFood()
if foodcha >= 14:
foodpick = foodPickup()
food = newfood
img = Image.open('food.png')
img.show()
print('\x1b[7;32;43m' + 'You are now at ' + str(newfood) + ' day(s) of food' + '\x1b[0m')
elif foodcha < 14:
print('\x1b[7;30;41m' + 'You come back empty handed.' + '\x1b[0m')
elif 'w' in resp or 'W' in resp:
watermis = pickwaterMission()
print "You go to a " + watermis
watercha = chancewater()
if watercha >= 14:
waterpick = waterPickup()
water = newwater
img = Image.open('water.png')
img.show()
print('\x1b[7;32;43m' + 'You are now at ' + str(newwater) + ' day(s) of water' + '\x1b[0m')
elif watercha <= 14:
print('\x1b[7;30;41m' + 'You come back empty handed.' + '\x1b[0m')
elif 's' in resp or 'S' in resp:
humanmis = picksurvivorMission()
print "You go to a " + humanmis
humancha = chancehuman()
if humancha >= 14:
humanpick = humanPickup()
human = newhuman
print('\x1b[7;32;43m' + 'You are now at ' + str(human) + ' survivor(s)' + '\x1b[0m')
img = Image.open('cats.jpg')
img.show()
elif humancha <= 14:
print('\x1b[7;30;41m' + 'You come back with no one else new.' + '\x1b[0m')
if 'B' in resp or 'b' in resp:
print "[F]ood"
You're never updating your support variable after you set it the first time so each time you print it out it's the same. Since support is dependent on human, you should either recalculate support every time human is updated or have a function like calculate_support() which calculates it when you need it.
As far as I can see at a quick glance you are only assigning value to the 'support' variable once in the code:
support = 0.1 * human
and I don't think this code gets to run again. Once support gets a value through this assignment statement it is not going to update even if you update the value of the 'human' variable.
We are supposed to use the code below to print out the parameters listed in it, currently however we are unable to do so and are using a round about method. This is supposed to print out things instead of what we print out in the Game class in the playturn function
def __str__(self):
x = self.name + ":\t"
x += "Card(s):"
for y in range(len(self.hand)):
x +=self.hand[y].face + self.hand[y].suit + " "
if (self.name != "dealer"):
x += "\t Money: $" + str(self.money)
return(x)
Here is our actual code, if you also see any other issues your input would be greatly appreciated
from random import*
#do we need to address anywhere that all face cards are worth 10?
class Card(object):
def __init__(self,suit,number):
self.number=number
self.suit=suit
def __str__(self):
return '%s'%(self.number)
class DeckofCards(object):
def __init__(self,deck):
self.deck=deck
self.shuffledeck=self.shuffle()
def shuffle(self):
b=[]
count=0
while count<len(self.deck):
a=randrange(0,len(self.deck))
if a not in b:
b.append(self.deck[a])
count+=1
return(b)
def deal(self):
if len(self.shuffledeck)>0:
return(self.shuffledeck.pop(0))
else:
shuffle(self)
return(self.shuffledeck.pop(0))
class Player(object):
def __init__(self,name,hand,inout,money,score,bid):
self.name=name
self.hand=hand
self.inout=inout
self.money=money
self.score=score
self.bid=bid
def __str__(self):
x = self.name + ":\t"
x += "Card(s):"
for y in range(len(self.hand)):
x +=self.hand[y].face + self.hand[y].suit + " "
if (self.name != "dealer"):
x += "\t Money: $" + str(self.money)
return(x)
class Game(object):
def __init__(self,deck, player):
self.player=Player(player,[],True,100,0,0)
self.dealer=Player("Dealer",[],True,100,0,0)
self.deck=DeckofCards(deck)
self.blackjack= False
def blackjacksearch(self):
if Game.gettot(self.player.hand)==21:#changed
return True
else:
return False
def firstround(self):
#self.player.inout=True#do we need this since this is above
#self.player.hand=[]#do wee need this....
#self.dealer.hand=[]#do we need this ....
self.player.hand.append(DeckofCards.deal(self.deck))
for card in self.player.hand:
a=card
print(self.player.name + ' ,you were dealt a '+str(a))
self.dealer.hand.append(DeckofCards.deal(self.deck))
for card in self.dealer.hand:
a=card
print('The Dealer has '+str(a))
playerbid=int(input(self.player.name + ' how much would you like to bet? '))
self.player.money-=playerbid
self.player.bid=playerbid
def playturn(self): #should this be changed to inout instead of hit.....we never use inout
#for player in self.player:
# a=player
#print(str(a))
hit=input('Would you like to hit? ') #should input be in loop?
while self.player.inout==True: #and self.blackjack!=True:#changed
print(self.player.name + ' , your hand has:' + str(self.player.hand)) #do we want to make this gettot? so it prints out the players total instead of a list....if we want it in a list we should print it with out brakets
self.player.hand.append(DeckofCards.deal(self.deck))
for card in self.player.hand:
a=card
print('The card that you just drew is: ' + str(a))
#print(Game.gettot(self.player.hand))
hit=input('Would you like to hit? ')
if hit=='yes':
(self.player.hand.append(DeckofCards.deal(self.deck)))#changed
self.player.inout==True#
else:
(self.player.hand) #changed
self.player.inout==False #changed
if self.player.blackjack==True:
print(self.player.name + " has blackjack ")
if hit=='no':
print (self.player.hand.gettot())
def playdealer(self):
while Game.gettot(self.dealer.hand)<17:#changed
self.dealer.hand.append(DeckofCards.deal(self.deck))
dealerhand=Game.gettot(self.dealer.hand) #changed
print(dealerhand)
if Game.gettot(self.dealer.hand)==21:#changed
self.dealer.blackhjack=True
dealerhand1=Game.gettot(self.dealer.hand)#changed
print(dealerhand1)
def gettot(self,hand):
total=0
for x in self.hand:
if x==Card('H','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('D','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('S','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('C','A'):
b=total+x #changed
if b>21:
total+=1
else:
total+=11
else:
total+=x
return(total)
def playgame(self):
play = "yes"
while (play.lower() == "yes"):
self.firstround()
self.playturn()
if self.player.blackjack == True:
print(self.player.name + " got BLACKJACK! ")
self.player.money += self.player.bid * 1.5
print (self.player.name + " now has " + str(self.player.money))
print("\n")
self.player.inout = False
if self.player.score > 21:
print(self.player.name + " lost with a tot of " + str(self.player.score))
self.player.money -= self.player.bid
print (self.player.name + " now has " + str(self.player.money))
print ("\n\n")
self.player.inout = False
self.playdealer()
if self.dealer.blackjack == True:
print("Dealer got blackjack, dealer wins\n")
self.player.money -= self.player.bid
print("Round\n")
print("\t",self.dealer)
print("\t",self.player)
print("\t Dealer has " + str(self.dealer.score) + ", " + self.player.name + " has " + str(self.player.score))
elif self.player.inout == True:
print("Round\n")
print("\t",self.dealer)
print("\t",self.player)
print("\n\t Dealer has " + str(self.dealer.score) + ", " + self.player.name + " has " + str(self.player.score))
if self.dealer.score > 21:
print("\t Dealer lost with a total of " + str(self.dealer.score))
self.player.money += self.player.bid
print(self.player.name + " now has " + str(self.player.money))
elif self.player.score > self.dealer.score:
print("\t" +self.player.name + " won with a total of " + str(self.player.score))
self.player.money += self.player.bid
print("\t"+self.player.name + " now has " + str(self.player.money))
else:
print("\t Dealer won with a total of " + str(self.dealer.score))
self.player.money -= self.player.bid
print("\t"+self.player.name + " now has " + str(self.player.money))
else:
print("Round")
print("\t",self.dealer)
print("\t",self.player)
if self.player.blackjack == False:
print("\t "+ self.player.name + " lost" )
else:
print("\t "+self.player.name + " Won!")
if self.player.money <= 0:
print(self.player.name + " out of money - out of game ")
play = "no"
else:
play = input("\nAnother round? ")
print("\n\n")
print("\nGame over. ")
print(self.player.name + " ended with " + str(self.player.money) + " dollars.\n")
print("Thanks for playing. Come back soon!")
ls= [Card('H','A'),Card('H','2'),Card('H','3'),Card('H','4'),Card('H','5'),Card('H','6'),Card('H','7'),Card('H','8'),Card('H','9'),Card('H','10'),
Card('H','J'),Card('H','Q'),Card('H','K'),
Card('S','A'),Card('S','2'),Card('S','3'),Card('S','4'),Card('S','5'),
Card('S','6'),Card('S','7'),Card('S','8'),Card('S','9'),Card('S','10'),
Card('S','J'),Card('S','Q'),Card('S','K'),
Card('C','A'),Card('C','2'),Card('C','3'),Card('C','4'),Card('C','5'),
Card('C','6'),Card('C','7'),Card('C','8'),Card('C','9'),Card('C','10'),
Card('C','J'),Card('C','Q'),Card('C','K'),
Card('D','A'),Card('D','2'),Card('D','3'),Card('D','4'),Card('D','5'),
Card('D','6'),Card('D','7'),Card('D','8'),Card('D','9'),Card('D','10'),
Card('D','J'),Card('D','Q'),Card('D','K')]
def main():
x = input("Player's name? ")
blackjack = Game(ls,x)
blackjack.playgame()
main()
The problem is that, in at least some places, you're trying to print a list.
While printing anything, including a list, calls str on it, the list.__str__ method calls repr on its elements. (If you don't know the difference between str and rep, see Difference between __str__ and __repr__ in Python.)
If you want to print the str of every element in a list, you have to do it explicitly, with a map or list comprehension.
For example, instead of this:
print(self.player.name + ' , your hand has:' + str(self.player.hand))
… do this:
print(self.player.name + ' , your hand has:' + [str(card) for card in self.player.hand])
But this is still probably not what you want. You will get ['8', '9'] instead of [<__main__.Card object at 0x1007aaad0>, <__main__.Card object at 0x1007aaaf0>], but you probably wanted something more like `8H 9C'. To do that, you'd want something like:
print(self.player.name + ' , your hand has:' +
' '.join(str(card) for card in self.player.hand))
You already have similar (although more verbose) code inside Player.__str__:
for y in range(len(self.hand)):
x +=self.hand[y].face + self.hand[y].suit + " "
This code could be improved in a few ways.
First, it's going to raise an AttributeError because you're using face instead of number. But really, you shouldn't need to do this at all—the whole reason you created a Card.__str__ method is so you can just use str(Card), right?
Second, you almost never want to loop over range(len(foo)), especially if you do foo[y] inside the loop. Just loop over foo directly.
Putting that together:
for card in self.hand:
x += str(card) + " "
At any rate, you need to do the same thing in both places.
The version that uses the join method and a generator expression is a little simpler than the explicit loop, but does require a bit more Python knowledge to understand. Here's how you'd use it here:
x += " ".join(str(card) for card in self.hand) + " "
Your next problem is that Card.__str__ doesn't include the suit. So, instead of 8H 9C, you're going to get 8 9. That should be an easy fix to do on your own.
Meanwhile, if you find yourself writing the same code more than once, you probably want to abstract it out. You could just write a function that takes a hand list and turns it into a string:
def str_hand(hand):
return " ".join(str(card) for card in self.hand)
But it might be even better to create a Hand class that wraps up a list of cards, and pass that around, instead of using a list directly.
You are not running the functionality you want because you are referencing player.hand. Try changing
str(self.player.hand)
to
str(self.player)