Morning all,
I'm an A level computer science teacher, and with their pre-release material exam coming up they're busy beavering away trying to make things work.
I don't teach the programming side of the course, focusing on the theory, and their programming teacher has been off ill for a while so I'm doing what I can but running out of time to support the top end.
Their pre-release material in Python is based on a foxes and rabbits game, and one of the pupils is trying to make a class called 'GiantWarren' that inherits the properties and functions of warren, but is a larger instance.
His code is below, and he's using 'super' to try and inherit the functions of warren, but it won't work unless he copy and pastes the functions. Any help on how to get super working would be greatly appreciated, not just by me, but my pupils as well:
Note - Warren is line 228, GiantWarren is line 351
#Skeleton Program code for the AQA A Level Paper 1 2017 examination
#this code should be used in conjunction with the Preliminary Material
#written by the AQA Programmer Team
#developed in the Python 3.4.1 programming environment
import enum
import random
import math
class Location:
def __init__(self):
self.Fox = None
self.Warren = None
class Simulation:
def __init__(self, LandscapeSize, InitialWarrenCount, InitialFoxCount, Variability, FixedInitialLocations):
self.__ViewRabbits = ""
self.__TimePeriod = 0
self.__WarrenCount = 0
self.__FoxCount = 0
self.__ShowDetail = False
self.__LandscapeSize = LandscapeSize
self.__Variability = Variability
self.__FixedInitialLocations = FixedInitialLocations
self.__Landscape = []
for Count1 in range (self.__LandscapeSize):
LandscapeRow = []
for Count2 in range (self.__LandscapeSize):
LandscapeLocation = None
LandscapeRow.append(LandscapeLocation)
self.__Landscape.append(LandscapeRow)
self.__CreateLandscapeAndAnimals(InitialWarrenCount, InitialFoxCount, self.__FixedInitialLocations)
self.__DrawLandscape()
MenuOption = 0
while (self.__WarrenCount > 0 or self.__FoxCount > 0) and MenuOption != 5:
print()
print("0. Advance 10 time periods hiding detail")
print("1. Advance to next time period showing detail")
print("2. Advance to next time period hiding detail")
print("3. Inspect fox")
print("4. Inspect warren")
print("5. Exit")
print()
try:
MenuOption = int(input("Select option: "))
except:
print("What you have entered is not an integer. Try again")
if MenuOption == 0:
for a in range(1, 11):
self.__TimePeriod += 1
self.__ShowDetail = False
self.__AdvanceTimePeriod()
if MenuOption == 1:
self.__TimePeriod += 1
self.__ShowDetail = True
self.__AdvanceTimePeriod()
if MenuOption == 2:
self.__TimePeriod += 1
self.__ShowDetail = False
self.__AdvanceTimePeriod()
if MenuOption == 3:
x = self.__InputCoordinate("x")
y = self.__InputCoordinate("y")
if not self.__Landscape[x][y].Fox is None:
self.__Landscape[x][y].Fox.Inspect()
if MenuOption == 4:
x = self.__InputCoordinate("x")
y = self.__InputCoordinate("y")
if not self.__Landscape[x][y].Warren is None:
self.__Landscape[x][y].Warren.Inspect()
self.__ViewRabbits = input("View individual rabbits (y/n)? ")
if self.__ViewRabbits == "y":
self.__Landscape[x][y].Warren.ListRabbits()
input()
def __InputCoordinate(self, CoordinateName):
Coordinate = int(input(" Input " + CoordinateName + " coordinate:"))
return Coordinate
def __AdvanceTimePeriod(self):
NewFoxCount = 0
if self.__ShowDetail:
print()
for x in range (0, self.__LandscapeSize):
for y in range (0, self.__LandscapeSize):
if not self.__Landscape[x][y].Warren is None:
if self.__ShowDetail:
print("Warren at (", x, ",", y, "):", sep = "")
print(" Period Start: ", end = "")
self.__Landscape[x][y].Warren.Inspect()
if self.__FoxCount > 0:
self.__FoxesEatRabbitsInWarren(x, y)
if self.__Landscape[x][y].Warren.NeedToCreateNewWarren():
self.__CreateNewWarren()
self.__Landscape[x][y].Warren.AdvanceGeneration(self.__ShowDetail)
if self.__ShowDetail:
print(" Period End: ", end = "")
self.__Landscape[x][y].Warren.Inspect()
input()
if self.__Landscape[x][y].Warren.WarrenHasDiedOut():
self.__Landscape[x][y].Warren = None
self.__WarrenCount -= 1
for x in range (0, self.__LandscapeSize):
for y in range (0, self.__LandscapeSize):
if not self.__Landscape[x][y].Fox is None:
if self.__ShowDetail:
print("Fox at (", x, ",", y, "): ", sep = "")
self.__Landscape[x][y].Fox.AdvanceGeneration(self.__ShowDetail)
if self.__Landscape[x][y].Fox.CheckIfDead():
self.__Landscape[x][y].Fox = None
self.__FoxCount -= 1
else:
if self.__Landscape[x][y].Fox.ReproduceThisPeriod():
if self.__ShowDetail:
print(" Fox has reproduced. ")
NewFoxCount += 1
if self.__ShowDetail:
self.__Landscape[x][y].Fox.Inspect()
self.__Landscape[x][y].Fox.ResetFoodConsumed()
if NewFoxCount > 0:
if self.__ShowDetail:
print("New foxes born: ")
for f in range (0, NewFoxCount):
self.__CreateNewFox()
if self.__ShowDetail:
input()
self.__DrawLandscape()
print()
def __CreateLandscapeAndAnimals(self, InitialWarrenCount, InitialFoxCount, FixedInitialLocations):
for x in range (0, self.__LandscapeSize):
for y in range (0, self.__LandscapeSize):
self.__Landscape[x][y] = Location()
if FixedInitialLocations:
self.__Landscape[1][1].Warren = Warren(self.__Variability, 38)
self.__Landscape[2][8].Warren = Warren(self.__Variability, 80)
self.__Landscape[9][7].Warren = Warren(self.__Variability, 20)
self.__Landscape[10][3].Warren = Warren(self.__Variability, 52)
self.__Landscape[13][4].Warren = Warren(self.__Variability, 67)
self.__Landscape[11][4].Warren = GiantWarren(self.__Variability, 115)
self.__WarrenCount = 6
self.__Landscape[2][10].Fox = Fox(self.__Variability)
self.__Landscape[6][1].Fox = Fox(self.__Variability)
self.__Landscape[8][6].Fox = Fox(self.__Variability)
self.__Landscape[11][13].Fox = Fox(self.__Variability)
self.__Landscape[12][4].Fox = Fox(self.__Variability)
self.__FoxCount = 5
else:
for w in range (0, InitialWarrenCount):
self.__CreateNewWarren()
for f in range (0, InitialFoxCount):
self.__CreateNewFox()
def __CreateNewWarren(self):
x = random.randint(0, self.__LandscapeSize - 1)
y = random.randint(0, self.__LandscapeSize - 1)
while not self.__Landscape[x][y].Warren is None:
x = random.randint(0, self.__LandscapeSize - 1)
y = random.randint(0, self.__LandscapeSize - 1)
if self.__ShowDetail:
print("New Warren at (", x, ",", y, ")", sep = "")
self.__Landscape[x][y].Warren = Warren(self.__Variability)
self.__WarrenCount += 1
def __CreateNewFox(self):
x = random.randint(0, self.__LandscapeSize - 1)
y = random.randint(0, self.__LandscapeSize - 1)
while not self.__Landscape[x][y].Fox is None:
x = random.randint(0, self.__LandscapeSize - 1)
y = random.randint(0, self.__LandscapeSize - 1)
if self.__ShowDetail:
print(" New Fox at (", x, ",", y, ")", sep = "")
self.__Landscape[x][y].Fox = Fox(self.__Variability)
self.__FoxCount += 1
def __FoxesEatRabbitsInWarren(self, WarrenX, WarrenY):
RabbitCountAtStartOfPeriod = self.__Landscape[WarrenX][WarrenY].Warren.GetRabbitCount()
for FoxX in range(0, self.__LandscapeSize):
for FoxY in range (0, self.__LandscapeSize):
if not self.__Landscape[FoxX][FoxY].Fox is None:
Dist = self.__DistanceBetween(FoxX, FoxY, WarrenX, WarrenY)
if Dist <= 3.5:
PercentToEat = 20
elif Dist <= 7:
PercentToEat = 10
else:
PercentToEat = 0
RabbitsToEat = int(round(float(PercentToEat * RabbitCountAtStartOfPeriod / 100)))
FoodConsumed = self.__Landscape[WarrenX][WarrenY].Warren.EatRabbits(RabbitsToEat)
self.__Landscape[FoxX][FoxY].Fox.GiveFood(FoodConsumed)
if self.__ShowDetail:
print(" ", FoodConsumed, " rabbits eaten by fox at (", FoxX, ",", FoxY, ").", sep = "")
def __DistanceBetween(self, x1, y1, x2, y2):
return math.sqrt((pow(x1 - x2, 2) + pow(y1 - y2, 2)))
def __DrawLandscape(self):
print()
print("TIME PERIOD:", self.__TimePeriod)
print()
print(" ", end = "")
for x in range (0, self.__LandscapeSize):
if x < 10:
print(" ", end = "")
print(x, "|", end = "")
print()
for x in range (0, self.__LandscapeSize * 4 + 3):
print("-", end = "")
print()
for y in range (0, self.__LandscapeSize):
if y < 10:
print(" ", end = "")
print("", y, "|", sep = "", end = "")
for x in range (0, self.__LandscapeSize):
if not self.__Landscape[x][y].Warren is None:
if self.__Landscape[x][y].Warren.GetRabbitCount() < 10:
print(" ", end = "")
print(self.__Landscape[x][y].Warren.GetRabbitCount(), end = "")
else:
print(" ", end = "")
if not self.__Landscape[x][y].Fox is None:
print("F", end = "")
else:
print(" ", end = "")
print("|", end = "")
print()
class Warren:
def __init__(self, Variability, RabbitCount = 0):
self.__MAX_RABBITS_IN_WARREN = 99
self.__RabbitCount = RabbitCount
self.__PeriodsRun = 0
self.__AlreadySpread = False
self.__Variability = Variability
self.__Rabbits = []
for Count in range(0, self.__MAX_RABBITS_IN_WARREN):
self.__Rabbits.append(None)
if self.__RabbitCount == 0:
self.__RabbitCount = int(self.__CalculateRandomValue(int(self.__MAX_RABBITS_IN_WARREN / 4), self.__Variability))
for r in range (0, self.__RabbitCount):
self.__Rabbits[r] = Rabbit(self.__Variability)
def __CalculateRandomValue(self, BaseValue, Variability):
return BaseValue - (BaseValue * Variability / 100) + (BaseValue * random.randint(0, Variability * 2) / 100)
def GetRabbitCount(self):
return self.__RabbitCount
def NeedToCreateNewWarren(self):
if self.__RabbitCount == self.__MAX_RABBITS_IN_WARREN and not self.__AlreadySpread:
self.__AlreadySpread = True
return True
else:
return False
def WarrenHasDiedOut(self):
if self.__RabbitCount == 0:
return True
else:
return False
def AdvanceGeneration(self, ShowDetail):
self.__PeriodsRun += 1
if self.__RabbitCount > 0:
self.__KillByOtherFactors(ShowDetail)
if self.__RabbitCount > 0:
self.__AgeRabbits(ShowDetail)
if self.__RabbitCount > 0 and self.__RabbitCount <= self.__MAX_RABBITS_IN_WARREN:
if self.__ContainsMales():
self.__MateRabbits(ShowDetail)
if self.__RabbitCount == 0 and ShowDetail:
print(" All rabbits in warren are dead")
def EatRabbits(self, RabbitsToEat):
DeathCount = 0
if RabbitsToEat > self.__RabbitCount:
RabbitsToEat = self.__RabbitCount
while DeathCount < RabbitsToEat:
RabbitNumber = random.randint(0, self.__RabbitCount - 1)
if not self.__Rabbits[RabbitNumber] is None:
self.__Rabbits[RabbitNumber] = None
DeathCount += 1
self.__CompressRabbitList(DeathCount)
return RabbitsToEat
def __KillByOtherFactors(self, ShowDetail):
DeathCount = 0
for r in range (0, self.__RabbitCount):
if self.__Rabbits[r].CheckIfKilledByOtherFactor():
self.__Rabbits[r] = None
DeathCount += 1
self.__CompressRabbitList(DeathCount)
if ShowDetail:
print(" ", DeathCount, "rabbits killed by other factors.")
def __AgeRabbits(self, ShowDetail):
DeathCount = 0
for r in range (0, self.__RabbitCount):
self.__Rabbits[r].CalculateNewAge()
if self.__Rabbits[r].CheckIfDead():
self.__Rabbits[r] = None
DeathCount += 1
self.__CompressRabbitList(DeathCount)
if ShowDetail:
print(" ", DeathCount, "rabbits die of old age.")
def __MateRabbits(self, ShowDetail):
Mate = 0
Babies = 0
for r in range (0, self.__RabbitCount):
if self.__Rabbits[r].IsFemale() and self.__RabbitCount + Babies < self.__MAX_RABBITS_IN_WARREN:
Mate = random.randint(0, self.__RabbitCount - 1)
while Mate == r or self.__Rabbits[Mate].IsFemale():
Mate = random.randint(0, self.__RabbitCount - 1)
CombinedReproductionRate = (self.__Rabbits[r].GetReproductionRate() + self.__Rabbits[Mate].GetReproductionRate()) / 2
if CombinedReproductionRate >= 1:
self.__Rabbits[self.__RabbitCount + Babies] = Rabbit(self.__Variability, CombinedReproductionRate)
Babies += 1
self.__RabbitCount = self.__RabbitCount + Babies
if ShowDetail:
print(" ", Babies, "baby rabbits born.")
def __CompressRabbitList(self, DeathCount):
if DeathCount > 0:
ShiftTo = 0
ShiftFrom = 0
while ShiftTo < self.__RabbitCount - DeathCount:
while self.__Rabbits[ShiftFrom] is None:
ShiftFrom += 1
if ShiftTo != ShiftFrom:
self.__Rabbits[ShiftTo] = self.__Rabbits[ShiftFrom]
ShiftTo += 1
ShiftFrom += 1
self.__RabbitCount = self.__RabbitCount - DeathCount
def __ContainsMales(self):
Males = False
for r in range (0, self.__RabbitCount):
if not self.__Rabbits[r].IsFemale():
Males = True
return Males
def Inspect(self):
print("Periods Run", self.__PeriodsRun, "Size", self.__RabbitCount)
def ListRabbits(self):
if self.__RabbitCount > 0:
for r in range (0, self.__RabbitCount):
self.__Rabbits[r].Inspect()
class GiantWarren(Warren):
def __init__(self, Variability, RabbitCount = 1):
super(GiantWarren, self).__init__(self.__RabbitCount, Variability)
self.__MAX_RABBITS_IN_WARREN = 200
self.__RabbitCount = RabbitCount
self.__PeriodsRun = 0
self.__Variability = Variability
self.__Rabbits = []
for Count in range(0, self.__MAX_RABBITS_IN_WARREN):
self.__Rabbits.append(None)
if self.__RabbitCount == 1:
self.__RabbitCount = int(self.__CalculateRandomValue(int(self.__MAX_RABBITS_IN_WARREN / 4), self.__Variability))
for r in range (0, self.__RabbitCount):
self.__Rabbits[r] = Rabbit(self.__Variability)
class Animal:
_ID = 1
def __init__(self, AvgLifespan, AvgProbabilityOfDeathOtherCauses, Variability):
self._NaturalLifespan = int(AvgLifespan * self._CalculateRandomValue(100, Variability) / 100)
self._ProbabilityOfDeathOtherCauses = AvgProbabilityOfDeathOtherCauses * self._CalculateRandomValue(100, Variability) / 100
self._IsAlive = True
self._ID = Animal._ID
self._Age = 0
Animal._ID += 1
def CalculateNewAge(self):
self._Age += 1
if self._Age >= self._NaturalLifespan:
self._IsAlive = False
def CheckIfDead(self):
return not self._IsAlive
def Inspect(self):
print(" ID", self._ID, "", end = "")
print("Age", self._Age, "", end = "")
print("LS", self._NaturalLifespan, "", end = "")
print("Pr dth", round(self._ProbabilityOfDeathOtherCauses, 2), "", end = "")
def CheckIfKilledByOtherFactor(self):
if random.randint(0, 100) < self._ProbabilityOfDeathOtherCauses * 100:
self._IsAlive = False
return True
else:
return False
def _CalculateRandomValue(self, BaseValue, Variability):
return BaseValue - (BaseValue * Variability / 100) + (BaseValue * random.randint(0, Variability * 2) / 100)
class Fox(Animal):
def __init__(self, Variability, genderRatio = 33):
self.__DEFAULT_LIFE_SPAN = 7
self.__DEFAULT_PROBABILITY_DEATH_OTHER_CAUSES = 0.1
super(Fox, self).__init__(self.__DEFAULT_LIFE_SPAN, self.__DEFAULT_PROBABILITY_DEATH_OTHER_CAUSES, Variability)
self.__FoodUnitsNeeded = int(10 * self._CalculateRandomValue(100, Variability) / 100)
self.__FoodUnitsConsumedThisPeriod = 0
if random.randint(0, 100) < genderRatio:
self.__Gender = Genders.Male
else:
self.__Gender = Genders.Female
def AdvanceGeneration(self, ShowDetail):
if self.__FoodUnitsConsumedThisPeriod == 0:
self._IsAlive = False
if ShowDetail:
print(" Fox dies as has eaten no food this period.")
else:
if self.CheckIfKilledByOtherFactor():
self._IsAlive = False
if ShowDetail:
print(" Fox killed by other factor.")
else:
if self.__FoodUnitsConsumedThisPeriod < self.__FoodUnitsNeeded:
self.CalculateNewAge()
if ShowDetail:
print(" Fox ages further due to lack of food.")
self.CalculateNewAge()
if not self._IsAlive:
if ShowDetail:
print(" Fox has died of old age.")
def ResetFoodConsumed(self):
self.__FoodUnitsConsumedThisPeriod = 0
def ReproduceThisPeriod(self):
REPRODUCTION_PROBABILITY = 0.25
if self.__Gender == Genders.Female:
if random.randint(0, 100) < REPRODUCTION_PROBABILITY * 100:
return True
else:
return False
def GiveFood(self, FoodUnits):
self.__FoodUnitsConsumedThisPeriod = self.__FoodUnitsConsumedThisPeriod + FoodUnits
def IsFemale(self):
if self.__Gender == Genders.Female:
return True
else:
return False
def Inspect(self):
super(Fox, self).Inspect()
print("Food needed", self.__FoodUnitsNeeded, "", end = "")
print("Food eaten", self.__FoodUnitsConsumedThisPeriod, "", end = "")
if self.__Gender == Genders.Male:
gender = "Male"
else:
gender = "Female"
print("Gender", gender, "", end="")
print()
class Genders(enum.Enum):
Male = 1
Female = 2
class Rabbit(Animal):
def __init__(self, Variability, ParentsReproductionRate = 1.2, genderRatio=50):
self.__DEFAULT_LIFE_SPAN = 4
self.__DEFAULT_PROBABILITY_DEATH_OTHER_CAUSES = 0.05
super(Rabbit, self).__init__(self.__DEFAULT_LIFE_SPAN, self.__DEFAULT_PROBABILITY_DEATH_OTHER_CAUSES, Variability)
self.__ReproductionRate = ParentsReproductionRate * self._CalculateRandomValue(100, Variability) / 100
if random.randint(0, 100) < genderRatio:
self.__Gender = Genders.Male
else:
self.__Gender = Genders.Female
def Inspect(self):
super(Rabbit, self).Inspect()
print("Rep rate", round(self.__ReproductionRate, 1), "", end = "")
if self.__Gender == Genders.Female:
print("Gender Female")
else:
print("Gender Male")
def IsFemale(self):
if self.__Gender == Genders.Female:
return True
else:
return False
def GetReproductionRate(self):
return self.__ReproductionRate
def Main():
MenuOption = 0
while MenuOption != 3:
print("Predator Prey Simulation Main Menu")
print()
print("1. Run simulation with default settings")
print("2. Run simulation with custom settings")
print("3. Rabbit Paradise")
print("4. Exit")
print()
try:
MenuOption = int(input("Select option: "))
except:
print("What you have entered is not an integer. Try again")
if MenuOption == 1 or MenuOption == 2 or MenuOption == 3:
if MenuOption == 1:
LandscapeSize = 15
InitialWarrenCount = 5
InitialFoxCount = 5
Variability = 0
FixedInitialLocations = True
elif MenuOption == 3:
LandscapeSize = 20
InitialWarrenCount = 20
InitialFoxCount = 0
Variability = 1
FixedInitialLocations = False
else:
LandscapeSize = int(input("Landscape Size: "))
InitialWarrenCount = int(input("Initial number of warrens: "))
InitialFoxCount = int(input("Initial number of foxes: "))
Variability = int(input("Randomness variability (percent): "))
FixedInitialLocations = False
Sim = Simulation(LandscapeSize, InitialWarrenCount, InitialFoxCount, Variability, FixedInitialLocations)
input()
if __name__ == "__main__":
Main()
The problem is the indiscriminate use of double-underscore prefixes on the method and attribute names. That's used to invoke name mangling and is specifically intended to prevent inheritance; it provides the closest thing to "private" variables that Python has.
The student definitely does not want to use it anywhere here; generally, I recommend never using it at all. Just give everything normal names.
(Note also, since they're programming Python, they should use Python conventions for naming: variables, attributes and methods should have lower_case_with_underscore names, not CamelCase which is intended for class names.)
Related
I'm taking CS50 Introduction to Programming with Python. I have problem with PSet4 (Little Professor). I don't have any problem while running, but when check50 running it keeps giving this error: "Little Professor accepts valid level timed out while waiting for program to exit." While I’m manually running the program, it accepts any level value lower than 4. But the check50 says otherwise. Here is my code:
import random
def main():
try:
level = input("Level: ")
first, second = get_level(level)
game_on(first, second, 0, 2, 0, level)
except WrongInputError:
main()
def get_level(x):
try:
x = int(x)
if 0 < x < 4:
first = generate_integer(x)
second = generate_integer(x)
return first, second
else:
raise WrongInputError
except ValueError:
raise WrongInputError
class WrongInputError(Exception):
"""You entered something wrong, try again """
def generate_integer(level):
if level == 1:
integer = random.randrange(10)
return integer
elif level == 2:
x = str(random.randrange(1, 10))
y = str(random.randrange(10))
integer = int(x + y)
return integer
elif level == 3:
x = str(random.randrange(1, 10))
y = str(random.randrange(10))
z = str(random.randrange(10))
integer = int(x + y + z)
return integer
def game_on(x , y, count, lives, score, level):
game_set = [x, y]
try:
if count < 10:
calculation = int(input(f"{x} + {y} = "))
count += 1
if calculation == sum(game_set):
score +=1
first, second = get_level(level)
game_on(first, second, count, 3, score, level)
elif calculation == sum(game_set):
print("EEE")
if lives > 0:
lives -= 1
count -= 1
game_on(x, y, count, lives, score, level)
elif lives == 0:
print(f"{x} + {y} = {sum(game_set)}")
first, second = get_level(level)
game_on(first, second, count, 2, score, level)
else:
print(f"Score: {score}")
except ValueError:
print("EEE")
if lives > 0:
lives -= 1
game_on(x, y, count, lives, score, level)
elif lives == 0:
print(f"{x} + {y} = {sum(game_set)}")
first, second = get_level(level)
game_on(first, second, count, 2, score, level)
if __name__ == "__main__":
main()
main()
import sys
import random
def main():
num = get_level()
errors = 1
score = 0
for i in range(10):
x = generate_integer(num)
for j in range(1):
y = generate_integer(num)
answer = x + y
equation = input(f"{x} + {y} = ")
if int(equation) == answer:
score += 1
while int(equation) != answer:
errors += 1
print("EEE")
equation = input(f"{x} + {y} = ")
if errors >= 3:
print(answer)
sys.exit("Score: " + str(score))
print("Score: " + str(score))
# prompt for level and reprompt if needed
def get_level():
levelChoice = input("Level: ")
if levelChoice.isalpha() or int(levelChoice) <= 0 or int(levelChoice) > 3:
input("Level: ")
else:
levelChoice = int(levelChoice)
for i in [1,2,3]:
if levelChoice == i:
return levelChoice
# generate int from level choice
def generate_integer(level):
try:
if level == 1:
return random.randint(0, 9)
elif level == 2:
return random.randint(10, 99)
elif level == 3:
return random.randint(100, 999)
except:
raise ValueError
if __name__ == "__main__":
main()
Here is the full code:
import random
import numpy as np
world = {}
class Player():
def __init__(self, health, maxHealth, baseDmg, dmg, name, weapons, items, isAlive, previousRoom, roomName):
self.health = health
self.maxHealth = maxHealth
self.baseDmg = baseDmg
self.dmg = dmg
self.name = name
self.weapons = weapons
self.items = items
self.isAlive = isAlive
self.previousRoom = previousRoom
self.room = world[roomName]
def Move(self, direction):
if direction not in self.room.exits:
print("Cannot Move In That Direction!")
return
newRoomName = self.room.exits[direction]
self.previousRoom = world[self.room.name]
print("Moving to", newRoomName)
self.room = world[newRoomName]
def MoveBack(self):
self.room = world[self.previousRoom.name]
print("Moving to", self.room.name)
class Enemy():
def __init__(self, health, dmg, hasLoot, lootItem, isAlive):
self.health = health
self.dmg = dmg
self.hasLoot = hasLoot
self.lootItem = lootItem
self.isAlive = isAlive
class Weapon():
def __init__(self, name, dmg, description):
self.name = name
self.dmg = dmg
self.description = description
class Item():
def __init__(self, name, amt, description):
self.name = name
self.amt = amt
self.description = description
class Room():
def __init__(self, name, description, exits, hasWeapon, weapon, hasItem, item, hasEnemy, enemy, isFirstVisit, coords):
self.name = name
self.description = description
self.exits = exits
self.hasWeapon = hasWeapon
self.weapon = weapon
self.hasItem = hasItem
self.item = item
self.hasEnemy = hasEnemy
self.enemy = enemy
self.isFirstVisit = isFirstVisit
self.coords = coords
#######################Dungeon Generation###################
rooms = np.zeros((11, 11))
maxRooms = 7
possibleNextRoom = []
def startLevel():
for r in range(len(rooms[0])):
for c in range(len(rooms[1])):
rooms[r][c] = 0
possibleNextRoom.clear()
halfHeight = int(len(rooms[1]) / 2)
halfWidth = int(len(rooms[0]) / 2)
rooms[halfWidth][halfHeight] = 1
def resetLevel():
for r in range(len(rooms[0])):
for c in range(len(rooms[1])):
rooms[r][c] = 0
possibleNextRoom.clear()
def countRooms():
roomCount = 0
for r in range(len(rooms)):
for c in range(len(rooms)):
if rooms[r][c] == 1:
roomCount += 1
return roomCount
def findPossibleRooms():
for r in range(len(rooms) - 1):
for c in range(len(rooms) - 1):
if rooms[r][c] == 1:
if rooms[r][c+1] != 1:
possibleNextRoom.append((r, c+1))
if rooms[r][c-1] != 1:
possibleNextRoom.append((r, c-1))
if rooms[r-1][c] != 1:
possibleNextRoom.append((r-1, c))
if rooms[r+1][c] != 1:
possibleNextRoom.append((r+1, c))
def addRoom():
x = random.randrange(0, len(possibleNextRoom))
rooms[possibleNextRoom[x][0]][possibleNextRoom[x][1]] = 1
possibleNextRoom.pop(x)
def generateLevel():
global x, possibleNextRoom
startLevel()
while countRooms() < maxRooms:
countRooms()
findPossibleRooms()
addRoom()
def makeRoomsForLevel():
counter = 1
for r in range(len(rooms)):
for c in range(len(rooms)):
if rooms[c][r] == 1:
world[f"room{counter}"] = Room(
f"room{counter}",
"",
{},
False,
None,
False,
None,
False,
None,
True,
(r, c)
)
counter += 1
def findRoom(x, y):
for i in range(len(world)):
if world[f"room{i+1}"].coords == (x, y):
return f"room{i+1}"
return None
def findExits():
for i in range(len(world)):
x, y = world[f"room{i+1}"].coords
exits = dict()
#east
if rooms[x, y+1] == 1:
exits["E"] = findRoom(x, y+1)
#south
if rooms[x+1, y] == 1:
exits["S"] = findRoom(x+1, y)
#west
if rooms[x, y-1] == 1:
exits["W"] = findRoom(x, y-1)
#north
if rooms[x-1, y] == 1:
exits["N"] = findRoom(x-1, y)
world[f"room{i+1}"].exits = exits
############################################################
generateLevel()
makeRoomsForLevel()
findExits()
WoodenSword = Weapon("Wooden Sword", 5, "A wooden sword. Looks like a kid's toy.")
IronDagger = Weapon("Iron Dagger", 8, "Small, sharp, and pointy. Good for fighting monsters!")
HealthPot = Item("Health Potion", 1, "A Potion of Instant Health. Restores 10 Health.")
goblin1 = Enemy(25, 2, True, [HealthPot, IronDagger], True)
player = Player(10, 10, 5, 5, "", [], [], True, "room1", "room1")
def ShowInv():
print("*******************************")
print("Name:", player.name)
print("Health:", player.health)
print("Weapons:")
for i in player.weapons:
print(" ===============================")
print(" Weapon:", i.name)
print(" Description:", i.description)
print(" Damage:", i.dmg)
print(" ===============================")
print("Items:")
for i in player.items:
print(" ===============================")
print(" Item:", i.name)
print(" Amount:", i.amt)
print(" Description:", i.description)
print(" ===============================")
print("*******************************")
def testItems(item):
exists = item in player.items
return exists
def fight(enemy):
print("Your Health:", player.health)
print("Enemy Health:", enemy.health)
ans = input("What would you like to do?\n>>")
if ans == "attack":
chance = random.randrange(1, 20)
if chance >= 10:
enemy.health -= player.dmg
else:
print("You did not roll high enough...\nYour turn has been passed...")
if ans == "heal":
chance = random.randrange(1, 20)
if testItems(HealthPot):
if chance >= 10:
x = 0
for item in player.items:
if item == HealthPot:
player.health += 10
if player.health > player.maxHealth:
player.health = player.maxHealth
item.amt -= 1
if item.amt <= 0:
player.items.pop(x)
break
x += 1
else:
print("You did not roll high enough...\nYour turn has been passed...")
if ans == "run":
chance = random.randrange(1, 20)
if chance >= 10:
player.MoveBack()
else:
print("You did not roll high enough...\nYour turn has been passed...")
if enemy.health > 0 and player.health > 0:
chance = random.randrange(1, 20)
if chance >= 10:
player.health -= enemy.dmg
else:
if enemy.health <= 0:
enemy.isAvile = False;
def testRoom():
if player.room.hasWeapon:
if player.room.isFirstVisit:
player.weapons.append(player.room.weapon)
if player.room.hasItem:
if player.room.isFirstVisit:
player.items.append(player.room.item)
if player.room.hasEnemy:
if player.room.isFirstVisit:
while player.room.enemy.health > 0:
fight(player.room.enemy)
player.room.isFirstVisit = False
while True:
command = input(">>")
if command in {"N", "S", "E", "W"}:
player.Move(command)
testRoom()
elif command == "look":
print(player.room.description)
print("Exits:", *','.join(list(player.room.exits.keys())))
elif command == "inv":
ShowInv()
elif command == "heal":
if testItems(HealthPot):
player.health += 10
if player.health > player.maxHealth:
player.health = player.maxHealth
else:
print("You don't have any", HealthPot.name, "\bs")
else:
print("Invalid Command")
And here is the problem:
Everything seems to work fine, until a couple moves in when it breaks and gives me a "KeyError: None" for the room I just walked in. I have no idea what could be causing this, and I am fairly new, so please simplify the explanations for me. I think it has something to do with the findExits() function and findRoom() function, but idk.
Here is the TraceBackError:
Traceback (most recent call last):
File "main.py", line 287, in <module>
player.Move(command)
File "main.py", line 26, in Move
self.room = world[newRoomName]
KeyError: None
I've tried fiddling with the function, but nothing i've tried worked. Here is the repl.it link:
https://replit.com/#samsonsbrother0/Dungeon-Crawler#main.py
your code is accessing a key before it exists, thus the error. to fix it, you need to assign the newroomname to the world dict as you move, like so:
print("Moving to", newRoomName)
world[newRoomName] = newRoomName
self.room = world[newRoomName]
For input 1 to self.trying, the set_jump() method doesn't work. the program dosent execute the while loop in it
Code:
jump = []
z = []
class jumps:
def __init__(self, numberOfJumps, trying):
self.numberOfJumps = numberOfJumps
self.trying = int(trying)
def setJumps(self):
if self.trying == 1:
# print("hello")
self.set_jump()
if self.trying == 2:
self.get_jump()
return ""
def set_jump(self):
counterSetJump = 0
while counterSetJump < int(self.numberOfJumps):
print("what was the distance the athlete jumped at jump number" + str(counterSetJump + 1))
z.append(float(input()))
counterSetJump += 1
return ""
def get_jump(self):
counterGetJumps = 0
while counterGetJumps < int(self.numberOfJumps):
print(z[counterGetJumps])
print("this is the jump for the " + str(counterGetJumps) + " time")
counterGetJumps += 1
return ""
class athlete:
def __init__(self, name, yearsPro):
self.name = name
self.yearsPro = yearsPro
def information(self):
print("the athletes name is " + self.name)
print("he as been active for " + str(self.yearsPro))
return ""
a = []
b = []
i = 0
know = int(input("how many athletes you know the information for"))
while i < know:
a.append(0)
b.append(0)
i = i + 1
j = 0
while j < know:
a[j] = athlete(input("what is the athletes name?"), input("how many years as the athlete been active"))
b[j] = jumps(input("how many jumps did the athlete jumped?"),
input("input 1 for settig and 2 for getting the jumps")) # not getting called?
b[j].setJumps()
j = j + 1
infoFor = int(input("who do you want the info for"))
print(a[int(infoFor) - 1].information())
print(b[int(infoFor) - 1].get_jump())
Check the code out
jump = []
z = []
class jumps:
def __init__(self, numberOfJumps, trying):
self.numberOfJumps = numberOfJumps
self.trying = int(trying)
print("trying = "+str(self.trying))
def setJumps(self) :
if self.trying == 1:
#print("hello")
self.set_jump()
if self.trying == 2:
self.get_jump()
print("Yes I have chnaged trying to = :"+str(self.trying))
return ""
def set_jump(self):
print("set_jump finally called")
i = 0
while(i < int(self.numberOfJumps)):
print("what was the distance the athlete jumped at jump number" + str(i))
z.append(int(input()))
i = i + 1
def get_jump(self):
i = 0
while(i < int(self.numberOfJumps)):
return z[i]
i = i + 1
class athlete:
def __init__(self, name, yearsPro):
self.name = name
self.yearsPro = yearsPro
def information(self):
print("the athletes name is " + self.name)
print("he as been active for " + str(self.yearsPro))
return ""
a = []
b = []
i = 0
know = int(input("how many athletes you know the information for"))
while(i < know):
a.append(0)
b.append(0)
i = i + 1
j = 0
while(j <know):
a[j] = athlete(input("what is the athletes name?"), input("how many years as the athlete been active"))
b[j] = jumps(input("how many jumps did the athlete jumped?"),
input("input 1 for settig and 2 for getting the jumps")) #not getting called?
b[j].setJumps()
k=j
for k in b:
k.setJumps()
#j=j+1
j = j + 1
infoFor = int(input("who do you want the info for"))
print(a[int(infoFor) - 1].information())
print(b[int(infoFor) - 1].setJumps())
I am currently working on a connect 4 game in python and I was hoping to allow the player to customise the board (be able to choose the size of the board. However when I try to add this in it breaks my code. Is there any way around this? Or will I just have to hard code the board size in?
def CreateBoard(r, c, b, n):
for i in range(1,(r+1)):
n.append(str(i))
b.append(n)
for i in range(c):
b.append(['*']*(r))
return(b)
def printBoard(b):
for lst in b:
print(" ".join(lst))
return b
def check(board, n):
n = []
for i in range(1,len(board[1])+1):
if board[1][i-1] == '*':
n.append(i)
print(n)
user = (input('Enter column: '))
if(user.isdigit() == True):
user = int(user)
if (user in n):
return(user)
print('Invalid input')
return check(board, n)
def WinningCon(b, r, u, c):
'row'
loop1 = True
rowCon = ""
colCon = ""
for i in range(0,len(b[1])):
rowCon += b[r][i]
if('X'*4 in rowCon) or('O'*4 in rowCon):
return(True)
for i in range(1,c+1):
colCon += b[i][u-1]
if('X'*4 in colCon) or('O'*4 in colCon):
return(True)
def Diag2(u, r, b, row, column):
utemp1 = u-1
utemp2 = u-1
rtemp1 = r
rtemp2 = r
end = ""
beg = ""
while(True):
beg += b[rtemp1][utemp1]
if(rtemp1 == 1):
break
elif(utemp1 == column):
break
rtemp1 -= 1
utemp1 += 1
while(True):
if(rtemp2 == row-1):
break
elif(utemp2 == 0):
break
rtemp2 +=1
utemp2 -=1
end += b[rtemp2][utemp2]
beg = beg[::-1]
fullstring = beg+end
if('X'*4 in fullstring) or('O'*4 in fullstring):
return(True)
def Diag1(u, r, b, row, column):
utemp1 = u-1
utemp2 = u-1
rtemp1 = r
rtemp2 = r
end = ""
beg = ""
while(True):
beg += b[rtemp1][utemp1]
if(rtemp1 == 1):
break
elif(utemp1 == 0):
break
rtemp1 -= 1
utemp1 -= 1
while(True):
if(rtemp2 == row-1):
break
elif(utemp2 == column):
break
rtemp2 +=1
utemp2 +=1
end += b[rtemp2][utemp2]
beg = beg[::-1]
fullstring = beg+end
if('X'*4 in fullstring) or('O'*4 in fullstring):
return(True)
def ProcessInput(u, s, b, r):
rowNum = r-1
u = u-1
while(not b[rowNum][u] == '*'):
rowNum -= 1
b[rowNum][u] = s
return(rowNum)
def EndGame(g, b, p):
printBoard(b)
print("Congrats %s, you've won!" %p)
replayGame = input('Would you like to play again? Yes or No?\n').lower()
if replayGame == 'yes':
MainGame()
else:
g = False
return(g)
def MainGame():
row = 7 #input('Enter number of rows')
column = 6 #input('Enter number of columns')
board = []
nums = []
board = CreateBoard(row, column, board, nums)
player1 = 'K'#input('Enter name: ')
player2 = 'A'#input('Enter name: ')
turn = 1
GameOn = True
while(GameOn):
board = printBoard(board)
if(not turn%2 == 0):
print("It's %s's turn" %player1)
user = check(board, nums)
rc = ProcessInput(user, "X", board, row)
if(WinningCon(board, rc , user, column) == True):
GameOn = EndGame(GameOn, board, player1)
elif(Diag1(user, rc, board, row, column) == True):
GameOn = EndGame(GameOn, board, player1)
elif(Diag2(user, rc, board, row, column) == True):
GameOn = EndGame(GameOn, board, player1)
else:
print("It's %s's turn" %player2)
user = check(board, nums)
rc = ProcessInput(user, "O", board, row)
if(WinningCon(board, rc , user, column) == True):
GameOn = EndGame(GameOn, board, player2)
elif(Diag1(user, rc, board, row, column) == True):
GameOn = EndGame(GameOn, board, player2)
elif(Diag2(user, rc, board, row, column) == True):
GameOn = EndGame(GameOn, board, player2)
turn +=1
MainGame()
An example of an error message it throws up:
Enter number of columns4
Enter number of rows5
1 2 3 4
* * * *
* * * *
* * * *
* * * *
* * * *
It's K's turn
[1, 2, 3, 4]
Enter column: 4
Traceback (most recent call last):
File "C:\Users\609380145\Python\Code Dojo\Connect 4\Connect 4 v3.py", line 169, in <module>
MainGame()
File "C:\Users\609380145\Python\Code Dojo\Connect 4\Connect 4 v3.py", line 150, in MainGame
GameOn = EndGame(GameOn, board, player1)
File "C:\Users\609380145\Python\Code Dojo\Connect 4\Connect 4 v3.py", line 127, in EndGame
MainGame()
File "C:\Users\609380145\Python\Code Dojo\Connect 4\Connect 4 v3.py", line 153, in MainGame
elif(Diag2(user, rc, board, row, column) == True):
File "C:\Users\609380145\Python\Code Dojo\Connect 4\Connect 4 v3.py", line 66, in Diag2
beg += b[rtemp1][utemp1]
IndexError: list index out of range
def CreateBoard(r, c, b, n):
for i in range(1,(r+1)):
n.append(str(i))
b.append(n)
for i in range(c):
b.append(['*']*(r))
return(b)
def printBoard(b):
for lst in b:
print(" ".join(lst))
return b
def check(board, n):
n = []
for i in range(1,len(board[1])+1):
if board[1][i-1] == '*':
n.append(i)
print(n)
user = (input('Enter column: '))
if(user.isdigit() == True):
user = int(user)
if (user in n):
return(user)
print('Invalid input')
return check(board, n)
def WinningCon(b, r, u, c):
loop1 = True
rowCon = ""
colCon = ""
for i in range(0,len(b[1])):
rowCon += b[r][i]
if('X'*4 in rowCon) or('O'*4 in rowCon):
return(True)
for i in range(1,c+1):
colCon += b[i][u-1]
if('X'*4 in colCon) or('O'*4 in colCon):
return(True)
def Diag2(u, r, b, column, row):
utemp1 = u-1
utemp2 = u-1
rtemp1 = r
rtemp2 = r
end = ""
beg = ""
while(True):
beg += b[rtemp1][utemp1]
rtemp1 -= 1
utemp1 += 1
if(rtemp1 == 1):
break
elif(utemp1 >= column - 1):
break
while(True):
end += b[rtemp2][utemp2]
rtemp2 +=1
utemp2 -=1
if(rtemp2 >= row):
break
elif(utemp2 == 0):
break
beg = beg[::-1]
fullstring = beg+end
if('X'*4 in fullstring) or('O'*4 in fullstring):
return(True)
def Diag1(u, r, b, column, row):
utemp1 = u-1
utemp2 = u-1
rtemp1 = r
rtemp2 = r
end = ""
beg = ""
while(True):
beg += b[rtemp1][utemp1]
rtemp1 -= 1
utemp1 -= 1
if(rtemp1 == 1):
break
elif(utemp1 == 0):
break
while(True):
print('Row ' + str(rtemp2))
print('Colum ' +str(utemp2))
end += b[rtemp2][utemp2]
rtemp2 +=1
utemp2 +=1
if(rtemp2 >= row):
break
elif(utemp2 >= column-1):
break
beg = beg[::-1]
fullstring = beg+end
if('X'*4 in fullstring) or('O'*4 in fullstring):
return(True)
def ProcessInput(u, s, b, r):
rowNum = r
u = u-1
print('Row: ' + str(rowNum))
print('Col: ' + str(u))
while(not b[rowNum][u] == '*'):
rowNum -= 1
print('New Row Num: ' + str(rowNum))
b[rowNum][u] = s
printBoard(b)
return(rowNum)
def EndGame(g, b, p):
printBoard(b)
print("Congrats %s, you've won!" %p)
replayGame = input('Would you like to play again? Yes or No?\n').lower()
if replayGame == 'yes':
MainGame()
else:
g = False
return(g)
def MainGame():
column = int(input('Enter number of columns'))
row = int(input('Enter number of rows'))
board = []
nums = []
board = CreateBoard(column, row, board, nums)
player1 = 'K'#input('Enter name: ')
player2 = 'A'#input('Enter name: ')
turn = 1
GameOn = True
while(GameOn):
board = printBoard(board)
user = check(board, nums)
if(turn%2 != 0):
print("It's %s's turn" %player1)
rc = ProcessInput(user, "X", board, row)
else:
print("It's %s's turn" %player2)
rc = ProcessInput(user, "O", board, row)
if(WinningCon(board, rc , user, row) == True):
GameOn = EndGame(GameOn, board, player1)
elif(Diag1(user, rc, board, column, row) == True):
GameOn = EndGame(GameOn, board, player1)
elif(Diag2(user, rc, board, column, row) == True):
GameOn = EndGame(GameOn, board, player1)
turn +=1
MainGame()
I've got a piece of code I'm working on for a school project and the basic idea is that there's a battle between two characters where the user can input 2 attributes to each character: Strength and Skill. Now there are also modifiers for skill and strength which is the difference of the player's skill and strength attributes, divided by 5 and then rounded down respectively. Then each player has a dice roll, depending on who got the higher roll, that player gets the skill and strength modifiers added to their given attributes whilst the one that lost gets the modifiers deducted from their score. This then repeats until the strength attribute of one of them reaches 0 where that player then dies and the game ends.
In my code, the dice rolling function runs twice, and then crashes for an unknown reason I cannot identify.
import random
import time
import math
import sys
strength_mod = 0
skill_mod = 0
def delay_print(s):
for c in s:
sys.stdout.write( '%s' % c )
sys.stdout.flush()
time.sleep(0.05)
def str_mod(charone_str,chartwo_str):
if charone_str > chartwo_str:
top = charone_str
bottom = chartwo_str
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
elif chartwo_str > charone_str:
top = chartwo_str
bottom = charone_str
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
elif charone_str == chartwo_str:
top = charone_str
bottom = chartwo_str
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
def skl_mod(charone_skl, chartwo_skl):
if charone_skl > chartwo_skl:
top = charone_skl
bottom = chartwo_skl;
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
elif chartwo_skl > charone_skl:
top = chartwo_skl
bottom = charone_skl
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
elif charone_skl == chartwo_skl:
top = charone_skl
bottom = chartwo_skl
calc = top - bottom
calc = calc / 5
calc = math.floor(calc)
return calc
def mods():
global strength_mod
global skill_mod
strength_mod = str_mod(charone_strength, chartwo_strength)
skill_mod = skl_mod(charone_skill, chartwo_skill)
print "\nFor this battle, the strength modifier is:",strength_mod
time.sleep(0.20)
print "For this battle, the skill modifier is: ",skill_mod
time.sleep(0.20)
diceroll(charone, chartwo)
print "\n"+str(charone)+"'s","dice roll is:",player1
time.sleep(1)
print "\n"+str(chartwo)+"'s","dice roll is:",player2
def diceroll(charone, chartwo):
print "\n"+str(charone)+" will roll the 6 sided dice first!"
time.sleep(0.5)
global player1
player1 = random.randint(1,6)
delay_print("\nRolling dice!")
global player2
player2 = random.randint(1,6)
time.sleep(0.5)
print "\nNow",chartwo,"will roll the 6 sided dice!"
time.sleep(0.5)
delay_print("\nRolling dice!")
def battle(charone_str, chartwo_str, charone_skl, chartwo_skl, str_mod, skl_mod):
global charone_strength
global charone_skill
global chartwo_strength
global chartwo_skill
if player1 == player2:
print "\nThis round is a draw! No damage done"
elif player1 > player2:
charone_strength = charone_str + str_mod
charone_skill = charone_skl + skl_mod
chartwo_strength = charwo_skl - str_mod
chartwo_skill = chartwo_skl - skl_mod
print "\n"+charone+" won this round"
print "\n"+"Character 1:",charone
print "Strength:",charone_strength
print "Skill:",charone_skill
time.sleep(1)
print "\nCharacter 2:",chartwo
print "Strength:",chartwo_strength
print "Skill:",chartwo_skill
elif player2 > player1:
chartwo_strength = chartwo_str + str_mod
chartwo_skill = chartwo_skl + skl_mod
charone_strength = charone_str - str_mod
charone_skill = charone_skl - skl_mod
print "\n"+chartwo+" won this round"
print "\nCharacter 2:",chartwo
print "Strength:",chartwo_strength
print "Skill:",chartwo_skilll
time.sleep(1)
print "\n"+"Character 1:",charone
print "Strength:",charone_strength
print "Skill:",charone_skill
if charone_skill >= 0:
charone_skill = 0
elif chartwo_skill >= 0:
chartwo_skill = 0
if charone_strength <= 0:
print charone,"has died!",chartwo,"wins!"
elif chartwo_strength <= 0:
print chartwo,"has died!",charone,"wins!"
charone = raw_input("Enter the name of character one: ")
chartwo = raw_input("Enter the name of character two: ")
time.sleep(1.5)
print "\n",charone,"encounters",chartwo
delay_print("\nBattle Initiated!")
charone_strength = int(raw_input("\nEnter the strength score for "+str(charone)+" (between 50 and 100): "))
while charone_strength > 100 or charone_strength < 50:
print "That number is not between 50-100"
charone_strength = int(raw_input("\nEnter the strength score for "+str(charone)+" (between 50 and 100): "))
else:
pass
charone_skill = int(raw_input("Enter the skill score for "+str(charone)+" (between 50 and 100): "))
while charone_skill > 100 or charone_skill < 50:
print "That number is not between 50-100"
charone_skill = int(raw_input("Enter the skill score for "+str(charone)+" (between 50 and 100): "))
else:
pass
time.sleep(1.0)
chartwo_strength = int(raw_input("\nEnter the strength score for "+str(chartwo)+" (between 50 and 100): "))
while chartwo_strength > 100 or chartwo_strength < 50:
print "That number is not between 50-100"
chartwo_strength = int(raw_input("\n Enter the strength score for "+str(chartwo)+" (between 50 and 100): "))
else:
pass
chartwo_skill = int(raw_input("Enter the skill score for "+str(chartwo)+" (between 50 and 100): "))
while chartwo_skill > 100 or chartwo_skill < 50:
print "That number is not between 50-100"
chartwo_skill = int(raw_input("Enter the skill score for "+str(chartwo)+" (between 50 and 100): "))
else:
pass
time.sleep(2)
print "\nCharacter 1:",charone
print "Strength:",charone_strength
print "Skill:",charone_skill
time.sleep(1)
print "\nCharacter 2:",chartwo
print "Strength:",chartwo_strength
print "Skill:",chartwo_skill
time.sleep(1)
while charone_strength != 0 or chartwo_strength != 0:
ent = raw_input("Press Enter to roll! ")
mods()
diceroll(charone,chartwo)
battle(charone_strength, chartwo_strength, charone_skill, chartwo_skill, str_mod, skl_mod)
else:
play = raw_input("\nWould you like to play again?")
if play in ["yes","y","Yes","Y"]:
execfile("gcse.py")
else:
print "Goodbye"
This code is an excellent example of how not to program:
heavy use of global variables
multiple variables with very similar names (ie charone_strength, charone_str)
reuse of names in different contexts (in global scope, str_mod is a function, but in function battle it is supposed to be an integer
Your immediate problem: in line 182, you call
battle(charone_strength, chartwo_strength, charone_skill, chartwo_skill, str_mod, skl_mod)
which should be
battle(charone_strength, chartwo_strength, charone_skill, chartwo_skill, strength_mod, skill_mod)
but is confused because in the function strength_mod is referred to as str_mod.
Here is a greatly cleaned-up version. (Further suggestions for improvement are welcome).
from __future__ import division, print_function
from random import randint
import sys
from time import sleep
# Python 2/3 compatibility shim
if sys.hexversion < 0x3000000:
# Python 2.x
inp = raw_input
rng = xrange
else:
# Python 3.x
inp = input
rng = range
PRINT_DELAY = 0.02
PAUSE_DELAY = 0.2
TF_VALUES = {
'y': True, 'yes': True, 't': True, '': True,
'n': False, 'no': False, 'f': False
}
def get_int(prompt="Enter an integer: ", lo=None, hi=None):
while True:
try:
i = int(inp(prompt))
if (lo is None or lo <= i) and (hi is None or i <= hi):
return i
except ValueError:
pass
def get_tf(prompt="Yes or no? ", tf_values=TF_VALUES):
while True:
s = inp(prompt).strip().lower()
tf = tf_values.get(s, None)
if tf is not None:
return tf
def pause(delay=PAUSE_DELAY):
sleep(delay)
def roll(die_sides=6):
return randint(1, die_sides)
def slow_print(s, delay=PRINT_DELAY):
for ch in s:
print(ch, end='', flush=True)
sleep(delay)
print('') # end of line
def wait_for_enter(prompt):
inp(prompt)
class Fighter:
#classmethod
def get_fighter(cls, prompt):
print(prompt)
name = inp ("Name: ")
health = get_int("Health: (50-100) ", 50, 100)
skill = get_int("Skill: (50-100) ", 50, 100)
return cls(name, health, skill)
def __init__(self, name, health, skill):
self.name = name
self.health = health
self.skill = skill
def is_alive(self):
return self.health > 0
def health_mod(self, other_fighter):
delta = abs(self.health - other_fighter.health)
return int(delta / 5)
def skill_mod(self, other_fighter):
delta = abs(self.skill - other_fighter.skill)
return int(delta / 5)
def attack(self, other_fighter):
wait_for_enter("Hit Enter to fight!")
# figure out mod values
health_mod = self.health_mod(other_fighter)
skill_mod = self.skill_mod (other_fighter)
self_roll = roll()
other_roll = roll()
slow_print(
"Health mod: {} Skill mod: {} {} rolls {} {} rolls {}"
.format(
health_mod, skill_mod,
self.name, self_roll,
other_fighter.name, other_roll
)
)
# figure out who won this round
if self_roll == other_roll:
print("Draw! No damage done.")
else:
winner, loser = (self, other_fighter) if self_roll > other_roll else (other_fighter, self)
print("{} hits {}!".format(winner.name, loser.name))
winner.health += health_mod
winner.skill += skill_mod
loser.health -= health_mod
loser.skill -= skill_mod
# show results
print('')
print(self)
print(other_fighter)
print('')
def __str__(self):
return "{}: health {}, skill {}".format(self.name, max(self.health, 0), max(self.skill, 0))
def fight():
f1 = Fighter.get_fighter("\nFirst fighter:")
pause()
f2 = Fighter.get_fighter("\nSecond fighter:")
pause()
slow_print("\n{} encounters {}\nBattle Initiated!".format(f1.name, f2.name))
while f1.is_alive() and f2.is_alive():
f1.attack(f2)
winner, loser = (f1, f2) if f1.is_alive() else (f2, f1)
print("{} has died; {} wins!".format(loser.name, winner.name))
def main():
while True:
fight()
if not get_tf("Would you like to play again? (Y/n)"):
print("Goodbye!")
break
if __name__=="__main__":
main()