# src/ai/l1_basic_ai.gd class_name L1BasicAI extends BaseAI const _C = preload("res://src/core/constants.gd") func _init(): ai_name = "Basic AI" func decide(hand: Array, table: Array, current_rank: int, config: RuleConfig) -> HandEvaluator.EvaluatedPlay: var moves := MoveGenerator.generate(hand, current_rank, config) var last_play := _last_non_pass(table) if last_play == null: return _smallest_play(moves) var candidates: Array = [] for m in moves: if m.type == -1: continue if m.type == last_play.type and m.primary_rank > last_play.primary_rank: candidates.append(m) elif (m.type == _C.TYPE_BOMB or m.type == _C.TYPE_ROCKET) and _beats(m, last_play, config): candidates.append(m) if candidates.is_empty(): return _pass_move() return _smallest_play(candidates) func _smallest_play(moves: Array) -> HandEvaluator.EvaluatedPlay: var best: HandEvaluator.EvaluatedPlay = null for m in moves: if m.type <= 0: continue if best == null or m.cards.size() < best.cards.size(): best = m elif m.cards.size() == best.cards.size() and m.primary_rank < best.primary_rank: best = m if best == null: return _pass_move() return best func _last_non_pass(table: Array) -> HandEvaluator.EvaluatedPlay: for i in range(table.size() - 1, -1, -1): if table[i].type != -1: return table[i] return null func _beats(a: HandEvaluator.EvaluatedPlay, b: HandEvaluator.EvaluatedPlay, config: RuleConfig) -> bool: return RuleEngine.compare(a, b, config) > 0 func _pass_move() -> HandEvaluator.EvaluatedPlay: var p := HandEvaluator.EvaluatedPlay.new() p.type = -1 p.primary_rank = 0 return p