Files
text-adventure-game/tests/verify-model.js

150 lines
6.2 KiB
JavaScript
Raw Permalink Normal View History

/**
* 数值模型验证脚本
* 运行: 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=== 验证完成 ===')