Variable X not updating when variables that should effect X change - python

I am a beginner at python. As most beginners, I am trying to make a text based rpg. I have finally gotten to the leveling up system and am at another roadblock. When the character levels up, they get to allot x skill points to a skill (add x to a variable x times). two of these variables effect the health of the character, however, when these two variables are changed by the user, the health variable stays the same. I have simplified my code for ease of reading (as my prose above is not that clear to begin with lol):
class Char:
def __init__(self, x, y):
self.str = x
self.con = y
self.hp = (self.con + self.str) / 2
player = Char(20, 20)
def main(dude):
print("strength: " + str(dude.str))
print("constitution: " + str(dude.con))
print("hp: " + str(dude.hp))
print("------")
action = input("press 1 to change str, 2 to change con")
if action == "1":
dude.str = dude.str + 10
main(dude)
elif action == "2":
dude.con = dude.con + 10
main(dude)
else:
main(dude)
main(player)
although these variables can increase by increments of ten in this situation, the hp remains at 20
how can I remedy this problem?
Thanks!

Whenever the Char's attributes are updated, the code needs to re-compute the HP.
All this sort of code is best put inside the Char object:
class Char:
def __init__(self, x, y):
self.str = x
self.con = y
self.setHP()
def __str__(self):
text = "strength: " + str(self.str) + "\n" +\
"constitution: " + str(self.con) + "\n" +\
"hp: " + str(self.hp)
return text
def setHP(self):
self.hp = (self.con + self.str) / 2
def adjustStr(self, amount):
self.str += amount
self.setHP()
def adjustCon(self, amount):
self.con += amount
self.setHP()
def main(dude):
print(str(dude))
print("------")
action = input("press 1 to change str, 2 to change con")
if action == "1":
dude.adjustStr(10)
main(dude)
elif action == "2":
dude.adjustCon(10)
main(dude)
else:
main(dude)
player = Char(20, 20)
main(player)

The hp attribute does not change when the str or con change. The only time it is set is in the constructor. You could define an update method to Char like this:
class Char:
def __init__(self, x, y):
self.str = x
self.con = y
self.update()
def update(self):
self.hp = (self.con + self.str) / 2
and call it at the end of main:
def main(dude):
print("strength: " + str(dude.str))
print("constitution: " + str(dude.con))
print("hp: " + str(dude.hp))
print("------")
action = input("press 1 to change str, 2 to change con")
if action == "1":
dude.str = dude.str + 10
main(dude)
elif action == "2":
dude.con = dude.con + 10
main(dude)
else:
main(dude)
dude.update()

Because you evaluate the hp attribute only in the __init__() method, i. e. only in your statement
player = Char(20, 20)
The most quick fix (not a very nice one, but a very simple) is to create a new instance of Char after each change:
if action == "1":
dude.str = dude.str + 10
dude = Char(dude.str, dude.con) # new dude (with current str and con)
main(dude)
elif action == "2":
dude.con = dude.con + 10
dude = Char(dude.str, dude.con) # new dude (with current str and con)
main(dude)

You have to update the hp each time, since you used self.str and self.con only once to compute hp and stored it independently from self.str and self.con. You could use a get_hp for that.
class Char:
def __init__(self, x, y):
self.str = x
self.con = y
def get_hp(self):
return (self.con + self.str) / 2
player = Char(20, 20)
def main(dude):
print("strength: " + str(dude.str))
print("constitution: " + str(dude.con))
print("hp: " + str(dude.get_hp()))
print("------")
action = input("press 1 to change str, 2 to change con")
if action == "1":
dude.str = dude.str + 10
main(dude)
elif action == "2":
dude.con = dude.con + 10
main(dude)
else:
main(dude)

I don't agree with the other answers, as the best way for me would have been to use a property. Properties work just like getters, but has the benefit to allow it to be dynamically calculated, which is exactly what you are looking for.
class Char:
def __init__(self, x, y):
self.str = x
self.con = y
#property
def hp(self):
# todo handle negative hp!
return (self.con + self.str) / 2.
def test_hp():
player = Char(20, 20)
assert player.hp == 20
def test_hp_with_changes_to_con_or_str():
player = Char(20, 20)
player.con += 10
assert player.hp == 25
player.str += 10
assert player.hp == 30
Also, as you can see, it is better to just write a test than to test stuff with output to stdout.
scratch_12.py .. [100%]
========================== 2 passed in 0.20 seconds ===========================
The above hp property is read-only, but you can make a setter for it as well if needed. Read up on property
PS: also, use full names, like Character as it is better to be explicit than implicit :)

