Files
oniagent/tools/oni_analyzer.py

150 lines
5.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
ONI Agent — Game State Analyzer
================================
Fetches comprehensive game state and produces actionable analysis across
6 dimensions: oxygen, food, power, temperature, water, research.
"""
import json, sys, io
# Fix GBK encoding
if sys.stdout.encoding and sys.stdout.encoding.upper() in ('GBK', 'GB2312', 'CP936'):
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
from oni_api import api_get
def get_data(endpoint):
r = api_get(endpoint)
if r.get("success"):
return r.get("data", r)
return None
def main():
game = get_data('/api/state/game')
resources = get_data('/api/state/resources') or []
buildings = get_data('/api/state/buildings') or []
dups = get_data('/api/state/duplicants') or []
alert_data = get_data('/api/state/alert') or []
research = get_data('/api/state/research') or {}
rdict = {}
if isinstance(resources, list):
for r in resources:
rdict[r.get('name', '')] = r.get('amountKg', 0)
# Building type counts
btypes = {}
for b in buildings if isinstance(buildings, list) else []:
bid = b.get('id', '')
btypes[bid] = btypes.get(bid, 0) + 1
print("=" * 56)
print(" ONI Agent — Game Analysis")
print("=" * 56)
if game:
speed_str = f"{game.get('gameSpeed','?')}x speed" if not game.get('isPaused') else "PAUSED"
print(f" Cycle {game.get('cycle','?')} | {game.get('duplicantCount','?')} dupes | "
f"{game.get('gridWidth','?')}x{game.get('gridHeight','?')} grid | {speed_str}")
print()
# 1. Oxygen
print("─── Oxygen ───")
o2 = rdict.get('Oxygen', 0)
algae = rdict.get('Algae', 0)
pw = rdict.get('PollutedWater', 0)
water = rdict.get('Water', 0)
has_elec = 'Electrolyzer' in btypes
has_diff = 'OxygenDiffuser' in btypes
print(f" O2: {o2:.0f} kg Algae: {algae:.0f} kg Water: {water:.0f} kg")
if o2 < 500:
print(f" ⚠ CRITICAL: Oxygen low! {o2:.0f} kg remaining")
if not has_elec and not has_diff:
print(f" ⚠ No oxygen production. Build OxygenDiffuser or plan SPOM")
elif not has_elec and algae < 1000:
print(f" ⚠ Algae running out ({algae:.0f} kg). Build Electrolyzer (SPOM)")
if water > 50000 and not has_elec:
print(f" Water abundant ({water:.0f} kg). Good time for SPOM")
if pw > 100000:
print(f" Polluted Water: {pw:.0f} kg — sieve into water or use for thimble reed")
# 2. Food
print(f"\n─── Food ───")
calories = rdict.get('Calories', 0)
dirt = rdict.get('Dirt', 0)
has_farm = any(bid in ('PlanterBox', 'FarmTile') for bid in btypes)
has_grill = 'ElectricGrill' in btypes
print(f" Calories: {calories:.0f} kcal Dirt: {dirt:.0f} kg")
if calories < 200000:
print(f" ⚠ CRITICAL: Food shortage! {calories:.0f} kcal")
elif calories < 500000:
print(f" ⚠ Food declining ({calories:.0f} kcal). Build farm")
if not has_farm:
print(f" No farm. Build 5x PlanterBox + plant Mealwood (uses Dirt)")
if not has_grill and has_farm:
print(f" No grill. Build ElectricGrill for better food quality")
# 3. Power
print(f"\n─── Power ───")
coal = rdict.get('Carbon', 0)
hydrogen = rdict.get('Hydrogen', 0)
has_manual = 'ManualGenerator' in btypes
has_coal = 'CoalGenerator' in btypes
has_hydro = 'HydrogenGenerator' in btypes
has_solar = 'SolarPanel' in btypes
has_natgas = 'NaturalGasGenerator' in btypes
print(f" Coal: {coal:.0f} kg Hydrogen: {hydrogen:.0f} kg")
gen_list = []
if has_manual: gen_list.append('Manual')
if has_coal: gen_list.append('Coal')
if has_hydro: gen_list.append('Hydrogen')
if has_natgas: gen_list.append('NaturalGas')
if has_solar: gen_list.append('Solar')
print(f" Generators: {', '.join(gen_list) if gen_list else 'None'}")
if coal < 1000 and has_coal:
print(f" ⚠ Coal low ({coal:.0f} kg). Diversify power production")
if not has_hydro and 'Electrolyzer' in btypes:
print(f" Have Electrolyzer but no HydrogenGenerator — wasting H2!")
if not any([has_manual, has_coal, has_hydro, has_natgas, has_solar]):
print(f" ⚠ No power generation! Build ManualGenerator or CoalGenerator")
# 4. Temperature
print(f"\n─── Temperature ───")
ice = rdict.get('Ice', 0) + rdict.get('CrushedIce', 0) + rdict.get('Snow', 0)
granite = rdict.get('Granite', 0)
igneous = rdict.get('IgneousRock', 0)
print(f" Ice/Snow: {ice:.0f} kg")
if ice > 0:
print(f" Ice available for cooling if melted")
# 5. Water
print(f"\n─── Water ───")
salt_water = rdict.get('SaltWater', 0)
brine = rdict.get('Brine', 0)
print(f" Water: {water:.0f} kg Polluted Water: {pw:.0f} kg Salt Water: {salt_water:.0f} kg")
if water < 10000 and pw < 10000:
print(f" ⚠ Low water! Collect from geysers or filter polluted water")
if water < 1000:
print(f" ⚠ CRITICAL: Water nearly empty!")
# 6. Research
print(f"\n─── Research ───")
completed = research.get('completedTechs', [])
print(f" Completed: {len(completed)} techs")
if completed:
print(f" Last: {completed[-1] if completed else 'none'}")
# 7. Alerts
if alert_data:
print(f"\n─── Active Alerts ───")
for a in alert_data:
print(f" [{a.get('severity','?')}] {a.get('title','?')}")
print()
print("=" * 56)
print(" Analysis complete.")
print("=" * 56)
if __name__ == "__main__":
main()