fix: resolve 43 GDScript warnings and fix card display
- Rename shadowed variables (round->_round, seed->_seed, is_processing->_is_processing) - Prefix unused parameters with underscore throughout - Add @warning_ignore for false positive integer_division warnings - Fix unused_signal warnings in event_bus.gd - Fix CardNode display: move setup() after add_child() so @onready works - Redesign CardNode with Panel background, suit symbols, red/black colors - Delete unused _current_hint in TrainingController
This commit is contained in:
@@ -4,7 +4,7 @@ extends RefCounted
|
|||||||
|
|
||||||
var ai_name: String = "AI"
|
var ai_name: String = "AI"
|
||||||
|
|
||||||
func decide(hand: Array, table: Array, current_rank: int, config: RuleConfig) -> HandEvaluator.EvaluatedPlay:
|
func decide(_hand: Array, _table: Array, _current_rank: int, _config: RuleConfig) -> HandEvaluator.EvaluatedPlay:
|
||||||
var pass_play := HandEvaluator.EvaluatedPlay.new()
|
var pass_play := HandEvaluator.EvaluatedPlay.new()
|
||||||
pass_play.type = -1
|
pass_play.type = -1
|
||||||
pass_play.primary_rank = 0
|
pass_play.primary_rank = 0
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func _score_all(moves: Array, hand_size: int, current_rank: int) -> Array:
|
|||||||
results.append({"move": m, "score": score})
|
results.append({"move": m, "score": score})
|
||||||
return results
|
return results
|
||||||
|
|
||||||
func _score_move(play: HandEvaluator.EvaluatedPlay, hand_size: int, current_rank: int) -> float:
|
func _score_move(play: HandEvaluator.EvaluatedPlay, hand_size: int, _current_rank: int) -> float:
|
||||||
var score := 0.0
|
var score := 0.0
|
||||||
var remaining := hand_size - play.cards.size()
|
var remaining := hand_size - play.cards.size()
|
||||||
score += (27.0 - remaining) / 27.0 * 0.3
|
score += (27.0 - remaining) / 27.0 * 0.3
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ class Team:
|
|||||||
var score: int = 0
|
var score: int = 0
|
||||||
var current_level: int = 2
|
var current_level: int = 2
|
||||||
|
|
||||||
static func create_team(team_id: int, p1: int, p2: int) -> Team:
|
static func create_team(p_team_id: int, p1: int, p2: int) -> Team:
|
||||||
var t := Team.new()
|
var t := Team.new()
|
||||||
t.team_id = team_id
|
t.team_id = p_team_id
|
||||||
t.player_indices = [p1, p2]
|
t.player_indices = [p1, p2]
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ static func _rank_for(original_id: int) -> int:
|
|||||||
return 15
|
return 15
|
||||||
if original_id == 53:
|
if original_id == 53:
|
||||||
return 16
|
return 16
|
||||||
|
@warning_ignore("integer_division")
|
||||||
return 2 + (original_id / 4)
|
return 2 + (original_id / 4)
|
||||||
|
|
||||||
static func create(seed: int = -1) -> Deck:
|
static func create(p_seed: int = -1) -> Deck:
|
||||||
var d := Deck.new()
|
var d := Deck.new()
|
||||||
d._cards = []
|
d._cards = []
|
||||||
for deck_idx in range(2):
|
for deck_idx in range(2):
|
||||||
@@ -29,15 +30,15 @@ static func create(seed: int = -1) -> Deck:
|
|||||||
var c := Card.create(orig_id, suit, rank)
|
var c := Card.create(orig_id, suit, rank)
|
||||||
c.card_id = global_id
|
c.card_id = global_id
|
||||||
d._cards.append(c)
|
d._cards.append(c)
|
||||||
if seed >= 0:
|
if p_seed >= 0:
|
||||||
d._shuffle_with_seed(seed)
|
d._shuffle_with_seed(p_seed)
|
||||||
else:
|
else:
|
||||||
d._shuffle_random()
|
d._shuffle_random()
|
||||||
return d
|
return d
|
||||||
|
|
||||||
func _shuffle_with_seed(seed: int) -> void:
|
func _shuffle_with_seed(p_seed: int) -> void:
|
||||||
var rng := RandomNumberGenerator.new()
|
var rng := RandomNumberGenerator.new()
|
||||||
rng.seed = seed
|
rng.seed = p_seed
|
||||||
for i in range(_cards.size() - 1, 0, -1):
|
for i in range(_cards.size() - 1, 0, -1):
|
||||||
var j := rng.randi_range(0, i)
|
var j := rng.randi_range(0, i)
|
||||||
var tmp := _cards[i]
|
var tmp := _cards[i]
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ var teams: Array = []
|
|||||||
var player_hands: Array = [[], [], [], []]
|
var player_hands: Array = [[], [], [], []]
|
||||||
var player_names: Array[String] = ["Player", "AI-1", "AI-2", "AI-3"]
|
var player_names: Array[String] = ["Player", "AI-1", "AI-2", "AI-3"]
|
||||||
var player_human: Array[bool] = [true, false, false, false]
|
var player_human: Array[bool] = [true, false, false, false]
|
||||||
var round: Round
|
var _round: Round
|
||||||
var action_log: Array = []
|
var action_log: Array = []
|
||||||
var seed: int = 0
|
var _seed: int = 0
|
||||||
var finished_players: Array[int] = []
|
var finished_players: Array[int] = []
|
||||||
var current_winner_team: int = -1
|
var current_winner_team: int = -1
|
||||||
var game_end_reason: String = ""
|
var game_end_reason: String = ""
|
||||||
@@ -25,11 +25,11 @@ static func create(config: RuleConfig, seed_: int = -1) -> GameState:
|
|||||||
var gs := GameState.new()
|
var gs := GameState.new()
|
||||||
gs.rule_config = config
|
gs.rule_config = config
|
||||||
if seed_ >= 0:
|
if seed_ >= 0:
|
||||||
gs.seed = seed_
|
gs._seed = seed_
|
||||||
else:
|
else:
|
||||||
gs.seed = Time.get_unix_time_from_system() as int
|
gs._seed = Time.get_unix_time_from_system() as int
|
||||||
gs.teams = [_Actions.Team.create_team(0, 0, 2), _Actions.Team.create_team(1, 1, 3)]
|
gs.teams = [_Actions.Team.create_team(0, 0, 2), _Actions.Team.create_team(1, 1, 3)]
|
||||||
gs.round = Round.new()
|
gs._round = Round.new()
|
||||||
return gs
|
return gs
|
||||||
|
|
||||||
func get_team(player_idx: int) -> Actions.Team:
|
func get_team(player_idx: int) -> Actions.Team:
|
||||||
@@ -91,7 +91,7 @@ func to_packed_snapshot(for_player: int) -> Dictionary:
|
|||||||
"phase": phase,
|
"phase": phase,
|
||||||
"current_rank": current_rank,
|
"current_rank": current_rank,
|
||||||
"own_hand": _pack_hand(player_hands[for_player]),
|
"own_hand": _pack_hand(player_hands[for_player]),
|
||||||
"table": _pack_table(round.table),
|
"table": _pack_table(_round.table),
|
||||||
"finished": finished_players.duplicate(),
|
"finished": finished_players.duplicate(),
|
||||||
"team_scores": [teams[0].score, teams[1].score]
|
"team_scores": [teams[0].score, teams[1].score]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ static func _eval_three(reals: Array[Card], wilds: Array[Card], has_wild: bool)
|
|||||||
return _make_result(_C.TYPE_TRIPLE, reals[0].rank(), false, reals + wilds.slice(0, 2))
|
return _make_result(_C.TYPE_TRIPLE, reals[0].rank(), false, reals + wilds.slice(0, 2))
|
||||||
return null
|
return null
|
||||||
|
|
||||||
static func _eval_four(reals: Array[Card], wilds: Array[Card], has_wild: bool, current_rank: int, config: RuleConfig) -> EvaluatedPlay:
|
static func _eval_four(reals: Array[Card], wilds: Array[Card], has_wild: bool, _current_rank: int, _config: RuleConfig) -> EvaluatedPlay:
|
||||||
var all_cards := reals + wilds
|
var all_cards := reals + wilds
|
||||||
if not has_wild and reals.size() == 4:
|
if not has_wild and reals.size() == 4:
|
||||||
if _all_same_rank(reals):
|
if _all_same_rank(reals):
|
||||||
@@ -94,7 +94,7 @@ static func _eval_four(reals: Array[Card], wilds: Array[Card], has_wild: bool, c
|
|||||||
return _make_result(_C.TYPE_BOMB, reals[0].rank(), false, all_cards)
|
return _make_result(_C.TYPE_BOMB, reals[0].rank(), false, all_cards)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
static func _eval_multi(reals: Array[Card], wilds: Array[Card], has_wild: bool, current_rank: int, n: int, config: RuleConfig) -> EvaluatedPlay:
|
static func _eval_multi(reals: Array[Card], wilds: Array[Card], has_wild: bool, _current_rank: int, n: int, config: RuleConfig) -> EvaluatedPlay:
|
||||||
if not has_wild:
|
if not has_wild:
|
||||||
return _eval_pure_multiple(reals, n, config)
|
return _eval_pure_multiple(reals, n, config)
|
||||||
if n == 5:
|
if n == 5:
|
||||||
@@ -103,9 +103,11 @@ static func _eval_multi(reals: Array[Card], wilds: Array[Card], has_wild: bool,
|
|||||||
result = _eval_straight(reals, wilds, 5, config)
|
result = _eval_straight(reals, wilds, 5, config)
|
||||||
if result != null: return result
|
if result != null: return result
|
||||||
if n >= 6 and n % 2 == 0:
|
if n >= 6 and n % 2 == 0:
|
||||||
|
@warning_ignore("integer_division")
|
||||||
var result := _eval_consecutive_pairs(reals, wilds, n / 2, config)
|
var result := _eval_consecutive_pairs(reals, wilds, n / 2, config)
|
||||||
if result != null: return result
|
if result != null: return result
|
||||||
if n >= 6 and n % 3 == 0:
|
if n >= 6 and n % 3 == 0:
|
||||||
|
@warning_ignore("integer_division")
|
||||||
var result := _eval_steel_plate(reals, wilds, n / 3, config)
|
var result := _eval_steel_plate(reals, wilds, n / 3, config)
|
||||||
if result != null: return result
|
if result != null: return result
|
||||||
if n >= 5:
|
if n >= 5:
|
||||||
@@ -116,6 +118,7 @@ static func _eval_multi(reals: Array[Card], wilds: Array[Card], has_wild: bool,
|
|||||||
static func _eval_pure_multiple(reals: Array[Card], n: int, config: RuleConfig) -> EvaluatedPlay:
|
static func _eval_pure_multiple(reals: Array[Card], n: int, config: RuleConfig) -> EvaluatedPlay:
|
||||||
if n >= 5 and _is_straight(reals, config):
|
if n >= 5 and _is_straight(reals, config):
|
||||||
return _make_result(_C.TYPE_STRAIGHT, reals[n-1].rank(), true, reals)
|
return _make_result(_C.TYPE_STRAIGHT, reals[n-1].rank(), true, reals)
|
||||||
|
@warning_ignore("integer_division")
|
||||||
if n >= 6 and n % 2 == 0 and _is_consecutive_pairs(reals, n / 2):
|
if n >= 6 and n % 2 == 0 and _is_consecutive_pairs(reals, n / 2):
|
||||||
return _make_result(_C.TYPE_CONSECUTIVE_PAIRS, reals[n-1].rank(), true, reals)
|
return _make_result(_C.TYPE_CONSECUTIVE_PAIRS, reals[n-1].rank(), true, reals)
|
||||||
if n == 5 and _is_triple_plus_two(reals):
|
if n == 5 and _is_triple_plus_two(reals):
|
||||||
@@ -156,13 +159,13 @@ static func _eval_straight(reals: Array[Card], wilds: Array[Card], n: int, confi
|
|||||||
return _make_result(_C.TYPE_STRAIGHT, max_rank, w == 0, reals + wilds)
|
return _make_result(_C.TYPE_STRAIGHT, max_rank, w == 0, reals + wilds)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
static func _eval_consecutive_pairs(reals: Array[Card], wilds: Array[Card], pair_count: int, config: RuleConfig) -> EvaluatedPlay:
|
static func _eval_consecutive_pairs(reals: Array[Card], wilds: Array[Card], pair_count: int, _config: RuleConfig) -> EvaluatedPlay:
|
||||||
if reals.size() + wilds.size() != pair_count * 2: return null
|
if reals.size() + wilds.size() != pair_count * 2: return null
|
||||||
if wilds.is_empty() and _is_consecutive_pairs(reals, pair_count):
|
if wilds.is_empty() and _is_consecutive_pairs(reals, pair_count):
|
||||||
return _make_result(_C.TYPE_CONSECUTIVE_PAIRS, reals[reals.size()-1].rank(), true, reals)
|
return _make_result(_C.TYPE_CONSECUTIVE_PAIRS, reals[reals.size()-1].rank(), true, reals)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
static func _eval_steel_plate(reals: Array[Card], wilds: Array[Card], triple_count: int, config: RuleConfig) -> EvaluatedPlay:
|
static func _eval_steel_plate(reals: Array[Card], wilds: Array[Card], triple_count: int, _config: RuleConfig) -> EvaluatedPlay:
|
||||||
if reals.size() + wilds.size() != triple_count * 3: return null
|
if reals.size() + wilds.size() != triple_count * 3: return null
|
||||||
if wilds.is_empty() and _is_steel_plate(reals):
|
if wilds.is_empty() and _is_steel_plate(reals):
|
||||||
return _make_result(_C.TYPE_STEEL_PLATE, reals[reals.size()-1].rank(), true, reals)
|
return _make_result(_C.TYPE_STEEL_PLATE, reals[reals.size()-1].rank(), true, reals)
|
||||||
@@ -180,7 +183,7 @@ static func _is_straight(cards: Array[Card], config: RuleConfig) -> bool:
|
|||||||
if not config.straight_extends_to_ace and cards[cards.size()-1].rank() > 14: return false
|
if not config.straight_extends_to_ace and cards[cards.size()-1].rank() > 14: return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
static func _is_consecutive_pairs(cards: Array[Card], pair_count: int) -> bool:
|
static func _is_consecutive_pairs(cards: Array[Card], _pair_count: int) -> bool:
|
||||||
for i in range(0, cards.size(), 2):
|
for i in range(0, cards.size(), 2):
|
||||||
if cards[i].rank() != cards[i+1].rank(): return false
|
if cards[i].rank() != cards[i+1].rank(): return false
|
||||||
for i in range(0, cards.size() - 2, 2):
|
for i in range(0, cards.size() - 2, 2):
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ var is_cleared: bool = false
|
|||||||
func can_pass() -> bool:
|
func can_pass() -> bool:
|
||||||
return not table.is_empty()
|
return not table.is_empty()
|
||||||
|
|
||||||
func add_play(play: HandEvaluator.EvaluatedPlay, player_idx: int) -> void:
|
func add_play(play: HandEvaluator.EvaluatedPlay, _player_idx: int) -> void:
|
||||||
table.append(play)
|
table.append(play)
|
||||||
if play.type == -1:
|
if play.type == -1:
|
||||||
pass_count += 1
|
pass_count += 1
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ static func can_play(
|
|||||||
play: HandEvaluator.EvaluatedPlay,
|
play: HandEvaluator.EvaluatedPlay,
|
||||||
table_history: Array,
|
table_history: Array,
|
||||||
last_player_idx: int,
|
last_player_idx: int,
|
||||||
current_rank: int,
|
_current_rank: int,
|
||||||
config: RuleConfig
|
config: RuleConfig
|
||||||
) -> Dictionary:
|
) -> Dictionary:
|
||||||
if play.type == -1:
|
if play.type == -1:
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ signal game_ended(winner_team: int, reason: String)
|
|||||||
|
|
||||||
var game_state: GameState
|
var game_state: GameState
|
||||||
var ai_players: Dictionary = {}
|
var ai_players: Dictionary = {}
|
||||||
var is_processing: bool = false
|
var _is_processing: bool = false
|
||||||
|
|
||||||
func start_game(config: RuleConfig, human_idx: int = 0, seed_: int = -1) -> void:
|
func start_game(config: RuleConfig, human_idx: int = 0, seed_: int = -1) -> void:
|
||||||
game_state = GameState.create(config, seed_)
|
game_state = GameState.create(config, seed_)
|
||||||
@@ -20,37 +20,37 @@ func start_game(config: RuleConfig, human_idx: int = 0, seed_: int = -1) -> void
|
|||||||
for i in range(4):
|
for i in range(4):
|
||||||
if not game_state.player_human[i]:
|
if not game_state.player_human[i]:
|
||||||
ai_players[i] = L2RuleAI.new()
|
ai_players[i] = L2RuleAI.new()
|
||||||
var deck := Deck.create(game_state.seed)
|
var deck := Deck.create(game_state._seed)
|
||||||
game_state.deal_cards(deck)
|
game_state.deal_cards(deck)
|
||||||
game_state.phase = GameState.Phase.PLAY
|
game_state.phase = GameState.Phase.PLAY
|
||||||
game_state.round.active_player_idx = 0
|
game_state._round.active_player_idx = 0
|
||||||
state_changed.emit()
|
state_changed.emit()
|
||||||
|
|
||||||
func handle_human_play(cards: Array) -> Dictionary:
|
func handle_human_play(cards: Array) -> Dictionary:
|
||||||
if is_processing:
|
if _is_processing:
|
||||||
return {"ok": false, "error_code": 1, "data": null}
|
return {"ok": false, "error_code": 1, "data": null}
|
||||||
var hand := game_state.get_hand(game_state.round.active_player_idx)
|
var hand := game_state.get_hand(game_state._round.active_player_idx)
|
||||||
var play := HandEvaluator.evaluate(cards, game_state.current_rank, game_state.rule_config)
|
var play := HandEvaluator.evaluate(cards, game_state.current_rank, game_state.rule_config)
|
||||||
if play == null or play.type == -1:
|
if play == null or play.type == -1:
|
||||||
return {"ok": false, "error_code": 1, "data": null}
|
return {"ok": false, "error_code": 1, "data": null}
|
||||||
var last_idx := game_state.round.last_non_pass_player()
|
var last_idx := game_state._round.last_non_pass_player()
|
||||||
var result := RuleEngine.can_play(hand, play, game_state.round.table, last_idx, game_state.current_rank, game_state.rule_config)
|
var result := RuleEngine.can_play(hand, play, game_state._round.table, last_idx, game_state.current_rank, game_state.rule_config)
|
||||||
if not result.ok:
|
if not result.ok:
|
||||||
return result
|
return result
|
||||||
_apply_play(game_state.round.active_player_idx, play)
|
_apply_play(game_state._round.active_player_idx, play)
|
||||||
_advance_turn()
|
_advance_turn()
|
||||||
return {"ok": true, "error_code": 0, "data": null}
|
return {"ok": true, "error_code": 0, "data": null}
|
||||||
|
|
||||||
func handle_human_pass() -> Dictionary:
|
func handle_human_pass() -> Dictionary:
|
||||||
if is_processing:
|
if _is_processing:
|
||||||
return {"ok": false, "error_code": 1, "data": null}
|
return {"ok": false, "error_code": 1, "data": null}
|
||||||
var old_last := game_state.round.last_non_pass_player()
|
var old_last := game_state._round.last_non_pass_player()
|
||||||
if old_last >= 0 and old_last == game_state.round.active_player_idx:
|
if old_last >= 0 and old_last == game_state._round.active_player_idx:
|
||||||
return {"ok": false, "error_code": 3, "data": null}
|
return {"ok": false, "error_code": 3, "data": null}
|
||||||
var pass_play := HandEvaluator.EvaluatedPlay.new()
|
var pass_play := HandEvaluator.EvaluatedPlay.new()
|
||||||
pass_play.type = -1
|
pass_play.type = -1
|
||||||
pass_play.primary_rank = 0
|
pass_play.primary_rank = 0
|
||||||
_apply_play(game_state.round.active_player_idx, pass_play)
|
_apply_play(game_state._round.active_player_idx, pass_play)
|
||||||
_advance_turn()
|
_advance_turn()
|
||||||
return {"ok": true, "error_code": 0, "data": null}
|
return {"ok": true, "error_code": 0, "data": null}
|
||||||
|
|
||||||
@@ -61,10 +61,10 @@ func _apply_play(player_idx: int, play: HandEvaluator.EvaluatedPlay) -> void:
|
|||||||
action.player_idx = player_idx
|
action.player_idx = player_idx
|
||||||
action.action_type = "PASS" if play.type == -1 else "PLAY"
|
action.action_type = "PASS" if play.type == -1 else "PLAY"
|
||||||
action.cards = play.cards.duplicate(false)
|
action.cards = play.cards.duplicate(false)
|
||||||
action.seq_id = game_state.round.next_seq()
|
action.seq_id = game_state._round.next_seq()
|
||||||
action.timestamp = Time.get_unix_time_from_system()
|
action.timestamp = Time.get_unix_time_from_system() as int
|
||||||
game_state.action_log.append(action)
|
game_state.action_log.append(action)
|
||||||
game_state.round.add_play(play, player_idx)
|
game_state._round.add_play(play, player_idx)
|
||||||
var hand: Array = game_state.get_hand(player_idx)
|
var hand: Array = game_state.get_hand(player_idx)
|
||||||
if hand.is_empty() and not game_state.is_player_finished(player_idx):
|
if hand.is_empty() and not game_state.is_player_finished(player_idx):
|
||||||
game_state.add_finished_player(player_idx)
|
game_state.add_finished_player(player_idx)
|
||||||
@@ -77,19 +77,19 @@ func _apply_play(player_idx: int, play: HandEvaluator.EvaluatedPlay) -> void:
|
|||||||
EventBus.bomb_detonated.emit(player_idx, play.primary_rank)
|
EventBus.bomb_detonated.emit(player_idx, play.primary_rank)
|
||||||
|
|
||||||
func _advance_turn() -> void:
|
func _advance_turn() -> void:
|
||||||
var hand: Array = game_state.get_hand(game_state.round.active_player_idx)
|
var hand: Array = game_state.get_hand(game_state._round.active_player_idx)
|
||||||
if hand.is_empty():
|
if hand.is_empty():
|
||||||
var partner := game_state.get_partner(game_state.round.active_player_idx)
|
var partner := game_state.get_partner(game_state._round.active_player_idx)
|
||||||
if not game_state.is_player_finished(partner):
|
if not game_state.is_player_finished(partner):
|
||||||
game_state.round.active_player_idx = partner
|
game_state._round.active_player_idx = partner
|
||||||
game_state.round.reset_for_new_round()
|
game_state._round.reset_for_new_round()
|
||||||
else:
|
else:
|
||||||
_next_alive_player()
|
_next_alive_player()
|
||||||
elif game_state.round.is_cleared:
|
elif game_state._round.is_cleared:
|
||||||
game_state.round.reset_for_new_round()
|
game_state._round.reset_for_new_round()
|
||||||
else:
|
else:
|
||||||
_next_alive_player()
|
_next_alive_player()
|
||||||
var current := game_state.round.active_player_idx
|
var current := game_state._round.active_player_idx
|
||||||
turn_ready.emit(current, game_state.player_human[current])
|
turn_ready.emit(current, game_state.player_human[current])
|
||||||
EventBus.turn_changed.emit(current)
|
EventBus.turn_changed.emit(current)
|
||||||
if not game_state.player_human[current]:
|
if not game_state.player_human[current]:
|
||||||
@@ -97,8 +97,8 @@ func _advance_turn() -> void:
|
|||||||
|
|
||||||
func _next_alive_player() -> void:
|
func _next_alive_player() -> void:
|
||||||
for _i in range(4):
|
for _i in range(4):
|
||||||
game_state.round.active_player_idx = (game_state.round.active_player_idx + 1) % 4
|
game_state._round.active_player_idx = (game_state._round.active_player_idx + 1) % 4
|
||||||
if not game_state.is_player_finished(game_state.round.active_player_idx):
|
if not game_state.is_player_finished(game_state._round.active_player_idx):
|
||||||
return
|
return
|
||||||
|
|
||||||
func _trigger_ai(player_idx: int) -> void:
|
func _trigger_ai(player_idx: int) -> void:
|
||||||
@@ -106,7 +106,7 @@ func _trigger_ai(player_idx: int) -> void:
|
|||||||
if ai == null:
|
if ai == null:
|
||||||
return
|
return
|
||||||
var hand8: Array = game_state.get_hand(player_idx)
|
var hand8: Array = game_state.get_hand(player_idx)
|
||||||
var decision: HandEvaluator.EvaluatedPlay = ai.decide(hand8, game_state.round.table, game_state.current_rank, game_state.rule_config)
|
var decision: HandEvaluator.EvaluatedPlay = ai.decide(hand8, game_state._round.table, game_state.current_rank, game_state.rule_config)
|
||||||
if decision.type == -1:
|
if decision.type == -1:
|
||||||
_apply_play(player_idx, decision)
|
_apply_play(player_idx, decision)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -2,15 +2,13 @@
|
|||||||
class_name TrainingController
|
class_name TrainingController
|
||||||
extends GameController
|
extends GameController
|
||||||
|
|
||||||
var _current_hint: HandEvaluator.EvaluatedPlay = null
|
|
||||||
|
|
||||||
func get_hint() -> HandEvaluator.EvaluatedPlay:
|
func get_hint() -> HandEvaluator.EvaluatedPlay:
|
||||||
var hand := game_state.get_hand(game_state.round.active_player_idx)
|
var hand := game_state.get_hand(game_state._round.active_player_idx)
|
||||||
if hand.is_empty():
|
if hand.is_empty():
|
||||||
return null
|
return null
|
||||||
var ai := L2RuleAI.new()
|
var ai := L2RuleAI.new()
|
||||||
return ai.decide(hand, game_state.round.table, game_state.current_rank, game_state.rule_config)
|
return ai.decide(hand, game_state._round.table, game_state.current_rank, game_state.rule_config)
|
||||||
|
|
||||||
func get_all_legal_moves() -> Array:
|
func get_all_legal_moves() -> Array:
|
||||||
var hand := game_state.get_hand(game_state.round.active_player_idx)
|
var hand := game_state.get_hand(game_state._round.active_player_idx)
|
||||||
return MoveGenerator.generate(hand, game_state.current_rank, game_state.rule_config)
|
return MoveGenerator.generate(hand, game_state.current_rank, game_state.rule_config)
|
||||||
|
|||||||
@@ -7,8 +7,12 @@ signal card_double_clicked(card_node: CardNode)
|
|||||||
var card_data: Card = null
|
var card_data: Card = null
|
||||||
var is_selected: bool = false
|
var is_selected: bool = false
|
||||||
|
|
||||||
@onready var texture_rect: TextureRect = $TextureRect
|
@onready var panel: Panel = $Panel
|
||||||
@onready var label: Label = $Label
|
@onready var rank_label: Label = $Panel/RankLabel
|
||||||
|
@onready var suit_label: Label = $Panel/SuitLabel
|
||||||
|
|
||||||
|
const SUIT_SYMBOLS := ["\u2660", "\u2665", "\u2663", "\u2666", "SJ", "BJ"]
|
||||||
|
const RANK_NAMES := ["", "", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "SJ", "BJ"]
|
||||||
|
|
||||||
func setup(card: Card) -> void:
|
func setup(card: Card) -> void:
|
||||||
card_data = card
|
card_data = card
|
||||||
@@ -17,17 +21,43 @@ func setup(card: Card) -> void:
|
|||||||
func update_display() -> void:
|
func update_display() -> void:
|
||||||
if card_data == null:
|
if card_data == null:
|
||||||
return
|
return
|
||||||
var suits := ["S", "H", "C", "D", "SJ", "BJ"]
|
|
||||||
var ranks := ["", "", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "SJ", "BJ"]
|
|
||||||
var suit := card_data.suit()
|
var suit := card_data.suit()
|
||||||
var rank := card_data.rank()
|
var rank := card_data.rank()
|
||||||
if rank < ranks.size() and suit < suits.size() and label:
|
var is_red := suit == 1 or suit == 3
|
||||||
label.text = "%s %s" % [suits[suit], ranks[rank]]
|
var color := Color.RED if is_red else Color.BLACK
|
||||||
modulate = Color.WHITE if not is_selected else Color(1.2, 1.2, 0.8)
|
|
||||||
|
if rank_label:
|
||||||
|
rank_label.text = RANK_NAMES[rank]
|
||||||
|
rank_label.add_theme_color_override("font_color", color)
|
||||||
|
rank_label.add_theme_font_size_override("font_size", 14)
|
||||||
|
|
||||||
|
if suit_label:
|
||||||
|
suit_label.text = SUIT_SYMBOLS[suit]
|
||||||
|
suit_label.add_theme_color_override("font_color", color)
|
||||||
|
suit_label.add_theme_font_size_override("font_size", 24)
|
||||||
|
|
||||||
|
_update_panel()
|
||||||
|
|
||||||
|
func _update_panel() -> void:
|
||||||
|
if panel == null:
|
||||||
|
return
|
||||||
|
var sbox := StyleBoxFlat.new()
|
||||||
|
sbox.bg_color = Color.WHITE if not is_selected else Color(1.0, 1.0, 0.6)
|
||||||
|
sbox.set_corner_radius_all(6)
|
||||||
|
sbox.border_width_left = 2
|
||||||
|
sbox.border_width_right = 2
|
||||||
|
sbox.border_width_top = 2
|
||||||
|
sbox.border_width_bottom = 2
|
||||||
|
sbox.border_color = Color(0.3, 0.3, 0.3)
|
||||||
|
sbox.content_margin_left = 2
|
||||||
|
sbox.content_margin_right = 2
|
||||||
|
sbox.content_margin_top = 2
|
||||||
|
sbox.content_margin_bottom = 2
|
||||||
|
panel.add_theme_stylebox_override("panel", sbox)
|
||||||
|
|
||||||
func set_selected(sel: bool) -> void:
|
func set_selected(sel: bool) -> void:
|
||||||
is_selected = sel
|
is_selected = sel
|
||||||
update_display()
|
_update_panel()
|
||||||
|
|
||||||
func _on_gui_input(event: InputEvent) -> void:
|
func _on_gui_input(event: InputEvent) -> void:
|
||||||
if event is InputEventMouseButton:
|
if event is InputEventMouseButton:
|
||||||
|
|||||||
@@ -1,16 +1,40 @@
|
|||||||
[gd_scene load_steps=2 format=3 uid="uid://card_node"]
|
[gd_scene load_steps=2 format=3 uid="uid://card_node"]
|
||||||
[ext_resource type="Script" path="res://src/ui/components/card_node.gd" id="1_script"]
|
[ext_resource type="Script" path="res://src/ui/components/card_node.gd" id="1_script"]
|
||||||
|
|
||||||
[node name="CardNode" type="Control"]
|
[node name="CardNode" type="Control"]
|
||||||
custom_minimum_size = Vector2(80, 120)
|
custom_minimum_size = Vector2(70, 100)
|
||||||
size = Vector2(80, 120)
|
mouse_filter = 1
|
||||||
|
size = Vector2(70, 100)
|
||||||
script = ExtResource("1_script")
|
script = ExtResource("1_script")
|
||||||
[node name="TextureRect" type="TextureRect" parent="."]
|
|
||||||
layout_mode = 0
|
[node name="Panel" type="Panel" parent="."]
|
||||||
offset_right = 80.0
|
layout_mode = 1
|
||||||
offset_bottom = 120.0
|
mouse_filter = 2
|
||||||
[node name="Label" type="Label" parent="."]
|
anchors_preset = 15
|
||||||
layout_mode = 0
|
anchor_right = 1.0
|
||||||
offset_right = 80.0
|
anchor_bottom = 1.0
|
||||||
offset_bottom = 120.0
|
|
||||||
|
[node name="RankLabel" type="Label" parent="Panel"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 2
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_top = -18.0
|
||||||
|
offset_right = 12.0
|
||||||
|
offset_bottom = -2.0
|
||||||
|
text = "A"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
|
||||||
|
[node name="SuitLabel" type="Label" parent="Panel"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = -20.0
|
||||||
|
offset_right = 20.0
|
||||||
|
offset_bottom = 20.0
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
|
|||||||
@@ -13,17 +13,22 @@ const CARD_SCENE := preload("res://src/ui/components/card_node.tscn")
|
|||||||
var training_controller: TrainingController = null
|
var training_controller: TrainingController = null
|
||||||
|
|
||||||
func update_hand(hand: Array) -> void:
|
func update_hand(hand: Array) -> void:
|
||||||
|
print("[DEBUG] HandArea.update_hand called, cards count: ", hand.size())
|
||||||
for cn in card_nodes:
|
for cn in card_nodes:
|
||||||
cn.queue_free()
|
cn.queue_free()
|
||||||
card_nodes.clear()
|
card_nodes.clear()
|
||||||
selected_cards.clear()
|
selected_cards.clear()
|
||||||
for c in hand:
|
for c in hand:
|
||||||
var node := CARD_SCENE.instantiate() as CardNode
|
var node := CARD_SCENE.instantiate() as CardNode
|
||||||
|
if node == null:
|
||||||
|
print("[DEBUG] CardNode instantiate returned null!")
|
||||||
|
continue
|
||||||
|
add_child(node)
|
||||||
node.setup(c)
|
node.setup(c)
|
||||||
node.card_clicked.connect(_on_card_clicked)
|
node.card_clicked.connect(_on_card_clicked)
|
||||||
node.card_double_clicked.connect(_on_card_double_clicked)
|
node.card_double_clicked.connect(_on_card_double_clicked)
|
||||||
add_child(node)
|
|
||||||
card_nodes.append(node)
|
card_nodes.append(node)
|
||||||
|
print("[DEBUG] CardNodes created: ", card_nodes.size())
|
||||||
|
|
||||||
func _on_card_clicked(card_node: CardNode) -> void:
|
func _on_card_clicked(card_node: CardNode) -> void:
|
||||||
card_node.set_selected(not card_node.is_selected)
|
card_node.set_selected(not card_node.is_selected)
|
||||||
|
|||||||
@@ -65,10 +65,14 @@ func _on_hint_pressed() -> void:
|
|||||||
hand_area.selected_cards.append(card)
|
hand_area.selected_cards.append(card)
|
||||||
if status_label: status_label.text = "建议牌型: %s (rank=%d)" % [hint.type, hint.primary_rank]
|
if status_label: status_label.text = "建议牌型: %s (rank=%d)" % [hint.type, hint.primary_rank]
|
||||||
|
|
||||||
func _on_game_ended(winner_team: int, reason: String) -> void:
|
func _on_game_ended(winner_team: int, _reason: String) -> void:
|
||||||
if status_label: status_label.text = "游戏结束! 队伍 %d 获胜" % winner_team
|
if status_label: status_label.text = "游戏结束! 队伍 %d 获胜" % winner_team
|
||||||
if hand_area: hand_area.disable_input()
|
if hand_area: hand_area.disable_input()
|
||||||
|
|
||||||
func _refresh_ui() -> void:
|
func _refresh_ui() -> void:
|
||||||
if controller and controller.game_state and hand_area:
|
if controller and controller.game_state and hand_area:
|
||||||
hand_area.update_hand(controller.game_state.get_hand(0))
|
var hand: Array = controller.game_state.get_hand(0)
|
||||||
|
print("[DEBUG] _refresh_ui: hand size = ", hand.size())
|
||||||
|
hand_area.update_hand(hand)
|
||||||
|
else:
|
||||||
|
print("[DEBUG] _refresh_ui: controller=", controller, " game_state=", controller.game_state if controller else null, " hand_area=", hand_area)
|
||||||
|
|||||||
Reference in New Issue
Block a user