This commit is contained in:
Sander Land committed 2020-10-09 19:19:07 +02:00
1 parent 8e0001b771
commit 28b8748e5f
23 files changed
+171 -43

No files matched your search

+32 -31
View File
@@ -18,7 +18,6 @@ from katrain.core.constants import (
AI_RANK,
AI_SCORELOSS,
AI_SCORELOSS_ELO,
AI_SIMPLE,
AI_SIMPLE_OWNERSHIP,
AI_STRATEGIES_PICK,
AI_STRATEGIES_POLICY,
@@ -205,13 +204,6 @@ def generate_ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move,
game.katrain.log(f"Error getting handicap-based move", OUTPUT_ERROR)
ai_mode = AI_DEFAULT
if ai_mode == AI_SIMPLE:
simple_moves = ai_settings["simple_moves"]
simple_analysis = request_ai_analysis(game, cn, {"simpleMovesBias": simple_moves, "wideRootNoise": 0.10})
if not simple_analysis:
game.katrain.log(f"Error getting simple-biased move", OUTPUT_ERROR)
ai_mode = AI_DEFAULT
while not cn.analysis_ready:
time.sleep(0.01)
game.engines[cn.next_player].check_alive(exception_if_dead=True)
@@ -335,18 +327,6 @@ def generate_ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move,
candidate_ai_moves = cn.candidate_moves
if ai_mode == AI_HANDICAP:
candidate_ai_moves = handicap_analysis["moveInfos"]
if ai_mode == AI_SIMPLE:
candidate_ai_moves = simple_analysis["moveInfos"]
for data in candidate_ai_moves:
print(
"{order} {move}: visits {visits} utility {util} utilityLcb {lcb}".format(
visits=data["visits"],
order=data["order"],
move=data["move"],
util=data["utility"],
lcb=data["utilityLcb"],
)
)
top_cand = Move.from_gtp(candidate_ai_moves[0]["move"], player=cn.next_player)
if top_cand.is_pass and ai_mode not in [
@@ -377,31 +357,54 @@ def generate_ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move,
aimove = topmove[2]
ai_thoughts += f"ScoreLoss strategy found {len(candidate_ai_moves)} candidate moves (best {top_cand.gtp()}) and chose {aimove.gtp()} (weight {topmove[1]:.3f}, point loss {topmove[0]:.1f}) based on score weights."
elif ai_mode == AI_SIMPLE_OWNERSHIP:
def settledness(d, player_fac):
return sum([abs(o) for o in d["ownership"] if player_fac * o > 0])
last_player_stones = {s.coords for s in game.stones if s.player == cn.player}
next_player_sign = cn.player_sign(cn.next_player)
def settledness(d, player_sign):
return sum([abs(o) for o in d["ownership"] if player_sign * o > 0])
def is_attachment(d):
return any(
(d.coords[0] + dx, d.coords[1] + dy) in last_player_stones
for dx in [-1, 0, 1]
for dy in [-1, 0, 1]
if abs(dx) + abs(dy) == 1
)
def is_tenuki(d):
return not any(
not node
or not node.move
or node.move.is_pass
or max(abs(last_c - cand_c) for last_c, cand_c in zip(node.move.coords, d.coords)) < 5
for node in [cn, cn.parent]
)
moves_with_settledness = sorted(
[
(
Move.from_gtp(d["move"], player=cn.next_player),
move,
settledness(d, next_player_sign),
settledness(d, -next_player_sign),
is_attachment(move),
is_tenuki(move),
d,
)
for d in candidate_ai_moves
if d["pointsLost"] < ai_settings["max_points_lost"]
and "ownership" in d
and (d["order"] < 5 or d["visits"] >= ai_settings.get("min_visits", 1))
for move in [Move.from_gtp(d["move"], player=cn.next_player)]
],
key=lambda t: t[3]["pointsLost"]
key=lambda t: t[5]["pointsLost"]
+ ai_settings["attach_penalty"] * t[3]
+ ai_settings["tenuki_penalty"] * t[4]
- ai_settings["settled_weight"] * (t[1] + ai_settings["opponent_fac"] * t[2]),
)
if moves_with_settledness:
cands = [
f"{move.gtp()} ({d['pointsLost']:.1f} pt lost, {d['visits']} visits, {settled:.1f} settledness, {oppsettled:.1f} opponent settledness)"
for move, settled, oppsettled, d in moves_with_settledness[:5]
f"{move.gtp()} ({d['pointsLost']:.1f} pt lost, {d['visits']} visits, {settled:.1f} settledness, {oppsettled:.1f} opponent settledness{', attachment' if isattach else ''}{', tenuki' if istenuki else ''})"
for move, settled, oppsettled, isattach, istenuki, d in moves_with_settledness[:5]
]
ai_thoughts += f"Simple ownership strategy. Top 5 Candidates {', '.join(cands)} "
aimove = moves_with_settledness[0][0]
@@ -411,14 +414,12 @@ def generate_ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move,
)
aimove = top_cand
else:
if ai_mode not in [AI_DEFAULT, AI_HANDICAP, AI_SIMPLE]:
if ai_mode not in [AI_DEFAULT, AI_HANDICAP]:
game.katrain.log(f"Unknown AI mode {ai_mode} or policy missing, using default.", OUTPUT_INFO)
ai_thoughts += f"Strategy {ai_mode} not found or unexpected fallback."
aimove = top_cand
if ai_mode == AI_HANDICAP:
ai_thoughts += f"Handicap strategy found {len(candidate_ai_moves)} moves returned from the engine and chose {aimove.gtp()} as top move. PDA based score {cn.format_score(handicap_analysis['rootInfo']['scoreLead'])} and win rate {cn.format_winrate(handicap_analysis['rootInfo']['winrate'])}"
elif ai_mode == AI_SIMPLE:
ai_thoughts += f"Simple moves strategy found {len(candidate_ai_moves)} moves returned from the engine and chose {aimove.gtp()} as top move. "
else:
ai_thoughts += f"Default strategy found {len(candidate_ai_moves)} moves returned from the engine and chose {aimove.gtp()} as top move"
game.katrain.log(f"AI thoughts: {ai_thoughts}", OUTPUT_DEBUG)