improvements to analysis, temperature, cutoff and updating of older analysis
This commit is contained in:
1 parent
6126bf45df
commit
13dcdcee55
3 files changed
+30
-11
No files matched your search
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
|
import math
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
@@ -51,6 +52,15 @@ class Move:
|
|||||||
def is_pass(self):
|
def is_pass(self):
|
||||||
return self.coords[0] is None
|
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
|
# various analysis functions
|
||||||
def set_analysis(self, analysis_blob, is_pass):
|
def set_analysis(self, analysis_blob, is_pass):
|
||||||
if is_pass:
|
if is_pass:
|
||||||
@@ -58,10 +68,9 @@ class Move:
|
|||||||
else:
|
else:
|
||||||
self.analysis = analysis_blob["moveInfos"]
|
self.analysis = analysis_blob["moveInfos"]
|
||||||
self.ownership = analysis_blob["ownership"]
|
self.ownership = analysis_blob["ownership"]
|
||||||
if self.parent and self.parent.analysis and self.parent.analysis[0]["move"] == self.gtp():
|
if self.children:
|
||||||
self.parent.analysis[0]["scoreLead"] = self.analysis[0]["scoreLead"]
|
self.children[0].update_top_move_evaluation()
|
||||||
if self.children and self.children[0].analysis and self.children[0].gtp() == self.analysis[0]["move"]:
|
self.update_top_move_evaluation()
|
||||||
self.analysis[0]["scoreLead"] = self.children[0].analysis[0]["scoreLead"] # if received out of order, some edge case with undos ignored
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def analysis_ready(self):
|
def analysis_ready(self):
|
||||||
@@ -127,7 +136,7 @@ class Move:
|
|||||||
def temperature_stats(self):
|
def temperature_stats(self):
|
||||||
best = float(self.analysis[0]["scoreLead"])
|
best = float(self.analysis[0]["scoreLead"])
|
||||||
worst = float(self.pass_analysis[0]["scoreLead"])
|
worst = float(self.pass_analysis[0]["scoreLead"])
|
||||||
return best, worst, abs(best - worst)
|
return best, worst, max(-self.player_sign * (best - worst), 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def score(self):
|
def score(self):
|
||||||
@@ -141,14 +150,15 @@ class Move:
|
|||||||
@property
|
@property
|
||||||
def evaluation(self):
|
def evaluation(self):
|
||||||
best, worst, temp = self.parent.temperature_stats
|
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 math.nan
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def outdated_evaluation(self):
|
def outdated_evaluation(self):
|
||||||
prev_analysis_current_move = [d for d in self.parent.analysis if d["move"] == self.gtp()]
|
prev_analysis_current_move = [d for d in self.parent.analysis if d["move"] == self.gtp()]
|
||||||
if prev_analysis_current_move:
|
if prev_analysis_current_move:
|
||||||
best_score, worst_score, prev_temp = self.parent.temperature_stats
|
best_score, worst_score, prev_temp = self.parent.temperature_stats
|
||||||
return self.player_sign * (prev_analysis_current_move[0]["scoreLead"] - worst_score) / prev_temp
|
score = prev_analysis_current_move[0].get("outdatedScoreLead") or prev_analysis_current_move[0]["scoreLead"]
|
||||||
|
return self.player_sign * (score - worst_score) / prev_temp if prev_temp > 0 else math.nan
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ai_moves(self):
|
def ai_moves(self):
|
||||||
@@ -156,7 +166,10 @@ class Move:
|
|||||||
return []
|
return []
|
||||||
_, worst_score, temperature = self.temperature_stats
|
_, worst_score, temperature = self.temperature_stats
|
||||||
for d in self.analysis:
|
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
|
return self.analysis
|
||||||
|
|
||||||
# various output and conversion functions
|
# various output and conversion functions
|
||||||
|
|||||||
+8
-3
@@ -1,6 +1,7 @@
|
|||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import math
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
@@ -97,16 +98,20 @@ class EngineControls(GridLayout):
|
|||||||
self.score.text = move.format_score().replace("-", "\u2013")
|
self.score.text = move.format_score().replace("-", "\u2013")
|
||||||
self.temperature.text = f"{move.temperature_stats[2]:.1f}"
|
self.temperature.text = f"{move.temperature_stats[2]:.1f}"
|
||||||
if move.parent and move.parent.analysis_ready:
|
if move.parent and move.parent.analysis_ready:
|
||||||
self.evaluation.text = f"{move.evaluation:.1%}"
|
if not math.isnan(move.evaluation):
|
||||||
|
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
|
# handles showing completed analysis and triggered actions like auto undo and ai move
|
||||||
def update_evaluation(self):
|
def update_evaluation(self):
|
||||||
current_move = self.board.current_move
|
current_move = self.board.current_move
|
||||||
self.score.set_prisoners(self.board.prisoner_count)
|
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.info.text = current_move.comment(eval=True, hints=self.hints.active(current_move.player))
|
||||||
self.evaluation.text = ""
|
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)
|
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"):
|
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"):
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ class BadukPanWidget(Widget):
|
|||||||
if self.engine.debug:
|
if self.engine.debug:
|
||||||
print("\nAnalysis:\n", stones_here[-1].analysis)
|
print("\nAnalysis:\n", stones_here[-1].analysis)
|
||||||
print("\nParent Analysis:\n", stones_here[-1].parent.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:
|
if not self.engine.ai_lock.active:
|
||||||
self.engine.info.text = stones_here[-1].comment(sgf=True)
|
self.engine.info.text = stones_here[-1].comment(sgf=True)
|
||||||
self.engine.show_evaluation_stats(stones_here[-1])
|
self.engine.show_evaluation_stats(stones_here[-1])
|
||||||
|
|||||||
Reference in new issue
Block a user