I am developing a simple text based Dungeon game using Python3. First the user is prompted to select the hero from screen.py file.
我正在使用Python3开发一个简单的基于文本的Dungeon游戏。首先提示用户从屏幕中选择英雄。py文件。
from game import *
class GameScreen:
'''Display the current state of a game in a text-based format.
This class is fully implemented and needs no
additional work from students.'''
def initialize_game(self):
'''(GameScreen) -> NoneType
Initialize new game with new user-selected hero class
and starting room files.'''
hero = None
while hero is None:
c = input("Select hero type:\n(R)ogue (M)age (B)arbarian\n")
c = c.lower()
if c == 'r':
hero = Rogue()
elif c == 'm':
hero = Mage()
elif c == 'b':
hero = Barbarian()
self.game = Game("rooms/startroom", hero)
def play(self):
'''(Game) -> NoneType
The main game loop.'''
exit = False
while not exit:
print(self)
if self.game.game_over():
break
c = input("Next: ")
if c in ['q', 'x']:
print("Thanks for playing!")
exit = True
elif c == 'w': # UP
self.game.move_hero(-1, 0)
elif c == 's': # DOWN
self.game.move_hero(1, 0)
elif c == 'a': # LEFT
self.game.move_hero(0, -1)
elif c == 'd': # RIGHT
self.game.move_hero(0, 1)
elif c == 'r':
## RESTART GAME
self.initialize_game()
else:
pass
def __str__(self):
'''(GameScreen) -> NoneType
Return a string representing the current room.
Include the game's Hero string represetation and a
status message from the last action taken.'''
room = self.game.current_room
s = ""
if self.game.game_over():
#render a GAME OVER screen with text mostly centered
#in the space of the room in which the character died.
#top row
s += "X" * (2 + room.cols) + "\n"
#empty rows above GAME OVER
for i in list(range(floor((room.rows - 2) / 2))):
s += "X" + " " * room.cols + "X\n"
# GAME OVER rows
s += ("X" + " " * floor((room.cols - 4) / 2) +
"GAME" + " " * ceil((room.cols - 4) / 2) + "X\n")
s += ("X" + " " * floor((room.cols - 4) / 2) +
"OVER" + " " * ceil((room.cols - 4) / 2) + "X\n")
#empty rows below GAME OVER
for i in list(range(ceil((room.rows - 2) / 2))):
s += "X" + " " * room.cols + "X\n"
#bottom row
s += "X" * (2 + room.cols) + "\n"
else:
for i in range(room.rows):
for j in room.grid[i]:
if j is not None:
if j.visible:
s += j.symbol()
else:
#This is the symbol for 'not yet explored' : ?
s += "?"
s += "\n"
#hero representation
s += str(self.game.hero)
#last status message
s += room.status
return s
if __name__ == '__main__':
gs = GameScreen()
gs.initialize_game()
gs.play()
Whenever I run this code, I get this error: TypeError: init() takes at least 2 arguments (1 given) which has to do with Rogue() or other hero classes. Here's the hero.py.
每当我运行这段代码时,我都会得到这个错误:TypeError: init()至少需要2个参数(1给定),这与流氓()或其他英雄类有关。这是hero.py。
class Rogue(Tile):
'''A class representing the hero venturing into the dungeon.
Heroes have the following attributes: a name, a list of items,
hit points, strength, gold, and a viewing radius. Heroes
inherit the visible boolean from Tile.'''
def __init__(self, rogue, bonuses=(0, 0, 0)):
'''(Rogue, str, list) -> NoneType
Create a new hero with name Rogue,
an empty list of items and bonuses to
hp, strength, gold and radius as specified
in bonuses'''
self.rogue = rogue
self.items = []
self.hp = 10 + bonuses[0]
self.strength = 2 + bonuses[1]
self.radius = 2 + bonuses[2]
Tile.__init__(self, True)
def symbol(self):
'''(Rogue) -> str
Return the map representation symbol of Hero: O.'''
#return "\u263b"
return "O"
def __str__(self):
'''(Item) -> str
Return the Hero's name.'''
return "{}\nHP:{:2d} STR:{:2d} RAD:{:2d}\n".format(
self.rogue, self.hp, self.strength, self.radius)
def take(self, item):
'''ADD SIGNATURE HERE
Add item to hero's items
and update their stats as a result.'''
# IMPLEMENT TAKE METHOD HERE
pass
def fight(self, baddie):
'''ADD SIGNATURE HERE -> str
Fight baddie and return the outcome of the
battle in string format.'''
# Baddie strikes first
# Until one opponent is dead
# attacker deals damage equal to their strength
# attacker and defender alternate
if self.hp < 0:
return "Killed by"
return "Defeated"
What am I doing wrong?
我做错了什么?
2 个解决方案
#1
9
The Problem
这个问题
In GameScreen.initialize_game()
, you set hero=Rogue()
, but the Rogue
constructor takes rogue
as an argument. (Said another way, the __init__
of Rogue
requires that rogue
be passed in.) You likely have this same issue when you set hero=Mage
and hero=Barbarian
.
在GameScreen.initialize_game()中,您设置hero=Rogue(),但是恶意的构造函数将流氓作为参数。(另一种说法是,无赖的行为要求他必须通过。)当你设定英雄=法师和英雄=野蛮人的时候,你可能会遇到同样的问题。
The Solution
解决方案
Luckily the fix is simple; you can just change hero=Rogue()
to hero=Rogue("MyRogueName")
. Maybe you could prompt the user for a name in initialize_game
, and then use that name.
幸运的是,修复很简单;您可以将hero=Rogue()改为hero=Rogue(“MyRogueName”)。也许您可以在initialize_game中提示用户名,然后使用该名称。
Notes on "at least 2 arguments (1 given)"
“至少两个参数(1)”
When you see errors like this, it means that you have called a function or a method without passing enough arguments to it. (__init__
is just a special method that is called when an object is initialized.) So when debugging stuff like this in the future, look at where you call a function/method, and where you define it, and make sure that the two have the same number of parameters.
当您看到这样的错误时,它意味着您已经调用了一个函数或方法,而没有传递足够的参数。(__init__只是在对象初始化时调用的一种特殊方法)。因此,在将来调试类似这样的东西时,看看你调用的函数/方法,以及定义它的地方,并确保两者的参数个数相同。
One thing that is sort of tricky about these kinds of errors, is the self
that gets passed around.
有一件事是很棘手的关于这些错误,是自我被传递。
>>> class MyClass:
... def __init__(self):
... self.foo = 'foo'
...
>>> myObj = MyClass()
In that example, one might think, "Weird, I initialized myObj
, so MyClass.__init__
was called; why didn't I have to pass in something for self
?" The answer is that self
is effectively passed in whenever the "object.method()" notation is used. Hopefully that helps clear up the error and explains how to debug it in the future.
在这个例子中,你可能会想,“奇怪,我初始化了myObj,所以MyClass。__init__叫;为什么我不需要传递一些东西给自己呢?答案是,每当使用“object.method()”符号时,self就会被有效传递。希望这有助于澄清错误,并说明如何在将来调试它。
#2
1
Class Rogue:
...
def __init__(self, rogue, bonuses=(0, 0, 0)):
...
__init__
of your Rogue
class needs parameter rogue
, but you are instantiating it as hero = Rogue()
in initialize_game
.
您的流氓类的__init__需要参数流氓,但是您在initialize_game中实例化它为hero = Rogue()。
You need to pass some appropriate parameter to it like hero = Rogue('somename')
您需要传递一些适当的参数,例如hero = Rogue('somename')
#1
9
The Problem
这个问题
In GameScreen.initialize_game()
, you set hero=Rogue()
, but the Rogue
constructor takes rogue
as an argument. (Said another way, the __init__
of Rogue
requires that rogue
be passed in.) You likely have this same issue when you set hero=Mage
and hero=Barbarian
.
在GameScreen.initialize_game()中,您设置hero=Rogue(),但是恶意的构造函数将流氓作为参数。(另一种说法是,无赖的行为要求他必须通过。)当你设定英雄=法师和英雄=野蛮人的时候,你可能会遇到同样的问题。
The Solution
解决方案
Luckily the fix is simple; you can just change hero=Rogue()
to hero=Rogue("MyRogueName")
. Maybe you could prompt the user for a name in initialize_game
, and then use that name.
幸运的是,修复很简单;您可以将hero=Rogue()改为hero=Rogue(“MyRogueName”)。也许您可以在initialize_game中提示用户名,然后使用该名称。
Notes on "at least 2 arguments (1 given)"
“至少两个参数(1)”
When you see errors like this, it means that you have called a function or a method without passing enough arguments to it. (__init__
is just a special method that is called when an object is initialized.) So when debugging stuff like this in the future, look at where you call a function/method, and where you define it, and make sure that the two have the same number of parameters.
当您看到这样的错误时,它意味着您已经调用了一个函数或方法,而没有传递足够的参数。(__init__只是在对象初始化时调用的一种特殊方法)。因此,在将来调试类似这样的东西时,看看你调用的函数/方法,以及定义它的地方,并确保两者的参数个数相同。
One thing that is sort of tricky about these kinds of errors, is the self
that gets passed around.
有一件事是很棘手的关于这些错误,是自我被传递。
>>> class MyClass:
... def __init__(self):
... self.foo = 'foo'
...
>>> myObj = MyClass()
In that example, one might think, "Weird, I initialized myObj
, so MyClass.__init__
was called; why didn't I have to pass in something for self
?" The answer is that self
is effectively passed in whenever the "object.method()" notation is used. Hopefully that helps clear up the error and explains how to debug it in the future.
在这个例子中,你可能会想,“奇怪,我初始化了myObj,所以MyClass。__init__叫;为什么我不需要传递一些东西给自己呢?答案是,每当使用“object.method()”符号时,self就会被有效传递。希望这有助于澄清错误,并说明如何在将来调试它。
#2
1
Class Rogue:
...
def __init__(self, rogue, bonuses=(0, 0, 0)):
...
__init__
of your Rogue
class needs parameter rogue
, but you are instantiating it as hero = Rogue()
in initialize_game
.
您的流氓类的__init__需要参数流氓,但是您在initialize_game中实例化它为hero = Rogue()。
You need to pass some appropriate parameter to it like hero = Rogue('somename')
您需要传递一些适当的参数,例如hero = Rogue('somename')