我正在为一个连续4的简单游戏编写一个类,但是我遇到了在同一个类中调用方法的问题。为了完整起见,这是全班:
class Grid:
grid = None
# creates a new empty 10 x 10 grid
def reset():
Grid.grid = [[0] * 10 for i in range(10)]
# places an X or O
def place(player,x,y):
Grid.grid[x][y] = player
# returns the element in the grid
def getAt(x,y):
return Grid.grid[x][y]
# checks for wins in a certain direction
def checkLine(player,v,count,x,y):
x = x+v[0]
y = y+v[1]
if x < 0 or x > 9:
return
if y < 0 or y > 9:
return
if Grid.grid[x][y] == p:
count = count+1
if count == 4:
return True
checkLine(player,v,count,x,y)
return False
# returns the number of the player that won
def check():
i = 'i'
for x in range(0,10):
for y in range(0,10):
if Grid.grid[x][y] > 0:
p = Grid.grid[x][y]
f = checkLine(p,0,array(i,[1,0]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[0,1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[1,1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[-1,0]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[0,-1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[-1,-1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[1,-1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[-1,1]),x,y)
if f:
return p
return 0
reset = staticmethod(reset)
place = staticmethod(place)
getAt = staticmethod(getAt)
check = staticmethod(check)
checkLine = staticmethod(checkLine)
我正在尝试从check()调用checkLine(),但是我收到错误“ NameError:全局名称'checkLine'未定义”。当我调用Grid.checkLine()时,我得到“ TypeError:'模块'对象不可调用”
如何调用checkLine()?
编辑:
@beer_monk
class Grid(object):
grid = None
# creates a new empty 10 x 10 grid
def reset(self):
Grid.grid = [[0] * 10 for i in range(10)]
# places an X or O
def place(self,player,x,y):
Grid.grid[x][y] = player
# returns the element in the grid
def getAt(self,x,y):
return Grid.grid[x][y]
# checks for wins in a certain direction
def checkLine(self,player,v,count,x,y):
x = x+v[0]
y = y+v[1]
if x < 0 or x > 9:
return
if y < 0 or y > 9:
return
if Grid.grid[x][y] == p:
count = count+1
if count == 4:
return True
checkLine(self,player,v,count,x,y)
return False
# returns the number of the player that won
def check(self):
i = 'i'
for x in range(0,10):
for y in range(0,10):
if Grid.grid[x][y] > 0:
p = Grid.grid[x][y]
for vx in range(-1,2):
for vy in range(-1,2):
f = self.checkLine(p,0,array(i,[vx,vy]),x,y)
if f:
return p
return 0
reset = staticmethod(reset)
place = staticmethod(place)
getAt = staticmethod(getAt)
check = staticmethod(check)
checkLine = staticmethod(checkLine)
答案 0 :(得分:8)
摆脱课堂。对grid
使用普通函数和模块级变量。
课程没有以任何方式帮助你。
PS。如果您真的想在课堂上拨打checkline
,请拨打Grid.checkline
。例如:
class Foo:
@staticmethod
def test():
print('Hi')
@staticmethod
def test2():
Foo.test()
Foo.test2()
打印
Hi
答案 1 :(得分:1)
<强>语法:强>
class_Name.function_Name(self)
示例:强>
Turn.checkHoriz(self)
答案 2 :(得分:0)
与java或c ++不同,在python中,所有类方法都必须接受类实例作为第一个变量。在我见过的每一个python代码中,该对象被称为self
。例如:
def reset(self):
self.grid = [[0] * 10 for i in range(10)]
请参阅http://docs.python.org/tutorial/classes.html
请注意,在其他语言中,翻译是自动进行的
答案 3 :(得分:0)
您实际上是在修改类本身,而不是对某个对象进行操作。 Python允许你这样做,但它不是真正的类。所以你遇到了几个问题
- 你永远无法以这种方式制作多个网格
在网格定义之后,尝试实例化网格并像这样调用方法
aGrid = Grid()
...
aGrid.checkLine()
要做到这一点,首先需要修改所有方法定义,将“self”作为第一个变量,并在检查中调用self.checkLine()
def check(self):
...
self.checkLine()
...
此外,您的重复检查会呼叫FOR循环。你不需要写出案例。
答案 4 :(得分:0)
您的班级定义中存在多个问题。您尚未定义在代码中使用的数组。同样在checkLine调用中,您正在发送一个int,并且在其定义中,您正在尝试下标它。抛开这些,我希望你意识到你在这里使用静态方法来处理所有的类方法。在这种情况下,无论何时在类中调用方法,您仍然需要通过类的类对象调用它们。因此,在您的课程中,当您致电 checkLine 时,请将其称为 Grid.checkLine 这应解决您的NameError问题。
此外,您的模块导入看起来有些问题。您可能已经按名称Grid导入了一个Module,并且您也有一个名为Grid的类。 Python认为您正在调用导入的模块Grid方法,该方法不可调用。 (我认为,这里没有完整的图片可以看出为什么会产生TypeError)
解决问题的最佳方法是使用最好使用的类,即在这些对象上创建对象和调用方法。还使用适当的命名空间。对于所有这些,您可以从一些很好的介绍性材料开始,比如Python教程。
答案 5 :(得分:0)
一个重做的例子(希望能更好地使用类!)
import itertools
try:
rng = xrange # Python 2.x
except NameError:
rng = range # Python 3.x
class Turn(object):
def __init__(self, players):
self.players = itertools.cycle(players)
self.next()
def __call__(self):
return self.now
def next(self):
self.now = self.players.next()
class Grid(object):
EMPTY = ' '
WIDTH = 10
HEIGHT = 10
WINLENGTH = 4
def __init__(self, debug=False):
self.debug = debug
self.grid = [Grid.EMPTY*Grid.WIDTH for i in rng(Grid.HEIGHT)]
self.player = Turn(['X','O'])
def set(self, x, y):
if self.grid[y][x]==Grid.EMPTY:
t = self.grid[y]
self.grid[y] = t[:x] + self.player() + t[x+1:]
self.player.next()
else:
raise ValueError('({0},{1}) is already taken'.format(x,y))
def get(self, x, y):
return self.grid[y][x]
def __str__(self):
corner = '+'
hor = '='
ver = '|'
res = [corner + hor*Grid.WIDTH + corner]
for row in self.grid[::-1]:
res.append(ver + row + ver)
res.append(corner + hor*Grid.WIDTH + corner)
return '\n'.join(res)
def _check(self, s):
if self.debug: print("Check '{0}'".format(s))
# Exercise left to you!
# See if a winning string exists in s
# If so, return winning player char; else False
return False
def _checkVert(self):
if self.debug: print("Check verticals")
for x in rng(Grid.WIDTH):
winner = self._check([self.get(x,y) for y in rng(Grid.HEIGHT)])
if winner:
return winner
return False
def _checkHoriz(self):
if self.debug: print("Check horizontals")
for y in rng(Grid.HEIGHT):
winner = self._check([self.get(x,y) for x in rng(Grid.WIDTH)])
if winner:
return winner
return False
def _checkUpdiag(self):
if self.debug: print("Check up-diagonals")
for y in rng(Grid.HEIGHT-Grid.WINLENGTH+1):
winner = self._check([self.get(d,y+d) for d in rng(min(Grid.HEIGHT-y, Grid.WIDTH))])
if winner:
return winner
for x in rng(1, Grid.WIDTH-Grid.WINLENGTH+1):
winner = self._check([self.get(x+d,d) for d in rng(min(Grid.WIDTH-x, Grid.HEIGHT))])
if winner:
return winner
return False
def _checkDowndiag(self):
if self.debug: print("Check down-diagonals")
for y in rng(Grid.WINLENGTH-1, Grid.HEIGHT):
winner = self._check([self.get(d,y-d) for d in rng(min(y+1, Grid.WIDTH))])
if winner:
return winner
for x in rng(1, Grid.WIDTH-Grid.WINLENGTH+1):
winner = self._check([self.get(x+d,d) for d in rng(min(Grid.WIDTH-x, Grid.HEIGHT))])
if winner:
return winner
return False
def isWin(self):
"Return winning player or False"
return self._checkVert() or self._checkHoriz() or self._checkUpdiag() or self._checkDowndiag()
def test():
g = Grid()
for o in rng(Grid.WIDTH-1):
g.set(0,o)
g.set(Grid.WIDTH-1-o,0)
g.set(Grid.WIDTH-1,Grid.HEIGHT-1-o)
g.set(o,Grid.HEIGHT-1)
print(g)
return g
g = test()
print g.isWin()
答案 6 :(得分:0)
Java程序员以及以下是我如何调用内部方法:
class Foo:
variable = 0
def test(self):
self.variable = 'Hi'
print(self.variable)
def test2(self):
Foo.test(self)
tmp = Foo()
tmp.test2()