Skip to content

Commit 160b6dd

Browse files
committed
go: tried collapsing import, still fail
1 parent 7988451 commit 160b6dd

File tree

2 files changed

+130
-36
lines changed

2 files changed

+130
-36
lines changed

Benchmark/go/advanced/main.py

Lines changed: 129 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
from __future__ import annotations
22
import random
33
import math
4-
from square import Square
5-
from typing import List, final, Set
4+
from typing import final, Set
65
from __static__ import int64, Array, CheckedList, cbool, box
76
import time
87

@@ -15,7 +14,94 @@
1514
#PASS: int64 = -1
1615
MAXMOVES: int = 9*9*3 #bg#SIZE*SIZE*3
1716
TIMESTAMP: int = 0
18-
#MOVES: int64 = 0
17+
MOVES: int = 0
18+
19+
def to_pos(x: int64, y: int64) -> int64:
20+
return y * 9 + x # SIZE + x
21+
22+
@final
23+
class Square:
24+
def __init__(self: Square, board: Board, pos: int) -> None:
25+
self.board: Board = board
26+
self.pos: int64 = int64(pos)
27+
self.timestamp: int = TIMESTAMP
28+
self.removestamp: int = TIMESTAMP
29+
self.zobrist_strings: Array[int64] = Array[int64](3)
30+
for ii in range(3):
31+
self.zobrist_strings[ii] = int64(random.randrange(9223372036854775807))
32+
self.color: int64 = 0
33+
self.reference: Square = self
34+
self.ledges: int64 = 0
35+
self.used: cbool = False
36+
self.neighbours: CheckedList[Square] = CheckedList[Square]([])
37+
self.temp_ledges: int64 = 0
38+
39+
40+
def set_neighbours(self: Square) -> None:
41+
x: int64 = self.pos % 9 ## SIZE
42+
y: int64 = self.pos // 9 ## SIZE
43+
self.neighbours = []
44+
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
45+
newx: int64 = x + int64(dx)
46+
newy: int64 = y + int64(dy)
47+
if 0 <= newx < 9 and 0 <= newy < 9: ## 9 = SIZE
48+
bbb: Square = self.board.squares[to_pos(newx, newy)]
49+
self.neighbours.append(bbb)
50+
51+
52+
53+
def move(self: Square, color: int64) -> None:
54+
global TIMESTAMP, MOVES
55+
TIMESTAMP += 1
56+
MOVES += 1
57+
self.board.zobrist.update(self, color)
58+
self.color = (color)
59+
self.reference = self
60+
self.ledges = int64(0)
61+
self.used = True
62+
for neighbour in self.neighbours:
63+
neighcolor: int64 = neighbour.color
64+
if neighcolor == 0: ## bg EMPTY:
65+
self.ledges += 1
66+
else:
67+
neighbour_ref: Square = neighbour.find(True)
68+
if neighcolor == self.color:
69+
if neighbour_ref.reference.pos != self.pos:
70+
self.ledges += neighbour_ref.ledges
71+
neighbour_ref.reference = self
72+
self.ledges -= 1
73+
else:
74+
neighbour_ref.ledges -= 1
75+
if neighbour_ref.ledges == 0:
76+
neighbour.remove(neighbour_ref, True)
77+
self.board.zobrist.add()
78+
79+
def remove(self: Square, reference: Square, update: bool) -> None:
80+
self.board.zobrist.update(self, 0) #bg EMPTY
81+
self.removestamp = TIMESTAMP
82+
if update:
83+
self.color = 0 #bg EMPTY
84+
self.board.emptyset.add(self.pos)
85+
# if color == BLACK:
86+
# self.board.black_dead += 1
87+
# else:
88+
# self.board.white_dead += 1
89+
for neighbour in self.neighbours:
90+
if neighbour.color != 0 and cbool(neighbour.removestamp != TIMESTAMP): # bg 0 = EMPTY
91+
neighbour_ref: Square = neighbour.find(update)
92+
if neighbour_ref.pos == reference.pos:
93+
neighbour.remove(reference, update)
94+
else:
95+
if update:
96+
neighbour_ref.ledges += 1
97+
98+
def find(self: Square, update: bool) -> Square:
99+
reference: Square = self.reference
100+
if reference.pos != self.pos:
101+
reference = reference.find(update)
102+
if update:
103+
self.reference = reference
104+
return reference
19105

20106
#@fields({'empties':List(int)
21107
# ,'board':{'useful':Function(NamedParameters([('pos',int)])
@@ -27,16 +113,16 @@ class EmptySet:
27113
def __init__(self, board: Board) -> None:
28114
self.board: Board = board
29115
S2 = 9*9 #bg#SIZE*SIZE
30-
self.empties: CheckedList[int64] = CheckedList[int64]([]) #TODO Array[int64](S2)
116+
self.empties: Array[int64] = Array[int64](S2)
31117
self.empty_pos: Array[int64] = Array[int64](S2)
32118
for kk in range(S2):
33119
ii: int64 = int64(kk)
34-
self.empties.append(ii)
120+
self.empties[ii] = ii
35121
self.empty_pos[ii] = ii
36122

