Files

2 lines
11 KiB
JavaScript

import{r as n,j as t}from"./index-CEeZxcxj.js";const ke="_wrapper_h2w9g_1",je="_frame_h2w9g_12",Pe="_frameSucceeded_h2w9g_25",ve="_header_h2w9g_33",$e="_title_h2w9g_37",Te="_statsLine_h2w9g_50",Oe="_boardPanel_h2w9g_58",Ee="_board_h2w9g_58",Re="_trailOverlay_h2w9g_76",Ae="_trailPath_h2w9g_85",Le="_trailHead_h2w9g_94",Me="_cell_h2w9g_99",Ie="_lightCell_h2w9g_105",De="_darkCell_h2w9g_109",He="_knight_h2w9g_113",Ge="_target_h2w9g_130",Be="_readout_h2w9g_138",Ue="_readoutLine_h2w9g_145",Fe="_programPanel_h2w9g_154",Ye="_programTrack_h2w9g_160",Ve="_placeholder_h2w9g_171",Xe="_step_h2w9g_176",Ke="_stepExecuted_h2w9g_187",Ze="_programButtons_h2w9g_192",ze="_controlRow_h2w9g_193",We="_button_h2w9g_199",qe="_buttonPrimary_h2w9g_200",Je="_legend_h2w9g_233",Qe="_promptOverlay_h2w9g_239",et="_promptTitle_h2w9g_250",tt="_promptText_h2w9g_258",rt="_promptOptions_h2w9g_264",st="_promptOption_h2w9g_264",nt="_promptSelected_h2w9g_282",at="_promptHint_h2w9g_287",e={wrapper:ke,frame:je,frameSucceeded:Pe,header:ve,title:$e,statsLine:Te,boardPanel:Oe,board:Ee,trailOverlay:Re,trailPath:Ae,trailHead:Le,cell:Me,lightCell:Ie,darkCell:De,knight:He,target:Ge,readout:Be,readoutLine:Ue,programPanel:Fe,programTrack:Ye,placeholder:Ve,step:Xe,stepExecuted:Ke,programButtons:Ze,controlRow:ze,button:We,buttonPrimary:qe,legend:Je,promptOverlay:Qe,promptTitle:et,promptText:tt,promptOptions:rt,promptOption:st,promptSelected:nt,promptHint:at},b=8,h={x:0,y:b-1},ot=220,ct=64,lt=3,I=100,it=5,dt={up:{dx:0,dy:-1},down:{dx:0,dy:1},left:{dx:-1,dy:0},right:{dx:1,dy:0}},pt={up:"↑",down:"↓",left:"←",right:"→"},de=[{dx:0,dy:1},{dx:1,dy:1},{dx:1,dy:2},{dx:1,dy:3},{dx:2,dy:3},{dx:1,dy:5},{dx:1,dy:6}],X=(s,o,u)=>Math.min(u,Math.max(o,s)),pe=s=>s.x>=0&&s.x<b&&s.y>=0&&s.y<b,ut=(s,o)=>s.x===o.x&&s.y===o.y,se=(s,o)=>o===0?s:se(o,s%o),mt=(s,o)=>{const u=Math.abs(o.x-s.x),d=Math.abs(o.y-s.y);if(u===0&&d===0)return 0;if(u===0||d===0)return u+d;const g=se(u,d);return u/g+d/g},ht=s=>new Promise(o=>{window.setTimeout(o,s)}),ie=s=>s==="Enter"||s==="NumpadEnter"||s===" "||s==="Space"||s==="Spacebar",gt=s=>`${(s.x+.5)*I},${(s.y+.5)*I}`,K=s=>X(s,0,de.length-1),ue=s=>de[K(s)],te=s=>{const o=ue(s);return o.dx+o.dy},re=s=>{const o=ue(s),u=[];for(let g=1;g<b;g+=1){const p={x:h.x+o.dx*g,y:h.y-o.dy*g};if(!pe(p))break;Math.abs(p.x-h.x)+Math.abs(p.y-h.y)>it&&u.push(p)}if(u.length===0)return{x:h.x+o.dx,y:h.y-o.dy};const d=Math.floor(Math.random()*u.length);return u[d]};function _t({config:s,onComplete:o,onProgress:u,theme:d,className:g}){const p=n.useMemo(()=>{const a=s.params.goalCaptures;return typeof a!="number"?lt:X(Math.round(a),1,10)},[s.params.goalCaptures]),[N,ne]=n.useState(0),[w,Z]=n.useState(h),[k,ae]=n.useState(()=>re(0)),[x,z]=n.useState([]),[D,H]=n.useState([h]),[_,j]=n.useState("idle"),[me,v]=n.useState(-1),[y,oe]=n.useState(0),[ce,O]=n.useState(""),[E,G]=n.useState("yes"),[R,B]=n.useState("continue"),[f,he]=n.useState(!1),C=n.useRef(0),U=n.useRef(!1),i=_==="running",m=_==="gameOverPrompt"||_==="successPrompt"||_==="finished",W=te(N),ge=n.useMemo(()=>d?{"--gc-primary":d.primary,"--gc-accent":d.accent,"--gc-bg":d.bg,"--gc-bg-secondary":d.bgSecondary,"--gc-text":d.text,"--gc-text-muted":d.textMuted,"--gc-border":d.border}:{},[d]);n.useEffect(()=>{const a=y/p;u?.(Math.round(X(a*100,0,100)))},[y,p,u]);const F=n.useCallback((a,r,c="")=>{C.current+=1,j("idle"),ne(K(a)),Z(h),ae(re(a)),H([h]),v(-1),oe(r),G("yes"),B("continue"),O(c)},[]),q=n.useCallback(()=>{F(N,0,`Looking for a ${W}-step move set.`)},[N,W,F]),Y=n.useCallback((a=0)=>{const r=K(N+1),c=te(r);F(r,a,`Looking for a ${c}-step move set.`)},[N,F]),J=n.useCallback(()=>{U.current||(U.current=!0,C.current+=1,j("finished"),o({success:!1,error:"Player chose no after game over.",data:{captures:y,goalCaptures:p,configId:s.id,completedAt:new Date().toISOString(),hasEverSucceeded:f}}))},[y,s.id,p,f,o]),L=n.useCallback(()=>{U.current||(U.current=!0,C.current+=1,j("finished"),o({success:!0,score:100,data:{captures:y,goalCaptures:p,configId:s.id,completedAt:new Date().toISOString(),hasEverSucceeded:f}}))},[y,s.id,p,f,o]),A=n.useCallback(a=>{z(r=>i||m||r.length>=ct?r:[...r,a])},[m,i]),xe=n.useCallback(()=>{i||m||z(a=>a.slice(0,-1))},[m,i]),_e=n.useCallback(()=>{i||m||z([])},[m,i]),ye=n.useCallback(()=>{C.current+=1,j("idle"),v(-1),O("Program stopped.")},[]),fe=n.useCallback(async()=>{if(i||m||x.length===0)return;const a=C.current+1;C.current=a;let r=w,c=k,l=y,P=0;for(j("running"),v(-1),H([w]),O("");C.current===a;)for(let S=0;S<x.length;S+=1){if(await ht(ot),C.current!==a)return;const M=x[S],V=dt[M],$={x:r.x+V.dx,y:r.y+V.dy};if(!pe($)){j("gameOverPrompt"),G("yes"),v(-1),O(`Game over after ${P} step(s). Try again?`);return}if(P+=1,r=$,Z($),H(T=>[...T,$]),v(S),ut($,c)){if(l+=1,oe(l),he(!0),l>=p){j("successPrompt"),B("continue"),v(-1),O(`Success. ${l} challenge(s) complete.`);return}const T=K(N+1),ee=re(T),Ne=te(T);r=h,c=ee,j("idle"),ne(T),Z(h),ae(ee),H([h]),v(-1),O(`Challenge ${l}/${p} complete. Looking for a ${Ne}-step move set.`);return}}},[y,N,p,m,w,x,i,k]);n.useEffect(()=>{const a=r=>{const c={ArrowUp:"up",ArrowDown:"down",ArrowLeft:"left",ArrowRight:"right"};if(_==="gameOverPrompt"){if(r.key==="ArrowLeft"||r.key==="ArrowUp"){r.preventDefault(),G("yes");return}if(r.key==="ArrowRight"||r.key==="ArrowDown"){r.preventDefault(),G("no");return}ie(r.key)&&(r.preventDefault(),E==="yes"?q():f?L():J());return}if(_==="successPrompt"){if(r.key==="ArrowLeft"||r.key==="ArrowUp"){r.preventDefault(),B("continue");return}if(r.key==="ArrowRight"||r.key==="ArrowDown"){r.preventDefault(),B("done");return}ie(r.key)&&(r.preventDefault(),R==="continue"?Y():L());return}if(_!=="idle")return;const l=c[r.key];l&&(r.preventDefault(),A(l))};return window.addEventListener("keydown",a),()=>{window.removeEventListener("keydown",a)}},[A,J,L,E,f,_,q,Y,R]),n.useEffect(()=>()=>{C.current+=1},[]);const be=n.useMemo(()=>{const a=k.x-w.x,r=w.y-k.y,c=Math.abs(a),l=Math.abs(r),P=mt(w,k);if(c===0&&l===0)return{angle:0,motifLength:P,motif:"On target"};if(c===0||l===0)return{angle:c===0?90:0,motifLength:P,motif:c===0?`${r>=0?"U":"D"} x ${l}`:`${a>=0?"R":"L"} x ${c}`};const S=se(c,l),M=c/S,V=l/S,$=`${a>=0?"R":"L"} x ${M}`,T=`${r>=0?"U":"D"} x ${V}`;return{angle:Math.atan2(l,c)*(180/Math.PI),motifLength:P,motif:`${$}, ${T}`}},[w,k]),we=Math.round(X(y/p*100,0,100)),Ce=g?`${e.wrapper} ${g}`:e.wrapper,le=b*I,Se=D.map(gt).join(" "),Q=D[D.length-1];return t.jsx("div",{className:Ce,style:ge,children:t.jsxs("section",{className:`${e.frame} ${f?e.frameSucceeded:""}`,"aria-label":"Chess move set trainer",children:[t.jsxs("header",{className:e.header,children:[t.jsx("h2",{className:e.title,children:"The Chess Analogy"}),t.jsxs("p",{className:e.statsLine,children:["Captures ",y,"/",p," • Progress ",we,"% • Program ",x.length," • Target ",W]})]}),t.jsx("div",{className:e.boardPanel,children:t.jsxs("div",{className:e.board,role:"grid","aria-label":"8 by 8 checkerboard",children:[t.jsxs("svg",{className:e.trailOverlay,viewBox:`0 0 ${le} ${le}`,preserveAspectRatio:"none","aria-hidden":"true",children:[D.length>1&&t.jsx("polyline",{className:e.trailPath,points:Se}),Q&&t.jsx("circle",{className:e.trailHead,cx:(Q.x+.5)*I,cy:(Q.y+.5)*I,r:6})]}),Array.from({length:b*b}).map((a,r)=>{const c=r%b,l=Math.floor(r/b),P=(c+l)%2===1,S=w.x===c&&w.y===l,M=k.x===c&&k.y===l;return t.jsxs("div",{className:`${e.cell} ${P?e.darkCell:e.lightCell}`,role:"gridcell","aria-label":`x ${c+1}, y ${b-l}`,children:[M&&t.jsx("span",{className:e.target,"aria-hidden":"true",children:"●"}),S&&t.jsx("span",{className:e.knight,"aria-hidden":"true",children:"♞"})]},`${c}-${l}`)})]})}),t.jsxs("div",{className:e.readout,children:[t.jsxs("p",{className:e.readoutLine,children:["Angle: ",t.jsxs("strong",{children:[be.angle.toFixed(1),"°"]})]}),!1]}),t.jsxs("div",{className:e.programPanel,children:[t.jsxs("div",{className:e.programTrack,"aria-live":"polite",children:[x.length===0&&t.jsx("span",{className:e.placeholder,children:"Empty move set"}),x.map((a,r)=>t.jsx("span",{className:`${e.step} ${i&&r===me?e.stepExecuted:""}`,children:pt[a]},`${a}-${r}`))]}),t.jsxs("div",{className:e.programButtons,children:[t.jsx("button",{type:"button",className:e.button,onClick:()=>A("up"),disabled:i||m,children:"↑"}),t.jsx("button",{type:"button",className:e.button,onClick:()=>A("left"),disabled:i||m,children:"←"}),t.jsx("button",{type:"button",className:e.button,onClick:()=>A("down"),disabled:i||m,children:"↓"}),t.jsx("button",{type:"button",className:e.button,onClick:()=>A("right"),disabled:i||m,children:"→"})]}),t.jsxs("div",{className:e.controlRow,children:[t.jsx("button",{type:"button",className:e.button,onClick:xe,disabled:i||m||x.length===0,children:"Undo"}),t.jsx("button",{type:"button",className:e.button,onClick:_e,disabled:i||m||x.length===0,children:"Clear"}),t.jsx("button",{type:"button",className:e.buttonPrimary,onClick:i?ye:fe,disabled:m||x.length===0,children:i?"Stop":"Run"}),t.jsx("button",{type:"button",className:e.button,onClick:()=>Y(),disabled:i,children:"Reset"})]}),ce&&t.jsx("p",{className:e.legend,children:ce})]}),_==="gameOverPrompt"&&t.jsxs("div",{className:e.promptOverlay,role:"dialog","aria-modal":"true","aria-label":"Game over prompt",children:[t.jsx("p",{className:e.promptTitle,children:"Game over"}),t.jsx("p",{className:e.promptText,children:f?"Try again or stop?":"Try again?"}),t.jsxs("div",{className:e.promptOptions,children:[t.jsxs("button",{type:"button",className:`${e.promptOption} ${E==="yes"?e.promptSelected:""}`,onClick:q,children:[E==="yes"?"▶ ":"","Yes"]}),t.jsxs("button",{type:"button",className:`${e.promptOption} ${E==="no"?e.promptSelected:""}`,onClick:f?L:J,children:[E==="no"?"▶ ":"",f?"I'm done":"No"]})]}),t.jsx("p",{className:e.promptHint,children:"Use arrows + Enter."})]}),_==="successPrompt"&&t.jsxs("div",{className:e.promptOverlay,role:"dialog","aria-modal":"true","aria-label":"Success prompt",children:[t.jsx("p",{className:e.promptTitle,children:"Success"}),t.jsx("p",{className:e.promptText,children:"Continue?"}),t.jsxs("div",{className:e.promptOptions,children:[t.jsxs("button",{type:"button",className:`${e.promptOption} ${R==="continue"?e.promptSelected:""}`,onClick:()=>Y(),children:[R==="continue"?"▶ ":"","Yes"]}),t.jsxs("button",{type:"button",className:`${e.promptOption} ${R==="done"?e.promptSelected:""}`,onClick:L,children:[R==="done"?"▶ ":"","I'm done"]})]}),t.jsx("p",{className:e.promptHint,children:"Use arrows + Enter."})]})]})})}const yt={name:"chess_analogy",displayName:"Chess Move Set Lab",version:"1.0.0",paramSchema:{goalCaptures:{type:"range",label:"Targets To Capture",description:"How many red targets must be captured before completion.",default:3,min:1,max:10,step:1}},defaultParams:{goalCaptures:3}};export{_t as default,yt as metadata};