readme update and undo lock option
This commit is contained in:
1 parent
136dff4f1c
commit
d57e6ce87d
5 files changed
+37
-11
No files matched your search
@@ -1,3 +1,19 @@
|
||||
Introduction
|
||||
============
|
||||
This repository contains tool for playing go with AI feedback aimed at kyu players.
|
||||
The idea is to give immediate feedback on the many large mistakes we make in terms of inefficient moves.
|
||||
It is based on the KataGo AI and relies heavily on score estimation rather than win rate.
|
||||
|
||||
Some uses include:
|
||||
|
||||
* Analyze your games to find the moves that were most costly in terms of points lost.
|
||||
* Play against AI and get immediate feedback on mistakes with option to retry.
|
||||
* Play against a stronger player and use the retry option instead of handicap stones.
|
||||
* Play a match with an evenly matched friend where both players get instant feedback.
|
||||
|
||||
|
||||

|
||||
|
||||
Manual
|
||||
======
|
||||
|
||||
@@ -23,7 +39,7 @@ Options
|
||||
* Undo: automatically undo poor moves for this player and make them try again.
|
||||
* AI: let the AI control this player. Check both for self-play.
|
||||
* Show owner: show expected control of territory.
|
||||
* Lock AI: disallow extra undos, changing hints options, changing auto move, or AI move.
|
||||
* Lock AI: disallow extra undos, changing hints options, changing auto move, or AI move. Also turns off the option to click on a move to see detailed comments.
|
||||
* Fast: use a lower number of max visits for evaluation/AI move.
|
||||
* Balance score: Deliberately make sub-optimal moves as the AI in an attempt to balance the score towawrds a slight win.
|
||||
|
||||
@@ -58,7 +74,7 @@ Play
|
||||
* Click `Analyze`
|
||||
|
||||
* Save game
|
||||
* Click save to get an sgf as `out.sgf` with comments (and a short version in the text box).
|
||||
* Click save to get an sgf with comments saved in the sgfout/ directory (and a short version in the text box).
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
@@ -315,8 +315,8 @@ class Board:
|
||||
return "\n".join("".join(Move.PLAYERS[self.chains[c][0].player] if c >= 0 else "-" for c in l) for l in self.board) + f"\ncaptures: {self.prisoner_count}"
|
||||
|
||||
def write_sgf(self, komi, train_settings, file_name=None):
|
||||
def sgfify(mvs):
|
||||
return f"(;GM[1]FF[4]SZ[{self.board_size}]KM[{komi}]RU[JP];" + ";".join(mvs) + ")"
|
||||
def sgfify(mvs, comment=""):
|
||||
return f"(;GM[1]FF[4]SZ[{self.board_size}]KM[{komi}]RU[JP];" + ";".join(mvs) + (f"C[{comment}])" if comment else "")
|
||||
|
||||
def format_move(move, prev_move):
|
||||
undos = [m for m in prev_move.children if m != move]
|
||||
@@ -349,4 +349,4 @@ class Board:
|
||||
pass
|
||||
with open(file_name, "w") as f:
|
||||
f.write(sgfify(sgfmoves))
|
||||
return sgfify(sgfmoves_small)
|
||||
return sgfify(sgfmoves_small, f"SGF with analysis written to {file_name}")
|
||||
+2
-1
@@ -39,7 +39,8 @@
|
||||
"undo_eval_threshold": 0.875,
|
||||
"undo_point_threshold": 1,
|
||||
"num_undo_prompts": 1,
|
||||
"sgf_show_best_move_threshold": 0.95
|
||||
"sgf_show_best_move_threshold": 0.95,
|
||||
"dont_lock_undos": false
|
||||
},
|
||||
"debug": {
|
||||
"level": 1
|
||||
|
||||
+10
-3
@@ -36,6 +36,7 @@ class EngineControls(GridLayout):
|
||||
self.komi = 6.5 # loaded from config in init
|
||||
self.outstanding_analysis_queries = [] # allows faster interaction while kata is starting
|
||||
self.kata = None
|
||||
self.query_time = {}
|
||||
|
||||
def redraw(self, include_board=False):
|
||||
if include_board:
|
||||
@@ -153,7 +154,12 @@ class EngineControls(GridLayout):
|
||||
self.play(aimove)
|
||||
|
||||
def _do_undo(self):
|
||||
if self.ai_lock.active and self.auto_undo.active(self.board.current_move.player) and len(self.board.current_move.parent.children) > self.train_settings["num_undo_prompts"]:
|
||||
if (
|
||||
self.ai_lock.active
|
||||
and self.auto_undo.active(self.board.current_move.player)
|
||||
and len(self.board.current_move.parent.children) > self.train_settings["num_undo_prompts"]
|
||||
and not self.train_settings.get("dont_lock_undos")
|
||||
):
|
||||
self.info.text = f"Can't undo more than {self.train_settings['num_undo_prompts']} time(s) when locked"
|
||||
return
|
||||
self.board.undo()
|
||||
@@ -183,8 +189,6 @@ class EngineControls(GridLayout):
|
||||
while self.outstanding_analysis_queries:
|
||||
self._send_analysis_query(self.outstanding_analysis_queries.pop(0))
|
||||
line = self.kata.stdout.readline()
|
||||
if self.debug:
|
||||
print("KATA ANALYSIS RECEIVED:", line[:80], "...")
|
||||
if not line: # occasionally happens?
|
||||
return
|
||||
try:
|
||||
@@ -192,10 +196,13 @@ class EngineControls(GridLayout):
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"JSON decode error: '{e}' encountered after receiving input '{line}'")
|
||||
return
|
||||
if self.debug:
|
||||
print(f"[{time.time()-self.query_time.get(analysis['id'],0):.1f}] kata analysis received:", line[:80], "...")
|
||||
self.board.store_analysis(analysis)
|
||||
self.update_evaluation()
|
||||
|
||||
def _send_analysis_query(self, query):
|
||||
self.query_time[query["id"]] = time.time()
|
||||
if self.kata:
|
||||
self.kata.stdin.write((json.dumps(query) + "\n").encode())
|
||||
self.kata.stdin.flush()
|
||||
|
||||
+4
-2
@@ -53,11 +53,13 @@ class BadukPanWidget(Widget):
|
||||
yd, yp = self._find_closest(touch.y)
|
||||
stones_here = [m for m in self.engine.board.stones if m.coords == (xp, yp)]
|
||||
if stones_here and max(yd, xd) < self.grid_size / 2: # load old comment
|
||||
self.engine.info.text = stones_here[-1].comment(sgf=True)
|
||||
self.engine.show_evaluation_stats(stones_here[-1])
|
||||
if self.engine.debug:
|
||||
print("\nAnalysis:\n", stones_here[-1].analysis)
|
||||
print("\nParent Analysis:\n", stones_here[-1].parent.analysis)
|
||||
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])
|
||||
|
||||
self.ghost_stone = None
|
||||
self.redraw() # remove ghost
|
||||
|
||||
|
||||
Reference in new issue
Block a user