37123
#def random_choice(self:EmptySet)->int:
38124
def random_choice(self) -> int64:
39-
choices: int64 = int64(len(self.empties))
125+
choices: int64 = int64(len(self.empties)) # TODO ... optional ?!
40126
while choices:
41127
i: int64 = int64(int(random.random()*box(choices)))
42128
pos = self.empties[i]
@@ -50,12 +136,12 @@ def random_choice(self) -> int64:
50136
#def add(self:EmptySet, pos:int)->Void:
51137
def add(self, pos: int64) -> None:
52138
self.empty_pos[pos] = int64(len(self.empties))
53-
self.empties.append(pos)
139+
self.empties[pos] = pos # TODO append
54140

55141
#def remove(self:EmptySet, pos:int, update:bool)->Void:
56-
def remove(self, pos: int, update: bool) -> None:
142+
def remove(self, pos: int64, update: bool) -> None:
57143
self.set(self.empty_pos[pos], self.empties[len(self.empties)-1])
58-
self.empties.pop()
144+
# self.empties.pop() # TODO pop
59145

60146
#def set(self:EmptySet, i:int, pos:int)->Void:
61147
def set(self, i: int64, pos: int64) -> None:
@@ -67,15 +153,15 @@ def set(self, i: int64, pos: int64) -> None:
67153
class ZobristHash:
68154
#def __init__(self:ZobristHash, board:{'squares':List(Square)})->Void:
69155
def __init__(self, board: Board) -> None:
70-
self.hash_set: Set[int] = set()
156+
self.hash_set: Set[int] = set() # TODO no Set?
71157
self.hash: int = 0
72158
for square in board.squares:
73159
self.hash ^= square.zobrist_strings[0] #bg# EMPTY
74160
self.hash_set.clear()
75161
self.hash_set.add(self.hash)
76162

77163
#def update(self:ZobristHash, square:Square, color:int)->Void:
78-
def update(self, square: Square, color: int) -> None:
164+
def update(self, square: Square, color: int64) -> None:
79165
self.hash ^= square.zobrist_strings[square.color]
80166
self.hash ^= square.zobrist_strings[color]
81167

@@ -99,13 +185,13 @@ def dupe(self) -> bool:
99185
class Board:
100186
#def __init__(self:Board)->Void:
101187
def __init__(self) -> None:
102-
self.squares: List[Square] = []
188+
self.squares: CheckedList[Square] = CheckedList[Square]([])
103189
self.emptyset: EmptySet = EmptySet(self)
104190
self.zobrist: ZobristHash = ZobristHash(self)
105-
self.color: int = 2 #bg#BLACK
191+
self.color: int64 = 2 #bg#BLACK
106192
self.finished: bool = False
107193
self.lastmove: int64 = -2
108-
self.history: List[int] = []
194+
self.history: CheckedList[int] = CheckedList[int]([])
109195
self.white_dead: int = 0
110196
self.black_dead: int = 0
111197
#bgWHYYY#self.squares = [Square(self, pos) for pos in range(9*9)] #bg#SIZE*SIZE)
@@ -193,16 +279,16 @@ def useful(self, pos: int64) -> int:
193279
(empties or weak_opps or (strong_neighs and (strong_opps or weak_neighs)))
194280

195281
#def useful_moves(self:Board)->List(int):
196-
def useful_moves(self) -> List[int64]:
197-
return [pos for pos in self.emptyset.empties if self.useful(pos)]
282+
def useful_moves(self) -> CheckedList[int]:
283+
return CheckedList[int]([pos for pos in self.emptyset.empties if self.useful(pos)])
198284

199285
#def replay(self:Board, history:List(int))->Void:
200286
def replay(self, history: Array[int64]) -> None:
201287
for pos in history:
202288
self.move(pos)
203289

204290
#def score(self:Board, color:int)->float:
205-
def score(self, color: int) -> float:
291+
def score(self, color: int64) -> float:
206292
if color == 1: #bg#WHITE
207293
count = 7.5 + self.black_dead #bg#KOMI
208294
else:
@@ -232,7 +318,7 @@ def check(self) -> None:
232318
changed = False
233319
for member in members1.copy():
234320
for neighbour in member.neighbours:
235-
if neighbour.color == square.color and neighbour not in members1:
321+
if int64(neighbour.color) == square.color and cbool(neighbour not in members1):
236322
changed = True
237323
members1.add(neighbour)
238324
ledges1 = 0
@@ -245,20 +331,21 @@ def check(self) -> None:
245331

246332
members2 = set()
247333
for square2 in self.squares:
248-
if square2.color != 0 and square2.find(False) == root: #bg#EMPTY
334+
if square2.color != 0 and cbool(square2.find(False) == root): #bg#EMPTY
249335
members2.add(square2)
250336

251337
ledges2 = root.ledges
252338

