Spaces:
Running
Running
| use crate::core::logic::*; | |
| use crate::core::enums::*; | |
| const TEST_CARDS: &str = r#"{ | |
| "member_db": { | |
| "0": { | |
| "card_id": 0, | |
| "card_no": "TEST-001", | |
| "name": "Test Member", | |
| "cost": 0, | |
| "hearts": [0, 0, 0, 0, 0, 0, 0], | |
| "blade_hearts": [0, 0, 0, 0, 0, 0, 0], | |
| "blades": 0, | |
| "groups": [], | |
| "units": [], | |
| "abilities": [], | |
| "rare": "R", | |
| "volume_icons": 0, | |
| "draw_icons": 0 | |
| } | |
| }, | |
| "live_db": {} | |
| }"#; | |
| fn test_baton_pass_restriction() { | |
| let db = CardDatabase::from_json(TEST_CARDS).unwrap(); | |
| let mut state = GameState { | |
| players: [ | |
| PlayerState { | |
| player_id: 0, | |
| hand: vec![0, 0], // Two test members | |
| deck: vec![0], // Non-empty deck to avoid Terminal | |
| ..PlayerState::default() | |
| }, | |
| PlayerState { | |
| player_id: 1, | |
| deck: vec![0], // Non-empty deck to avoid Terminal | |
| ..PlayerState::default() | |
| }, | |
| ], | |
| phase: Phase::Main, | |
| ..GameState::default() | |
| }; | |
| // 1. First play to slot 0 should succeed | |
| state.play_member(&db, 0, 0).expect("First play should succeed"); | |
| assert_eq!(state.players[0].stage[0], 0); | |
| assert!(state.players[0].moved_members_this_turn[0]); | |
| // 2. Second play (Baton Pass) to the SAME slot in the SAME turn should fail (Rule 9.6.2.1.2.1) | |
| let result = state.play_member(&db, 0, 0); | |
| assert!(result.is_err(), "Second play to same slot should fail this turn"); | |
| assert_eq!(result.unwrap_err(), "Already played/moved to this slot this turn"); | |
| // 3. get_legal_actions_into should also mask out slot 0 | |
| let mut mask = vec![false; 2000]; | |
| state.get_legal_actions_into(&db, &mut mask); | |
| // Action ID for hand_idx 0, slot 0 is 1 + 0*3 + 0 = 1 | |
| assert!(!mask[1], "Play to slot 0 should be masked out in legal actions"); | |
| // Action ID for hand_idx 0, slot 1 is 1 + 0*3 + 1 = 2 | |
| assert!(mask[2], "Play to slot 1 should still be legal"); | |
| // 4. End turn and start new turn | |
| state.end_main_phase(&db); // This advances to next player's Active phase (if first player) | |
| // Fast forward back to Player 0's Main Phase | |
| state.current_player = 0; | |
| state.phase = Phase::Main; | |
| state.players[0].untap_all(); // This should reset moved_members_this_turn | |
| assert!(!state.players[0].moved_members_this_turn[0]); | |
| // 5. Now Baton Pass to slot 0 should be legal | |
| state.get_legal_actions_into(&db, &mut mask); | |
| assert!(mask[1], "Play to slot 0 should be legal in the next turn"); | |
| state.play_member(&db, 0, 0).expect("Baton pass in next turn should succeed"); | |
| assert_eq!(state.players[0].baton_touch_count, 1); | |
| } | |