Related

How can I move around a list filled with class calls and when I'm on the class' indexspot how can I call it?

I've recently been trying to make a Textadventure but I'm having a big problem with the idea of "moving" around a List (x_achses) with a List inside(y-achses) it (my father called it a matrix) and in the second list (y-achses) there are a bunch of random types of things like an enemy. In that "Matrix" I wanna move around and on certain fields it should activate the assigned class(here it should simply print the classes name).
I've tried using the index of the list and changing dependently but it didn't work, I've tried using the len() function and changing it dependently but nothing ever seems to be happening. No classes or anything seem to be called. I have no idea what to do.
import random
import secrets
class Character:
def __init__(self, hp, ad, name):
self.hp = hp
self.ad = ad
self.name = name
def get_hit(self, ad):
self.hp = self.hp - ad
if self.hp <= 0:
self.die()
def is_dead(self):
return self.hp <= 0
def die(self):
print(self.name + " died")
class Human_enemies(Character):
def __init__(self):
super().__init__(self, 10, 3, "Mermaids")
Human_enemies.enemie_amount = random.randint(1, 9)
print("Mermaids")
def enemie_amount(self):
enemie_amount = random.randint(1, 9)
enemies = []
for i in range(enemie_amount):
enemies.append(Human_enemies())
class Vessel:
def __init__(self, hp, ad, storage, name):
self.hp = hp
self.ad = ad
self.storage = storage
self.name = name
def get_hit(self, ad):
self.hp = self.hp - ad
if self.hp <= 0:
self.die()
def is_dead(self):
return self.hp <= 0
def die(self):
print(self.name + " died")
class Sloop_ship(Vessel):
def __init__(self):
super().__init__(self, 1000, 50-100, 0, "Sloop")
def type(self):
print("Sloop")
class Brigattine_ship(Vessel):
def __init__(self):
super().__init__(self, 2500, 70-110, 15, "Brig")
def type(self):
print("Brig")
class Galleon_ship(Vessel):
def __init__(self):
super().__init__(self, 5000, 150-200, 40, "Galleon")
def type(self):
print("Galleon")
class Shipwreck:
def __init__(self):
print("Shipwreck")
wanna_loot = input("Do you want to check the wreck for any loot or survivors?\n")
#TODO: Make this better, sth. like chance of death or sth.
class Fields:
def Rougethingi(self):
random1 = random.randint(0, 5)
if random1 == 0:
return Shipwreck
elif random1 == 1:
return Human_enemies
elif random1 == 2:
return Sloop_ship
elif random1 == 3:
return Brigattine_ship
elif random1 == 4:
return Galleon_ship
else:
return None
class Map():
def __init__(self, x, y):
self.rowsX = []
self.x = x
self.y = y
for i in range(x):
self.rowsY = []
for r in range(y):
self.rowsY.append(Fields.Rougethingi(self))
self.rowsX.append(self.rowsY)
def print_map(self):
for j in self.rowsX:
print("")
for f in self.rowsY:
if f == None:
print("0 ", end = "")
elif f != None:
print("1 ", end = "")
print("\n")
class Player(Character):
def __init__(self):
super().__init__(self, 100, 1, player_name)
def start(self):
self.player_x = 1
self.player_y = 1
n.rowsX[self.player_x].__init__()
n.rowsY[self.player_y].__init__()
def move_right(self):
self.player_x = self.player_x + 1
if self.player_x >= n.x or self.player_x >= n.x - n.x:
print("You can't go further right")
def move_left(self):
self.player_x = self.player_x - 1
if self.player_x >= n.x or self.player_x >= n.x - n.x:
print("You can't go further right")
def move_up(self):
self.player_y = self.player_y + 1
if self.player_y >= n.y or self.player_y >= n.y - n.y:
print("You can't go further right")
def move_down(self):
self.player_y = self.player_y - 1
if self.player_y >= n.y or self.player_y >= n.y - n.y:
print("You can't go further right")
def quit_game():
exit("And the mighty adventurer decided to rest for the day...")
def print_help():
utility = print("(help, save, load, map,)")
movement = print("(forward, backwards, starboard, port)")
utility
movement
def save():
#TODO: Make a save system
pass
def load():
#TODO: Make a load system
pass
if __name__ == "__main__":
player_name = input("What is thy title scalywag?\n")
n = Map(30, 30)
m = Player.start
print("You shall call us for 'help' to help you with your role of Captain\n")
#? This is the main input loop --------------------------------------v
while True:
cmd = input(">>>")
if cmd == "help":
print_help()
continue
elif cmd == "map":
n.print_map()
continue
elif cmd == "quit":
quit_game()
elif cmd == "save":
save()
continue
elif cmd == "load":
load()
continue
elif cmd == "forward":
Player.move_up
continue
elif cmd == "backwards":
Player.move_down
continue
elif cmd == "starboard":
Player.move_right
continue
elif cmd == "port":
Player.move_left
continue
else:
print("I dont understand that... \n")
continue
#? This is the main input loop --------------------------------------v

