extends Node ## Test-Mitspieler: tritt einem Host bei und spielt einfache Züge; mit --host eröffnet er ## selbst und startet, sobald ein zweiter Mensch am Tisch sitzt (ohne KI). ## godot --path . tests/net_bot.tscn -- --ip=127.0.0.1 --name=Bot ## godot --path . tests/net_bot.tscn -- --host --name=BotHost var net: Net var seat := -1 var game: Game var t := 0.0 var hosting := false func _ready() -> void: var ip := "127.0.0.1" var bot_name := "Bot" for a in OS.get_cmdline_user_args(): if a.begins_with("--ip="): ip = a.substr(5) if a.begins_with("--name="): bot_name = a.substr(7) if a == "--host": hosting = true net = Net.new() net.name = "Net" get_tree().root.add_child.call_deferred(net) net.my_name = bot_name net.my_pick = {"elements": ["Feuer", "Erde"], "looks": {}} net.started.connect(func(s): seat = s if hosting: net.broadcast() # erster Zustand für alle, wie es sonst der Kampfbildschirm tut _act_host.call_deferred()) net.snapshot_received.connect(_on_snapshot) net.ended.connect(func(_r): get_tree().quit()) await get_tree().process_frame if hosting: net.host() net.lobby_changed.connect(func(): if net.game == null and net.names.size() >= 2: net.start_battle(0)) net.action_applied.connect(func(): net.broadcast() _act_host.call_deferred()) else: net.join(ip) func _process(delta: float) -> void: t += delta if hosting and net.game != null: net.tick() if t > 180.0 or FileAccess.file_exists("user://bot_quit"): net.leave() get_tree().quit() func _on_snapshot(snap: Dictionary) -> void: game = Game.from_snapshot(snap) if game.winner != "": await get_tree().create_timer(1.0).timeout get_tree().quit() return if game.current_idx != seat: return _decide(game.players[seat]) func _act_host() -> void: if not hosting or net.game == null or net.game.winner != "" or seat < 0 or net.game.current_idx != seat: return game = net.game _decide(game.players[seat]) ## Einfache Züge mit kurzer Bedenkzeit: erst das billigste bezahlbare Angebot kaufen, dann das ## erste spielbare Wesen ohne Ziel, dann angreifen, sonst Zug beenden. func _decide(me: Game.Player) -> void: var g := game await get_tree().create_timer(0.25).timeout if game != g or (hosting and (net.game == null or net.game.current_idx != seat)): return # inzwischen ein neuer Zustand for i in me.shop.size(): var offer = me.shop[i] if offer != null and me.energy >= offer.cost and me.hand.size() < Game.MAX_HAND: net.send_action({"type": "buy", "slot": i}) return for i in me.hand.size(): var card: Cards.Card = me.hand[i] if game.can_play(me, card)[0] and card.target_type() == "": net.send_action({"type": "play", "hand": i, "target": null}) return for cr in me.board: if cr.can_attack(): for e in game.enemies_of(me): if game.can_attack(cr, e)[0]: net.send_action({"type": "attack", "uid": cr.uid, "target": {"kind": "player", "index": game.players.find(e)}}) return for c in e.board: if game.can_attack(cr, c)[0]: net.send_action({"type": "attack", "uid": cr.uid, "target": {"kind": "creature", "uid": c.uid}}) return net.send_action({"type": "end"})