/** * 数值模型验证脚本 * 运行: node tests/verify-model.js */ // 游戏常量 const GAME_CONSTANTS = { QUALITY_LEVELS: { 1: { name: '垃圾', color: '#6b7280', range: [0, 49], multiplier: 0.5 }, 2: { name: '普通', color: '#ffffff', range: [50, 99], multiplier: 1.0 }, 3: { name: '优秀', color: '#22c55e', range: [100, 139], multiplier: 1.2 }, 4: { name: '稀有', color: '#3b82f6', range: [140, 169], multiplier: 1.5 }, 5: { name: '史诗', color: '#a855f7', range: [170, 199], multiplier: 2.0 }, 6: { name: '传说', color: '#f59e0b', range: [200, 250], multiplier: 3.0 } }, QUALITY: { BASE_MULTIPLIER: 0.01 }, STAT_SCALING: { STRENGTH_TO_ATTACK: 1.0, AGILITY_TO_DODGE: 0.5, DEXTERITY_TO_CRIT: 0.3, VITALITY_TO_HP: 10, VITALITY_TO_REGEN: 0.05 }, MONSTER: { HP_SCALING: 1.12, ATTACK_SCALING: 1.08, DEFENSE_SCALING: 1.06, EXP_SCALING: 1.10 } } // ==================== 计算函数 ==================== function calculateCharacterStats(baseStats, level = 1) { const s = GAME_CONSTANTS.STAT_SCALING return { hp: Math.floor(100 + (baseStats.vitality || 10) * s.VITALITY_TO_HP + level * 5), attack: Math.floor((baseStats.strength || 10) * s.STRENGTH_TO_ATTACK + level * 2), critRate: 5 + (baseStats.dexterity || 8) * s.DEXTERITY_TO_CRIT } } function calculateEquipmentStats(baseDamage, quality, itemLevel = 1) { const qualityMultiplier = 1 + (quality - 100) * GAME_CONSTANTS.QUALITY.BASE_MULTIPLIER const levelMultiplier = 1 + (itemLevel - 1) * 0.02 return Math.floor(baseDamage * qualityMultiplier * levelMultiplier) } function calculateMonsterStats(baseHp, level) { return Math.floor(baseHp * Math.pow(GAME_CONSTANTS.MONSTER.HP_SCALING, level - 1)) } function getExpForLevel(level) { return Math.floor(100 * Math.pow(1.15, level - 2) * (level - 1) * 0.8) } function getQualityLevel(quality) { if (quality < 50) return GAME_CONSTANTS.QUALITY_LEVELS[1] if (quality < 100) return GAME_CONSTANTS.QUALITY_LEVELS[2] if (quality < 140) return GAME_CONSTANTS.QUALITY_LEVELS[3] if (quality < 170) return GAME_CONSTANTS.QUALITY_LEVELS[4] if (quality < 200) return GAME_CONSTANTS.QUALITY_LEVELS[5] return GAME_CONSTANTS.QUALITY_LEVELS[6] } // ==================== 验证测试 ==================== console.log('=== 数值模型验证 ===\n') // 1. 品质系统测试 console.log('1. 品质倍率验证:') console.log(` 品质50 (垃圾): 攻击力20 -> ${calculateEquipmentStats(20, 50, 1)} (0.5x)`) console.log(` 品质100 (普通): 攻击力20 -> ${calculateEquipmentStats(20, 100, 1)} (1.0x)`) console.log(` 品质150 (优秀): 攻击力20 -> ${calculateEquipmentStats(20, 150, 1)} (1.5x)`) console.log(` 品质200 (史诗): 攻击力20 -> ${calculateEquipmentStats(20, 200, 1)} (2.0x)`) console.log(` 品质250 (传说): 攻击力20 -> ${calculateEquipmentStats(20, 250, 1)} (2.5x)`) // 2. 物品等级测试 console.log('\n2. 物品等级影响 (品质100):') console.log(` Lv1: 攻击力20 -> ${calculateEquipmentStats(20, 100, 1)}`) console.log(` Lv5: 攻击力20 -> ${calculateEquipmentStats(20, 100, 5)}`) console.log(` Lv10: 攻击力20 -> ${calculateEquipmentStats(20, 100, 10)}`) console.log(` Lv50: 攻击力20 -> ${calculateEquipmentStats(20, 100, 50)}`) // 3. 角色属性测试 console.log('\n3. 角色属性 (Lv1, 默认属性):') const defaultStats = { strength: 10, agility: 8, dexterity: 8, intuition: 10, vitality: 10 } const stats = calculateCharacterStats(defaultStats, 1) console.log(` HP: ${stats.hp}`) console.log(` 攻击: ${stats.attack}`) console.log(` 暴击率: ${stats.critRate}%`) console.log(` 体质+10 -> HP +${calculateCharacterStats({ vitality: 20 }, 1).hp - stats.hp}`) // 4. 怪物缩放测试 console.log('\n4. 怪物等级缩放 (基础HP 100):') console.log(` Lv1: HP = ${calculateMonsterStats(100, 1)}`) console.log(` Lv5: HP = ${calculateMonsterStats(100, 5)} (1.12^4 ≈ 1.57x)`) console.log(` Lv10: HP = ${calculateMonsterStats(100, 10)} (1.12^9 ≈ 2.8x)`) console.log(` Lv20: HP = ${calculateMonsterStats(100, 20)} (1.12^19 ≈ 8.0x)`) // 5. 经验曲线测试 console.log('\n5. 升级经验需求:') console.log(` Lv1 -> Lv2: ${getExpForLevel(2)} 经验`) console.log(` Lv5 -> Lv6: ${getExpForLevel(6)} 经验`) console.log(` Lv10 -> Lv11: ${getExpForLevel(11)} 经验`) console.log(` Lv20 -> Lv21: ${getExpForLevel(21)} 经验`) console.log(` Lv50 -> Lv51: ${getExpForLevel(51)} 经验`) // 6. 品质等级验证 console.log('\n6. 品质等级判定:') for (let q = 0; q <= 250; q += 50) { const level = getQualityLevel(q) console.log(` 品质 ${q}: ${level.name.padEnd(6)} (${level.color})`) } // 7. 可玩性验证 console.log('\n=== 可玩性验证 ===\n') // 新手阶段 const playerLv1 = calculateCharacterStats(defaultStats, 1) const monsterLv1 = calculateMonsterStats(50, 1) console.log('新手阶段 (Lv1 vs Lv1 怪物):') console.log(` 玩家 HP: ${playerLv1.hp}, 攻击: ${playerLv1.attack}`) console.log(` 怪物 HP: ${monsterLv1}, 攻击: ${calculateEquipmentStats(5, 100, 1)}`) console.log(` 预期: 玩家约需 5-6 次攻击击杀怪物,能承受 20+ 次攻击`) console.log(` 结论: ${playerLv1.attack > 5 ? '✓ 可玩' : '✗ 太难'}`) // 中期阶段 const playerLv15 = calculateCharacterStats({ strength: 20, agility: 15, dexterity: 15, intuition: 15, vitality: 15 }, 15) const monsterLv15 = calculateMonsterStats(100, 15) console.log('\n中期阶段 (Lv15 vs Lv15 怪物):') console.log(` 玩家 HP: ${playerLv15.hp}, 攻击: ${playerLv15.attack}`) console.log(` 怪物 HP: ${monsterLv15}, 攻击: ${calculateEquipmentStats(10, 100, 15)}`) console.log(` 预期: 玩家约需 15-20 次攻击击杀怪物`) console.log(` 结论: ${playerLv15.attack > 20 ? '✓ 可玩' : '需要提升'}`) // 战斗经济 console.log('\n经济系统:') const normalItemPrice = 100 * 1.0 const epicItemPrice = 100 * 2.0 const monsterGold = 20 console.log(` 普通装备价格: ${normalItemPrice} 铜币`) console.log(` 史诗装备价格: ${epicItemPrice} 铜币`) console.log(` Lv1 怪物掉落: ${monsterGold} 铜币 (假设)`) console.log(` 需要击败 ${Math.ceil(epicItemPrice / monsterGold)} 只怪物购买史诗装备`) console.log('\n=== 验证完成 ===')