def analyse_moves(): should_black = conf.get("shouldBlack", True) should_white = conf.get("shouldWhite", True) from_current = conf.get("fromCurrent", True) start_ply = gmwidg.board.view.shown if from_current else 0 move_time = int(conf.get("max_analysis_spin", 3)) threshold = int(conf.get("variation_threshold_spin", 50)) for board in gamemodel.boards[start_ply:]: if stop_event.is_set(): break @idle_add def do(): gmwidg.board.view.setShownBoard(board) do() analyzer.setBoard(board) if threat_PV: inv_analyzer.setBoard(board) time.sleep(move_time + 0.1) ply = board.ply color = (ply - 1) % 2 if ply - 1 in gamemodel.scores and ply in gamemodel.scores and ( (color == BLACK and should_black) or (color == WHITE and should_white)): oldmoves, oldscore, olddepth = gamemodel.scores[ply - 1] oldscore = oldscore * -1 if color == BLACK else oldscore score_str = prettyPrintScore(oldscore, olddepth) moves, score, depth = gamemodel.scores[ply] score = score * -1 if color == WHITE else score diff = score - oldscore if (diff > threshold and color == BLACK) or (diff < -1 * threshold and color == WHITE): if threat_PV: try: if ply - 1 in gamemodel.spy_scores: oldmoves0, oldscore0, olddepth0 = gamemodel.spy_scores[ply - 1] score_str0 = prettyPrintScore(oldscore0, olddepth0) pv0 = listToMoves(gamemodel.boards[ply - 1], ["--"] + oldmoves0, validate=True) if len(pv0) > 2: gamemodel.add_variation(gamemodel.boards[ply - 1], pv0, comment="Treatening", score=score_str0) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" % (' '.join(oldmoves), e)) try: pv = listToMoves(gamemodel.boards[ply - 1], oldmoves, validate=True) gamemodel.add_variation(gamemodel.boards[ply - 1], pv, comment="Better is", score=score_str) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" % (' '.join(oldmoves), e)) widgets["analyze_game"].hide() widgets["analyze_ok_button"].set_sensitive(True) conf.set("analyzer_check", old_check_value) if threat_PV: conf.set("inv_analyzer_check", old_inv_check_value) message.dismiss()
def on_analyze(self, engine, analysis): if self.boardview.animating: return if self.boardview.model.isPlayingICSGame(): return if not self.active: return is_FAN = conf.get("figuresInNotation", False) for i, line in enumerate(analysis): if line is None: self.store[self.path + (i, )] = self.textOnlyRow("") continue board0 = self.engine.board board = board0.clone() movstrs, score, depth = line try: pv = listToMoves(board, movstrs, validate=True) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" % (' '.join(movstrs), e)) return except: return move = None if pv: move = pv[0] ply0 = board.ply if self.mode == HINT else board.ply + 1 counted_pv = [] for j, pvmove in enumerate(pv): ply = ply0 + j if ply % 2 == 0: mvcount = "%d." % (ply / 2 + 1) elif j == 0: mvcount = "%d..." % (ply / 2 + 1) else: mvcount = "" counted_pv.append("%s%s" % (mvcount, toFAN(board, pvmove) if is_FAN else toSAN(board, pvmove, True))) board = board.move(pvmove) goodness = (min(max(score, -250), 250) + 250) / 500.0 if self.engine.board.color == BLACK: score = -score self.store[self.path + (i, )] = [ (board0, move, pv), (prettyPrintScore(score, depth), 1, goodness), 0, False, " ".join(counted_pv), False, False ]
def insert_nodes(self, board, level=0, parent=None, result=None): """ Recursively builds the node tree """ end_iter = self.textbuffer.get_end_iter # Convenience shortcut to the function while True: start = end_iter().get_offset() if board is None: break # Initial game or variation comment if board.prev is None: for index, child in enumerate(board.children): if isinstance(child, basestring): if 0: # TODO board.plyCount == self.gamemodel.lowply: self.insert_comment(child + "\n", board, index, parent, level) else: self.insert_comment(child, board, index, parent, level) board = board.next continue if board.fen_was_applied: self.insert_node(board, end_iter(), -1, level, parent) if self.showEmt and level == 0 and board.fen_was_applied and self.gamemodel.timemodel.hasTimes: elapsed = self.gamemodel.timemodel.getElapsedMoveTime(board.plyCount - self.gamemodel.lowply) self.textbuffer.insert_with_tags_by_name(end_iter(), "%s " % formatTime(elapsed), "emt") if self.showEval and level == 0 and board.fen_was_applied and board.plyCount in self.gamemodel.scores: moves, score, depth = self.gamemodel.scores[board.plyCount] score = score * -1 if board.color == BLACK else score endIter = self.textbuffer.get_iter_at_offset(end_iter().get_offset()) self.textbuffer.insert_with_tags_by_name(end_iter(), "%s " % prettyPrintScore(score, depth), "emt") for index, child in enumerate(board.children): if isinstance(child, basestring): # comment self.insert_comment(child, board, index, parent, level) else: # variation diff, opening_node = self.variation_start(end_iter(), -1, level) self.insert_nodes(child[0], level+1, parent=board) self.variation_end(end_iter(), -1, level, child[1], board, opening_node) if board.next: board = board.next else: break if result and result != "*": self.textbuffer.insert_with_tags_by_name(end_iter(), " "+result, "move")
def analysis_changed(self, gamemodel, ply): if self.boardview.animating: return if not self.boardview.shownIsMainLine(): return board = gamemodel.getBoardAtPly(ply).board node = None if self.showEval or self.showBlunder: for n in self.nodelist: if n["board"] == board: start = self.textbuffer.get_iter_at_offset(n["start"]) end = self.textbuffer.get_iter_at_offset(n["end"]) node = n break if node is None: return if self.showBlunder: self.colorize_node(ply, start, end) emt_eval = "" if self.showEmt and self.gamemodel.timemodel.hasTimes: elapsed = gamemodel.timemodel.getElapsedMoveTime(board.plyCount - gamemodel.lowply) emt_eval = "%s " % formatTime(elapsed) if self.showEval: if board.plyCount in gamemodel.scores: moves, score, depth = gamemodel.scores[board.plyCount] score = score * -1 if board.color == BLACK else score emt_eval += "%s " % prettyPrintScore(score, depth) if emt_eval: if node == self.nodelist[-1]: next_node = None self.textbuffer.delete(end, self.textbuffer.get_end_iter()) else: next_node = self.nodelist[self.nodelist.index(node) + 1] next_start = self.textbuffer.get_iter_at_offset(next_node[ "start"]) self.textbuffer.delete(end, next_start) self.textbuffer.insert_with_tags_by_name(end, emt_eval, "emt") if next_node is not None: diff = end.get_offset() - next_node["start"] for node in self.nodelist[self.nodelist.index(next_node):]: node["start"] += diff node["end"] += diff
def on_analyze (self, engine, analysis): m = self.boardview.model if m.isPlayingICSGame(): return if not self.active: return is_FAN = conf.get("figuresInNotation", False) for i, line in enumerate(analysis): if line is None: self.store[self.path + (i,)] = self.textOnlyRow("") continue pv, score, depth = line move = None if pv: move = pv[0] board0 = self.engine.board board = board0.clone() ply0 = board.ply if self.mode == HINT else board.ply+1 counted_pv = [] for j, pvmove in enumerate(pv): ply = ply0 + j if ply % 2 == 0: mvcount = "%d." % (ply/2+1) elif j==0: mvcount = "%d..." % (ply/2+1) else: mvcount = "" counted_pv.append("%s%s" % (mvcount, toFAN(board, pvmove) if is_FAN else toSAN(board, pvmove, True))) board = board.move(pvmove) # TODO make a move's "goodness" relative to other moves or past scores goodness = (min(max(score, -250), 250) + 250) / 500.0 if self.engine.board.color == BLACK: score = -score self.store[self.path + (i,)] = [(board0, move, pv), (prettyPrintScore(score, depth), 1, goodness), 0, False, " ".join(counted_pv), False, False]
def variation_added(self, gamemodel, boards, parent, comment, score): # first find the iter where we will inset this new variation node = None for n in self.nodelist: if n["board"] == parent: end = self.textbuffer.get_iter_at_offset(n["end"]) node = n if node is None: next_node_index = len(self.nodelist) end = self.textbuffer.get_end_iter() level = 0 else: next_node_index = self.nodelist.index(node) + 1 level = node["level"] # diff will store the offset we need to shift the remaining stuff diff = 0 # inserting score of move we variating as comment if parent.plyCount in gamemodel.scores and not isinstance( parent.children[0], basestring): bmoves, bscore, bdepth = gamemodel.scores[parent.plyCount] bscore = bscore * -1 if parent.color == BLACK else bscore bcomment = prettyPrintScore(bscore, bdepth) parent.children.insert(0, bcomment) inserted_node = self.insert_comment(bcomment, parent, None, level=level) diff += inserted_node["end"] - inserted_node["start"] end = self.textbuffer.get_iter_at_offset(inserted_node["end"]) next_node_index += 1 # variation opening parenthesis sdiff, opening_node = self.variation_start(end, next_node_index, level) diff += sdiff ini_board = None for i, board in enumerate(boards): # do we have initial variation comment? if (board.prev is None): if comment: board.children.append(comment) ini_board = board continue else: # insert variation move inserted_node = self.insert_node(board, end, next_node_index + i, level + 1, parent) diff += inserted_node["end"] - inserted_node["start"] end = self.textbuffer.get_iter_at_offset(inserted_node["end"]) if ini_board is not None: # insert initial variation comment inserted_comment = self.insert_comment(comment, board, parent, level=level + 1, ini_board=ini_board) comment_diff = inserted_comment["end"] - inserted_comment[ "start"] inserted_node["start"] += comment_diff inserted_node["end"] += comment_diff end = self.textbuffer.get_iter_at_offset( inserted_node["end"]) diff += comment_diff leading = False next_node_index += 1 ini_board = None if score: # insert score of variation latest move as comment board.children.append(score) inserted_node = self.insert_comment(score, board, parent, level=level + 1) diff += inserted_node["end"] - inserted_node["start"] end = self.textbuffer.get_iter_at_offset(inserted_node["end"]) next_node_index += 1 diff += self.variation_end(end, next_node_index + len(boards), level, boards[0], parent, opening_node) # adjust remaining stuff offsets if next_node_index > 0: for node in self.nodelist[next_node_index + len(boards) + 1:]: node["start"] += diff node["end"] += diff # if new variation is coming from clicking in book panel # we want to jump into the first board in new vari if not comment: self.boardview.setShownBoard(boards[1].pieceBoard) self.gamemodel.needsSave = True
def on_analyze(self, engine, analysis): if self.boardview.animating: return if self.boardview.model.isPlayingICSGame(): return if not self.active: return for i, line in enumerate(analysis): if line is None: self.store[self.path + (i,)] = self.textOnlyRow("") continue ply, movstrs, score, depth, nps = line board0 = self.engine.board board = board0.clone() try: pv = listToMoves(board, movstrs, validate=True) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug( "EngineAdvisor.on_analyze(): Ignored (%s) from analyzer: ParsingError%s" % (" ".join(movstrs), e) ) return move = None if pv: move = pv[0] ply0 = board.ply if self.mode == HINT else board.ply + 1 counted_pv = [] for j, pvmove in enumerate(pv): ply = ply0 + j if ply % 2 == 0: mvcount = "%d." % (ply / 2 + 1) elif j == 0: mvcount = "%d..." % (ply / 2 + 1) else: mvcount = "" counted_pv.append( "%s%s" % ( mvcount, toFAN(board, pvmove) if self.figuresInNotation else toSAN(board, pvmove, True), ) ) board = board.move(pvmove) goodness = (min(max(score, -250), 250) + 250) / 500.0 if self.engine.board.color == BLACK: score = -score self.store[self.path + (i,)] = [ (board0, move, pv), (prettyPrintScore(score, depth, format_mate=True), 1, goodness), 0, False, " ".join(counted_pv), False, False, ]
def insert_nodes(self, board, level=0, parent=None, result=None): """ Recursively builds the node tree """ end_iter = self.textbuffer.get_end_iter # Convenience shortcut to the function while True: # start = end_iter().get_offset() if board is None: break # Initial game or variation comment if board.prev is None: for index, child in enumerate(board.children): if isinstance(child, str): self.insert_comment(child, board, parent, index=index, level=level, ini_board=board) board = board.next continue if board.fen_was_applied: self.insert_node(board, end_iter(), -1, level, parent) if self.showEmt and level == 0 and board.fen_was_applied and self.gamemodel.timemodel.hasTimes: elapsed = self.gamemodel.timemodel.getElapsedMoveTime( board.plyCount - self.gamemodel.lowply) self.textbuffer.insert_with_tags_by_name( end_iter(), "%s " % formatTime(elapsed), "emt") if self.showEval and level == 0 and board.fen_was_applied and board.plyCount in self.gamemodel.scores: moves, score, depth = self.gamemodel.scores[board.plyCount] score = score * -1 if board.color == BLACK else score # endIter = self.textbuffer.get_iter_at_offset(end_iter().get_offset()) self.textbuffer.insert_with_tags_by_name( end_iter(), "%s " % prettyPrintScore(score, depth), "emt") for index, child in enumerate(board.children): if isinstance(child, str): # comment self.insert_comment(child, board, parent, index=index, level=level) else: # variation diff, opening_node = self.variation_start( end_iter(), -1, level) self.insert_nodes(child[0], level + 1, parent=board) self.variation_end(end_iter(), -1, level, child[1], board, opening_node) if board.next: board = board.next else: break if result and result != "*": self.textbuffer.insert_with_tags_by_name(end_iter(), " " + result, "move")
def analyse_moves(): should_black = conf.get("shouldBlack", True) should_white = conf.get("shouldWhite", True) from_current = conf.get("fromCurrent", True) start_ply = gmwidg.board.view.shown if from_current else 0 move_time = int(conf.get("max_analysis_spin", 3)) threshold = int(conf.get("variation_threshold_spin", 50)) for board in gamemodel.boards[start_ply:]: if stop_event.is_set(): break gmwidg.board.view.setShownBoard(board) analyzer.setBoard(board) if threat_PV: inv_analyzer.setBoard(board) yield from asyncio.sleep(move_time + 0.1) ply = board.ply color = (ply - 1) % 2 if ply - 1 in gamemodel.scores and ply in gamemodel.scores and ( (color == BLACK and should_black) or (color == WHITE and should_white)): oldmoves, oldscore, olddepth = gamemodel.scores[ply - 1] oldscore = oldscore * -1 if color == BLACK else oldscore score_str = prettyPrintScore(oldscore, olddepth) moves, score, depth = gamemodel.scores[ply] score = score * -1 if color == WHITE else score diff = score - oldscore if ((diff > threshold and color == BLACK) or (diff < -1 * threshold and color == WHITE)) and ( gamemodel.moves[ply - 1] != parseAny( gamemodel.boards[ply - 1], oldmoves[0])): if threat_PV: try: if ply - 1 in gamemodel.spy_scores: oldmoves0, oldscore0, olddepth0 = gamemodel.spy_scores[ ply - 1] score_str0 = prettyPrintScore( oldscore0, olddepth0) pv0 = listToMoves(gamemodel.boards[ply - 1], ["--"] + oldmoves0, validate=True) if len(pv0) > 2: gamemodel.add_variation( gamemodel.boards[ply - 1], pv0, comment="Treatening", score=score_str0, emit=False) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug( "__parseLine: Ignored (%s) from analyzer: ParsingError%s" % (' '.join(oldmoves), e)) try: pv = listToMoves(gamemodel.boards[ply - 1], oldmoves, validate=True) gamemodel.add_variation(gamemodel.boards[ply - 1], pv, comment="Better is", score=score_str, emit=False) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug( "__parseLine: Ignored (%s) from analyzer: ParsingError%s" % (' '.join(oldmoves), e)) widgets["analyze_game"].hide() widgets["analyze_ok_button"].set_sensitive(True) conf.set("analyzer_check", old_check_value) if threat_PV: conf.set("inv_analyzer_check", old_inv_check_value) message.dismiss() gamemodel.emit("analysis_finished")
def variation_added(self, gamemodel, boards, parent, comment, score): # first find the iter where we will inset this new variation node = None for n in self.nodelist: if n["board"] == parent: end = self.textbuffer.get_iter_at_offset(n["end"]) node = n if node is None: next_node_index = len(self.nodelist) end = self.textbuffer.get_end_iter() level = 0 else: next_node_index = self.nodelist.index(node) + 1 level = node["level"] # diff will store the offset we need to shift the remaining stuff diff = 0 # inserting score of move we variating as comment if parent.plyCount in gamemodel.scores and not isinstance(parent.children[0], basestring): bmoves, bscore, bdepth = gamemodel.scores[parent.plyCount] bscore = bscore * -1 if parent.color == BLACK else bscore bcomment = prettyPrintScore(bscore, bdepth) parent.children.insert(0, bcomment) inserted_node = self.insert_comment(bcomment, parent, None, level=level) diff += inserted_node["end"] - inserted_node["start"] end = self.textbuffer.get_iter_at_offset(inserted_node["end"]) next_node_index += 1 # variation opening parenthesis sdiff, opening_node = self.variation_start(end, next_node_index, level) diff += sdiff ini_board = None for i, board in enumerate(boards): # do we have initial variation comment? if (board.prev is None): if comment: board.children.append(comment) ini_board = board continue else: # insert variation move inserted_node = self.insert_node(board, end, next_node_index+i, level+1, parent) diff += inserted_node["end"] - inserted_node["start"] end = self.textbuffer.get_iter_at_offset(inserted_node["end"]) if ini_board is not None: # insert initial variation comment inserted_comment = self.insert_comment(comment, board, parent, level=level+1, ini_board=ini_board) comment_diff = inserted_comment["end"] - inserted_comment["start"] inserted_node["start"] += comment_diff inserted_node["end"] += comment_diff end = self.textbuffer.get_iter_at_offset(inserted_node["end"]) diff += comment_diff leading = False next_node_index += 1 ini_board = None if score: # insert score of variation latest move as comment board.children.append(score) inserted_node = self.insert_comment(score, board, parent, level=level+1) diff += inserted_node["end"] - inserted_node["start"] end = self.textbuffer.get_iter_at_offset(inserted_node["end"]) next_node_index += 1 diff += self.variation_end(end, next_node_index + len(boards), level, boards[0], parent, opening_node) # adjust remaining stuff offsets if next_node_index > 0: for node in self.nodelist[next_node_index + len(boards)+1:]: node["start"] += diff node["end"] += diff # if new variation is coming from clicking in book panel # we want to jump into the first board in new vari if not comment: self.boardview.setShownBoard(boards[1].pieceBoard) self.gamemodel.needsSave = True