This commit is contained in:
team3
2026-09-16 17:00:41 +02:00
parent f1c78f66f4
commit 9800c614bb
21 changed files with 497 additions and 191 deletions

View File

@@ -21,6 +21,10 @@ var tempo := 1.0
## Würfel je Platz zu Beginn. Bonuswürfel (Nachschub, Genau) füllen nur bis
## hierhin auf - so wird der Tisch über die Partie sicher leerer.
var dice_start := START_DICE
## Simulation: kein Würfelwurf, keine Physik - Werte werden direkt gezogen.
## Nur für `make sim`; fünfzig Partien in Sekunden statt Minuten.
var simulation := false
var runde := 0 ## laufende Rundennummer, für Anzeige und Messung
var rng := RandomNumberGenerator.new()
var seats: Array = [] ## [{peer, name, ai, count, alive}]
@@ -259,6 +263,7 @@ func _now() -> float:
func _phase_roll() -> void:
phase = "roll"
runde += 1
deadline = 0.0
reveal_total = 0
bid = {}
@@ -277,6 +282,15 @@ func _phase_roll() -> void:
table.set_cup_down(i, i != local_seat)
_push_state()
if simulation:
for i in _alive_seats():
host_values[i] = []
for _k in seats[i].count:
host_values[i].append(rng.randi_range(1, 6))
table.arrange_and_show(i, host_values[i], rng)
_push_state()
return
_stream = true
for i in _alive_seats():
table.throw_dice(i, rng)
@@ -369,6 +383,11 @@ func _all_values() -> Array:
## Würfel neu werfen und die Augenzahl danach übernehmen.
func _neu_werfen(seat: int, idxs: Array) -> void:
if simulation:
for k: int in idxs:
if k < host_values[seat].size():
host_values[seat][k] = rng.randi_range(1, 6)
return
_stream = true
_throw_subset(seat, idxs)
await _await_settled([seat])
@@ -415,10 +434,10 @@ func _phase_bid() -> Dictionary:
# Erst planen, dann passend dazu eine Münze werfen. Die kann die
# Lage ändern - also danach noch einmal entscheiden.
var a := DiceAI.choose_action(host_values[turn], _total_dice(), bid,
must_bid.get(turn, false), rng)
must_bid.get(turn, false), rng, _bot_wissen(turn))
if await _bot_muenze(turn, a):
a = DiceAI.choose_action(host_values[turn], _total_dice(), bid,
must_bid.get(turn, false), rng)
must_bid.get(turn, false), rng, _bot_wissen(turn))
if not _alive():
return {}
var res := _apply_action(turn, a)
@@ -433,7 +452,7 @@ func _phase_bid() -> Dictionary:
else:
# Zeit abgelaufen oder getrennt: automatisch entscheiden
var a := DiceAI.choose_action(host_values[turn], _total_dice(), bid,
must_bid.get(turn, false), rng)
must_bid.get(turn, false), rng, _bot_wissen(turn))
_log("%s wird automatisch gespielt." % seats[turn].name)
var res := _apply_action(turn, a)
if not res.is_empty():
@@ -442,6 +461,22 @@ func _phase_bid() -> Dictionary:
return {}
## Nachschub gibt es nur, wer wirklich hinten liegt: höchstens die halbe
## Startzahl. Gemessen: mit jedem Rückweg dehnt sich die Partie - einzelne
## liefen über 50 Runden.
func _hinten(seat: int) -> bool:
return seats[seat].count * 2 <= dice_start
## Was ein Platz über die anderen weiss: aufgedeckte Würfel und Zählfenster.
func _bot_wissen(seat: int) -> Dictionary:
var bekannt: Array = []
for o in peeked.get(seat, {}):
for paar in peeked[seat][o]:
bekannt.append(int(paar[1]))
return {"bekannt": bekannt, "fenster": gezaehlt.get(seat, {})}
## Gibt {} zurück wenn das Spiel weitergeht, sonst das Anfechtungs-Ergebnis.
func _apply_action(seat: int, a: Dictionary) -> Dictionary:
if a.type == "exact":
@@ -633,7 +668,7 @@ func _state_for(seat: int) -> Dictionary:
"bids": _seat_bids(),
"verlauf": verlauf.duplicate(true),
"topf_an": _topf_ziel,
"voll": seats[seat].count >= dice_start,
"voll": not _hinten(seat),
"log": log_lines.duplicate(),
"hand": (hand.get(seat, []) as Array).duplicate(),
}