Skip to content

Commit 6ab550f

Browse files
StopDragonclaude
andcommitted
Add detailed session statistics on exit
- Track: trash count, hidden count, enhance success/hold/destroy - Calculate: gold per hour, average cycle time/gold - Display formatted stats summary on session end - Match Python version's detailed statistics output Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent fe722e4 commit 6ab550f

File tree

1 file changed

+133
-9
lines changed

1 file changed

+133
-9
lines changed

internal/game/engine.go

Lines changed: 133 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@ type Engine struct {
6262
// v2: 세션 분석 및 알림
6363
session *analysis.SessionTracker
6464
alerts *analysis.AlertEngine
65+
66+
// 세션 통계 (종료 시 출력용)
67+
sessionStats struct {
68+
startGold int
69+
endGold int
70+
trashCount int
71+
hiddenCount int
72+
enhanceSuccess int
73+
enhanceHold int
74+
enhanceDestroy int
75+
cycleTimeSum float64 // 사이클 시간 합계 (초)
76+
cycleGoldSum int // 사이클 수익 합계
77+
}
6578
}
6679

6780
// NewEngine 엔진 생성
@@ -255,6 +268,17 @@ func (e *Engine) setupAndRun() {
255268
e.totalGold = 0
256269
e.startTime = time.Now()
257270

271+
// 세션 통계 초기화
272+
e.sessionStats.startGold = e.readCurrentGold()
273+
e.sessionStats.endGold = 0
274+
e.sessionStats.trashCount = 0
275+
e.sessionStats.hiddenCount = 0
276+
e.sessionStats.enhanceSuccess = 0
277+
e.sessionStats.enhanceHold = 0
278+
e.sessionStats.enhanceDestroy = 0
279+
e.sessionStats.cycleTimeSum = 0
280+
e.sessionStats.cycleGoldSum = 0
281+
258282
// 타이머 설정 (시간 제한이 있는 경우)
259283
if e.duration > 0 {
260284
e.stopTimer = time.AfterFunc(e.duration, func() {
@@ -283,15 +307,13 @@ func (e *Engine) setupAndRun() {
283307
time.Sleep(500 * time.Millisecond)
284308
overlay.HideAll()
285309

286-
// 종료 시 통계 출력 및 텔레메트리 전송
287-
elapsed := time.Since(e.startTime)
288-
fmt.Println()
289-
fmt.Println("=== 매크로 종료 ===")
290-
fmt.Printf("⏱️ 실행 시간: %s\n", formatDuration(elapsed))
291-
fmt.Printf("🔄 총 사이클: %d회\n", e.cycleCount)
292-
if e.totalGold > 0 {
293-
fmt.Printf("💰 총 수익: %dG\n", e.totalGold)
294-
}
310+
// 종료 시 현재 골드 읽기
311+
e.sessionStats.endGold = e.readCurrentGold()
312+
313+
// 상세 통계 출력
314+
e.printSessionStats()
315+
316+
// 텔레메트리 전송
295317
fmt.Println("📤 통계 전송 중...")
296318
e.telem.Flush()
297319
fmt.Println("✅ 완료!")
@@ -311,6 +333,97 @@ func formatDuration(d time.Duration) string {
311333
return fmt.Sprintf("%d초", s)
312334
}
313335

336+
// printSessionStats 세션 종료 시 상세 통계 출력
337+
func (e *Engine) printSessionStats() {
338+
elapsed := time.Since(e.startTime)
339+
elapsedSec := elapsed.Seconds()
340+
341+
// 골드 변화 계산
342+
goldDiff := e.sessionStats.endGold - e.sessionStats.startGold
343+
if e.sessionStats.startGold <= 0 {
344+
goldDiff = e.totalGold // 시작 골드를 못 읽었으면 누적 수익 사용
345+
}
346+
347+
// 시간당 골드 계산
348+
goldPerHour := 0
349+
if elapsedSec > 0 {
350+
goldPerHour = int(float64(goldDiff) / elapsedSec * 3600)
351+
}
352+
353+
// 사이클 평균 계산
354+
avgCycleTime := 0.0
355+
avgCycleGold := 0
356+
if e.cycleCount > 0 {
357+
avgCycleTime = e.sessionStats.cycleTimeSum / float64(e.cycleCount)
358+
avgCycleGold = e.sessionStats.cycleGoldSum / e.cycleCount
359+
}
360+
361+
// 골드 부호
362+
goldSign := "+"
363+
if goldDiff < 0 {
364+
goldSign = ""
365+
}
366+
gphSign := "+"
367+
if goldPerHour < 0 {
368+
gphSign = ""
369+
}
370+
371+
fmt.Println()
372+
fmt.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
373+
fmt.Printf(" 📊 세션 통계 (%s)\n", formatDuration(elapsed))
374+
fmt.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
375+
376+
// 파밍 통계
377+
if e.sessionStats.trashCount > 0 || e.sessionStats.hiddenCount > 0 {
378+
fmt.Printf(" 🎣 트래시 판매: %d회\n", e.sessionStats.trashCount)
379+
fmt.Printf(" ⭐ 히든 발견: %d회\n", e.sessionStats.hiddenCount)
380+
}
381+
382+
// 강화 통계
383+
enhanceTotal := e.sessionStats.enhanceSuccess + e.sessionStats.enhanceHold + e.sessionStats.enhanceDestroy
384+
if enhanceTotal > 0 {
385+
fmt.Printf(" ✅ 강화 성공: %d회\n", e.sessionStats.enhanceSuccess)
386+
fmt.Printf(" ⏸️ 강화 유지: %d회\n", e.sessionStats.enhanceHold)
387+
fmt.Printf(" 💥 강화 파괴: %d회\n", e.sessionStats.enhanceDestroy)
388+
}
389+
390+
// 배틀 통계
391+
if e.battleWins > 0 || e.battleLosses > 0 {
392+
winRate := 0.0
393+
if e.battleWins+e.battleLosses > 0 {
394+
winRate = float64(e.battleWins) / float64(e.battleWins+e.battleLosses) * 100
395+
}
396+
fmt.Printf(" ⚔️ 배틀 전적: %d승 %d패 (%.1f%%)\n", e.battleWins, e.battleLosses, winRate)
397+
}
398+
399+
fmt.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
400+
401+
// 골드 통계
402+
if e.sessionStats.startGold > 0 && e.sessionStats.endGold > 0 {
403+
fmt.Printf(" 💰 골드 변화: %sG → %sG (%s%sG)\n",
404+
FormatGold(e.sessionStats.startGold),
405+
FormatGold(e.sessionStats.endGold),
406+
goldSign, FormatGold(goldDiff))
407+
} else if e.totalGold != 0 {
408+
fmt.Printf(" 💰 총 수익: %s%sG\n", goldSign, FormatGold(goldDiff))
409+
}
410+
411+
fmt.Printf(" 📈 시간당 골드: %s%sG/h\n", gphSign, FormatGold(goldPerHour))
412+
413+
// 사이클 통계
414+
if e.cycleCount > 0 {
415+
avgGoldSign := "+"
416+
if avgCycleGold < 0 {
417+
avgGoldSign = ""
418+
}
419+
fmt.Printf(" 🔄 완료 사이클: %d회 (평균 %.0f초, %s%sG/사이클)\n",
420+
e.cycleCount, avgCycleTime, avgGoldSign, FormatGold(avgCycleGold))
421+
}
422+
423+
fmt.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
424+
fmt.Println()
425+
}
426+
314427
func (e *Engine) loopEnhance() {
315428
for e.running {
316429
if e.checkStop() {
@@ -368,13 +481,15 @@ func (e *Engine) loopHidden() {
368481
e.telem.RecordFarmingWithItem(itemName, "hidden")
369482
e.telem.RecordSword()
370483
e.telem.TrySend()
484+
e.sessionStats.hiddenCount++
371485
return
372486
}
373487

374488
// 트래시면 판매
375489
if state.ItemType == "trash" || state.ItemType == "normal" {
376490
// v2 텔레메트리
377491
e.telem.RecordFarmingWithItem(itemName, state.ItemType)
492+
e.sessionStats.trashCount++
378493
e.sendCommand("/판매")
379494
time.Sleep(500 * time.Millisecond)
380495
}
@@ -428,6 +543,10 @@ func (e *Engine) loopGoldMine() {
428543
e.telem.RecordGoldChange(endGold)
429544
e.telem.TrySend()
430545

546+
// 세션 통계 업데이트
547+
e.sessionStats.cycleTimeSum += cycleTime.Seconds()
548+
e.sessionStats.cycleGoldSum += goldEarned
549+
431550
// 사이클 완료 상태 업데이트
432551
overlay.UpdateStatus("💰 골드 채굴 #%d ✅\n%s +%d → %+sG\n누적: %sG", e.cycleCount, itemName, finalLevel, FormatGold(goldEarned), FormatGold(e.totalGold))
433552

@@ -589,11 +708,13 @@ func (e *Engine) farmUntilHiddenWithName() (string, bool) {
589708
if state.ItemType == "hidden" {
590709
// v2 텔레메트리
591710
e.telem.RecordFarmingWithItem(itemName, "hidden")
711+
e.sessionStats.hiddenCount++
592712
return itemName, true
593713
}
594714
if state.ItemType == "trash" || state.ItemType == "normal" {
595715
// v2 텔레메트리
596716
e.telem.RecordFarmingWithItem(itemName, state.ItemType)
717+
e.sessionStats.trashCount++
597718
e.sendCommand("/판매")
598719
time.Sleep(300 * time.Millisecond)
599720
}
@@ -630,13 +751,16 @@ func (e *Engine) enhanceToTargetWithLevel() (int, bool) {
630751
currentLevel++
631752
fmt.Printf(" ✅ +%d 성공\n", currentLevel)
632753
e.telem.RecordEnhance(currentLevel-1, "success")
754+
e.sessionStats.enhanceSuccess++
633755
case "destroy":
634756
fmt.Println(" 💥 파괴!")
635757
e.telem.RecordEnhance(currentLevel, "destroy")
758+
e.sessionStats.enhanceDestroy++
636759
return currentLevel, false
637760
case "hold":
638761
fmt.Printf(" ⏸️ +%d 유지\n", currentLevel)
639762
e.telem.RecordEnhance(currentLevel, "hold")
763+
e.sessionStats.enhanceHold++
640764
}
641765
}
642766

0 commit comments

Comments
 (0)