use crate::core::logic::*; use crate::core::enums::*; #[test] 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); } #[test] 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); } #[test] 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); } #[test] 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); } #[test] 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 } #[test] 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]); }