148 lines
5.3 KiB
GDScript
148 lines
5.3 KiB
GDScript
extends "res://tests/basis.gd"
|
|
## Ein Client. "-- host" macht den Raum auf, "-- join" tritt bei und steigt
|
|
## in Runde zwei einmal aus und wieder ein. Beide spielen über die echten
|
|
## RPC-Wege. Der Raumcode wandert über eine Datei im Scratch-Verzeichnis.
|
|
|
|
var game: Node
|
|
var rolle := ""
|
|
var runden := 0
|
|
var zuege := 0
|
|
var wuerfe := 0
|
|
var genau := 0
|
|
var wieder_da := false
|
|
var _letzte_phase := ""
|
|
var _rng := RandomNumberGenerator.new()
|
|
var _code_datei := ""
|
|
|
|
|
|
func _ready() -> void:
|
|
_rng.randomize()
|
|
var args := OS.get_cmdline_user_args()
|
|
rolle = args[0]
|
|
_code_datei = args[1]
|
|
await get_tree().create_timer(0.5).timeout
|
|
_lauf()
|
|
|
|
|
|
func _lauf() -> void:
|
|
if rolle == "host":
|
|
Net.create_room("Host")
|
|
await _warte(func(): return Net.room_code != "", 40.0)
|
|
var f := FileAccess.open(_code_datei, FileAccess.WRITE)
|
|
f.store_string(Net.room_code)
|
|
f.close()
|
|
await _warte(func(): return Net.lobby.size() >= 2, 80.0)
|
|
Net.request_start(1, 1, 2)
|
|
else:
|
|
await _beitreten()
|
|
await _warte(func(): game = _find(get_tree().root, "Game"); return game != null, 120.0)
|
|
if game == null:
|
|
_pruef("%s: Spiel kommt an" % rolle, false)
|
|
_fertig()
|
|
return
|
|
var erste := await _warte(func(): return game.phase == "bid" or game.phase == "roll", 60.0)
|
|
_pruef("%s: erster Zustand kommt an (Platz %d)" % [rolle, game.local_seat], erste)
|
|
|
|
var t := 0.0
|
|
var gewartet := 0.0
|
|
while t < 1400.0 and is_instance_valid(game) and game.phase != "over":
|
|
await get_tree().create_timer(0.1).timeout
|
|
t += 0.1
|
|
if not is_instance_valid(game):
|
|
break
|
|
if game.phase != _letzte_phase:
|
|
_letzte_phase = game.phase
|
|
if game.phase == "roll":
|
|
runden += 1
|
|
# Der Gast geht in Runde zwei einmal raus und kommt zurück.
|
|
if rolle == "join" and not wieder_da and runden >= 2 and game.phase == "bid":
|
|
await _wiederkommen()
|
|
continue
|
|
var me: int = game.local_seat
|
|
if game.phase != "bid" or game.turn != me or not game.seats[me].alive:
|
|
gewartet = 0.0
|
|
continue
|
|
gewartet += 0.1
|
|
if gewartet < 0.2:
|
|
continue
|
|
var hand: Array = game.hand.get(me, [])
|
|
if not hand.is_empty() and (not BoosterDB.needs_bid(hand[0]) or not game.bid.is_empty()) and _rng.randf() < 0.7:
|
|
game._on_booster_chosen(hand[0], 0)
|
|
wuerfe += 1
|
|
await get_tree().create_timer(0.4).timeout
|
|
if not is_instance_valid(game) or game.turn != me or game.phase != "bid":
|
|
continue
|
|
var total := 0
|
|
for s in game.seats:
|
|
total += int(s.count)
|
|
var a: Dictionary = DiceAI.choose_action(game.my_values, total, game.bid, false, _rng)
|
|
if a.type == "challenge" and not game.bid.is_empty() and _rng.randf() < 0.3:
|
|
a = {"type": "exact"}
|
|
match a.type:
|
|
"bid":
|
|
game._on_bid_pressed(int(a.count), int(a.face))
|
|
"challenge":
|
|
game._on_challenge_pressed()
|
|
"exact":
|
|
game._on_exact_pressed()
|
|
genau += 1
|
|
zuege += 1
|
|
gewartet = -1.5
|
|
_pruef("%s: Partie endet über RPC (Runden=%d Züge=%d Würfe=%d Genau=%d)" % [rolle, runden, zuege, wuerfe, genau],
|
|
is_instance_valid(game) and game.phase == "over")
|
|
if rolle == "join":
|
|
_pruef("join: Wiedereinstieg hat geklappt", wieder_da)
|
|
# Nochmal: der Besitzer bittet darum, beide bekommen eine frische Partie.
|
|
var alt: Node = game
|
|
await get_tree().create_timer(0.5).timeout
|
|
if Net.is_owner:
|
|
Net.request_rematch()
|
|
var neu := await _warte(func(): game = _find(get_tree().root, "Game"); return game != null and game != alt, 20.0)
|
|
var laeuft := false
|
|
if neu:
|
|
laeuft = await _warte(func(): return game.phase == "bid" or game.phase == "roll", 20.0)
|
|
_pruef("%s: Nochmal im Netz bringt eine neue Partie (Platz %d)" % [rolle, game.local_seat if neu else -1],
|
|
neu and laeuft and game.local_seat >= 0)
|
|
# Kurz bleiben: sonst schliesst der Raum, bevor der Server-Läufer die
|
|
# neue Partie überhaupt gesehen hat.
|
|
await get_tree().create_timer(1.5).timeout
|
|
if is_instance_valid(game):
|
|
print("%s: '%s'" % [rolle, game.banner])
|
|
for i in game.seats.size():
|
|
print("%s: Platz %d %s count=%d alive=%s" % [rolle, i, game.seats[i].name, game.seats[i].count, game.seats[i].alive])
|
|
_fertig()
|
|
|
|
|
|
func _beitreten() -> void:
|
|
await _warte(func(): return FileAccess.file_exists(_code_datei), 80.0)
|
|
await get_tree().create_timer(0.5).timeout
|
|
Net.join_room(FileAccess.get_file_as_string(_code_datei).strip_edges(), "Gast")
|
|
|
|
|
|
## Verbindung reisst ab (kein bewusstes Verlassen), frisches Menü, dann der
|
|
## Weg des Knopfs "Zurück in Raum XY".
|
|
func _wiederkommen() -> void:
|
|
var alter_platz: int = game.local_seat
|
|
var alte_zuege := zuege
|
|
var code := Net.room_code
|
|
multiplayer.multiplayer_peer.close()
|
|
if Net.in_game:
|
|
Net._on_server_disconnected() # der Verlust-Handler, wie bei echtem Abbruch
|
|
await get_tree().create_timer(1.0).timeout
|
|
_pruef("join: Raum nach Abbruch gemerkt", Net.letzter_raum.get("code", "") == code)
|
|
game = null
|
|
Net.wieder_rein()
|
|
var ok := await _warte(func(): game = _find(get_tree().root, "Game"); return game != null, 60.0)
|
|
if not ok:
|
|
_pruef("join: nach Rückkehr kommt ein Spiel", false)
|
|
wieder_da = true
|
|
return
|
|
var zustand := await _warte(func(): return game.phase == "bid" or game.phase == "roll" or game.phase == "reveal", 60.0)
|
|
_pruef("join: nach Rückkehr kommt der Zustand", zustand)
|
|
_pruef("join: alter Platz zurück, kein Bot mehr",
|
|
game.local_seat == alter_platz and not game.seats[game.local_seat].ai)
|
|
_pruef("join: HUD steht wieder", game.hud != null and game.hud.hand_box != null)
|
|
_letzte_phase = ""
|
|
wieder_da = true
|
|
zuege = alte_zuege
|