refactor: 进化链动态生成替代硬编码

- PokedexView.tsx: groupByChain() 改用 ALL_SPECIES_IDS + getNextEvolution 动态构建
- SpeciesDetail.tsx: EvolutionChain 用相同方式找链头
- 删除未使用的 isInChain 函数

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
claude-code-best
2026-04-22 06:32:36 +08:00
parent 3c64113d77
commit 70d8c0038c
2 changed files with 35 additions and 22 deletions

View File

@@ -154,10 +154,33 @@ function getTypeColor(type: string): Color {
/** Group species by evolution chain for visual display */
function groupByChain(): SpeciesId[][] {
return [
['bulbasaur', 'ivysaur', 'venusaur'],
['charmander', 'charmeleon', 'charizard'],
['squirtle', 'wartortle', 'blastoise'],
['pikachu'],
]
const visited = new Set<SpeciesId>()
const chains: SpeciesId[][] = []
for (const id of ALL_SPECIES_IDS) {
if (visited.has(id)) continue
// Walk back to find chain head
let head: SpeciesId = id
for (const candidate of ALL_SPECIES_IDS) {
const evo = getNextEvolution(candidate)
if (evo?.to === head) {
head = candidate
break
}
}
// Walk forward to build chain
const chain: SpeciesId[] = []
let current: SpeciesId | undefined = head
while (current && !visited.has(current)) {
chain.push(current)
visited.add(current)
current = getNextEvolution(current)?.to
}
if (chain.length > 0) chains.push(chain)
}
return chains
}

View File

@@ -1,7 +1,7 @@
import React from 'react'
import { Box, Text, type Color } from '@anthropic/ink'
import type { SpeciesId, StatName } from '../types'
import { STAT_NAMES, STAT_LABELS } from '../types'
import { STAT_NAMES, STAT_LABELS, ALL_SPECIES_IDS } from '../types'
import { getSpeciesData } from '../data/species'
import { getNextEvolution } from '../data/evolution'
import { StatBar } from './StatBar'
@@ -135,12 +135,12 @@ export function SpeciesDetail({ speciesId, caughtLevel, spriteLines }: SpeciesDe
/** Render evolution chain arrow */
function EvolutionChain({ speciesId }: { speciesId: SpeciesId }) {
// Find the chain head
const chainHeads: SpeciesId[] = ['bulbasaur', 'charmander', 'squirtle', 'pikachu']
// Walk back to find chain head
let head: SpeciesId = speciesId
for (const starter of chainHeads) {
if (isInChain(speciesId, starter)) {
head = starter
for (const candidate of ALL_SPECIES_IDS) {
const evo = getNextEvolution(candidate)
if (evo?.to === head) {
head = candidate
break
}
}
@@ -174,13 +174,3 @@ function EvolutionChain({ speciesId }: { speciesId: SpeciesId }) {
)
}
function isInChain(target: SpeciesId, head: SpeciesId): boolean {
let current: SpeciesId | undefined = head
while (current) {
if (current === target) return true
const next = getNextEvolution(current)
current = next ? next.to : undefined
}
return false
}