Spaces:
Running
Running
| use crate::core::logic::*; | |
| use crate::core::enums::*; | |
| fn test_opcode_draw() { | |
| let mut state = GameState::default(); | |
| state.players[0].deck = vec![1, 2, 3, 4, 5]; | |
| let db = CardDatabase { | |
| members: std::collections::HashMap::new(), | |
| lives: std::collections::HashMap::new(), | |
| members_vec: vec![], | |
| lives_vec: vec![], | |
| }; | |
| let ctx = AbilityContext { | |
| player_id: 0, | |
| ..AbilityContext::default() | |
| }; | |
| // O_DRAW, Value 2, Attr 0, Slot 0 | |
| let bytecode = vec![O_DRAW, 2, 0, 0, O_RETURN, 0, 0, 0]; | |
| state.resolve_bytecode(&db, &bytecode, &ctx); | |
| assert_eq!(state.players[0].hand.len(), 2); | |
| assert_eq!(state.players[0].deck.len(), 3); | |
| } | |
| fn test_opcode_blades() { | |
| let mut state = GameState::default(); | |
| state.players[0].stage[0] = 0; // Member ID 0 | |
| let db = CardDatabase { | |
| members: std::collections::HashMap::new(), | |
| lives: std::collections::HashMap::new(), | |
| members_vec: vec![], | |
| lives_vec: vec![], | |
| }; | |
| let ctx = AbilityContext { | |
| player_id: 0, | |
| area_idx: 0, | |
| ..AbilityContext::default() | |
| }; | |
| // O_BLADES, Value 3, Attr 0, Slot 4 (SELF) | |
| let bytecode = vec![O_BLADES, 3, 0, 4, O_RETURN, 0, 0, 0]; | |
| state.resolve_bytecode(&db, &bytecode, &ctx); | |
| assert_eq!(state.players[0].blade_buffs[0], 3); | |
| } | |
| fn test_opcode_hearts() { | |
| let mut state = GameState::default(); | |
| state.players[0].stage[0] = 0; | |
| let db = CardDatabase { | |
| members: std::collections::HashMap::new(), | |
| lives: std::collections::HashMap::new(), | |
| members_vec: vec![], | |
| lives_vec: vec![], | |
| }; | |
| let ctx = AbilityContext { | |
| player_id: 0, | |
| area_idx: 0, | |
| ..AbilityContext::default() | |
| }; | |
| // O_HEARTS, Value 1, Attr 1 (Red), Slot 4 (SELF) | |
| let bytecode = vec![O_HEARTS, 1, 1, 4, O_RETURN, 0, 0, 0]; | |
| state.resolve_bytecode(&db, &bytecode, &ctx); | |
| assert_eq!(state.players[0].heart_buffs[0][1], 1); | |
| } | |
| fn test_opcode_reduce_cost() { | |
| let mut state = GameState::default(); | |
| let db = CardDatabase { | |
| members: std::collections::HashMap::new(), | |
| lives: std::collections::HashMap::new(), | |
| members_vec: vec![], | |
| lives_vec: vec![], | |
| }; | |
| let ctx = AbilityContext { player_id: 0, ..AbilityContext::default() }; | |
| // O_REDUCE_COST, Value 2 | |
| let bytecode = vec![O_REDUCE_COST, 2, 0, 0, O_RETURN, 0, 0, 0]; | |
| state.resolve_bytecode(&db, &bytecode, &ctx); | |
| assert_eq!(state.players[0].cost_reduction, 2); | |
| } | |
| fn test_condition_count_hand() { | |
| let mut state = GameState::default(); | |
| state.players[0].hand = vec![1, 2, 3]; // 3 cards | |
| let db = CardDatabase { | |
| members: std::collections::HashMap::new(), | |
| lives: std::collections::HashMap::new(), | |
| members_vec: vec![], | |
| lives_vec: vec![], | |
| }; | |
| let ctx = AbilityContext { player_id: 0, ..AbilityContext::default() }; | |
| // Condition: C_HND (204), Value 3 | |
| // Effect: O_DRAW (10), Value 1 | |
| // Bytecode: [C_HND, 3, 0, 0, O_JUMP_F, 1, 0, 0, O_DRAW, 1, 0, 0, O_RETURN, 0, 0, 0] | |
| let bytecode = vec![ | |
| C_HND, 3, 0, 0, | |
| O_JUMP_F, 1, 0, 0, | |
| O_DRAW, 1, 0, 0, | |
| O_RETURN, 0, 0, 0 | |
| ]; | |
| // Case 1: Met | |
| state.players[0].deck = vec![100]; | |
| state.resolve_bytecode(&db, &bytecode, &ctx); | |
| assert_eq!(state.players[0].hand.len(), 4); | |
| // Case 2: Not Met | |
| state.players[0].hand = vec![1]; // 1 card | |
| state.players[0].deck = vec![200]; | |
| state.resolve_bytecode(&db, &bytecode, &ctx); | |
| assert_eq!(state.players[0].hand.len(), 1); // Stayed at 1 | |
| } | |
| fn test_opcode_play_member_from_hand() { | |
| let mut state = GameState::default(); | |
| state.players[0].hand = vec![10, 20]; // Card 10 at index 0, Card 20 at index 1 | |
| let mut members = std::collections::HashMap::new(); | |
| let test_member = MemberCard { | |
| card_id: 20, | |
| card_no: "TEST-001".to_string(), | |
| name: "Test Member".to_string(), | |
| cost: 0, | |
| hearts: [0; 7], | |
| blade_hearts: [0; 7], | |
| blades: 0, | |
| groups: vec![], | |
| units: vec![], | |
| abilities: vec![], | |
| volume_icons: 0, | |
| draw_icons: 0, | |
| ability_text: "".to_string(), | |
| char_id: 0, | |
| img_path: "".to_string(), | |
| }; | |
| members.insert(20, test_member.clone()); | |
| let mut db = CardDatabase { | |
| members, | |
| lives: std::collections::HashMap::new(), | |
| members_vec: vec![None; 21], | |
| lives_vec: vec![], | |
| }; | |
| db.members_vec[20] = Some(test_member); | |
| // We assume choice_index=1 (Card 20), target_slot=2 | |
| let ctx = AbilityContext { | |
| player_id: 0, | |
| choice_index: 1, | |
| target_slot: 2, | |
| ..AbilityContext::default() | |
| }; | |
| // O_PLAY_MEMBER_FROM_HAND (57) | |
| let bytecode = vec![O_PLAY_MEMBER_FROM_HAND, 0, 0, 0, O_RETURN, 0, 0, 0]; | |
| state.resolve_bytecode(&db, &bytecode, &ctx); | |
| // Card 20 should be on stage slot 2 | |
| assert_eq!(state.players[0].stage[2], 20); | |
| // Hand should have 1 card (Card 10) | |
| assert_eq!(state.players[0].hand.len(), 1); | |
| assert_eq!(state.players[0].hand[0], 10); | |
| // Tapped should be false | |
| assert!(!state.players[0].tapped_members[2]); | |
| } | |