Merge pull request #8 from sanderland/better_analysis

Better analysis
This commit is contained in:
sanderland authored and GitHub committed 2020-03-01 21:26:48 +01:00
commit be50c23a1c
3 files changed
+36 -13

No files matched your search

+28 -10
View File
@@ -51,6 +51,15 @@ class Move:
def is_pass(self):
return self.coords[0] is None
def update_top_move_evaluation(self): # a move's outdated analysis
if self.analysis and self.parent and self.parent.analysis:
for move_dict in self.parent.analysis:
if move_dict["move"] == self.gtp():
move_dict["outdatedScoreLead"] = move_dict["scoreLead"]
move_dict["scoreLead"] = self.analysis[0]["scoreLead"]
self.parent.update_top_move_evaluation()
return
# various analysis functions
def set_analysis(self, analysis_blob, is_pass):
if is_pass:
@@ -58,10 +67,9 @@ class Move:
else:
self.analysis = analysis_blob["moveInfos"]
self.ownership = analysis_blob["ownership"]
if self.parent and self.parent.analysis and self.parent.analysis[0]["move"] == self.gtp():
self.parent.analysis[0]["scoreLead"] = self.analysis[0]["scoreLead"]
if self.children and self.children[0].analysis and self.children[0].gtp() == self.analysis[0]["move"]:
self.analysis[0]["scoreLead"] = self.children[0].analysis[0]["scoreLead"] # if received out of order, some edge case with undos ignored
if self.children:
self.children[0].update_top_move_evaluation()
self.update_top_move_evaluation()
@property
def analysis_ready(self):
@@ -125,9 +133,9 @@ class Move:
# needing own analysis ready
@property
def temperature_stats(self):
best = float(self.analysis[0]["scoreLead"])
worst = float(self.pass_analysis[0]["scoreLead"])
return best, worst, abs(best - worst)
best = self.analysis[0]["scoreLead"]
worst = self.pass_analysis[0]["scoreLead"]
return best, worst, max(-self.player_sign * (best - worst), 0)
@property
def score(self):
@@ -141,14 +149,21 @@ class Move:
@property
def evaluation(self):
best, worst, temp = self.parent.temperature_stats
return self.player_sign * (self.score - worst) / temp
return self.player_sign * (self.score - worst) / temp if temp > 0 else None
@property
def outdated_evaluation(self):
def outdated_score(move_dict):
return move_dict.get("outdatedScoreLead") or move_dict["scoreLead"]
prev_analysis_current_move = [d for d in self.parent.analysis if d["move"] == self.gtp()]
if prev_analysis_current_move:
best_score, worst_score, prev_temp = self.parent.temperature_stats
return self.player_sign * (prev_analysis_current_move[0]["scoreLead"] - worst_score) / prev_temp
best_score = outdated_score(self.parent.analysis[0])
worst_score = self.parent.pass_analysis[0]["scoreLead"]
prev_temp = max(self.player_sign * (best_score - worst_score), 0)
score = outdated_score(prev_analysis_current_move[0])
return self.player_sign * (score - worst_score) / prev_temp if prev_temp > 0 else None
@property
def ai_moves(self):
@@ -156,7 +171,10 @@ class Move:
return []
_, worst_score, temperature = self.temperature_stats
for d in self.analysis:
d["evaluation"] = -self.player_sign * (d["scoreLead"] - worst_score) / temperature
if temperature > 0.5:
d["evaluation"] = -self.player_sign * (d["scoreLead"] - worst_score) / temperature
else:
d["evaluation"] = int(-self.player_sign * d["scoreLead"] >= -self.player_sign * self.analysis[0]["scoreLead"])
return self.analysis
# various output and conversion functions
+7 -3
View File
@@ -97,16 +97,20 @@ class EngineControls(GridLayout):
self.score.text = move.format_score().replace("-", "\u2013")
self.temperature.text = f"{move.temperature_stats[2]:.1f}"
if move.parent and move.parent.analysis_ready:
self.evaluation.text = f"{move.evaluation:.1%}"
if move.evaluation is not None:
self.evaluation.text = f"{move.evaluation:.1%}"
else:
self.evaluation.text = f"?"
# handles showing completed analysis and triggered actions like auto undo and ai move
def update_evaluation(self):
current_move = self.board.current_move
self.score.set_prisoners(self.board.prisoner_count)
if not self.ai_auto.active(current_move.player) and current_move is not self.board.root:
current_player_is_human_or_both_robots = not self.ai_auto.active(current_move.player) or self.ai_auto.active(1 - current_move.player)
if current_player_is_human_or_both_robots and current_move is not self.board.root:
self.info.text = current_move.comment(eval=True, hints=self.hints.active(current_move.player))
self.evaluation.text = ""
if not self.ai_auto.active(current_move.player):
if current_player_is_human_or_both_robots:
self.show_evaluation_stats(current_move)
if current_move.analysis_ready and current_move.parent and current_move.parent.analysis_ready and not current_move.children and not current_move.x_comment.get("undo"):
+1
View File
@@ -55,6 +55,7 @@ class BadukPanWidget(Widget):
if self.engine.debug:
print("\nAnalysis:\n", stones_here[-1].analysis)
print("\nParent Analysis:\n", stones_here[-1].parent.analysis)
print("\nParent Pass Analysis:\n", stones_here[-1].parent.pass_analysis[0])
if not self.engine.ai_lock.active:
self.engine.info.text = stones_here[-1].comment(sgf=True)
self.engine.show_evaluation_stats(stones_here[-1])