I'm really new to this, and am always stuck by basic issues. Please can you show and explain my errors in this chunk of code. Right now the problem is that self is not defined, but I don't understand why.
It would be amazing if someone could clear this up.
import random
import time
class Building:
number_of_floors = 0
customer_list = []
elevator = 0
def __init__(self, floors, customers):
self.number_of_floors = floors
for customerID in range(1, customers + 1):
new = Customer(customerID,self.number_of_floors)
self.customer_list.append(new)
self.customer_list.sort(key = lambda x: x.current_floor)
self.elevator = Elevator(floors,self.customer_list)
self.run()
def run(self):
print('++++++++++++++++++++++++++ELEVATOR IS NOW STARTING+++++++++++++++')
print('Ther are %d customers in the building' % (len(self.customer_list)))
number_of_customers = len(self.customer_list)
self.output()
def output(self):
for customer in self.customer_list:
print("Customer",customer.customerID,"is on floor",customer.current_floor,"and wants to go",customer.destination_floor)
# ELEVATOR MOVING UP
while (self.elevator.current_floor <= self.number_of_floors) & (self.elevator.current_floor > 1):
self.elevator.current_floor -= 1
print(len(self.customer_list),'Customers in lift.')
print('ELEVATOR MOVING DOWN')
print('++++++++++++++++++++++++++++++++++++++++++++++++++++')
print('FLOOR',self.elevator.current_floor)
for customer in self.customer_list:
if (customer.in_elevator == True):
customer.current_floor = self.elevator.current_floor
if (slef.elevator.current_floor == customer.destination_floor) & (customer.in_elevator == True) & (customer.customer_direction == -1):
customer.in_elevator = False
self.customer_list.remove(customer)
print('Customer',customer.customerID,'has reached their destination')
print('There are',len(self.customer_list),'trapped in the elevator')
print('There are',len(Elevator.register_list),'people left on the register')
print('Elevator run is done!!!')
print('CUSTOMERS STUCK IN LIFT ARE BELOW')
for stuck in self.customer_list:
print('Cust. ID:',stuck.customerID,'Dest. Floor:',stuck.destination_floor,'Curr. Floor:',stuck.current_floor,'In Elevator',stuck.in_elevator,'Direction',stuck.customer_direction)
class Elevator:
number_of_floors = 0
register_list = []
current_floor = 0
up = 1
down = -1
def __init__(self, number_of_floors, register_list):
self.number_of_floors = number_of_floors
self.register_list = register_list
def move(self):
pass;
def register_customer(self, customers):
for reg in customers:
self.register_list.append(reg)
def cancel_customer(self, customers):
pass;
class Customer:
current_floor = 0
destination_floor = 0
customerID = 0
in_elevator = False
finished = False
customer_direction = 0
def __init__(self, customerID, floors):
self.customerID = customerID
self.current_floor = random.randint(1, floors)
self.destination_floor = random.randint(1, floors)
while self.destination_floor == self.current_floor:
self.desination_floor = random.randint(1, floors)
if self.current_floor < self.destination_floor:
self.customer_direction = 1
else:
self.customer_direction = -1
def header(): # elevator animation at beginning of program
print(" ELEVATOR OPENING ")
time.sleep(.2)
print("+++++++++++++++++++++++++++++||+++++++++++++++++++++++++++++++++++")
time.sleep(.2)
print("+++++++++++++++++++++++++| |++++++++++++++++++++++++++++++++")
time.sleep(.2)
print("++++++++++++++++| |+++++++++++++++++++")
time.sleep(.2)
print("++++++| |+++++++++")
time.sleep(.2)
print(" ")
time.sleep(.2)
print(" ELEVATOR CLOSING ")
time.sleep(.2)
print("++++++| |+++++++++")
time.sleep(.2)
print("++++++++++++++++| |+++++++++++++++++++")
time.sleep(.2)
print("+++++++++++++++++++++++++| |++++++++++++++++++++++++++++++++")
time.sleep(.2)
print("+++++++++++++++++++++++++++++||+++++++++++++++++++++++++++++++++++")
def main():
try:
floors = int(input('Enter the number of floors: '))
customers = int(input('Enter number of customers: '))
building = Building(floors, customers)
except ValueError:
print('YOU DIDNT ENTER A NUMBER. START AGAIN.')
main()
if __name__ == "__main__":
main()
You haven't indented the functions in your Building class.
Related
So I've made a python program that creates a fake access point by sending lots of beacon frames using Scapy. The program works fine, but i wanted to expand it. I want the program to be able to make multiple fake access points. I tried simple threading but that didn't work out. I tried running the program on 3 different terminals and give each terminal another SSID. That worked fine, but i want my code to do that.
Here's my code:
from scapy.all import Dot11, Dot11Beacon, Dot11Elt, RadioTap, sendp, hexdump
import random, time, sys
class CreateBeacon:
def __init__(self, ssid, number, addr):
#info for frame
self.ssid = ssid
self.number = number
self.addr = addr
self.iface = 'wlan0mon'
#attribute test
#print('ssid: '+self.ssid+"\nnumber given: "+str(self.number)+"\naddress given: "+ self.addr)
#Dot11 layer
self.dot11 = Dot11(type=0, subtype=8,
addr1='ff:ff:ff:ff:ff:ff',
addr2 = addr,
addr3 = addr)
#Beacon layer
self.beacon = Dot11Beacon(cap='ESS+privacy')
#Information Element
self.essid = Dot11Elt(ID='SSID', info=self.ssid, len=len(self.ssid))
self.rsn = Dot11Elt(ID='RSNinfo', info=(
'\x01\x00'
'\x00\x0f\xac\x02'
'\x02\x00'
'\x00\x0f\xac\x04'
'\x00\x0f\xac\x02'
'\x01\x00'
'\x00\x0f\xac\x02'
'\x00\x00'))
#all layers stacked
self.frame = RadioTap()/self.dot11/self.beacon/self.essid/self.rsn
def sendBeacon(self):
self.frame.show()
time.sleep(.2)
print("\nHexDump of frame: ")
time.sleep(.2)
hexdump(self.frame)
enterStart = input("\nPress enter to start\n")
sendp(self.frame, inter=0.050, iface=self.iface, loop=1)
class Number:
def __init__(self, number):
self.number1 = number
try:
int(self.number1)
if type(self.number1) == int:
if self.number1 == 0:
print('well goodbye then....')
time.sleep(.2)
sys.exit()
except ValueError:
self.number1 = int(1)
class SSID:
def __init__(self, ssid):
self.ssid = ssid
if len(self.ssid) > 30:
self.ssid = self.ssid[:30]
class Randmac:
def __init__(self, number):
self.number = number
def generateMac(self):
for i in range(self.number):
random_mac = "%02x:%02x:%02x:%02x:%02x:%02x" % (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
return random_mac
#User Input
name_input = str(input('Enter the name of the fake AP(max 30 charachters): '))
num_input = int(input('Enter the how many fake APs u want: '))
num = Number(number=1)
name = SSID(ssid=name_input)
random_mac = Randmac(num.number1)
make_packet = CreateBeacon(name.ssid, num.number1, random_mac.generateMac())
send_packet = make_packet.sendBeacon()
Any help would be appreciated!
So since nobody wanted to help me with my problem, i figured it out myself with simple multiprocessing. Here's my new code
from scapy.all import Dot11, Dot11Beacon, Dot11Elt, RadioTap, sendp,
hexdump, RandMAC
import time, sys, multiprocessing
class CreateBeacon:
def __init__(self, ssid, number):
#info for frame
self.ssid = ssid
self.number = number
self.addr = RandMAC()
self.iface = 'wlan0mon'
self.dot11 = Dot11(type=0, subtype=8,
addr1='ff:ff:ff:ff:ff:ff',
addr2 = self.addr,
addr3 = self.addr)
#Beacon layer
self.beacon = Dot11Beacon(cap='ESS+privacy')
#Information Element
self.essid = Dot11Elt(ID='SSID', info=self.ssid, len=len(self.ssid))
self.rsn = Dot11Elt(ID='RSNinfo', info=(
'\x01\x00'
'\x00\x0f\xac\x02'
'\x02\x00'
'\x00\x0f\xac\x04'
'\x00\x0f\xac\x02'
'\x01\x00'
'\x00\x0f\xac\x02'
'\x00\x00'))
#all layers stacked
self.frame = RadioTap()/self.dot11/self.beacon/self.essid/self.rsn
def Send(self):
sendp(self.frame, inter=0.050, iface=self.iface, loop=1)
# class SendBeacon:
# def __init__(self, frame):
# self.frame = frame
# def Send(self):
# sendp(self.frame, inter=0.050, iface=self.iface, loop=1)
class MultiProcessBeacon:
def __init__(self, ssid, number):
self.ssid = ssid
self.number = number
def MultiProcessSend(self):
for i in range(self.number):
Beacon = CreateBeacon(ssid=self.ssid[i], number=self.number)
i += 1
str(i)
# i = multiprocessing.Process(target=SendBeacon.Send,
args=Beacon.frame)
for _ in range(3): #sending out the same beacon 3 times because
for some reason sending only 1 beacon does not always work
try:
i = multiprocessing.Process(target=Beacon.Send)
i.start()
except KeyboardInterrupt:
print('processes stopped')
time.sleep(1)
class InputMain():
def __init__(self):
input_number = input('Enter how many fake AP\'s do you want (In
intregers): ')#int(4)
#intreger input handeling
try:
int(input_number)
if int(input_number) == 0:
print('well goodbye then....')
time.sleep(1)
sys.exit()
except ValueError:
print("ValueError detected; number of fake AP(s) = 1")
time.sleep(1)
input_number = int(1)
input_ssid = []#('s-one', 's-two', 's-three', 's-fore') #we'll make
it first a list so we can append stuff to it
for n in range(int(input_number)):
n += 1 #because it starts with 0
ask_ssid = input('Name SSID for AP number ' + str(n)+': ')
if len(ask_ssid) > 32:
print('Maximum length of ssid exceeded.')
ask_ssid = ask_ssid[32]
input_ssid.append(ask_ssid)
tuple(input_ssid)
self.given_number = int(input_number)
self.given_ssid = input_ssid
passInfo_toMulti = MultiProcessBeacon(ssid=self.given_ssid,
number=self.given_number)
passInfo_toMulti.MultiProcessSend()
start = InputMain()
I tried to make a "typing game" and at first, it worked out pretty nice. But when I translated my code to English (variable names, class names, function names etc.) it gave me the warning "Object int is not callable". How can I solve this?
Here's my code:
import time
import random
import sys
class Player():
def __init__(self, name, health = 5, energy = 10):
self.name = name
self.health = health
self.energy = energy
self.hit = 0
def inf(self):
print("Health: ", self.health, "\nEnergy: ", self.energy, "\nName: ", self.name)
def attack(self, opponent):
print("Attacking")
time.sleep(.300)
for i in range(3):
print(".", end=" ", flush=True)
x = self.randomAttack()
if x == 0:
print("Nobody attacks.")
elif x == 1:
print("{} hits {} !".format(name, opponentName))
self.hit(opponent)
opponent.health -= 1
elif x == 2:
print("{} hits {}!".format(opponentName, name))
opponent.hit(self)
self.health -= 1
def randomAttack(self):
return random.randint(0, 2)
def hit(self, hit):
hit.hitVariable += 1
hit.energy -= 1
if (hit.hitVariable % 5) == 0:
hit.health -= 1
if hit.health < 1:
hit.energy = 0
print('{} won the game!'.format(self.name))
self.exit()
#classmethod
def exit(cls):
sys.exit()
def run(self):
print("Running...")
time.sleep(.300)
print("Opponent catch you!")
#######################################################
print("Welcome!\n----------")
name = input("What's your name?\n>>>")
opponentName = input("What's your opponent's name?\n>>>")
you = Player(name)
opponent = Player(opponentName)
print("Commands: \nAttack: a\nRun: r\nInformation: i\nExit: e")
while True:
x = input(">>>")
if x == "a":
you.attack(opponent)
elif x == "r":
you.run()
elif x == "i":
you.inf()
elif x == "e":
Player.exit()
break
else:
print("Command not found!")
continue
It gives me the error at line 24 (self.hit(opponent)).
Your hit function is the problem. You have member and a function with the same name. Change one of them.
Also rename the hit argument of the hit(). You call it via self.hit(opponent) so I would rename it to def hit(self, opponent):.
def __init__(self, name, health = 5, energy = 10):
self.hit = 0
def hit(self, hit):
hit.hitVariable += 1
hit.energy -= 1
if (hit.hitVariable % 5) == 0:
hit.health -= 1
if hit.health < 1:
hit.energy = 0
print('{} won the game!'.format(self.name))
self.exit()
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 was sitting all week on this and I don't know how to get rid of these global points.
Here I define points.
def init():
global points, hidden_password, hidden_password2, country, used, start_time
points = 0
hidden_password = []
hidden_password2 = []
country = ""
used = []
start_time = datetime.now()
welcome()
choice()
Then it goes to choice() from choice to play_game() than to guessing_capital() and here I use points for the first time, and the program is working until var points reach 5.
def guessing_capital(password, used, user_name):
global points
while points < 5:
checking(password, user_name)
time.sleep(1)
print("\n Letters You failed guessing: ", ", ".join(used), end=".\n")
time.sleep(2)
print("\n *** You lost! Sorry, but the GAME is OVER! ***\n")
time.sleep(3)
init()
Then it goes to checking() and from checking it goes to the letter() and then to checking_password() where if the user didn't guess right letter it adds 1 to points and returns it.
def checking_password(number):
global points, hidden_password2, hidden_password
if hidden_password2 == hidden_password:
points += number
time.sleep(1)
print("\n Boo! You have +", number, "penalty points!")
time.sleep(1)
hidden_password2 = hidden_password
if points < 4:
manage_graphics(points)
elif points == 4:
manage_graphics(points)
print(" Hint: It's a capital of " + country + ".")
elif points >= 5:
manage_graphics(5)
return points
Here is a full code if someone wants: https://codeshare.io/aYBAzb
You can use a class to store attributes.
Class Game:
def __init__():
points = 0
self.hidden_password = []
self.hidden_password2 = []
self.country = ""
self.used = []
self.start_time = datetime.now()
self.welcome() # This should be in main function
self.choice() # This should be in main function
def choice(self, ...):
pass
def welcome(self, ...):
pass
def guessing_capital(self, ...):
pass
def checking_password(self, ...):
pass
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()