package main import ( "fmt" "math/rand" "time" ) // ======================== // 测试辅助结构 // ======================== type TestPlayer struct { UserID string Username string Character string HP, MaxHP int Shield bool Poisoned bool PoisonSteps int Curse bool Revive bool TimeBombTurns int SkipTurn bool RevealedCells map[int]string MonkeyBananaCount int ChickenItemCount int HippoDeathImmune bool } type TestGrid struct { Type string ItemID string Revealed bool } func NewTestPlayer(id, character string) *TestPlayer { maxHP := 4 if character == "elephant" { maxHP = 5 } else if character == "cat" { maxHP = 3 } return &TestPlayer{ UserID: id, Username: "Player_" + id, Character: character, HP: maxHP, MaxHP: maxHP, RevealedCells: make(map[int]string), } } // ======================== // 核心逻辑函数 // ======================== func testApplyDamage(target *TestPlayer, amount int) int { if target.HP <= 0 { return 0 } if target.Shield { target.Shield = false return 0 } if target.Character == "cat" { amount = 1 target.Curse = false } else if target.Curse { amount *= 2 target.Curse = false } target.HP -= amount if target.HP <= 0 { if target.Revive { target.Revive = false target.HP = 1 } else if target.Character == "hippo" && !target.HippoDeathImmune { if rand.Float32() < 0.55 { target.HP = 1 target.HippoDeathImmune = true } } } if target.HP < 0 { target.HP = 0 } return amount } func testHealPlayer(p *TestPlayer, amount int) { if p.HP < p.MaxHP { p.HP += amount if p.HP > p.MaxHP { p.HP = p.MaxHP } } } // ======================== // 测试结果 // ======================== var passed, failed int func assert(name string, condition bool, msg string) { if !condition { fmt.Printf(" ❌ %s: %s\n", name, msg) failed++ } else { passed++ } } // ======================== // 道具测试 // ======================== func TestMedkit() { fmt.Println("\n📦 测试: 医疗包") p := NewTestPlayer("1", "default") p.HP = 2 p.Poisoned = true p.PoisonSteps = 3 p.Poisoned = false p.PoisonSteps = 0 testHealPlayer(p, 1) assert("回复1血", p.HP == 3, fmt.Sprintf("期望HP=3, 实际HP=%d", p.HP)) assert("解除中毒", !p.Poisoned, "中毒状态未解除") } func TestBombTimer() { fmt.Println("\n📦 测试: 定时炸弹") // 普通玩家 p := NewTestPlayer("1", "default") p.TimeBombTurns = 3 for i := 0; i < 3; i++ { if p.TimeBombTurns > 0 { p.TimeBombTurns-- if p.TimeBombTurns == 0 { testApplyDamage(p, 2) } } } assert("3回合后扣2血", p.HP == 2, fmt.Sprintf("期望HP=2, 实际HP=%d", p.HP)) // 懒懒 p2 := NewTestPlayer("1", "sloth") p2.TimeBombTurns = 3 for i := 0; i < 3; i++ { if p2.TimeBombTurns > 0 { p2.TimeBombTurns-- if p2.TimeBombTurns == 0 { testApplyDamage(p2, 1) // 懒懒减伤 } } } assert("懒懒伤害降为1", p2.HP == 3, fmt.Sprintf("期望HP=3, 实际HP=%d", p2.HP)) } func TestPoison() { fmt.Println("\n📦 测试: 毒药瓶") p := NewTestPlayer("1", "default") p.Poisoned = true p.PoisonSteps = 0 for i := 0; i < 4; i++ { if p.Poisoned { p.PoisonSteps++ if p.PoisonSteps%2 == 0 { testApplyDamage(p, 1) } } } assert("每2回合扣1血(4回合扣2)", p.HP == 2, fmt.Sprintf("期望HP=2, 实际HP=%d", p.HP)) } func TestShield() { fmt.Println("\n📦 测试: 护盾") p := NewTestPlayer("1", "default") p.Shield = true testApplyDamage(p, 2) assert("免疫1次伤害", p.HP == 4, fmt.Sprintf("期望HP=4, 实际HP=%d", p.HP)) assert("使用后消失", !p.Shield, "护盾应消失") } func TestSkip() { fmt.Println("\n📦 测试: 好人卡") p := NewTestPlayer("1", "default") p.SkipTurn = true p.Shield = true assert("跳过回合", p.SkipTurn, "SkipTurn应为true") assert("附带护盾", p.Shield, "应带护盾效果") } func TestKnife() { fmt.Println("\n📦 测试: 飞刀") target := NewTestPlayer("2", "default") testApplyDamage(target, 1) assert("随机敌人1伤害", target.HP == 3, fmt.Sprintf("期望HP=3, 实际HP=%d", target.HP)) // 老虎飞刀 t1 := NewTestPlayer("2", "default") t2 := NewTestPlayer("3", "default") testApplyDamage(t1, 2) testApplyDamage(t2, 2) assert("老虎全体2伤害", t1.HP == 2 && t2.HP == 2, fmt.Sprintf("期望2,2 实际%d,%d", t1.HP, t2.HP)) } func TestRevive() { fmt.Println("\n📦 测试: 复活甲") p := NewTestPlayer("1", "default") p.Revive = true p.HP = 1 testApplyDamage(p, 5) assert("免疫一次死亡保留1血", p.HP == 1, fmt.Sprintf("期望HP=1, 实际HP=%d", p.HP)) assert("使用后消失", !p.Revive, "复活甲应消失") } func TestLightning() { fmt.Println("\n📦 测试: 闪电") players := []*TestPlayer{NewTestPlayer("1", "default"), NewTestPlayer("2", "default")} for _, p := range players { testApplyDamage(p, 1) } assert("全体扣1血", players[0].HP == 3 && players[1].HP == 3, "所有玩家应扣1血") } func TestCurse() { fmt.Println("\n📦 测试: 诅咒") p := NewTestPlayer("1", "default") p.Curse = true testApplyDamage(p, 1) assert("伤害翻倍", p.HP == 2, fmt.Sprintf("期望HP=2(4-1*2), 实际HP=%d", p.HP)) assert("触发后消失", !p.Curse, "诅咒应消失") } // ======================== // 角色测试 // ======================== func TestElephant() { fmt.Println("\n🐘 测试: 大象") p := NewTestPlayer("1", "elephant") assert("HP=5", p.MaxHP == 5, fmt.Sprintf("期望MaxHP=5, 实际=%d", p.MaxHP)) // 模拟禁用道具逻辑 bannedItems := map[string]bool{"medkit": true, "skip": true, "revive": true} for item := range bannedItems { canUse := !(p.Character == "elephant" && bannedItems[item]) assert(fmt.Sprintf("禁用%s", item), !canUse, "应禁用该道具") } } func TestCat() { fmt.Println("\n🐱 测试: 猫咪") p := NewTestPlayer("1", "cat") assert("HP=3", p.MaxHP == 3, fmt.Sprintf("期望MaxHP=3, 实际=%d", p.MaxHP)) testApplyDamage(p, 5) assert("伤害强制为1", p.HP == 2, fmt.Sprintf("期望HP=2, 实际HP=%d", p.HP)) p2 := NewTestPlayer("1", "cat") p2.Curse = true testApplyDamage(p2, 1) assert("诅咒无效", p2.HP == 2, fmt.Sprintf("期望HP=2, 实际HP=%d", p2.HP)) } func TestDog() { fmt.Println("\n🐶 测试: 狗狗") p := NewTestPlayer("1", "dog") grid := []TestGrid{{Type: "bomb"}, {Type: "item", ItemID: "medkit"}} idx := 0 cellType := grid[idx].Type p.RevealedCells[idx] = cellType assert("透视存入RevealedCells", p.RevealedCells[idx] == "bomb", "应存入bomb") } func TestMonkey() { fmt.Println("\n🐒 测试: 猴子(吉吉国王)") p := NewTestPlayer("1", "monkey") p.HP = 2 for i := 0; i < 3; i++ { if p.MonkeyBananaCount < 2 { testHealPlayer(p, 1) p.MonkeyBananaCount++ } } assert("香蕉最多2次", p.MonkeyBananaCount == 2, fmt.Sprintf("触发%d次", p.MonkeyBananaCount)) assert("回复2血", p.HP == 4, fmt.Sprintf("期望HP=4, 实际HP=%d", p.HP)) } func TestChicken() { fmt.Println("\n🐔 测试: 坤坤") p := NewTestPlayer("1", "chicken") for i := 0; i < 3; i++ { if p.ChickenItemCount < 2 { p.ChickenItemCount++ } } assert("道具触发最多2次", p.ChickenItemCount == 2, fmt.Sprintf("触发%d次", p.ChickenItemCount)) } func TestSloth() { fmt.Println("\n🦥 测试: 懒懒") p := NewTestPlayer("1", "sloth") canPoison := p.Character != "sloth" assert("免疫毒药", !canPoison, "应免疫毒药") dmg := 2 if p.Character == "sloth" { dmg = 1 } assert("炸弹伤害降为1", dmg == 1, fmt.Sprintf("伤害=%d", dmg)) } func TestHippo() { fmt.Println("\n🦛 测试: 河马") p := NewTestPlayer("1", "hippo") canPickup := p.Character != "hippo" assert("无法拾取道具", !canPickup, "应无法拾取") // 统计性测试 survived := 0 trials := 10000 for i := 0; i < trials; i++ { testP := NewTestPlayer("1", "hippo") testP.HP = 1 testApplyDamage(testP, 2) if testP.HP > 0 { survived++ } } rate := float64(survived) / float64(trials) assert("55%免死概率", rate > 0.50 && rate < 0.60, fmt.Sprintf("实际=%.1f%%", rate*100)) } func TestTiger() { fmt.Println("\n🐯 测试: 老虎") attacker := NewTestPlayer("1", "tiger") dmg := 1 isAOE := false if attacker.Character == "tiger" { dmg = 2 isAOE = true } assert("飞刀变2伤害", dmg == 2, fmt.Sprintf("伤害=%d", dmg)) assert("变为全体攻击", isAOE, "应为AOE") } func TestMagnifier() { fmt.Println("\n🔍 测试: 放大镜") p := NewTestPlayer("1", "default") grid := []TestGrid{ {Type: "empty"}, {Type: "bomb"}, {Type: "item", ItemID: "shield"}, } // 模拟放大镜逻辑 idx := 2 cellType := grid[idx].Type if grid[idx].Type == "item" { cellType = grid[idx].ItemID } p.RevealedCells[idx] = cellType assert("存入道具ID", p.RevealedCells[idx] == "shield", fmt.Sprintf("应为shield,实际=%s", p.RevealedCells[idx])) } // ======================== // 综合场景测试 // ======================== func TestComplexScenarios() { fmt.Println("\n🎮 测试: 综合场景") // 护盾+诅咒 p1 := NewTestPlayer("1", "default") p1.Shield = true p1.Curse = true testApplyDamage(p1, 2) assert("护盾优先于诅咒", p1.HP == 4 && p1.Curse, "护盾应先生效,诅咒保留") // 复活甲+毒死 p2 := NewTestPlayer("1", "default") p2.Revive = true p2.Poisoned = true p2.PoisonSteps = 1 testApplyDamage(p2, 5) p2.PoisonSteps++ if p2.PoisonSteps%2 == 0 { testApplyDamage(p2, 1) } assert("复活后被毒死", p2.HP == 0, fmt.Sprintf("期望HP=0, 实际=%d", p2.HP)) } // ======================== // 主函数 // ======================== func main() { rand.Seed(time.Now().UnixNano()) fmt.Println("╔═══════════════════════════════════════════╗") fmt.Println("║ 🎮 动物扫雷 - 道具&角色逻辑测试 ║") fmt.Println("╚═══════════════════════════════════════════╝") // 道具测试 fmt.Println("\n━━━ 道具测试 ━━━") TestMedkit() TestBombTimer() TestPoison() TestShield() TestSkip() TestMagnifier() TestKnife() TestRevive() TestLightning() TestCurse() // 角色测试 fmt.Println("\n━━━ 角色测试 ━━━") TestElephant() TestCat() TestDog() TestMonkey() TestChicken() TestSloth() TestHippo() TestTiger() // 综合测试 fmt.Println("\n━━━ 综合场景 ━━━") TestComplexScenarios() // 结果 fmt.Println("\n╔═══════════════════════════════════════════╗") total := passed + failed if failed == 0 { fmt.Printf("║ ✅ 全部通过! %d/%d 测试用例 ║\n", passed, total) } else { fmt.Printf("║ ⚠️ %d 通过, %d 失败 (共%d) ║\n", passed, failed, total) } fmt.Println("╚═══════════════════════════════════════════╝") }