VSClone/Assets/Editor/HeadlessRun.Balance.cs

65 lines
3.2 KiB
C#

using System;
using System.Numerics;
using UnityEditor;
using UnityEngine;
using VS.Sim;
namespace VS.EditorTools
{
// 진행 속도 측정: -executeMethod VS.EditorTools.HeadlessRun.Balance (자동 플레이어 = 1 초 1탭 + 하이프 탭 5회/초 · 30 초마다 후원 받기 · 가장 싼 구매)
public static partial class HeadlessRun
{
public static void Balance()
{
int exit = 0;
try
{
Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
var t = LoadTables();
double hours = 12;
var env = Environment.GetEnvironmentVariable("VS_HOURS");
if (!string.IsNullOrEmpty(env)) double.TryParse(env, out hours);
var g = NewGame(t, out var clk);
float dt = 0.2f;
double nextDonate = 30, nextLog = 600;
int lastRank = g.S.rankIndex, lastHouse = g.S.house;
long buys = 0;
for (double tm = 0; tm < hours * 3600; tm += dt)
{
g.Tap();
g.Tick(dt);
if (g.Time >= nextDonate) { g.ClaimDonate(1); nextDonate += 30; }
if (g.RankUpPending) g.ApplyRankUp();
for (int k = 0; k < 20; k++) { if (!BuyCheapest(g)) break; buys++; }
if (g.CanBuyNextHouse()) g.BuyNextHouse();
if (g.S.rankIndex != lastRank) { Debug.Log($"[VS] BAL t={g.Time / 60:0.0}m rank {lastRank}->{g.S.rankIndex} follower={g.Follower}"); lastRank = g.S.rankIndex; }
if (g.S.house != lastHouse) { Debug.Log($"[VS] BAL t={g.Time / 60:0.0}m house {lastHouse + 1}->{g.S.house + 1}"); lastHouse = g.S.house; }
if (g.Time >= nextLog) { nextLog += 1800; Debug.Log($"[VS] BAL t={g.Time / 60:0}m coin={g.Coin} pass/s={g.PassGps():0.###} tap={g.TapGps():0.###} house={g.S.house + 1} rank={g.S.rankIndex} buys={buys}"); }
}
Debug.Log($"[VS] BALANCE DONE hours={hours} house={g.S.house + 1} rank={g.S.rankIndex} follower={g.Follower} coin={g.Coin} buys={buys}");
}
catch (Exception e) { Debug.LogError("[VS] EXCEPTION " + e); exit = 2; }
EditorApplication.Exit(exit);
}
static bool BuyCheapest(Game g)
{
int bestType = -1; bool bestSkill = false; BigInteger best = BigInteger.Zero;
foreach (var it in g.Room.Items)
{
if (!g.RoomUnlocked(it.Index) || g.RoomMaxed(it.Index) || g.RoomUpgrading(it.Index)) continue;
var p = g.RoomNextPrice(it.Index);
if (p <= g.Coin && (bestType < 0 || p < best)) { best = p; bestType = it.Index; bestSkill = false; }
}
foreach (var it in g.T.Skills.Items)
{
if (!g.CanBuySkill(it.Index) || g.SkillUpgrading(it.Index)) continue;
var p = g.SkillNextPrice(it.Index);
if (p <= g.Coin && (bestType < 0 || p < best)) { best = p; bestType = it.Index; bestSkill = true; }
}
if (bestType < 0) return false;
return (bestSkill ? g.BuySkill(bestType) : g.BuyRoomItem(bestType)) == BuyResult.Ok;
}
}
}