253-
assert members1 == members2
254-
assert ledges1 == ledges2, ('ledges differ at %r: %d %d' % (square, ledges1, ledges2))
339+
# TODO
340+
# assert members1 == members2
341+
# assert ledges1 == ledges2, ('ledges differ at %r: %d %d' % (square, ledges1, ledges2))
255342

256343
empties1 = set(self.emptyset.empties)
257344

258345
empties2 = set()
259346
for square in self.squares:
260347
if square.color == 0: #bg#EMPTY
261-
empties2.add(square.pos)
348+
empties2.add(box(square.pos))
262349

263350

264351
#@fields({'pos':int, 'wins':int, 'losses':int})
@@ -270,16 +357,16 @@ def __init__(self) -> None:
270357
self.pos: int64 = -1
271358
self.wins: int64 = 0
272359
self.losses: int64 = 0
273-
self.pos_child: List[None | UCTNode] = [None for x in range(9*9)] #bg#SIZE*SIZE
360+
self.pos_child: CheckedList[None | UCTNode] = CheckedList[None | UCTNode]([None for x in range(9*9)]) #bg#SIZE*SIZE
274361
self.parent: None | UCTNode = None
275-
self.unexplored: List[int64] = []
362+
self.unexplored: CheckedList[int] = CheckedList[int]([])
276363

277364
#def play(self:UCTNode, board:Board)->Void:
278365
def play(self, board: Board) -> None:
279366
""" uct tree search """
280-
color: int = board.color
367+
color: int = box(board.color)
281368
node: UCTNode = self
282-
path: List[UCTNode] = [node]
369+
path: CheckedList[UCTNode] = CheckedList[UCTNode]([node])
283370
pos: int64 = 0
284371
while True:
285372
pos = node.select(board)
@@ -322,7 +409,7 @@ def random_playout(self, board: Board) -> None:
322409
board.move(board.random_move())
323410

324411
#def update_path(self:UCTNode, board:Board, color:int, path:List(UCTNode))->Void:
325-
def update_path(self, board: Board, color: int, path: List[UCTNode]) -> None:
412+
def update_path(self, board: Board, color: int, path: CheckedList[UCTNode]) -> None:
326413
""" update win/loss count along path """
327414
wins = board.score(2) >= board.score(1) #bg#BLACK #bg#WHITE
328415
for node in path:
@@ -332,8 +419,11 @@ def update_path(self, board: Board, color: int, path: List[UCTNode]) -> None:
332419
node.wins += 1
333420
else:
334421
node.losses += 1
335-
if node.parent:
336-
node.parent.bestchild = node.parent.best_child()
422+
if node.parent is not None:
423+
mypar = node.parent
424+
bc = mypar.best_child()
425+
if node.parent is not None:
426+
node.parent.bestchild = bc
337427

338428
#def score(self:UCTNode)->float:
339429
def score(self) -> float:
@@ -349,7 +439,7 @@ def score(self) -> float:
349439
return winrate + math.sqrt((math.log(parentvisits))/(5*nodevisits))
350440

351441
#def best_child(self:UCTNode)->UCTNode:
352-
def best_child(self) -> UCTNode:
442+
def best_child(self) -> None | UCTNode:
353443
maxscore = -1
354444
maxchild = None
355445
for child in self.pos_child:
@@ -359,12 +449,13 @@ def best_child(self) -> UCTNode:
359449
return maxchild
360450

361451
#def best_visited(self:UCTNode)->UCTNode:
362-
def best_visited(self) -> UCTNode:
363-
maxvisits = -1
452+
def best_visited(self) -> None | UCTNode:
453+
maxvisits: int64 = -1
364454
maxchild = None
365455
for child in self.pos_child:
366-
if child and (child.wins+child.losses) > maxvisits:
367-
maxvisits, maxchild = (child.wins+child.losses), child
456+
if child is not None and box((child.wins+child.losses) > maxvisits):
457+
maxvisits = (child.wins+child.losses)
458+
maxchild = child
368459
return maxchild
369460

370461
#def computer_move(board:{'useful_moves':Function([], List(int)),
@@ -387,7 +478,10 @@ def computer_move(board: Board) -> int:
387478
nboard.reset()
388479
nboard.replay(ahist)
389480
node.play(nboard)
390-
return box(tree.best_visited().pos)
481+
bvv = tree.best_visited()
482+
if bvv is not None:
483+
return box(bvv.pos)
484+
return -1
391485

392486
ITERATIONS = 2
393487

Benchmark/go/advanced/square.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def remove(self: Square, reference: Square, update: bool) -> None:
9090
self.removestamp = TIMESTAMP
9191
if update:
9292
self.color = EMPTY
93-
self.board.emptyset.add(self.pos)
93+
self.board.emptyset.add(self.pos) # TODO ERROR: expected int got int64, likely cannot pass int64 across boundary https://github.com/facebookincubator/cinder/issues/146
9494
# if color == BLACK:
9595
# self.board.black_dead += 1
9696
# else:

0 commit comments

Comments
 (0)