def set_naf(self, naf, rotate=False): for h in reversed(self.history): for o in h.objects: o.undraw() self.history = [] self.known_moves = set() if not rotate: xyp = lambda x, y: twixt.Point(x, y) pp = lambda p: p cp = lambda c: 1-c else: xyp = lambda x, y: twixt.Point(y, x) cp = lambda c: c pp = lambda p: twixt.Point(p.y, p.x) objs = [] for x, y, i in zip(*naf[:,:,8:].nonzero()): objs.append(self._create_drawn_peg(xyp(x, y), cp(i&1))) for x, y, j in zip(*naf[:,:,:8].nonzero()): link = twixt.Game.describe_link(j, x, y) objs.append(self._create_drawn_link(pp(link.p1), pp(link.p2), cp(i&1))) nho = TBWHistory("nninputs") self.history.append(nho) nho.objects = objs
def set_nn_inputs(self, pegs, links, rotate=False): for h in reversed(self.history): for o in h.objects: o.undraw() self.history = [] self.known_moves = set() if not rotate: xyp = lambda x, y: twixt.Point(x, y) pp = lambda p: p cp = lambda c: 1-c else: xyp = lambda x, y: twixt.Point(y, x) cp = lambda c: c pp = lambda p: twixt.Point(p.y, p.x) objs = [] for x, y, i in zip(*pegs.nonzero()): objs.append(self._create_drawn_peg(xyp(x, y), cp(i))) i_px_py = [] # color = game.WHITE for vertical in [False, True]: for diff_sign in [False, True]: for as_me in [False, True]: index = ifelse0(vertical, twixt.Game.LINK_LONGY) index += ifelse0(diff_sign, twixt.Game.LINK_DIFFSIGN) index += 1 if as_me else 0 pad_x = ifelse0(vertical or diff_sign, 1) pad_y = ifelse0(not vertical or diff_sign, 1) i_px_py.append((index, pad_x, pad_y)) for x, y, j in zip(*links.nonzero()): index, pad_x, pad_y = i_px_py[j] lx = x - pad_x ly = y - pad_y desc = twixt.Game.describe_link(index, lx, ly) c1 = 2 - 2*pegs[desc.p1.x, desc.p1.y, 0] - pegs[desc.p1.x, desc.p1.y, 1] c2 = 2 - 2*pegs[desc.p2.x, desc.p2.y, 0] - pegs[desc.p2.x, desc.p2.y, 1] if c1 == 0 and c2 == 0: color = 0 elif c1 == 1 and c2 == 1: color = 1 else: color = 2 objs.append(self._create_drawn_link(pp(desc.p1), pp(desc.p2), color)) nho = TBWHistory("nninputs") self.history.append(nho) nho.objects = objs
def policy_index_point(thing, index): if isinstance(thing, twixt.Game): color = thing.turn elif isinstance(thing, int): color = thing else: raise ValueError("Bad type for thing") assert color in (0, 1) major, minor = divmod(index, twixt.Game.SIZE) assert 0 <= major and major < twixt.Game.SIZE - 2 assert 0 <= minor and minor < twixt.Game.SIZE if color == twixt.Game.WHITE: return twixt.Point(major + 1, minor) else: return twixt.Point(minor, major + 1)
def points_and_locs(): cum = 0.0 locations = [0.0] points = [] for x in range(1, twixt.Game.SIZE - 1): for y in range(twixt.Game.SIZE): point = twixt.Point(x, y) score = _point_score(point) weight = math.exp(math.log(0.5) * abs(score - 0.5) / _halflife) cum += weight locations.append(cum) points.append(point) return points, locations
def _init_front_bytes(self, b): if b[:self.HEADER_BYTES] != self.HEADER: raise ValueError("Header sanity error (%s)" % (b[:self.HEADER_BYTES])) self.recents = [] for i in range(self.NUM_RECENTS): x = ord(b[self.HEADER_BYTES + i * 2]) y = ord(b[self.HEADER_BYTES + i * 2 + 1]) if x == 255 and y == 255: continue if x >= twixt.Game.SIZE or y >= twixt.Game.SIZE: raise ValueError("Recent Point Error") self.recents.append(twixt.Point(x, y)) self._load_recents()
def _load_initial(self, override=False): self.cur.execute("SELECT COUNT(*) FROM first_move_v2 WHERE model_id=%d" % (self.model_id)) n = self.cur.fetchone()[0] if n: if override: self.cur.execute("DELETE FROM first_move_v2 WHERE model_id=%d" % (mself.model_id)) else: raise Exception("Rows already exist in first_move_v2") S = twixt.Game.SIZE M = S/2 for x in range(1,M): for y in range(M): p = twixt.Point(x, y) sql = "INSERT first_move_v2 (model_id, move, white, black, draws, visits) VALUES (%d, '%s', 0, 0, 0, 0)" % (self.model_id, str(p)) print "sql:", sql self.cur.execute(sql) self.conn.commit()
def get_init_moves(fmdb_lock=None): if args.moves: return args.moves elif args.first_moves: if fmdb_lock: fmdb_lock.acquire() init_moves = fmdb_.select_move(2) if fmdb_lock: fmdb_lock.release() print "next first move:", str(init_moves) return init_moves elif args.random_first_moves: x = random.randint(1, twixt.Game.SIZE//2) y = random.randint(0, twixt.Game.SIZE//2) init_moves = twixt.Point(x, y) print "random first move:", str(init_moves) return init_moves else: return None
def hflip(self): tmp = numpy.flip(self.naf, 0) S = twixt.Game.SIZE vix = twixt.Game.LINK_LONGY self.naf = numpy.zeros((S, S, 11), dtype=numpy.uint8) self.naf[:, :, 10] = tmp[:, :, 10] for color in range(2): self.naf[:, :, 8 + color] = tmp[:, :, 8 + color] for diffsign in range(2): dix = diffsign * twixt.Game.LINK_DIFFSIGN adix = (1 - diffsign) * twixt.Game.LINK_DIFFSIGN # non verticals are easy self.naf[:, :, color + dix] = tmp[:, :, color + adix] # verticals need to be shifted. self.naf[:-1, :, color + dix + vix] = tmp[1:, :, color + adix + vix] self.recents = [ twixt.Point(twixt.Game.SIZE - 1 - p.x, p.y) for p in self.recents ]
def _select_move(self, visit_count, verbose): self.cur.execute("SELECT move, white, black, draws, visits FROM first_move_v2 WHERE model_id=%d" % (self.model_id)) all_rows = list(self.cur.fetchall()) N = sum([x[4] for x in all_rows]) numerator = math.sqrt(2.0 * math.log(N + 1.0)) if verbose: print "N=", N, "numerator=", numerator verbose_rows = [] def row_util(row): move, white, black, draws, visits = row assert visits >= white + black + draws mean = (white + draws*0.5 + 0.5) / (1.0 + white + black + draws) if mean > 0.5: mean = 1.0 - mean util = mean + numerator / math.sqrt(1.0 + visits) if verbose: verbose_rows.append((move, white, black, draws, visits, visits-black-white-draws, mean, util)) # print "%s w=%d b=%d d=%d v=%d xv=%d mean=%5.2f%% util=%5.2f%%" % (str(move), white, black, draws, visits, visits-black-white-draws, mean*100, util*100) return util best_row = max(all_rows, key=row_util) move = best_row[0] self.cur.execute("UPDATE first_move_v2 SET visits=visits+%d WHERE move=\"%s\" AND model_id=%d" % (visit_count, move, self.model_id)) self.conn.commit() if verbose: n = 0 for row in sorted(verbose_rows, key=lambda x:x[7], reverse=True): if n % 20 == 0: print "%3s %5s %5s %5s %5s %3s %6s %6s" % ("mve", "white", "black", "draws", "visit", "xv", "mean", "util") n += 1 print "%3s %5d %5d %5d %5d %3d %6.2f %6.2f" % (str(row[0]), row[1], row[2], row[3], row[4], row[5], row[6]*100.0, row[7]*100.0) sys.stdout.flush() return twixt.Point(move)
def first_move_report(): points, locations = points_and_locs() cum = locations[-1] for i, p in enumerate(points): if p.x >= twixt.Game.SIZE // 2 or p.y >= twixt.Game.SIZE // 2: continue pct = 4.0 * (locations[i + 1] - locations[i]) / cum print "%3s %5.2f" % (str(p), pct * 100) def choose_first_move(): points, locations = points_and_locs() cum = locations[-1] z = random.uniform(0, cum) i = bisect.bisect(locations, z) if i == len(locations): i -= 1 return points[i] if __name__ == "__main__": if len(sys.argv) == 1: print choose_first_move() elif len(sys.argv) == 2 and sys.argv[1] == "all": first_move_report() elif len(sys.argv) == 2: p = twixt.Point(sys.argv[1]) print _point_score(p), want_swap(p)
if args.thinker: thinker = twixt.get_thinker(args.thinker, resources) tup = thinker.pick_move(game) if type(tup) == tuple: m, n = thinker.pick_move(game) else : m = tup # if m != "resign": # game.play(m) if args.think_report: _,rep = thinker.report.split("=") for m in rep.split(","): thinker_moves.append(twixt.Point(m)) print thinker.report if args.show_game_state: print "currently",game.COLOR_NAME[game.turn],"to play" if game.is_winning(game.BLACK): print "Black won" elif game.is_winning(game.WHITE): print "White won" else: count = 0 if not game.can_win(game.BLACK): print "Black cannot win" count += 1 if not game.can_win(game.WHITE): print "White cannot win"