你好!有一个类具有类似此构造函数的内容:
class GameTree:
evaled = 0 # количество просчитанных листьев
nodes = [] # уникальные листья
def __init__(self, players, points, cp=0, level=0, line=0):
# cp - current player
self.state = arr_to_state(players) # arr_to_state превращает последовательность ходов в состояние поля
for j in GameTree.nodes: # для каждого уникального листа
if j.state == self.state: # если состояния равны - равны и объекты
self = deepcopy(j)
return
GameTree.evaled += 1
self.index = len(GameTree.nodes)
GameTree.nodes.append(self) # сохраняем ссылку на себя
#
# ...
#
assert hasattr(self, 'index')
问题是这样的:为 m 个玩家构建一个 n 维井字游戏的完整图。每个对象都GameTree包含该领域的状态和游戏的可能发展。所有唯一(具有相同字段状态的)实例都存储在GameTree.nodes. 同时,按照计划,每个对象都有一个索引,该索引可以是显式设置的,也可以是从已经计算好的索引中获取的。
尝试为二维井字游戏构建图形时:
GameTree(points=[[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]],
players=[[[0, 0]], []],
cp=1})
抛出一个错误:
File "C:\Programing\Python\V4.py", line 151, in pprint
s += ' %'+str(i.index)
AttributeError: 'GameTree' object has no attribute 'index'
请帮我解决。整个代码(在某些地方 - 很脏):
from copy import deepcopy, copy
from time import time
from threading import Thread
from math import factorial
point_class = lambda a: a.count(0)
class slist(list):
def without(self, x):
b = self[:]
b.remove(x)
return b
def to_ter_arr(i):
if i<3:
return [i]
return to_ter_arr(i // 3) + [i%3]
def arr_to_num(arr):
arr = list(map(lambda a: a+1, arr))
ret = 0
arr.reverse()
for i in range(len(arr)):
ret += (3**i)*arr[i]
return ret
def arr_to_state(arr):
ret = [0 for i in range(3**len(arr[0][0]))]
for p in range(len(arr)):
for i in arr[p]:
ret[arr_to_num(i)] = p+1
return ret
def gen(n):
ret = slist()
for i in range(pow(3, n)):
buff = to_ter_arr(i)
buff = [0 for i in range((n-len(buff)))]+buff
buff = list(map(lambda a: a-1, buff))
ret.append(buff)
return ret
def three(a, b, c):
if a == [] or b == [] or c== []:
return False
for i in range(len(a)):
s = [a[i], b[i], c[i]]
if not s in [[1,1,1], [-1,-1,-1], [0,0,0], [1,0,-1], [-1,0,1]]:
return False
return True and a!=b and a!=c and b!=c
def won(pl):
for a in pl:
for b in pl:
for c in pl:
if three(a, b, c):
return True
return False
class GameTree:
evaled = 0 # количество просчитанных листьев
nodes = [] # уникальные листья
def __init__(self, players, points, cp=0, level=0, line=0):
self.state = arr_to_state(players) # arr_to_state превращает последовательность ходов в состояние поля
for j in GameTree.nodes: # для каждого уникального листа
if j.state == self.state: # если состояния равны - равны и листья
self = deepcopy(j)
return
GameTree.evaled += 1
self.index = len(GameTree.nodes)
GameTree.nodes.append(self) # сохраняем ссылку на себя
players = slist(deepcopy(players)) # slist это list, для которого
points = slist(deepcopy(points)) # определен метод without
if cp == len(players):
cp = 0
self.children = []
for player in players:
if won(player):
return
if points == []:
return
me = players[cp]
enemies = players.without(me)
if len(me)>=2:
for point in points:
me_ = me + [point]
if won(me_):
players[cp].append(point)
self.children.append(GameTree(players, points.without(point), cp+1, level=level+1))
return
blocked = False
for point in points:
for en in enemies:
en_ = en + [point]
if won(en_):
buff = deepcopy(players)
players[cp].append(point)
self.children.append(GameTree(players, points.without(point), cp+1, level=level+1))
players = buff
blocked = True
if blocked:
return
for point in points:
buff = deepcopy(players)
players[cp].append(point)
self.children.append(GameTree(players, points.without(point), cp+1, level=level+1))
players = buff
assert hasattr(self, 'index')
def pprint(self, f):
s = '#{} {}'.format(self.index, self.state)
for i in self.children:
s += ' %'+str(i.index)
f.write(s+'\n')
@staticmethod
def print_result(file_name):
f = open(file_name, 'w')
print('len =', len(GameTree.nodes))
for i in GameTree.nodes:
i.pprint(f)
f.close()
def progress():
global aprox, game, start
while game.is_alive():
print('\r{} , {} s'.format(GameTree.evaled, int(time()-start)), end='')
n = int(input('N = ') or '2')
points = gen(n)
pc = int(input('Количество игроков: ') or '2')
center = slist([0 for i in range(n)])
players = slist([[center]]+[[] for i in range(pc-1)])
file_name = input('Имя файла: ') or 'log.txt'
f = open(file_name, 'w')
show = input('Показывать прогресс (Д\Н, Д по умолчанию)') or 'д'
if show == 'H' or show == 'н':
show = False
elif show == 'Д' or show == 'д':
show = True
else:
print('Ошибка!!!')
exit(1)
print('\nCenter =', center)
print('Players =', players)
print('Points =', points)
start = time()
game = Thread(target = GameTree, kwargs = {'players': players, 'points': points.without(center), 'cp': 1, 'level': 1})
prog = Thread(target = progress)
game.start()
if show:
prog.start()
game.join()
progress()
GameTree.print_result(file_name)
print(time()-start, 's')
我现在无法深入研究这一块代码,但怀疑问题出在这里:
尝试更换
在