from pathlib import Path
import pandas as pd,numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter
R=Path(__file__).resolve().parent
o=pd.read_csv(R/'overview.csv');x=o[o.period.eq('2023_2025')].set_index('host')
BLUE='#287ba5';ORANGE='#d56b43';INK='#243444';GRAY='#9aa9b4'
plt.rcParams.update({'font.family':'DejaVu Sans','font.size':11,'text.color':INK,'text.parse_math':False,
 'axes.spines.top':False,'axes.spines.right':False,'axes.spines.left':False,'axes.edgecolor':'#ced7df','figure.facecolor':'#fafbfc','axes.facecolor':'#fafbfc','savefig.facecolor':'#fafbfc'})
hosts=['Deckbuilding','Auto battler','Action roguelike','Top-down/arena shooting','Tactical RPG','Tower defense','Action RPG','First-person shooting','City/colony building','Sports','Platforming','Puzzle','Racing','Horror']
fig,ax=plt.subplots(figsize=(13,9));fig.subplots_adjust(left=.25,right=.97,top=.85,bottom=.16)
fig.suptitle('Where explicit build promises appear in store descriptions',x=.04,ha='left',y=.975,fontsize=18,fontweight='bold')
fig.text(.04,.921,'2023–2025 paid releases • relevant top-10 tag + activity language • selected categories from the 34-category study',fontsize=11)
for i,h in enumerate(hosts):
 r=x.loc[h];ax.barh(i,r.share,color=BLUE,height=.62)
 ax.text(r.share+.01,i,f'{int(r.b_n):,}/{int(r.n):,}  ({r.share:.1%})',va='center',fontsize=10)
ax.set_yticks(range(len(hosts)),hosts);ax.invert_yaxis();ax.set_xlim(0,1.0);ax.set_xticks([0,.2,.4,.6,.8]);ax.xaxis.set_major_formatter(PercentFormatter(1))
ax.set_xlabel('Share matching the strict advertised-build screen')
fig.text(.04,.078,'These are wording/positioning counts, not a census of actual deep build systems. Unmatched games may still contain configuration.',fontsize=10)
fig.text(.04,.035,'Genres overlap. Description confirmation trades coverage for specificity; the companion tables retain tag-only and broader-screen results.',fontsize=10)
for e in ['png','svg']:fig.savefig(R/f'prevalence.{e}',dpi=160)
plt.close(fig)

hosts=['City/colony building','Sports','Board/dice/tabletop','First-person shooting','Top-down/arena shooting','Tower defense','Platforming','Puzzle','Management','Horror']
fig,ax=plt.subplots(figsize=(14,8.4));fig.subplots_adjust(left=.24,right=.94,top=.81,bottom=.21)
fig.suptitle('How the build-promising games compare with nearby, similarly priced games',x=.035,ha='left',y=.975,fontsize=17,fontweight='bold')
fig.text(.035,.916,'2023–2025 • review-count outcomes only • observed counts versus expectations from matched games without a detected build promise',fontsize=10.5)
for i,h in enumerate(hosts):
 r=x.loc[h];n=int(r.supported_n);a=r.observed100/n;b=r.matched_expected100/n
 ax.plot([a,b],[i,i],color='#c9d3db',lw=2,zorder=1)
 ax.scatter([b],[i+.06],color=ORANGE,s=55,zorder=3)
 ax.scatter([a],[i-.06],color=BLUE,s=55,zorder=4)
 ax.text(.73,i,f'{int(r.observed100)}/{n} vs {r.matched_expected100:.1f}/{n}\n{r.matched_ratio100:.2f}×',va='center',fontsize=9.5)
ax.set_yticks(range(len(hosts)),hosts);ax.invert_yaxis();ax.set_xlim(0,.94);ax.set_xticks([0,.2,.4,.6]);ax.xaxis.set_major_formatter(PercentFormatter(1))
ax.set_xlabel('Share reaching 100 reviews in the matched comparison')
fig.text(.035,.125,'● Observed build-promising games',color=BLUE,fontweight='bold')
fig.text(.40,.125,'● Expected from matched comparison games',color=ORANGE,fontweight='bold')
fig.text(.035,.070,'Each build game uses 3–5 different-developer peers within 90 days and the same price band (missing prices grouped). Unsupported games are omitted.',fontsize=9.5)
fig.text(.035,.025,'Associations, not causal effects or sales estimates. Ratios for small groups are exploratory; the report includes newer-cohort and sensitivity checks.',fontsize=10)
for e in ['png','svg']:fig.savefig(R/f'matched_comparison.{e}',dpi=160)
plt.close(fig)
print('Saved two PNG/SVG figures.')
