update
This commit is contained in:
@@ -5,9 +5,12 @@ extends RefCounted
|
||||
|
||||
var pref: Array[int] = []
|
||||
var greed: float = 0.5 ## wie stark der Bot Gold hortet
|
||||
var difficulty: int = Data.Difficulty.NORMAL
|
||||
var opponent: PlayerState = null ## bekannter Gegner der Runde, für Konterwahl
|
||||
|
||||
|
||||
func setup(rand: RandomNumberGenerator) -> void:
|
||||
func setup(rand: RandomNumberGenerator, p_difficulty: int = Data.Difficulty.NORMAL) -> void:
|
||||
difficulty = p_difficulty
|
||||
var all: Array[int] = []
|
||||
for e in Data.ELEMENT_COUNT:
|
||||
all.append(e)
|
||||
@@ -19,18 +22,23 @@ func setup(rand: RandomNumberGenerator) -> void:
|
||||
all[i] = all[j]
|
||||
all[j] = tmp
|
||||
pref = [all[0], all[1], all[2]]
|
||||
greed = rand.randf_range(0.3, 0.8)
|
||||
var g: Array = Data.BOT_GREED[difficulty]
|
||||
greed = rand.randf_range(g[0], g[1])
|
||||
|
||||
|
||||
func take_turn(p: PlayerState, pool: Pool, rand: RandomNumberGenerator) -> void:
|
||||
func take_turn(p: PlayerState, pool: Pool, rand: RandomNumberGenerator, opp: PlayerState = null) -> void:
|
||||
opponent = opp
|
||||
_do_upgrades(p, pool)
|
||||
_do_buys(p, pool)
|
||||
_do_placements(p)
|
||||
_do_upgrades(p, pool)
|
||||
var keep := int(lerpf(2.0, 18.0, greed))
|
||||
# Wer kurz vor einem Upgrade steht, würfelt gezielt nach Futter.
|
||||
var hunting := _closest_upgrade_gap(p) <= 3
|
||||
# Leichte Bots jagen nicht, schwere immer.
|
||||
var hunting := difficulty != Data.Difficulty.LEICHT and _closest_upgrade_gap(p) <= 3
|
||||
var rolls := 3 if hunting else 1
|
||||
if difficulty == Data.Difficulty.SCHWER:
|
||||
rolls += 1
|
||||
for i in rolls:
|
||||
if p.gold > keep + Data.REROLL_COST and (hunting or rand.randf() < 0.6):
|
||||
p.reroll(pool, rand)
|
||||
@@ -71,8 +79,13 @@ func arrange(p: PlayerState, opp: PlayerState) -> void:
|
||||
return _min_dist(a, enemy_tanks) > _min_dist(b, enemy_tanks))
|
||||
units.sort_custom(func(a, b): return a.role == Data.Role.TANK and b.role != Data.Role.TANK)
|
||||
for u in units:
|
||||
var rows: Array = [0, 1, 2, 3] if u.role == Data.Role.TANK else [3, 2, 1, 0]
|
||||
var cols: Array = tank_cols if u.role == Data.Role.TANK else far_cols
|
||||
# Heiler direkt hinter die Tanks, sonst reicht ihre Heilung (2 Felder) nicht.
|
||||
var rows: Array
|
||||
match u.role:
|
||||
Data.Role.TANK: rows = [0, 1, 2, 3]
|
||||
Data.Role.HEILER: rows = [1, 2, 0, 3]
|
||||
_: rows = [3, 2, 1, 0]
|
||||
var cols: Array = tank_cols if u.role != Data.Role.DPS else far_cols
|
||||
var placed := false
|
||||
for r in rows:
|
||||
for c in cols:
|
||||
@@ -179,6 +192,13 @@ func _pick_bench_for_board(p: PlayerState) -> int:
|
||||
|
||||
func _pick_element(p: PlayerState) -> int:
|
||||
var counts := p.trait_counts()
|
||||
# Konter: schlägt eines meiner Lieblingselemente das häufigste Element des Gegners,
|
||||
# nehme ich das. Schwere Bots kontern auch außerhalb ihrer Vorlieben.
|
||||
var dominant := _dominant_element(opponent)
|
||||
if dominant >= 0:
|
||||
var counter := Data.beaten_by(dominant)
|
||||
if pref.has(counter) or difficulty == Data.Difficulty.SCHWER:
|
||||
return counter
|
||||
var best := pref[0]
|
||||
var best_c := -1
|
||||
for e in pref:
|
||||
@@ -189,6 +209,23 @@ func _pick_element(p: PlayerState) -> int:
|
||||
return best
|
||||
|
||||
|
||||
## Häufigstes Hauptelement auf dem Brett eines Spielers, -1 wenn leer.
|
||||
func _dominant_element(p: PlayerState) -> int:
|
||||
if p == null or p.board.is_empty():
|
||||
return -1
|
||||
var counts := {}
|
||||
for u in p.board_units():
|
||||
var e: int = u.primary_element()
|
||||
counts[e] = counts.get(e, 0) + 1
|
||||
var best := -1
|
||||
var best_n := 1 # ab zwei Einheiten lohnt das Kontern
|
||||
for e in counts:
|
||||
if counts[e] > best_n:
|
||||
best_n = counts[e]
|
||||
best = e
|
||||
return best
|
||||
|
||||
|
||||
func _pick_hex(p: PlayerState, role: int) -> Vector2i:
|
||||
var rows: Array
|
||||
match role:
|
||||
|
||||
Reference in New Issue
Block a user