def acceptReceived(self, player, offer): log.debug("ICGameModel.acceptReceived: accepter=%s %s" % (repr(player), offer)) if player.__type__ == LOCAL: GameModel.acceptReceived(self, player, offer) log.debug("ICGameModel.acceptReceived: connection.om.accept(%s)" % offer) self.connection.om.accept(offer)
def runGame(): a, b = findMatch() if a == None: print("All games have now been played. Here are the final scores:") printResults() mainloop.quit() return current[0] = a current[1] = b game = GameModel(TimeModel(minutes * 60, 0)) game.connect('game_started', cb_gamestarted) game.connect('game_ended', cb_gameended) p0 = discoverer.initPlayerEngine(engines[a], WHITE, 8, variants[NORMALCHESS], secs=minutes * 60, incr=0, forcePonderOff=True) p1 = discoverer.initPlayerEngine(engines[b], BLACK, 8, variants[NORMALCHESS], secs=minutes * 60, incr=0, forcePonderOff=True) game.setPlayers([p0, p1]) game.start()
def coro(variant): self.game = GameModel(TimeModel(60, 0), variant) self.game.setPlayers([self.p0, self.p1]) def on_game_end(game, state, event): event.set() event = asyncio.Event() self.game.connect("game_ended", on_game_end, event) self.p0.prestart() self.p1.prestart() if self.game.variant.need_initial_board: for player in self.game.players: player.setOptionInitialBoard(self.game) print(variant.name) self.game.start() yield from event.wait() pgn = StringIO() print(save(pgn, self.game)) self.assertIsNone(self.p0.invalid_move) self.assertIsNone(self.p1.invalid_move)
def coro(): gamemodel = GameModel(TimeModel(1, 0)) player0tup = (LOCAL, Human, (WHITE, "w"), "w") player1tup = (LOCAL, Human, (BLACK, "b"), "b") def on_game_end(game, state, event): event.set() event = asyncio.Event() gamemodel.connect("game_ended", on_game_end, event) def on_players_changed(game): # fill fools mate moves to players move queue p0 = game.players[0] p0.move_queue.put_nowait(Move(newMove(F2, F3))) p0.move_queue.put_nowait(Move(newMove(G2, G4))) p1 = gamemodel.players[1] p1.move_queue.put_nowait(Move(newMove(E7, E5))) p1.move_queue.put_nowait(Move(newMove(D8, H4))) gamemodel.connect("players_changed", on_players_changed) asyncio.async(self.games_persp.generalStart(gamemodel, player0tup, player1tup)) # waiting for game end ... yield from event.wait() fen = "rnb1kbnr/pppp1ppp/8/4p3/6Pq/5P2/PPPPP2P/RNBQKBNR w KQkq - 1 3" self.assertEqual(gamemodel.boards[-1].board.asFen(), fen) # Now save our game to pychess.pgn self.games_persp.saveGamePGN(gamemodel)
def loadToModel(self, rec, position, model=None): if not model: model = GameModel() if self.fen_is_string: rec = self.games[0] if isinstance(rec, dict) and "Variant" in rec: model.variant = FischerandomBoard fen = self.games[0]["FEN"] try: board = model.variant(setup=fen) model.tags["FEN"] = fen except SyntaxError as err: board = model.variant() raise LoadingError( _("The game can't be loaded, because of an error parsing FEN"), err.args[0], ) model.boards = [board] model.variations = [model.boards] model.moves = [] if model.status == WAITING_TO_START: status, reason = getStatus(model.boards[-1]) if status in (BLACKWON, WHITEWON, DRAW): model.status, model.reason = status, reason return model
def __init__(self, connection, ficsgame, timemodel): assert ficsgame.game_type in GAME_TYPES.values() GameModel.__init__(self, timemodel, ficsgame.game_type.variant) self.connection = connection self.ficsgame = ficsgame self.ficsplayers = (ficsgame.wplayer, ficsgame.bplayer) connections = self.connections connections[connection.bm].append( connection.bm.connect("boardUpdate", self.onBoardUpdate)) connections[connection.bm].append( connection.bm.connect("obsGameEnded", self.onGameEnded)) connections[connection.bm].append( connection.bm.connect("curGameEnded", self.onGameEnded)) connections[connection.bm].append( connection.bm.connect("gamePaused", self.onGamePaused)) connections[connection.om].append( connection.om.connect("onActionError", self.onActionError)) connections[connection].append( connection.connect("disconnected", self.onDisconnected)) rated = "rated" if ficsgame.rated else "unrated" # This is in the format that ficsgames.org writes these PGN headers self.tags["Event"] = "FICS %s %s game" % (rated, ficsgame.game_type.fics_name) self.tags["Site"] = "FICS"
def __init__ (self, connection, ficsgame, timemodel): assert ficsgame.game_type in GAME_TYPES.values() GameModel.__init__(self, timemodel, ficsgame.game_type.variant) self.connection = connection self.ficsgame = ficsgame self.ficsplayers = (ficsgame.wplayer, ficsgame.bplayer) self.gmwidg_ready = threading.Event() connections = self.connections connections[connection.bm].append(connection.bm.connect("boardUpdate", self.onBoardUpdate)) connections[connection.bm].append(connection.bm.connect("obsGameEnded", self.onGameEnded)) connections[connection.bm].append(connection.bm.connect("curGameEnded", self.onGameEnded)) connections[connection.bm].append(connection.bm.connect("gamePaused", self.onGamePaused)) connections[connection.bm].append(connection.bm.connect("madeExamined", self.onMadeExamined)) connections[connection.bm].append(connection.bm.connect("madeUnExamined", self.onMadeUnExamined)) connections[connection.om].append(connection.om.connect("onActionError", self.onActionError)) connections[connection.cm].append(connection.cm.connect("kibitzMessage", self.onKibitzMessage)) connections[connection.cm].append(connection.cm.connect("whisperMessage", self.onWhisperMessage)) connections[connection.cm].append(connection.cm.connect("observers_received", self.onObserversReceived)) connections[connection].append(connection.connect("disconnected", self.onDisconnected)) rated = "rated" if ficsgame.rated else "unrated" # This is in the format that ficsgames.org writes these PGN headers self.tags["Event"] = "FICS %s %s game" % (rated, ficsgame.game_type.fics_name) self.tags["Site"] = "freechess.org"
def row_activated(self, widget, path, col): if path is None: return pieces = ENDGAMES[path[0]][0] fen = self.create_fen(pieces) timemodel = TimeModel(0, 0) gamemodel = GameModel(timemodel) gamemodel.set_practice_game() name = conf.get("firstName", _("You")) p0 = (LOCAL, Human, (WHITE, name), name) engine = discoverer.getEngineByName(stockfish_name) name = discoverer.getName(engine) p1 = (ARTIFICIAL, discoverer.initPlayerEngine, (engine, BLACK, 20, variants[NORMALCHESS], 60, 0, 0, True), name) perspective = perspective_manager.get_perspective("games") asyncio. async (perspective.generalStart(gamemodel, p0, p1, loaddata=(StringIO(fen), fen_loader, 0, -1)))
def feed_book(self, records, positions): BOOK_DEPTH_MAX = conf.get("book_depth_max") for rec in records: model = GameModel() if rec["Result"] == DRAW: score = (1, 1) elif rec["Result"] == WHITEWON: score = (2, 0) elif rec["Result"] == BLACKWON: score = (0, 2) else: score = (0, 0) fenstr = rec["FEN"] variant = self.chessfile.get_variant(rec) if variant: model.variant = name2variant[variant] board = LBoard(model.variant.variant) else: model.variant = NormalBoard board = LBoard() if fenstr: try: board.applyFen(fenstr) except SyntaxError: continue else: board.applyFen(FEN_START) boards = [board] movetext = self.chessfile.get_movetext(rec) boards = self.chessfile.parse_movetext(movetext, boards[0], -1) for board in boards: if board.plyCount > BOOK_DEPTH_MAX: break move = board.lastMove if move is not None: poly_move = toPolyglot(board.prev, move) # move_str = "%s%s" % (reprCord[FCORD(move)], reprCord[TCORD(move)]) # print("%0.16x" % board.prev.hash, poly_move, board.prev.asFen(), move_str) if board.prev.hash in positions: if poly_move in positions[board.prev.hash]: positions[board.prev.hash][poly_move] += score[ board.prev.color ] else: positions[board.prev.hash][poly_move] = score[ board.prev.color ] else: # board.prev.asFen(), move_str, positions[board.prev.hash] = { poly_move: score[board.prev.color] }
def row_activated(self, widget, path, col): if path is None: return filename = addDataPrefix("lectures/%s" % LESSONS[path[0]][0]) chessfile = PGNFile(protoopen(filename)) self.importer = PgnImport(chessfile) chessfile.init_tag_database(self.importer) records, plys = chessfile.get_records() rec = records[random.randrange(0, len(records))] print(rec) timemodel = TimeModel(0, 0) gamemodel = GameModel(timemodel) gamemodel.set_lesson_game() chessfile.loadToModel(rec, -1, gamemodel) name = conf.get("firstName", _("You")) p0 = (LOCAL, Human, (WHITE, name), name) name = "pychessbot" p1 = (LOCAL, Human, (BLACK, name), name) gamemodel.status = WAITING_TO_START perspective = perspective_manager.get_perspective("games") asyncio. async (perspective.generalStart(gamemodel, p0, p1))
def terminate(self): for obj in self.connections: for handler_id in self.connections[obj]: if obj.handler_is_connected(handler_id): obj.disconnect(handler_id) self.connections = None GameModel.terminate(self)
def loadToModel(self, rec, position, model=None): if not model: model = GameModel() if "Variant" in rec: model.variant = FischerandomBoard fieldlist = rec["FEN"].split(" ") if len(fieldlist) == 4: fen = rec["FEN"] opcodestr = "" elif len(fieldlist) > 4: fen = " ".join(fieldlist[:4]) opcodestr = " ".join(fieldlist[4:]) else: raise LoadingError("EPD string can not have less than 4 field") opcodes = {} for opcode in map(str.strip, opcodestr.split(";")): space = opcode.find(" ") if space == -1: opcodes[opcode] = True else: opcodes[opcode[:space]] = opcode[space + 1:] if "hmvc" in opcodes: fen += " " + opcodes["hmvc"] else: fen += " 0" if "fmvn" in opcodes: fen += " " + opcodes["fmvn"] else: fen += " 1" model.boards = [model.variant(setup=fen)] model.variations = [model.boards] model.status = WAITING_TO_START # rc is kinda broken # if "rc" in opcodes: # model.boards[0].board.rc = int(opcodes["rc"]) if "resign" in opcodes: if fieldlist[1] == "w": model.status = BLACKWON else: model.status = WHITEWON model.reason = WON_RESIGN if model.status == WAITING_TO_START: status, reason = getStatus(model.boards[-1]) if status in (BLACKWON, WHITEWON, DRAW): model.status, model.reason = status, reason return model
def terminate(self): for obj in self.connections: for handler_id in self.connections[obj]: if obj.handler_is_connected(handler_id): obj.disconnect(handler_id) self.connections = None GameModel.terminate(self) if self.kibitz_task is not None: self.kibitz_task.cancel()
def loadToModel(self, gameno, position, model=None): if not model: model = GameModel() fieldlist = self.games[gameno].split(" ") if len(fieldlist) == 4: fen = self.games[gameno] opcodestr = "" elif len(fieldlist) > 4: fen = " ".join(fieldlist[:4]) opcodestr = " ".join(fieldlist[4:]) else: raise LoadingError("EPD string can not have less than 4 field") opcodes = {} for opcode in map(strip, opcodestr.split(";")): space = opcode.find(" ") if space == -1: opcodes[opcode] = True else: opcodes[opcode[:space]] = opcode[space + 1:] if "hmvc" in opcodes: fen += " " + opcodes["hmvc"] else: fen += " 0" if "fmvn" in opcodes: fen += " " + opcodes["fmvn"] else: fen += " 1" model.boards = [model.variant(setup=fen)] model.variations = [model.boards] model.status = WAITING_TO_START # rc is kinda broken # if "rc" in opcodes: # model.boards[0].board.rc = int(opcodes["rc"]) if "resign" in opcodes: if fieldlist[1] == "w": model.status = BLACKWON else: model.status = WHITEWON model.reason = WON_RESIGN if model.status == WAITING_TO_START: status, reason = getStatus(model.boards[-1]) if status in (BLACKWON, WHITEWON, DRAW): model.status, model.reason = status, reason return model
def loadToModel(self, rec, position, model=None): if not model: model = GameModel() if self.fen_is_string: rec = self.games[0] if isinstance(rec, dict) and "Variant" in rec: model.variant = FischerandomBoard fen = self.games[0]["FEN"] try: board = model.variant(setup=fen) model.tags["FEN"] = fen except SyntaxError as err: board = model.variant() raise LoadingError( _("The game can't be loaded, because of an error parsing FEN"), err.args[0]) model.boards = [board] model.variations = [model.boards] model.moves = [] if model.status == WAITING_TO_START: status, reason = getStatus(model.boards[-1]) if status in (BLACKWON, WHITEWON, DRAW): model.status, model.reason = status, reason return model
def end (self, status, reason): if self.status in UNFINISHED_STATES: self.__disconnect() if self.inControl: self.connection.om.offer(Offer(ABORT_OFFER), -1) self.connection.om.offer(Offer(RESIGNATION), -1) else: self.connection.bm.unobserve(self.gameno) GameModel.end(self, status, reason)
def end(self, status, reason): if self.status in UNFINISHED_STATES: self.__disconnect() if self.inControl: self.connection.om.offer(Offer(ABORT_OFFER), -1) self.connection.om.offer(Offer(RESIGNATION), -1) else: self.connection.bm.unobserve(self.gameno) GameModel.end(self, status, reason)
def end (self, status, reason): if self.status in UNFINISHED_STATES: self.__disconnect() if self.isObservationGame(): self.connection.bm.unobserve(self.ficsgame) else: self.connection.om.offer(Offer(ABORT_OFFER), -1) self.connection.om.offer(Offer(RESIGNATION), -1) GameModel.end(self, status, reason)
def __init__(self, gamelist): self.gamelist = gamelist self.filtered = False self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) selection = self.gamelist.get_selection() self.conid = selection.connect_after('changed', self.on_selection_changed) self.gamelist.preview_cid = self.conid # buttons toolbar = Gtk.Toolbar() firstButton = Gtk.ToolButton(Gtk.STOCK_MEDIA_PREVIOUS) toolbar.insert(firstButton, -1) prevButton = Gtk.ToolButton(Gtk.STOCK_MEDIA_REWIND) toolbar.insert(prevButton, -1) nextButton = Gtk.ToolButton(Gtk.STOCK_MEDIA_FORWARD) toolbar.insert(nextButton, -1) lastButton = Gtk.ToolButton(Gtk.STOCK_MEDIA_NEXT) toolbar.insert(lastButton, -1) filterButton = Gtk.ToggleToolButton(Gtk.STOCK_FIND) toolbar.insert(filterButton, -1) firstButton.connect("clicked", self.on_first_clicked) prevButton.connect("clicked", self.on_prev_clicked) nextButton.connect("clicked", self.on_next_clicked) lastButton.connect("clicked", self.on_last_clicked) filterButton.connect("clicked", self.on_filter_clicked) tool_box = Gtk.Box() tool_box.pack_start(toolbar, False, False, 0) # board self.gamemodel = GameModel() self.boardcontrol = BoardControl(self.gamemodel, {}, game_preview=True) self.boardview = self.boardcontrol.view self.boardview.set_size_request(170, 170) self.boardview.got_started = True self.boardview.auto_update_shown = False self.box.pack_start(self.boardcontrol, True, True, 0) self.box.pack_start(tool_box, False, True, 0) self.box.show_all() # force first game to show self.gamelist.set_cursor(0)
def start_lecture_game(self): timemodel = TimeModel(0, 0) gamemodel = GameModel(timemodel) gamemodel.set_offline_lecture() white_name = black_name = "pychessbot" p0 = (LOCAL, Human, (WHITE, white_name), white_name) p1 = (LOCAL, Human, (BLACK, black_name), black_name) perspective = perspective_manager.get_perspective("games") asyncio.async(perspective.generalStart(gamemodel, p0, p1)) return gamemodel
def feed_book(self, records, positions): for rec in records: model = GameModel() if rec["Result"] == DRAW: score = (1, 1) elif rec["Result"] == WHITEWON: score = (2, 0) elif rec["Result"] == BLACKWON: score = (0, 2) else: score = (0, 0) fenstr = rec["FEN"] variant = self.chessfile.get_variant(rec) if variant: model.variant = name2variant[variant] board = LBoard(model.variant.variant) else: model.variant = NormalBoard board = LBoard() if fenstr: try: board.applyFen(fenstr) except SyntaxError as err: continue else: board.applyFen(FEN_START) boards = [board] movetext = self.chessfile.get_movetext(rec) boards = self.chessfile.parse_movetext(movetext, boards[0], -1) for board in boards: if board.plyCount > BOOK_DEPTH: break move = board.lastMove if move is not None: poly_move = toPolyglot(board.prev, move) # move_str = "%s%s" % (reprCord[FCORD(move)], reprCord[TCORD(move)]) # print("%0.16x" % board.prev.hash, poly_move, board.prev.asFen(), move_str) if board.prev.hash in positions: if poly_move in positions[board.prev.hash]: positions[board.prev.hash][poly_move] += score[board.prev.color] else: positions[board.prev.hash][poly_move] = score[board.prev.color] else: # board.prev.asFen(), move_str, positions[board.prev.hash] = {poly_move: score[board.prev.color]}
def setPlayers(self, players): GameModel.setPlayers(self, players) if self.players[WHITE].icrating: self.tags["WhiteElo"] = self.players[WHITE].icrating if self.players[BLACK].icrating: self.tags["BlackElo"] = self.players[BLACK].icrating if (self.connection.username == self.ficsplayers[WHITE].name) and self.ficsplayers[WHITE].isGuest(): self.tags["White"] += " (Player)" self.emit("players_changed") if (self.connection.username == self.ficsplayers[BLACK].name) and self.ficsplayers[BLACK].isGuest(): self.tags["Black"] += " (Player)" self.emit("players_changed")
def __init__(self, connection, ficsgame, timemodel): assert ficsgame.game_type in GAME_TYPES.values() GameModel.__init__(self, timemodel, ficsgame.game_type.variant) self.connection = connection self.ficsgame = ficsgame self.ficsplayers = (ficsgame.wplayer, ficsgame.bplayer) self.gmwidg_ready = asyncio.Event() self.kibitz_task = None self.disconnected = False connections = self.connections connections[connection.bm].append( connection.bm.connect("boardSetup", self.onBoardSetup)) connections[connection.bm].append( connection.bm.connect("exGameReset", self.onExGameReset)) connections[connection.bm].append( connection.bm.connect("gameUndoing", self.onGameUndoing)) connections[connection.bm].append( connection.bm.connect("timesUpdate", self.onTimesUpdate)) connections[connection.bm].append( connection.bm.connect("obsGameEnded", self.onGameEnded)) connections[connection.bm].append( connection.bm.connect("curGameEnded", self.onGameEnded)) connections[connection.bm].append( connection.bm.connect("gamePaused", self.onGamePaused)) connections[connection.bm].append( connection.bm.connect("madeExamined", self.onMadeExamined)) connections[connection.bm].append( connection.bm.connect("madeUnExamined", self.onMadeUnExamined)) connections[connection.om].append( connection.om.connect("onActionError", self.onActionError)) connections[connection.cm].append( connection.cm.connect("kibitzMessage", self.onKibitzMessage)) connections[connection.cm].append( connection.cm.connect("whisperMessage", self.onWhisperMessage)) connections[connection.cm].append( connection.cm.connect("observers_received", self.onObserversReceived)) connections[connection].append( connection.connect("disconnected", self.onDisconnected)) rated = "rated" if ficsgame.rated else "unrated" # This is in the format that ficsgames.org writes these PGN headers ics = "ICC" if self.connection.ICC else "FICS" self.tags["Event"] = "%s %s %s game" % ( ics, rated, ficsgame.game_type.fics_name, ) self.tags[ "Site"] = "chessclub.com" if self.connection.ICC else "freechess.org"
def start(discoverer): pgnfile, gameno = queryGameno(sys.argv[1]) analyzer = queryAnalyzer(list(discoverer.getAnalyzers())) secs = queryTime() name1, name2 = pgnfile.get_player_names(gameno) print "%s will now analyze the game between %s and %s with %d seconds per move." % \ (discoverer.getName(analyzer), name1, name2, secs) print global game, values values = {} game = GameModel() game.setPlayers([DummyPlayer(), DummyPlayer()]) analyzer = discoverer.initAnalyzerEngine(analyzer, ANALYZING, game.variant) analyzer.connect('analyze', onAnalyze) game.setSpectactors({0: analyzer}) game.loadAndStart(sys.argv[1], pgn, gameno, -1) def cb(): if game.ply == game.lowply: on_finish() return False check_blund() return True glib.timeout_add_seconds(secs, cb)
def end(self, status, reason): if self.status in UNFINISHED_STATES: self.__disconnect() if self.isObservationGame(): self.connection.bm.unobserve(self.ficsgame) else: self.connection.om.offer(Offer(ABORT_OFFER), -1) self.connection.om.offer(Offer(RESIGNATION), -1) if status == KILLED: GameModel.kill(self, reason) else: GameModel.end(self, status, reason)
def loadToModel(self, gameno, position, model=None): if not model: model = GameModel() # We have to set full move number to 1 to make sure LBoard and GameModel # are synchronized. # fenlist = self.games[gameno].split(" ") # if len(fenlist) == 6: # fen = " ".join(fenlist[:5]) + " 1" fen = self.games[gameno] try: board = model.variant(setup=fen) except SyntaxError as err: board = model.variant() raise LoadingError( _("The game can't be loaded, because of an error parsing FEN"), err.args[0]) model.boards = [board] model.variations = [model.boards] model.moves = [] if model.status == WAITING_TO_START: status, reason = getStatus(model.boards[-1]) if status in (BLACKWON, WHITEWON, DRAW): model.status, model.reason = status, reason return model
def __init__ (self, connection, gameno, timemodel, variant, rated=False): GameModel.__init__(self, timemodel, variant) self.connection = connection self.gameno = gameno connections = self.connections connections[connection.bm].append(connection.bm.connect("boardUpdate", self.onBoardUpdate)) connections[connection.bm].append(connection.bm.connect("obsGameEnded", self.onGameEnded)) connections[connection.bm].append(connection.bm.connect("curGameEnded", self.onGameEnded)) connections[connection.bm].append(connection.bm.connect("gamePaused", self.onGamePaused)) connections[connection.om].append(connection.om.connect("onActionError", self.onActionError)) connections[connection].append(connection.connect("disconnected", self.onDisconnected)) self.inControl = True self.rated = rated
def do(discoverer): game = GameModel(TimeModel(60,0)) #game.connect('game_started', cb_gamestarted2) game.connect('game_ended', lambda *a: mainloop.quit()) p0 = discoverer.initPlayerEngine(discoverer.getEngines()['rybka'], WHITE, 7, variants[NORMALCHESS], 60) p1 = discoverer.initPlayerEngine(discoverer.getEngines()['gnuchess'], BLACK, 7, variants[NORMALCHESS], 60) game.setPlayers([p0,p1]) game.start()
def startClicked(self, button): color = self.widgets["colorDock"].get_child().get_active() if color == 2: color = random.choice([WHITE, BLACK]) opp = self.widgets["opponentDock"].get_child() tree_iter = opp.get_active_iter() if tree_iter is not None: model = opp.get_model() engine = model[tree_iter][1] opponent = self.widgets["opponentDock"].get_child().get_active() difficulty = int(self.widgets["skillSlider"].get_value()) gamemodel = GameModel(TimeModel(5 * 60, 0)) name = conf.get("firstName") player0tup = (LOCAL, Human, (color, name), name) if opponent == 0: name = conf.get("secondName") player1tup = (LOCAL, Human, (1 - color, name), name) else: engine = discoverer.getEngineByName(engine) name = discoverer.getName(engine) player1tup = (ARTIFICIAL, discoverer.initPlayerEngine, (engine, 1 - color, difficulty, variants[NORMALCHESS], 5 * 60, 0), name) perspective = perspective_manager.get_perspective("games") if color == WHITE: asyncio. async (perspective.generalStart(gamemodel, player0tup, player1tup)) else: asyncio. async (perspective.generalStart(gamemodel, player1tup, player0tup))
def row_activated(self, widget, path, col): print(self.modelsort.convert_path_to_child_path(path)[0]) game_id = self.liststore[self.modelsort.convert_path_to_child_path( path)[0]][0] print("game_id=%s" % game_id) gameno = self.id_list.index(game_id) print("gameno=%s" % gameno) gamemodel = GameModel() wp, bp = self.chessfile.get_player_names(gameno) p0 = (LOCAL, Human, (WHITE, wp), wp) p1 = (LOCAL, Human, (BLACK, bp), bp) self.chessfile.loadToModel(gameno, -1, gamemodel) gamemodel.status = WAITING_TO_START game_handler.generalStart(gamemodel, p0, p1)
def __repr__(self): string = GameModel.__repr__(self) string = string.replace("<GameModel", "<ICGameModel") fics_game = repr(self.ficsgame) string = string.replace(", players=", ", ficsgame=%s, players=" % fics_game) return string
def createRematch(gamemodel): """ If gamemodel contains only LOCAL or ARTIFICIAL players, this starts a new game, based on the info in gamemodel """ if gamemodel.timed: secs = gamemodel.timemodel.intervals[0][WHITE] gain = gamemodel.timemodel.gain else: secs = 0 gain = 0 newgamemodel = GameModel(TimeModel(secs, gain), variant=gamemodel.variant) wp = gamemodel.players[WHITE] bp = gamemodel.players[BLACK] if wp.__type__ == LOCAL: player1tup = (wp.__type__, wp.__class__, (BLACK, repr(wp)), repr(wp)) if bp.__type__ == LOCAL: player0tup = (bp.__type__, bp.__class__, (WHITE, repr(wp)), repr(bp)) else: engine = discoverer.getEngineByMd5(bp.md5) player0tup = (ARTIFICIAL, discoverer.initPlayerEngine, (engine, WHITE, bp.strength, gamemodel.variant, secs, gain), repr(bp)) else: player0tup = (bp.__type__, bp.__class__, (WHITE, repr(bp)), repr(bp)) engine = discoverer.getEngineByMd5(wp.md5) player1tup = (ARTIFICIAL, discoverer.initPlayerEngine, (engine, BLACK, wp.strength, gamemodel.variant, secs, gain), repr(wp)) ionest.generalStart(newgamemodel, player0tup, player1tup)
def startClicked(self, button): color = self.widgets["colorDock"].get_child().active if color == 2: color = random.choice([WHITE, BLACK]) opponent = self.widgets["opponentDock"].get_child().active difficulty = int(self.widgets["skillSlider"].get_value()) gamemodel = GameModel(TimeModel(5 * 60, 0)) name = conf.get("firstName", _("You")) player0tup = (LOCAL, Human, (color, name), name) if opponent == 0: name = conf.get("secondName", _("Guest")) player1tup = (LOCAL, Human, (1 - color, name), name) else: engine = discoverer.getEngineN(opponent - 1) name = discoverer.getName(engine) player1tup = (ARTIFICIAL, discoverer.initPlayerEngine, (engine, 1 - color, difficulty, variants[NORMALCHESS], 5 * 60, 0), name) if color == WHITE: game_handler.generalStart(gamemodel, player0tup, player1tup) else: game_handler.generalStart(gamemodel, player1tup, player0tup)
def row_activated(self, widget, path, col): rec, ply = self.get_record(path) if rec is None: return # Enable unfinished games to continue from newgamedialog if rec["Result"] not in UNDOABLE_STATES: newGameDialog.EnterNotationExtension.run() model = self.persp.chessfile.loadToModel(rec) text = pgn.save(StringIO(), model) newGameDialog.EnterNotationExtension.sourcebuffer.set_text(text) return self.gamemodel = GameModel() variant = rec["Variant"] if variant: self.gamemodel.tags["Variant"] = variant # Lichess exports study .pgn without White and Black tags wp = "" if rec["White"] is None else rec["White"] bp = "" if rec["Black"] is None else rec["Black"] p0 = (LOCAL, Human, (WHITE, wp), wp) p1 = (LOCAL, Human, (BLACK, bp), bp) self.persp.chessfile.loadToModel(rec, -1, self.gamemodel) self.gamemodel.endstatus = (self.gamemodel.status if self.gamemodel.status in UNDOABLE_STATES else None) self.gamemodel.status = WAITING_TO_START perspective_manager.activate_perspective("games") perspective = perspective_manager.get_perspective("games") create_task(perspective.generalStart(self.gamemodel, p0, p1))
def loadToModel (self, gameno, position, model=None): if not model: model = GameModel() # We have to set full move number to 1 to make sure LBoard and GameModel # are synchronized. #fenlist = self.games[gameno].split(" ") #if len(fenlist) == 6: # fen = " ".join(fenlist[:5]) + " 1" fen = self.games[gameno] model.boards = [model.variant.board(setup=fen)] model.variations = [model.boards] if model.status == WAITING_TO_START: model.status, model.reason = getStatus(model.boards[-1]) return model
def showDesignGW(): global designGW designGW = GameWidget(GameModel()) if isDesignGWShown(): return getWidgets()["show_sidepanels"].set_active(True) getWidgets()["show_sidepanels"].set_sensitive(False) attachGameWidget(designGW)
def end(self, status, reason): if self.examined: self.connection.bm.unexamine() if self.status in UNFINISHED_STATES: self.__disconnect() if self.isObservationGame(): self.connection.bm.unobserve(self.ficsgame) else: self.connection.om.offer(Offer(ABORT_OFFER)) self.connection.om.offer(Offer(RESIGNATION)) if status == KILLED: GameModel.kill(self, reason) else: GameModel.end(self, status, reason)
def loadPgnAndRun(data): if data in [None, '']: return False perspective = perspective_manager.get_perspective("games") p0 = (LOCAL, Human, (WHITE, _("White")), _("White")) p1 = (LOCAL, Human, (BLACK, _("Black")), _("Black")) create_task(perspective.generalStart(GameModel(), p0, p1, (StringIO(data), enddir['pgn'], 0, -1))) return True
def __init__(self, connection, ficsgame, timemodel): assert ficsgame.game_type in GAME_TYPES.values() GameModel.__init__(self, timemodel, ficsgame.game_type.variant) self.connection = connection self.ficsgame = ficsgame self.ficsplayers = (ficsgame.wplayer, ficsgame.bplayer) self.gmwidg_ready = asyncio.Event() self.kibitz_task = None self.disconnected = False connections = self.connections connections[connection.bm].append(connection.bm.connect( "boardSetup", self.onBoardSetup)) connections[connection.bm].append(connection.bm.connect( "exGameReset", self.onExGameReset)) connections[connection.bm].append(connection.bm.connect( "gameUndoing", self.onGameUndoing)) connections[connection.bm].append(connection.bm.connect( "timesUpdate", self.onTimesUpdate)) connections[connection.bm].append(connection.bm.connect( "obsGameEnded", self.onGameEnded)) connections[connection.bm].append(connection.bm.connect( "curGameEnded", self.onGameEnded)) connections[connection.bm].append(connection.bm.connect( "gamePaused", self.onGamePaused)) connections[connection.bm].append(connection.bm.connect( "madeExamined", self.onMadeExamined)) connections[connection.bm].append(connection.bm.connect( "madeUnExamined", self.onMadeUnExamined)) connections[connection.om].append(connection.om.connect( "onActionError", self.onActionError)) connections[connection.cm].append(connection.cm.connect( "kibitzMessage", self.onKibitzMessage)) connections[connection.cm].append(connection.cm.connect( "whisperMessage", self.onWhisperMessage)) connections[connection.cm].append(connection.cm.connect( "observers_received", self.onObserversReceived)) connections[connection].append(connection.connect("disconnected", self.onDisconnected)) rated = "rated" if ficsgame.rated else "unrated" # This is in the format that ficsgames.org writes these PGN headers ics = "ICC" if self.connection.ICC else "FICS" self.tags["Event"] = "%s %s %s game" % (ics, rated, ficsgame.game_type.fics_name) self.tags["Site"] = "chessclub.com" if self.connection.ICC else "freechess.org"
def loadToModel(self, gameno, position, model=None): if not model: model = GameModel() # We have to set full move number to 1 to make sure LBoard and GameModel # are synchronized. #fenlist = self.games[gameno].split(" ") #if len(fenlist) == 6: # fen = " ".join(fenlist[:5]) + " 1" fen = self.games[gameno] try: board = model.variant(setup=fen) except SyntaxError as err: board = model.variant() raise LoadingError( _("The game can't be loaded, because of an error parsing FEN"), err.args[0]) model.boards = [board] model.variations = [model.boards] model.moves = [] if model.status == WAITING_TO_START: status, reason = getStatus(model.boards[-1]) if status in (BLACKWON, WHITEWON, DRAW): model.status, model.reason = status, reason return model
def showDesignGW(): global designGW perspective = perspective_manager.get_perspective("games") designGW = GameWidget(GameModel(), perspective) if isDesignGWShown(): return getWidgets()["show_sidepanels"].set_active(True) getWidgets()["show_sidepanels"].set_sensitive(False) perspective.attachGameWidget(designGW)
def __init__(self, connection, ficsgame, timemodel): assert ficsgame.game_type in GAME_TYPES.values() GameModel.__init__(self, timemodel, ficsgame.game_type.variant) self.connection = connection self.ficsgame = ficsgame self.ficsplayers = (ficsgame.wplayer, ficsgame.bplayer) connections = self.connections connections[connection.bm].append(connection.bm.connect("boardUpdate", self.onBoardUpdate)) connections[connection.bm].append(connection.bm.connect("obsGameEnded", self.onGameEnded)) connections[connection.bm].append(connection.bm.connect("curGameEnded", self.onGameEnded)) connections[connection.bm].append(connection.bm.connect("gamePaused", self.onGamePaused)) connections[connection.om].append(connection.om.connect("onActionError", self.onActionError)) connections[connection].append(connection.connect("disconnected", self.onDisconnected)) rated = "rated" if ficsgame.rated else "unrated" # This is in the format that ficsgames.org writes these PGN headers self.tags["Event"] = "FICS %s %s game" % (rated, ficsgame.game_type.fics_name) self.tags["Site"] = "FICS"
def runGame(): a, b = findMatch() if a == None: print("All games have now been played. Here are the final scores:") printResults() mainloop.quit() return current[0] = a current[1] = b game = GameModel(TimeModel(minutes*60,0)) game.connect('game_started', cb_gamestarted) game.connect('game_ended', cb_gameended) p0 = discoverer.initPlayerEngine(engines[a], WHITE, 8, variants[NORMALCHESS], secs=minutes*60, incr=0, forcePonderOff=True) p1 = discoverer.initPlayerEngine(engines[b], BLACK, 8, variants[NORMALCHESS], secs=minutes*60, incr=0, forcePonderOff=True) game.setPlayers([p0,p1]) game.start()
def setPlayers (self, players): if [player.__type__ for player in players] == [REMOTE, REMOTE]: self.inControl = False GameModel.setPlayers(self, players)
class CECPTests(unittest.TestCase): def setUp(self): self.engine = discoverer.getEngineByName("PyChess.py") def test(self): """ Play PyChess-PyChess 1 min variant games """ if sys.platform == "win32": from asyncio.windows_events import ProactorEventLoop loop = ProactorEventLoop() asyncio.set_event_loop(loop) else: loop = asyncio.SelectorEventLoop() asyncio.set_event_loop(loop) loop = asyncio.get_event_loop() loop.set_debug(enabled=True) for vari in PYCHESS_VARIANTS: variant = variants[vari] def coro(): self.p0 = yield from discoverer.initEngine(self.engine, WHITE, False) self.p1 = yield from discoverer.initEngine(self.engine, BLACK, False) loop.run_until_complete(coro()) def optionsCallback(engine): engine.setOptionVariant(variant) engine.setOptionStrength(1, False) engine.setOptionTime(60, 0, 0) self.p0.connect("readyForOptions", optionsCallback) self.p1.connect("readyForOptions", optionsCallback) def coro(variant): self.game = GameModel(TimeModel(60, 0), variant) self.game.setPlayers([self.p0, self.p1]) def on_game_end(game, state, event): event.set() event = asyncio.Event() self.game.connect("game_ended", on_game_end, event) self.p0.prestart() self.p1.prestart() if self.game.variant.need_initial_board: for player in self.game.players: player.setOptionInitialBoard(self.game) print(variant.name) self.game.start() yield from event.wait() pgn = StringIO() print(save(pgn, self.game)) self.assertIsNone(self.p0.invalid_move) self.assertIsNone(self.p1.invalid_move) loop.run_until_complete(coro(variant))
def setPlayers (self, players): GameModel.setPlayers(self, players) if self.players[WHITE].icrating: self.tags["WhiteElo"] = self.players[WHITE].icrating if self.players[BLACK].icrating: self.tags["BlackElo"] = self.players[BLACK].icrating
def loadToModel(self, rec, position=-1, model=None): """ Parse game text and load game record header tags to a GameModel object """ if not model: model = GameModel() if self.pgn_is_string: rec = self.games[0] game_date = rec["Date"] result = rec["Result"] variant = rec["Variant"] else: game_date = self.get_date(rec) result = reprResult[rec["Result"]] variant = self.get_variant(rec) # the seven mandatory PGN headers model.tags['Event'] = rec["Event"] model.tags['Site'] = rec["Site"] model.tags['Date'] = game_date model.tags['Round'] = rec["Round"] model.tags['White'] = rec["White"] model.tags['Black'] = rec["Black"] model.tags['Result'] = result if model.tags['Date']: date_match = re.match(".*(\d{4}).(\d{2}).(\d{2}).*", model.tags['Date']) if date_match: year, month, day = date_match.groups() model.tags['Year'] = year model.tags['Month'] = month model.tags['Day'] = day # non-mandatory tags for tag in ('Annotator', 'ECO', 'WhiteElo', 'BlackElo', 'TimeControl'): value = rec[tag] if value: model.tags[tag] = value else: model.tags[tag] = "" if not self.pgn_is_string: model.info = self.tag_database.get_info(rec) if model.tags['TimeControl']: secs, gain = parseTimeControlTag(model.tags['TimeControl']) model.timed = True model.timemodel.secs = secs model.timemodel.gain = gain model.timemodel.minutes = secs / 60 for tag, color in (('WhiteClock', WHITE), ('BlackClock', BLACK)): if hasattr(rec, tag): try: millisec = parseClockTimeTag(rec[tag]) # We need to fix when FICS reports negative clock time like this # [TimeControl "180+0"] # [WhiteClock "0:00:15.867"] # [BlackClock "23:59:58.820"] start_sec = ( millisec - 24 * 60 * 60 * 1000 ) / 1000. if millisec > 23 * 60 * 60 * 1000 else millisec / 1000. model.timemodel.intervals[color][0] = start_sec except ValueError: raise LoadingError( "Error parsing '%s'" % tag) fenstr = rec["FEN"] if variant: if variant not in name2variant: raise LoadingError("Unknown variant %s" % variant) model.tags["Variant"] = variant # Fixes for some non statndard Chess960 .pgn if (fenstr is not None) and variant == "Fischerandom": parts = fenstr.split() parts[0] = parts[0].replace(".", "/").replace("0", "") if len(parts) == 1: parts.append("w") parts.append("-") parts.append("-") fenstr = " ".join(parts) model.variant = name2variant[variant] board = LBoard(model.variant.variant) else: model.variant = NormalBoard board = LBoard() if fenstr: try: board.applyFen(fenstr) except SyntaxError as err: board.applyFen(FEN_EMPTY) raise LoadingError( _("The game can't be loaded, because of an error parsing FEN"), err.args[0]) else: board.applyFen(FEN_START) boards = [board] del model.moves[:] del model.variations[:] self.error = None movetext = self.get_movetext(rec) boards = self.parse_movetext(movetext, boards[0], position) # The parser built a tree of lboard objects, now we have to # create the high level Board and Move lists... for board in boards: if board.lastMove is not None: model.moves.append(Move(board.lastMove)) self.has_emt = False self.has_eval = False def walk(model, node, path): if node.prev is None: # initial game board board = model.variant(setup=node.asFen(), lboard=node) else: move = Move(node.lastMove) try: board = node.prev.pieceBoard.move(move, lboard=node) except: raise LoadingError( _("Invalid move."), "%s%s" % (move_count(node, black_periods=True), move)) if node.next is None: model.variations.append(path + [board]) else: walk(model, node.next, path + [board]) for child in node.children: if isinstance(child, list): if len(child) > 1: # non empty variation, go walk walk(model, child[1], list(path)) else: if not self.has_emt: self.has_emt = child.find("%emt") >= 0 if not self.has_eval: self.has_eval = child.find("%eval") >= 0 # Collect all variation paths into a list of board lists # where the first one will be the boards of mainline game. # model.boards will allways point to the current shown variation # which will be model.variations[0] when we are in the mainline. walk(model, boards[0], []) model.boards = model.variations[0] self.has_emt = self.has_emt and "TimeControl" in model.tags if self.has_emt or self.has_eval: if self.has_emt: blacks = len(model.moves) // 2 whites = len(model.moves) - blacks model.timemodel.intervals = [ [model.timemodel.intervals[0][0]] * (whites + 1), [model.timemodel.intervals[1][0]] * (blacks + 1), ] secs, gain = parseTimeControlTag(model.tags['TimeControl']) model.timemodel.intervals[0][0] = secs model.timemodel.intervals[1][0] = secs for ply, board in enumerate(boards): for child in board.children: if isinstance(child, str): if self.has_emt: match = movetime.search(child) if match: movecount, color = divmod(ply + 1, 2) hour, minute, sec, msec = match.groups() prev = model.timemodel.intervals[color][ movecount - 1] hour = 0 if hour is None else int(hour[:-1]) minute = 0 if minute is None else int(minute[:-1]) msec = 0 if msec is None else int(msec) msec += int(sec) * 1000 + int( minute) * 60 * 1000 + int( hour) * 60 * 60 * 1000 model.timemodel.intervals[color][ movecount] = prev - msec / 1000. + gain if self.has_eval: match = moveeval.search(child) if match: sign, num, fraction, depth = match.groups() sign = 1 if sign is None or sign == "+" else -1 num = int(num) if int( num) == MATE_VALUE else int(num) fraction = 0 if fraction is None else int( fraction) value = sign * (num * 100 + fraction) depth = "" if depth is None else depth if board.color == BLACK: value = -value model.scores[ply] = ("", value, depth) log.debug("pgn.loadToModel: intervals %s" % model.timemodel.intervals) # Find the physical status of the game model.status, model.reason = getStatus(model.boards[-1]) # Apply result from .pgn if the last position was loaded if position == -1 or len(model.moves) == position - model.lowply: status = rec["Result"] if status in (WHITEWON, BLACKWON) and status != model.status: model.status = status model.reason = WON_RESIGN elif status == DRAW and status != model.status: model.status = DRAW model.reason = DRAW_AGREE # If parsing gave an error we throw it now, to enlarge our possibility # of being able to continue the game from where it failed. if self.error: raise self.error return model
def __repr__ (self): s = GameModel.__repr__(self) s = s.replace("<GameModel", "<ICGameModel") fg = repr(self.ficsgame) s = s.replace(", players=", ", ficsgame=%s, players=" % fg) return s
def loadToModel (self, gameno, position=-1, model=None, quick_parse=True): if not model: model = GameModel() model.tags['Event'] = self._getTag(gameno, 'Event') model.tags['Site'] = self._getTag(gameno, 'Site') model.tags['Date'] = self._getTag(gameno, 'Date') model.tags['Round'] = self._getTag(gameno, 'Round') model.tags['White'], model.tags['Black'] = self.get_player_names(gameno) model.tags['WhiteElo'] = self._getTag(gameno, 'WhiteElo') model.tags['BlackElo'] = self._getTag(gameno, 'BlackElo') model.tags['Result'] = reprResult[self.get_result(gameno)] model.tags['ECO'] = self._getTag(gameno, "ECO") fenstr = self._getTag(gameno, "FEN") variant = self._getTag(gameno, "Variant") if variant and ("fischer" in variant.lower() or "960" in variant): from pychess.Variants.fischerandom import FRCBoard model.variant = FischerRandomChess model.boards = [FRCBoard(fenstr)] else: if fenstr: model.boards = [Board(fenstr)] else: model.boards = [Board(setup=True)] del model.moves[:] model.status = WAITING_TO_START model.reason = UNKNOWN_REASON error = None if quick_parse: movstrs = self._getMoves (gameno) for i, mstr in enumerate(movstrs): if position != -1 and model.ply >= position: break try: move = parseAny (model.boards[-1], mstr) except ParsingError, e: notation, reason, boardfen = e.args ply = model.boards[-1].ply if ply % 2 == 0: moveno = "%d." % (i/2+1) else: moveno = "%d..." % (i/2+1) errstr1 = _("The game can't be read to end, because of an error parsing move %(moveno)s '%(notation)s'.") % { 'moveno': moveno, 'notation': notation} errstr2 = _("The move failed because %s.") % reason error = LoadingError (errstr1, errstr2) break model.moves.append(move) model.boards.append(model.boards[-1].move(move))
def loadToModel(self, rec, position, model=None): if not model: model = GameModel() model.tags['Event'] = rec["Event"] model.tags['Site'] = rec["Site"] model.tags['Date'] = self.get_date(rec) model.tags['Round'] = "" model.tags['White'] = "?" model.tags['Black'] = "?" model.tags['Termination'] = rec["Termination"] fen = rec["FEN"] model.boards = [model.variant(setup=fen)] model.variations = [model.boards] model.status = WAITING_TO_START return model
def loadToModel (self, gameno, position=-1, model=None): if not model: model = GameModel() # the seven mandatory PGN headers model.tags['Event'] = self._getTag(gameno, 'Event') model.tags['Site'] = self._getTag(gameno, 'Site') model.tags['Date'] = self._getTag(gameno, 'Date') model.tags['Round'] = self.get_round(gameno) model.tags['White'], model.tags['Black'] = self.get_player_names(gameno) model.tags['Result'] = reprResult[self.get_result(gameno)] pgnHasYearMonthDay = True for tag in ('Year', 'Month', 'Day'): if not self._getTag(gameno, tag): pgnHasYearMonthDay = False break if model.tags['Date'] and not pgnHasYearMonthDay: date_match = re.match(".*(\d{4}).(\d{2}).(\d{2}).*", model.tags['Date']) if date_match: year, month, day = date_match.groups() model.tags['Year'] = year model.tags['Month'] = month model.tags['Day'] = day # non-mandatory headers for tag in ('Annotator', 'ECO', 'EventDate', 'Time', 'WhiteElo', 'BlackElo', 'TimeControl'): if self._getTag(gameno, tag): model.tags[tag] = self._getTag(gameno, tag) else: model.tags[tag] = "" # TODO: enable this when NewGameDialog is altered to give user option of # whether to use PGN's clock time, or their own custom time. Also, # dialog should set+insensitize variant based on the variant of the # game selected in the dialog if model.tags['TimeControl']: secs, gain = parseTimeControlTag(model.tags['TimeControl']) model.timed = True model.timemodel.secs = secs model.timemodel.gain = gain model.timemodel.minutes = secs / 60 for tag, color in (('WhiteClock', WHITE), ('BlackClock', BLACK)): if self._getTag(gameno, tag): try: ms = parseClockTimeTag(self._getTag(gameno, tag)) model.timemodel.intervals[color][0] = ms / 1000 except ValueError: raise LoadingError( \ "Error parsing '%s' Header for gameno %s" % (tag, gameno)) fenstr = self._getTag(gameno, "FEN") variant = self.get_variant(gameno) if variant: model.tags["Variant"] = variant # Fixes for some non statndard Chess960 .pgn if (fenstr is not None) and variant == "Fischerandom": parts = fenstr.split() parts[0] = parts[0].replace(".", "/").replace("0", "") if len(parts) == 1: parts.append("w") parts.append("-") parts.append("-") fenstr = " ".join(parts) model.variant = name2variant[variant] board = LBoard(model.variant.variant) else: model.variant = NormalBoard board = LBoard() if fenstr: try: board.applyFen(fenstr) except SyntaxError as e: board.applyFen(FEN_EMPTY) raise LoadingError(_("The game can't be loaded, because of an error parsing FEN"), e.args[0]) else: board.applyFen(FEN_START) boards = [board] del model.moves[:] del model.variations[:] self.error = None movetext = self.get_movetext(gameno) boards = self.parse_string(movetext, boards[0], position) # The parser built a tree of lboard objects, now we have to # create the high level Board and Move lists... for board in boards: if board.lastMove is not None: model.moves.append(Move(board.lastMove)) self.has_emt = False self.has_eval = False def walk(node, path): if node.prev is None: # initial game board board = model.variant(setup=node.asFen(), lboard=node) else: move = Move(node.lastMove) try: board = node.prev.pieceBoard.move(move, lboard=node) except: raise LoadingError(_("Invalid move."), "%s%s" % (move_count(node, black_periods=True), move)) if node.next is None: model.variations.append(path+[board]) else: walk(node.next, path+[board]) for child in node.children: if isinstance(child, list): if len(child) > 1: # non empty variation, go walk walk(child[1], list(path)) else: if not self.has_emt: self.has_emt = child.find("%emt") >= 0 if not self.has_eval: self.has_eval = child.find("%eval") >= 0 # Collect all variation paths into a list of board lists # where the first one will be the boards of mainline game. # model.boards will allways point to the current shown variation # which will be model.variations[0] when we are in the mainline. walk(boards[0], []) model.boards = model.variations[0] self.has_emt = self.has_emt and "TimeControl" in model.tags if self.has_emt or self.has_eval: if self.has_emt: blacks = len(model.moves)//2 whites = len(model.moves)-blacks model.timemodel.intervals = [ [model.timemodel.intervals[0][0]]*(whites+1), [model.timemodel.intervals[1][0]]*(blacks+1), ] secs, gain = parseTimeControlTag(model.tags['TimeControl']) model.timemodel.intervals[0][0] = secs model.timemodel.intervals[1][0] = secs for ply, board in enumerate(boards): for child in board.children: if isinstance(child, basestring): if self.has_emt: match = movetime.search(child) if match: movecount, color = divmod(ply+1, 2) hour, minute, sec, msec = match.groups() prev = model.timemodel.intervals[color][movecount-1] msec = 0 if msec is None else int(msec) msec += int(sec)*1000 + int(minute)*60*1000 + int(hour)*60*60*1000 model.timemodel.intervals[color][movecount] = prev - msec/1000 if self.has_eval: match = moveeval.search(child) if match: sign, num, fraction, depth = match.groups() sign = 1 if sign is None or sign == "+" else -1 num = int(num) if int(num) == MATE_VALUE else int(num) fraction = 0 if fraction is None else float(fraction)/100 value = sign * (num + fraction) depth = "" if depth is None else depth model.scores[ply] = ("", value, depth) log.debug("pgn.loadToModel: intervals %s" % model.timemodel.intervals) # Find the physical status of the game model.status, model.reason = getStatus(model.boards[-1]) # Apply result from .pgn if the last position was loaded if position == -1 or len(model.moves) == position - model.lowply: status = self.get_result(gameno) if status in (WHITEWON, BLACKWON) and status != model.status: model.status = status model.reason = WON_RESIGN elif status == DRAW and status != model.status: model.status = DRAW model.reason = DRAW_AGREE # If parsing gave an error we throw it now, to enlarge our possibility # of being able to continue the game from where it failed. if self.error: raise self.error return model