Spiel untersucht und optimiert: KI-Suche, Hintergrund-Threads, Dialog-Helfer
- KI-Vorausschau in zwei Stufen mit Zielvorauswahl (höchstens 4 Ziele je Karte und Angreifer, die 8 besten Erstschritte vertieft): 5 Gegner 2063 ms -> 101 ms, 1 Gegner 160 ms -> 36 ms, alle Kandidaten im Budget; 52:48 gegen die alte Suche - KI rechnet im WorkerThreadPool auf einer Spielkopie, schon während der Wartezeit; längste Bildzeit im Kampf mit 5 Gegnern 108 ms -> 38 ms - Musik wird im Hintergrund erzeugt (Start 185 ms schneller) - Style.overlay und Style.confirm ersetzen vier kopierte Dialoge - Übersetzungen für Abbrechen und Zurücksetzen, Archetypen neu gemessen - tests/perf_probe.gd (Laufzeiten) und tests/frame_probe.tscn (Bildzeiten) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QPgKvy5W9WRNFHjkm5QsHx
This commit is contained in:
@@ -19,6 +19,9 @@ var pending = null # Cards.Card, wartet auf Ziel
|
||||
var msg_t := 0.0
|
||||
var ai_delay := 0.75
|
||||
var ai_timer := 0.0
|
||||
var ai_task := -1 # WorkerThreadPool-Aufgabe der laufenden KI-Berechnung
|
||||
var ai_copy: Game # Spielkopie, auf der die KI rechnet
|
||||
var ai_box := {} # Ergebnis der Berechnung (vom Thread befüllt)
|
||||
var reward := -1
|
||||
var ended := false
|
||||
var zoom_player = null
|
||||
@@ -301,12 +304,7 @@ func _build_static() -> void:
|
||||
notice_label = Style.label(overlay, "", 18, Style.GREEN, Rect2(0, 385, 1280, 80), "center")
|
||||
Style.button(overlay, "Zurück zum Menü", Rect2(530, 480, 220, 50), leave, Color("285a3c"))
|
||||
# Aufgeben bestätigen
|
||||
confirm = _overlay()
|
||||
Style.panel(confirm, Rect2(390, 300, 500, 180), Style.PANEL, 10, Style.MUTED, 2)
|
||||
Style.label(confirm, "Wirklich aufgeben?", 26, Style.TEXT, Rect2(390, 320, 500, 40), "center", true)
|
||||
Style.label(confirm, "Der Kampf endet ohne Münzen.", 16, Style.MUTED, Rect2(390, 365, 500, 24), "center")
|
||||
Style.button(confirm, "Ja, aufgeben", Rect2(420, 410, 200, 46), leave, Color("5a2828"))
|
||||
Style.button(confirm, "Weiterspielen", Rect2(660, 410, 200, 46), func(): confirm.visible = false)
|
||||
confirm = Style.confirm(self, "Wirklich aufgeben?", "Der Kampf endet ohne Münzen.", "Ja, aufgeben", leave, "Weiterspielen")
|
||||
# Übergabe zwischen Menschen (Hotseat)
|
||||
handover = _overlay()
|
||||
Style.panel(handover, Rect2(340, 280, 600, 220), Style.PANEL, 10, Style.GOLD, 2)
|
||||
@@ -323,16 +321,7 @@ func _layer() -> Control:
|
||||
|
||||
|
||||
func _overlay() -> Control:
|
||||
var o := Control.new()
|
||||
o.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
o.visible = false
|
||||
var dark := ColorRect.new()
|
||||
dark.color = Color(0, 0, 0, 0.67)
|
||||
dark.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dark.mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
o.add_child(dark)
|
||||
add_child(o)
|
||||
return o
|
||||
return Style.overlay(self)
|
||||
|
||||
|
||||
func leave() -> void:
|
||||
@@ -520,9 +509,22 @@ func _process(delta: float) -> void:
|
||||
ai_timer = 0.0
|
||||
else:
|
||||
ai_timer -= delta
|
||||
if ai_timer > 0:
|
||||
return
|
||||
var action := AI.choose_action(game, cur) if smart_ai else AI.choose_action_greedy(game, cur)
|
||||
var action: Dictionary
|
||||
if smart_ai:
|
||||
# Die Vorausschau rechnet im Hintergrund auf einer Kopie, schon während der Wartezeit,
|
||||
# damit Animationen nicht stocken.
|
||||
if ai_task < 0:
|
||||
_start_ai(cur)
|
||||
if ai_timer > 0 or not WorkerThreadPool.is_task_completed(ai_task):
|
||||
return
|
||||
WorkerThreadPool.wait_for_task_completion(ai_task)
|
||||
ai_task = -1
|
||||
action = AI.map_action(game, ai_copy, ai_box.action)
|
||||
ai_copy = null
|
||||
else:
|
||||
if ai_timer > 0:
|
||||
return
|
||||
action = AI.choose_action_greedy(game, cur)
|
||||
AI.apply_action(game, cur, action)
|
||||
ai_timer = ai_delay * (0.6 if action.type == "end" else 1.0)
|
||||
if game.current().is_human:
|
||||
@@ -530,6 +532,20 @@ func _process(delta: float) -> void:
|
||||
after_action()
|
||||
|
||||
|
||||
func _start_ai(cur: Game.Player) -> void:
|
||||
ai_copy = game.clone_for(cur)
|
||||
var copy := ai_copy
|
||||
var idx := game.current_idx
|
||||
var box := ai_box
|
||||
ai_task = WorkerThreadPool.add_task(func(): box["action"] = AI.choose_action(copy, copy.players[idx]))
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if ai_task >= 0:
|
||||
WorkerThreadPool.wait_for_task_completion(ai_task)
|
||||
ai_task = -1
|
||||
|
||||
|
||||
func _finish() -> void:
|
||||
var won := game.winner == "human"
|
||||
if counts_for_profile():
|
||||
|
||||
Reference in New Issue
Block a user