How to use classes to create attacks in python

I am trying to make it so that the user can input the name of another pokemon class so that I can use the attack function. Is there any way I could do this from user input? It seems as though even when I put in a valid name it returns an error. I would love to know as to how I can do this so that I can finish my game.
import random
class Pokemon(object):
def __init__(self, name, level, pokemon_type, max_health, current_health, is_knocked_out):
self.name = name
self.level = level
self.pokemon_type = pokemon_type
self.current_health = current_health
self.max_health = max_health
self.is_knocked_out = is_knocked_out
#knock out function
def knock_out(self):
self.is_knocked_out = True
print(self.name + " is now knocked out")
#lose health func, takes in one parameter which is damage
def lose_health(self, amount):
if amount > self.current_health:
print(self.name + " has been knocked out and now has 0 hp")
self.current_health = 0
self.is_knocked_out = True
else:
self.current_health -= amount
print(self.name + " now has " + str(self.current_health) + " HP")
#hp regen function, takes in one parameter which is the amount of hp to be regained, wont allow you to go above the max
def regain_health(self, amount):
if amount > self.max_health:
print("You cannot heal past your max HP")
else:
self.current_health += amount
print(self.current_health)
#function to revive dead mons
def revive(self):
if self.is_knocked_out == True:
self.is_knocked_out = False
print(self.name + " has been revived and half of his hp has been restored!")
self.current_health = self.max_health / 2
else:
print("This pokemon is still alive ")
return
#attack function, in progress
def attack(self, pokemon_name, move_number):
if self.current_health > 0 and self.is_knocked_out == False:
if move_number == 1:
pokemon_name.lose_health(random.randint(1,150)) #Here is where the issue is, how can I make user input determine the name of the pokemon which is being attacked and sequentially make it lose HP?
print(pokemon_name + " was attacked")
elif move_number == 2:
pass
elif move_number == 3:
pass
elif move_number == 4:
pass
else:
print("You are knocked out!")
Lucario = Pokemon("Lucario", 12, "fighting", 200, 200, False)
Blastoise = Pokemon("Blastoise", 12, "water", 200,200, False)
Blastoise.attack("Lucario", 1)
just use:
if move_number == 1:
globals()[pokemon_name]
what is globals()? it's a built-in function that load all global variable (predefined or user-defined), it's a dictionary
data = 5
globals()["data"]
every variable you defined, it will be added to globals() as
globals()[name] = value
def attack(self, pokemon, move_number):
if self.current_health > 0 and self.is_knocked_out == False:
if move_number == 1:
pokemon.lose_health(random.randint(1,150)) #Here is where the issue is, how can I make user input determine the name of the pokemon which is being attacked and sequentially make it lose HP?
print(pokemon.name + " was attacked")
elif move_number == 2:
pass
elif move_number == 3:
pass
elif move_number == 4:
pass
else:
print("You are knocked out!")
Characters = dict()
Characters["Lucario"] = Pokemon("Lucario", 12, "fighting", 200, 200, False)
Characters["Blastoise"] = Pokemon("Blastoise", 12, "water", 200,200, False)
Characters["Blastoise"].attack(Characters["Lucario"], 1)
you also can use dictionary. what is dictionary? a dictionary is a collection of named variable, like list, but you can add to it by name...
how to define dictionary?
Characters = dict()
and add your variables:
Characters["<name>"] = value
like:
Characters["Blastoise"] = Pokemon("Blastoise", 12, "water", 200,200, False)
and use variables:
Characters["<name>"].<your-method>
like:
Characters["Blastoise"].attack(Characters["Lucario"], 1)
just one point: if you use dictionary, so you send variable (Pokemon object, not it's name), so attack's second parameter is pokemon and use:
print(pokemon.name + " was attacked")

how to sort a list by a attribute [duplicate]

This question already has answers here:
How to sort a list of objects based on an attribute of the objects in descending order?
(9 answers)
Closed 2 years ago.
Yes, I have looked at other posts but I am still a bit confused, some use lambda or make multiple methods and I am confused.
I have this class, and I want to create multiple instances (members of the team) and before I call my function to start a fight, I want to arrange a list so that the person with the highest self.full_speed goes first, etc. (I have a full_speed and speed attributes for debuffs/buffs)
class Player:
"""Describes the main player."""
def __init__(self, level, health, will, speed):
"""Initializes stats"""
self.level = level
self.health = health
self.full_health = health
self.will = will
self.full_will = will
self._cheat = "cheat" # Protected instance attribute has a leading underscore
# Private starts with two leading underscores
self.speed = speed
self.full_speed = speed
def level_up(self, skill):
"""Choose where to distribute skill points."""
pass
def default_attack(self, enemy):
"""Normal attack that damages enemy target."""
damage = 0
if random.randint(1,100) <= 95:
damage = (self.level * 2)
critical_hit = random.randint(1,10)
if critical_hit == 1:
damage += int(self.level * 0.5)
print("Critical hit!")
enemy.health -= damage
print("The enemy took " + str(damage) + " damage.")
def special_attack(self, enemy):
"""Deals more damage but uses will, more likely to miss."""
damage = 0
if random.randint(1,100) <= 90:
damage = (self.level * 3)
critical_hit = random.randint(1, 10)
if critical_hit == 1:
damage += self.level
print("Critical hit!")
enemy.health -= damage
self.will -= 2
print("The enemy took " + str(damage) + " damage.")
def heal(self):
"""Heals self by 10%."""
self.will -= 2
recovered = int(self.full_health * 0.10)
self.health += recovered
if self.health > self.full_health:
self.health = self.full_health
print("Recovered " + str(recovered) + " HP.")
I've started here but I am unsure where to go at this point..
def team_by_speed(team):
new_team = []
for member in team:
# member.full_speed
return new_team
Used Sorted() function
Call sorted(iterable, key: NoneType=None) with a list of objects as iterable

MVC infrastructure

import random
class Spinner(object):
#staticmethod
def getSpin():
newSpin = random.randint(1,6)
return newSpin
class Player(object):
def __init__(self,name):
self.position = 1
self.name = name
def setName(self,name):
self.name = name
def changePosition(self,number):
self.position = self.position + number
def setPosition(self,pos):
self.position = pos
return self.position
def getPosition(self):
return self.position
def getName(self):
return self.name
def spin(self):
newSpin = Spinner.getSpin()
self.position = self.position + newSpin
print(str(self.name) + "'s spin was: " + str(newSpin))
class Display():
def buildLadders():
ladders = [[0 for x in range(2)] for x in range(2)]
ladders[0][0] = 2
ladders[0][1] = 7
ladders[1][0] = 4
ladders[1][1] = 5
return ladders
def buildChutes():
chutes = [[0 for x in range(2)] for x in range(2)]
chutes[0][0] = 9
chutes[0][1] = 2
chutes[1][0] = 6
chutes[1][1] = 3
return chutes
class Check(Player):
def checkLadders(self):
ladders = Display.buildLadders()
for i in range(0,len(ladders),1):
if self.getPosition() == ladders[i][0]:
self.position = self.setPosition(ladders[i][1])
print(str(self.name) + " Landed on a Ladder! from " + \
str(ladders[i][0]) +" to " + str(ladders[i][1]))
def checkChutes(self):
chutes = Display.buildChutes()
for i in range(0,len(chutes),1):
if self.getPosition() == chutes[i][0]:
self.position = self.setPosition(chutes[i][1])
print(str(self.name) + " Landed on a Chutes! from " + \
str(chutes[i][0]) + " to " + str(chutes[i][1]))
def checkQuestions(num):
one = random.randint(num,num*10)
two = random.randint(num,num*10)
listqq = [one,two]
return listqq
class Controller(object):
def __init__(self,names):
self.winner = ''
self.players = []
for n in names:
p = Player(n)
self.players.append(p)
def move(self):
players = self.players
winner = self.winner
click = ''
count = 1
while True:
for i in range(0,len(players)):
if winner == '' and click != 'e':
print("----" + str(players[i].getName()) + "'s TURN----")
click = input("Press r to roll or e to exit: ")
while click != 'r' and click != 'e':
click = input("Press r to roll or e to exit: ")
if click == 'r' and click != 'e':
count = count + 1
listqq = Check.checkQuestions(count)
answer = input(str(listqq[0]) + ' + ' + str(listqq[1]) +' is:')
if answer == str(listqq[0]+listqq[1]):
print(str(players[i].getName()) + "'s initial position is " \
+ str(players[i].getPosition()))
View(players).display()
players[i].spin()
Check.checkLadders(players[i])
Check.checkChutes(players[i])
else:
pass
if players[i].getPosition() >= 12:
players[i].position = players[i].setPosition(12 - (players[i].getPosition() - 12))
print(str(players[i].getName()) + "'s new position is " \
+ str(players[i].getPosition()))
View(players).display()
if players[i].getPosition() == 12:
winner = players[i].getName()
if click == 'e' and click != 'r':
print('Bye')
break
if winner != '':
print(str(winner) + " is the winner!!!")
break
class View(Player):
def __init__(self,player):
self.players = player
def display(self):
players = self.players
listof = [9,10,11,12,8,7,6,5,1,2,3,4]
ladders = Display.buildLadders()
chutes = Display.buildChutes()
board = [[]] * 3
for i in range(len(players)):
for j in range(len(listof)):
if self.players[i].position == listof[j]:
listof[j] = 'X'
for j in range(len(listof)):
for i in range(len(ladders)):
if ladders[i][0] == listof[j]:
listof[j] = 'L'
for j in range(len(listof)):
for i in range(len(chutes)):
if chutes[i][0] == listof[j]:
listof[j] = 'C'
for i in range(0,4):
board[0] = board[0] + [listof[i]]
for i in range(4,8):
board[1] = board[1] + [listof[i]]
for i in range(8,12):
board[2] = board[2] + [listof[i]]
for row in board:
for num in row:
if num == 'X':
print(" X", end=" ")
if num == 'L':
print(" L", end= " ")
if num == 'C':
print(" C", end= " ")
if num != 'X' and num != 'L' and num != 'C':
if 10 <= num <= 20:
print(num,end=" ")
if num != 'X' and num != 'L' and num!= 'C':
if 1 <= num <= 9:
print(str(num).rjust(2), end= " ")
print()
def main():
n = input("Please enter number of players: ")
names = []
for i in range (0,int(n)):
name = input("Please input your name: ")
names.append(name)
game = Controller(names)
game.move()
while True:
ask = input("Do you want to play again? (y/n)")
if ask == 'y':
game = Controller(names)
game.move()
if ask == 'n':
print("Bye, see you again!")
break
main()
fixed version:
import random
class Player(object):
def __init__(self,name):
self.position = 1
self.name = name
def setName(self,name):
self.name = name
def changePosition(self,number):
self.position = self.position + number
def setPosition(self,pos):
self.position = pos
return self.position
def spin(self):
newSpin = self.getSpin()
self.position = self.position + newSpin
print(str(self.name) + "'s spin was: " + str(newSpin))
def checkLadders(self):
ladders = self.buildLadders()
for i in range(0,len(ladders),1):
if self.position == ladders[i][0]:
self.position = self.setPosition(ladders[i][1])
print(str(self.name) + " Landed on a Ladder! from " + \
str(ladders[i][0]) +" to " + str(ladders[i][1]))
def checkChutes(self):
chutes = self.buildChutes()
for i in range(0,len(chutes),1):
if self.position == chutes[i][0]:
self.position = self.setPosition(chutes[i][1])
print(str(self.name) + " Landed on a Chutes! from " + \
str(chutes[i][0]) + " to " + str(chutes[i][1]))
#staticmethod
def checkQuestions(num):
one = random.randint(num,num*10)
two = random.randint(num,num*10)
listqq = [one,two]
return listqq
#staticmethod
def getSpin():
newSpin = random.randint(1,6)
return newSpin
#staticmethod
def buildLadders():
ladders = [[0 for x in range(2)] for x in range(2)]
ladders[0][0] = 2
ladders[0][1] = 7
ladders[1][0] = 4
ladders[1][1] = 5
return ladders
#staticmethod
def buildChutes():
chutes = [[0 for x in range(2)] for x in range(2)]
chutes[0][0] = 9
chutes[0][1] = 2
chutes[1][0] = 6
chutes[1][1] = 3
return chutes
class Controller(object):
def __init__(self,names):
self.winner = ''
self.players = []
for n in names:
p = Player(n)
self.players.append(p)
def move(self):
players = self.players
winner = self.winner
click = ''
count = 1
while True:
for i in range(0,len(players)):
if winner == '' and click != 'e':
print("----" + str(players[i].name) + "'s TURN----")
click = input("Press r to roll or e to exit: ")
while click != 'r' and click != 'e':
click = input("Press r to roll or e to exit: ")
if click == 'r' and click != 'e':
count = count + 1
listqq = Player.checkQuestions(count)
answer = input(str(listqq[0]) + ' + ' + str(listqq[1]) +' is:')
if answer == str(listqq[0]+listqq[1]):
print(str(players[i].name) + "'s initial position is " \
+ str(players[i].position))
View(players).display()
players[i].spin()
Player.checkLadders(players[i])
Player.checkChutes(players[i])
else:
pass
if players[i].position >= 12:
players[i].position = players[i].setPosition(12 - (players[i].getPosition() - 12))
print(str(players[i].name) + "'s new position is " \
+ str(players[i].position))
View(players).display()
if players[i].position == 12:
winner = players[i].name
if click == 'e' and click != 'r':
print('Bye')
break
if winner != '':
print(str(winner) + " is the winner!!!")
break
class View():
def __init__(self,player):
self.players = player
def display(self):
players = self.players
listof = [9,10,11,12,8,7,6,5,1,2,3,4]
ladders = Player.buildLadders()
chutes = Player.buildChutes()
board = [[]] * 3
for i in range(len(players)):
for j in range(len(listof)):
if self.players[i].position == listof[j]:
listof[j] = 'X'
for j in range(len(listof)):
for i in range(len(ladders)):
if ladders[i][0] == listof[j]:
listof[j] = 'L'
for j in range(len(listof)):
for i in range(len(chutes)):
if chutes[i][0] == listof[j]:
listof[j] = 'C'
for i in range(0,4):
board[0] = board[0] + [listof[i]]
for i in range(4,8):
board[1] = board[1] + [listof[i]]
for i in range(8,12):
board[2] = board[2] + [listof[i]]
for row in board:
for num in row:
if num == 'X':
print(" X", end=" ")
if num == 'L':
print(" L", end= " ")
if num == 'C':
print(" C", end= " ")
if num != 'X' and num != 'L' and num != 'C':
if 10 <= num <= 20:
print(num,end=" ")
if num != 'X' and num != 'L' and num!= 'C':
if 1 <= num <= 9:
print(str(num).rjust(2), end= " ")
print()
def main():
n = input("Please enter number of players: ")
names = []
for i in range (0,int(n)):
name = input("Please input your name: ")
names.append(name)
game = Controller(names)
game.move()
while True:
ask = input("Do you want to play again? (y/n)")
if ask == 'y':
game = Controller(names)
game.move()
if ask == 'n':
print("Bye, see you again!")
break
main()
Is this following the MVC infrastructure? How to know if it fits the MVC structure or not? Thanks. Does we have to put each model,view,and controller in different module for it to be described as following the MVC structure?
First off the program is not really object oriented. View is instanciated every time when the game state has to be displayed just to call the one and only method. Classes with just the __init__() and one other method are a code smell because, like in this case, it's just a function crammed into a class for no good reason. The same can be said about Control — also just the __init__() and one additional method that get's called exactly once right after instanciating the object and directly after the call the object isn't used anymore.
Taking those ”fake” classes and considering the amount of static methods it seems you are under the impression classes automatically lead to object oriented programs — they don't. And there is nothing wrong with using functions instead of artificially introducing unnecessary complexity with classes that are just syntactically classes. Functions are objects too in Python, so when you have a display function it's okay to pass that around as „view” part of an MVC pattern. It's a callable object.
Which brings us to the MVC question: Supposing Player is the model then it should not interact with the user by printing stuff. Display and input is for the view to handle. So Control isn't a controller because the function in disguise also heavily interacts with the user via print() and input().

Recording a win or loss in a game of craps

So I have to create a game of craps that takes into account bets for an assignment. So far, my code works in that the dice rolls are correct and other little tidbits the assignment called for. But now I don't know how to record each game as a win / lose for the player or computer so that the pot can be added to the winner's money. I realize that my code is half doe, isn't finished, and doesn't run as is, but I just seriously need some help from someone. Please and thank you. Here are more specific directions on my assignment:
http://www.ics.uci.edu/~kay/courses/i42/hw/labA.html
import random
def craps():
print("Welcome to Sky Masterson's Craps Game")
handle_commands()
def handle_commands(): # Collection -> Collection (plus interaction)
""" Display menu to user, accept and process commands
"""
playerInitial = 500
compInitial = 500
MENU = "How much would you like to bet?: "
while True:
bet = float(input(MENU))
if bet <= playerInitial:
human_game()
elif bet > playerInitial:
print("Sorry, you can't bet more than you have")
def handle_commands2():
MENU2 = "Would you like to play again? (y or n): "
while True:
response = input (MENU2)
if response=="y":
counter = counter + multipleGames()
elif response=="n":
while ( counter < 2000):
roll = random.randint(1, 6) + random.randint(1,6)
updateCount(roll)
counter += 1
print ("Thank you for playing." + "\n" + "\n" + "Distribution of dice rolls: " + "\n")
return
else:
invalid_command(response)
def invalid_command(reponse):
"""print message for invalid menu command.
"""
print("Sorry; '" + response + "' isn't a valid command. Please try again.")
def play_game():
"""prints shooters roll results
"""
diceRoll = 0
roll = random.randint(1, 6) + random.randint(1, 6)
updateCount(roll)
diceRoll = diceRoll + 1
point = 0
print("The roll is " + str(roll))
response = (roll)
if response== 7 or response== 11:
print("Natural; shooter wins" + "\n" + "Thank you for playing")
handle_commands2()
elif response== 2 or response== 3 or response== 12:
print("Crapped out; shooter loses" + "\n" + "Thank you for playing")
handle_commands2()
else:
print("The point is " + str(roll))
point = roll
secondRoll = 0
handle_commands()
while (secondRoll !=point) and (secondRoll != 7):
secondRoll = random.randint(1, 6) + random.randint(1, 6)
updateCount(secondRoll)
diceRoll += 1
print("The roll is " + str(secondRoll))
handle_commands()
if secondRoll== point:
print ("Made the point; shooter wins." + "\n" + "Thank you for playing")
handle_commands2()
elif (secondRoll == 7):
print ("Crapped out; shooter loses." + "\n" + "Thank you for playing")
handle_commands2()
return diceRoll
def multipleGames():
gameCounter = 0
while (gameCounter <= 2000):
print("Your game: ")
gameCounter += play_game()
print("\n")
print("Computer's game: ")
gameCounter += play_game()
print( "\n")
return gameCounter
def updateCount(point):
count =List[point] + 1
List[point] = count
List = {2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0, 11:0, 12:0}
def human_game():
playerInitial = 500
compInitial = 500
while True:
play_game()
if
playerInitial += bet
compInitial += bet
counter = 0
counter = counter + multipleGames()
playerInitial -= bet
craps()
for point in List:
print("%2d" %(point) + ": " + "%3d" %(List[point]) + " " + "(" + ("%2d" % (int((List[point])/2000*100)))+ "%" + ")" + " " + ("*" *(int((List[point])/2000*100))))
Use classes:
import random
class Human:
def __init__(self):
self.name = 'Human'
self.wins = []
self.losses = []
self.bets = []
self.total = 0
class Computer:
def __init__(self):
self.name = 'Computer'
self.wins = []
self.losses = []
self.bets = []
self.total = 0
class Game:
def __init__(self):
self.rolls = []
self.currentPlayer = None
def roll(self):
self.rolls.append(random.randint(1, 6))
if __name__ == '__main__':
human = Human()
computer = Computer()
game = Game()
game.roll()
print games.rolls
I won't code all of it for you, but using classes will make things much simpler.

Categories