Related
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]
The problem is this:
It is required to create and use the hash table structure in a problem
large number of keys.
Here are the steps:
Creating one million (1,000,000) visits to a department store
and Credit Card Payment.
From the very large number of different cards, a relatively small subset is created
as follows. Credit cards for visits will have
sixteen (16) specific fixed digits eg 1234567890123456,
but in four (4) of the sixteen (16) random positions they will also have
four characters: X, Y, Z, W in random order.
eg 12Y45W789012Z4X6
In the other places the prices are the initial ones.
I have written the codes. Is is supposed to run super fast but it runs super slowly and I don't know why... Currently, I am running my code for 10,000 cards. Could you help me? Please excuse my poor english...
The code is bellow:
import string
import random
import time
random.seed(1059442)
global max_load_factor
max_load_factor = 0.6
def printGreaterThan2(num):
while True:
if num % 2 == 1:
isPrime = True
for x in range(3,int(num**0.5),2):
if num % x == 0:
isPrime = False
break
if isPrime:
return num
num += 1
N = printGreaterThan2(1000)
arr = [ [] for _ in range(N)]
arr = [ None for _ in range(N)]
def CreatNewItem():
letters = "WXZY"
days = ["Mon", "Tue", "Wed" , "Thu" , "Fri", "Sat"]
s = ''
count = 0
num = ['1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6']
list_a = []
while(count!=4):
a = random.randint(0,15)
b = random.choice(letters)
if b not in num and a not in list_a:
num[a] = b
count = count + 1
list_a.append(a)
s = ''.join(num)
d = random.randint(0,5)
day = days[d]
money = random.randint(10,100)
a = [s,day,money]
return a
def hash(key, tablesize):
sum = 0
for pos in range(len(key)):
sum = sum + ord(key[pos])
hash = sum % tablesize
return hash
#--------------------------------------
def rehash(oldhash , tablesize):
rehash = ( oldhash + 1 ) % tablesize
return rehash
#--------------------------------------
def put2 (arr,a,N,lenght,collitions):
if float(lenght)/float(N) >= max_load_factor:
(arr,N,collitions) = Resize(arr,N,lenght,collitions)
key = a[0]
i = hash(key,N)
j =0
while (True):
if arr[i] is None:
arr[i] = a
lenght = lenght + 1
break
elif arr[i][0] == key:
arr[i][2] = arr[i][2] + a[2]
arr[i][1] = arr[i][1] + a[1]
break
else:
if j == 0 :
collitions = collitions +1
j = 1
i = rehash(i,N)
return (lenght,N,arr,collitions )
#----------------------------------------
def Resize(arr,N,lenght,collitions):
print("resize")
N = printGreaterThan2(2*N)
collitions = 0
arr2 = [ [] for _ in range(N)]
arr2 = [ None for _ in range(N)]
for p in arr:
if p is not None:
(lenght,N,arr2,collitions)=put2(arr2,p,N,lenght,collitions)
return (arr2,N,collitions)
#-----------------------------------------
l = 0
cards = []
collitions = 0
t0 = time.time()
i=0
while i!=10000:
b = CreatNewItem()
(l,N,arr,collitions) = put2(arr,b,N,l,collitions)
i=i+1
t1 = time.time() - t0
print('\ntime is {:0.20f}'.format(t1))
classes = []
due = []
minutes =[]
grade = []
classname = []
classnume = []
form_orderer = []
listobj = []
i = 0
n = 0
k = 0
def classesl(): #setup class list
classesnum = int(input("How many classes do you have?"))
classnume.append(classesnum)
for _ in range(0,int(classnume[0])):
classname = input("What is the class name??")
classes.append(classname)
def duel(): #setup class list
print("How many days is this assignment for", classes[i], "due in?")
c = input()
due.append(c)
def minutesl(): #setup class list
print("How many minutes will this take", classes[i], "?")
e = input()
minutes.append(e)
def gradesl(): #setup class list
print("What is your grade in that", classes[i], "?")
g = input()
grade.append(g)
def getvars():
global i
for _ in range(0,int(classnume[0])):
duel()
minutesl()
gradesl()
make_dicts()
i += 1
def form_order():
for n in range(0,int(classnume[0])):
a = int(minutes[n])
b = int(grade[n])
form_orderer.append(a/b)
print(form_orderer)
n += 1
def make_dicts():
for k in range(0,int(classnume[0])):
dictx = {'keyz': 'valz'}
dictx.update({'class': classes[k], 'form_order': int(form_orderer[k])})
listobj.append(dictx)
k += 1
def sort(form_orderer):
size = len(form_orderer)
for x in range(form_orderer):
for y in range(form_orderer-x-1):
if(form_orderer[y] > form_orderer[y+1]):
tmp = form_orderer[j]
form_orderer[y] = form_orderer[y+1]
form_orderer[y+1] = tmp
def setup():
while True:
classesl()
getvars()
form_order()
make_dicts()
# sort(form_orderer)
print()
break
setup()
I was wondering how would I get it so the form_orderer list corresponds with a classes list in a dict. So I can then print out the classes in order based off of the order of the form_order list sorted from least to greatest. I already have the bubble sort method down, just need help with the dict.
You call make_dicts twice, which leads to an exception, it's called in get_vars and in setup, if i comment it out in get_vars i don't get any errors
classes = []
due = []
minutes =[]
grade = []
classname = []
classnume = []
form_orderer = []
listobj = []
i = 0
n = 0
k = 0
def classesl(): #setup class list
classesnum = int(input("How many classes do you have?"))
classnume.append(classesnum)
for _ in range(0,int(classnume[0])):
classname = input("What is the class name??")
classes.append(classname)
def duel(): #setup class list
print("How many days is this assignment for", classes[i], "due in?")
c = input()
due.append(c)
def minutesl(): #setup class list
print("How many minutes will this take", classes[i], "?")
e = input()
minutes.append(e)
def gradesl(): #setup class list
print("What is your grade in that", classes[i], "?")
g = input()
grade.append(g)
def getvars():
global i
for _ in range(0,int(classnume[0])):
duel()
minutesl()
gradesl()
#make_dicts()
i += 1
def form_order():
for n in range(0,int(classnume[0])):
a = int(minutes[n])
b = int(grade[n])
form_orderer.append(a/b)
print(form_orderer)
n += 1
def make_dicts():
for k in range(0,int(classnume[0])):
dictx = {'keyz': 'valz'}
dictx.update({'class': classes[k], 'form_order': int(form_orderer[k])})
listobj.append(dictx)
k += 1
def sort(form_orderer):
size = len(form_orderer)
for x in range(form_orderer):
for y in range(form_orderer-x-1):
if(form_orderer[y] > form_orderer[y+1]):
tmp = form_orderer[j]
form_orderer[y] = form_orderer[y+1]
form_orderer[y+1] = tmp
def setup():
while True:
classesl()
getvars()
form_order()
make_dicts()
# sort(form_orderer)
print()
break
setup()
My code:
class Persistence:
num = 0
counter1 = 0
counter2 = 0
def __init__(self, num):
self.num = num
#num = input("Enter a non-negative number:: ")
if num < 0:
raise NameError("Negative")
#test else:
#print "ok!"
num_list = []
def digitize(self, num):
num_list = []
n = str(num)
for digit in n:
num_list.append(int(digit))
return num_list
def sum_digits(self, num):
the_list = self.digitize(num)
the_sum = 0
for digit in the_list:
the_sum = the_sum + digit
return the_sum
def times_digits(self, num):
the_list = self.digitize(num)
the_product = 0
for digit in the_list:
the_product = the_product * digit
return the_product
def additive(self, num):
global counter1
sum1 = self.sum_digits(num)
list1 = []
list1 = self.digitize(sum1)
if list1.__len__() > 1:
global counter1
counter1 = counter1 + 1
self.additive(sum1)
return sum1, counter1
def multiplicative(self, num):
global counter2
prod1 = self.times_digits(num)
list1 = []
list1 = self.digitize(prod1)
if list1.__len__() > 1:
global counter1
counter2 = counter2 + 1
self.multiplicative(prod1)
return prod1, counter2
c = Persistence(5)
print c.additive(5)
print c.multiplicative(5)
Not sure why I'm getting this error? It seems to me that I have defined the global variable counter1. I'm also getting this error for counter2, and the only way I've been able to resolve the error is by inserting counter1 = 0 (or any other number) a single line above the return statement on the additive() method. Help would be much appreciated!!
One of the solutions is to move the counters out of class like:
# global variables
num = 0
counter1 = 0
counter2 = 0
class Persistence:
....
....
Leave the rest of your code unmodified.
counter1 and counter2 are defined as class attributes currently, if you want to keep it that way, just access them as classname.attrname:
class Persistence:
num = 0
counter1 = 0
counter2 = 0
def __init__(self, num):
self.num = num
#num = input("Enter a non-negative number:: ")
if num < 0:
raise NameError("Negative")
#test else:
#print "ok!"
num_list = []
def digitize(self, num):
...
def sum_digits(self, num):
...
def times_digits(self, num):
...
def additive(self, num):
sum1 = self.sum_digits(num)
list1 = []
list1 = self.digitize(sum1)
if list1.__len__() > 1:
Persistence.counter1 = Persistence.counter1 + 1
self.additive(sum1)
return sum1, Persistence.counter1
def multiplicative(self, num):
prod1 = self.times_digits(num)
list1 = []
list1 = self.digitize(prod1)
if list1.__len__() > 1:
Persistence.counter2 = Persistence.counter2 + 1
self.multiplicative(prod1)
return prod1, Persistence.counter2
c = Persistence(5)
print c.additive(5)
print c.multiplicative(5)
The appropriate way of solving this issue will be to move the 3 class variables to init method. These variable will become associated with the object can be accessed using 'self'
class Persistence(object):
def __init__(self):
self.counter1 = 0
self.counter2 = 0
def digitize(self, num):
return [int(digit) for digit in str(num)]
def sum_digits(self, num):
return sum(self.digitize(num))
def times_digits(self, num):
the_list = self.digitize(num)
the_product = 0
for digit in the_list:
the_product = the_product * digit
return the_product
def additive(self, num):
sum1 = self.sum_digits(num)
list1 = []
list1 = self.digitize(sum1)
if len(list1) > 1:
self.counter1 += 1
self.additive(sum1)
return sum1, self.counter1
def multiplicative(self, num):
prod1 = self.times_digits(num)
list1 = []
list1 = self.digitize(prod1)
if len(list1) > 1:
self.counter2 += 1
self.multiplicative(prod1)
return prod1, self.counter2
c = Persistence()
print c.additive(5)
print c.multiplicative(5)
You don't num in the constructor if you are not actually using it.
from informedSearch import *
from search import *
class EightPuzzleProblem(InformedProblemState):
"""
Inherited from the InformedProblemState class. To solve
the eight puzzle problem.
"""
def __init__(self, myList, list = {}, operator = None):
self.myList = list
self.operator = operator
def __str__(self):
## Method returns a string representation of the state.
result = ""
if self.operator != None:
result += "Operator: " + self.operator + ""
result += " " + ' '.join(self.myList[0:3]) + "\n"
result += " " + ' '.join(self.myList[3:6]) + "\n"
result += " " + ' '.join(self.myList[6:9]) + "\n"
return result
def illegal(self):
## Tests whether the state is illegal.
if self.myList < 0 or self.myList > 9: return 1
return 0
def equals(self, state):
## Method to determine whether the state instance
## and the given state are equal.
return ' '.join(self.myList) == ' '.join(state.myList)
## The five methods below perform the tree traversing
def move(self, value):
nList = self.myList[:] # make copy of the current state
position = nList.index('P') # P acts as the key
val = nList.pop(position + value)
nList.insert(position + value, 'P')
nList.pop(position)
nList.insert(position, val)
return nList
def moveleft(self):
n = self.move(-1)
return EightPuzzleProblem(n, "moveleft")
def moveright(self):
n = self.move(1)
return EightPuzzleProblem(n, "moveright")
def moveup(self):
n = self.move(-3)
return EightPuzzleProblem(n, "moveup")
def movedown(self):
n = self.move(+3)
return EightPuzzleProblem(n, "movedown")
def operatorNames(self):
return ["moveleft", "moveright", "moveup", "movedown"]
def enqueue(self):
q = []
if (self.myList.index('P') != 0) and (self.myList.index('P') != 3) and (self.myList.index('P') != 6):
q.append(self.moveleft())
if (self.myList.index('P') != 2) and (self.myList.index('P') != 5) and (self.myList.index('P') != 8):
q.append(self.moveright())
if self.myList.index('P') >= 3:
q.append(self.moveup())
if self.myList.index('P') >= 5:
q.append(self.movedown())
def applyOperators(self):
return [self.moveleft(), self.moveright(), self.moveup(), self.movedown()]
def heuristic():
counter = 0
for i in range(len(self.myList)):
if ((self.myList[i] != goal.myList[i]) and self.myList[i] != 'P'):
## Position of current:
current = goal.myList.index(self.myList[i])
if current < 3: goalRow = 0
elif current < 6: goalRow = 1
else: goalRow = 2
if i < 3: initRow = 0
elif i < 6: initRow = 1
else: startRow = 2
initColumn = i % 3
goalColumn = current % 3
counter += (abs(goalColumn - initColumn) + abs(goalRow - initRow))
return counter
#Uncomment to test the starting states:
init = ['1','3','P','8','2','4','7','6','5'] #A
#init = ['1','3','4','8','6','2','P','7','5'] #B
#init = ['P','1','3','4','2','5','8','7','6'] #C
#init = ['7','1','2','8','P','3','6','5','4'] #D
#init = ['8','1','2','7','P','4','6','5','3'] #E
#init = ['2','6','3','4','P','5','1','8','7'] #F
#init = ['7','3','4','6','1','5','8','P','2'] #G
#init = ['7','4','5','6','P','3','8','1','2'] #H
goal = ['1','2','3','8','P','4','7','6','5'] #goal state
InformedSearch(EightPuzzleProblem(init), EightPuzzleProblem(goal))
I run it and it shows error
line 34, in __str__ result += " " + ' '.join(self.myList[0:3]) + "\n"
TypeError: unhashable type: 'slice'
Any Ideas?
You're setting the "list" to a dictionary as a default value: list = {} in:
def __init__(self, myList, list = {}, operator = None):
and then assigning it to myList with:
self.myList = list
A dictionary cannot be sliced like a list. So when you try to slice it:
self.myList[0:3]
it fails.