From e3fc11d13aeae8ac1e8d10122527459cd5bd3f35 Mon Sep 17 00:00:00 2001 From: Brian Fertig Date: Sat, 20 Jun 2026 00:16:34 -0600 Subject: [PATCH] feat: add Genius Square single-player game with AI opponent Implement Genius Square, a 6x6 grid puzzle game where players place 9 polyomino pieces to fill the board around randomly placed blockers. Key features: - Pure JS game logic (GeniusSquareLogic.js) with backtracking solver - AI opponent with 5 skill levels using pre-computed solutions - Phaser-based UI with piece tray, grid rendering, and animations - Dice-based blocker placement using zone partitioning for balanced boards - Orientation support: rotate (R), flip (F), and piece lifting - Win/loss overlay with play again and menu options - Register game in server registry and scene dispatchers --- public/assets/images/game-icons.png | Bin 266337 -> 270308 bytes public/assets/images/game-icons.psd | Bin 689968 -> 701150 bytes .../src/games/geniussquare/GeniusSquareAI.js | 52 ++ .../games/geniussquare/GeniusSquareGame.js | 600 ++++++++++++++++++ .../games/geniussquare/GeniusSquareLogic.js | 177 ++++++ public/src/main.js | 2 + public/src/scenes/GameRoomScene.js | 2 +- public/src/scenes/OpponentSelectScene.js | 2 +- server/games/registry.js | 1 + 9 files changed, 834 insertions(+), 2 deletions(-) create mode 100644 public/src/games/geniussquare/GeniusSquareAI.js create mode 100644 public/src/games/geniussquare/GeniusSquareGame.js create mode 100644 public/src/games/geniussquare/GeniusSquareLogic.js diff --git a/public/assets/images/game-icons.png b/public/assets/images/game-icons.png index 269ce15a30373505db8fc40052ae5a765012abdd..91d804628c9db17b3137fc24d7d978a69a8987b7 100644 GIT binary patch delta 55636 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 z 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 F`d`#26C?lt delta 51634 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�^GVA82P@)~DF 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

5QrpgO<-ClTHy3sasKhNlQYJ ze2;Wo?9qA0-w5sh_Ft<2Cuf09(~3;0n%+m0&stPcGzv&ys8y(u)fEeXQprUN=oOeM z!E=;qNJK8D+LMXMy|S98Cwy?vwZ3@&ktP0$y2pGaV`oaXQbx2@k?Rv7nrcBJ)KCB| z4U;O4(%`2oSdzdX=VOdC0i0QXay=>)|0F-%R<$}~pG~LIZzJsF@O2Jude~rIz3z(H7vA#wS6=9^=d&sj@isQf z7{zI5P@Slc>_ks@3W#hs@DAG2e z)KSAo2fAl9tVzwXl_lUUFGW&G;=={YA;}&DYBhFzojhp%Tm5wlpKWg~{IqIYr&!w@ z5sRiz3{>=F;1vbdY2)Eeq?nRK!YotOSg_n16M4s=-Bm$$qo5{Vc=j)U`sCqzZW~DB z*bA#~Y`KN$ZM%k3A_bv;d8(1k=Aq>>$REs5_TvOmoT}@3aU!0) zuWr;qw|~>u_ieK~es#_Xjvwg$wJAdtV&{9WWmZ#2;_Hvx_qr^3e|VE0HSHB z9hnvnDOK{ID&CY=lC-lWzsFdyM+0`d&4P)!yxOM|UswvyYlUMLh%=589Tng>KRLf_DfARLEmdp7 z9zFTLWtbI|n?S*TCKX#XDVL^R_?)Gwm9%aoXKBxaA@^jY$R4y-NFZNtCErWIAmA~d zBzxo~a(yhpr#a}U9Wc^upz3^yw1)280&G1&PgSk-yL+xb|D#{r{8+y@e0eh?`HQQe z7&gQ;CxX@05FG({y!Nk!mvO)bY{2^8_6bm$M$gGDt#NmME~6m5@*xZgFqnBp5yUbP z(L@8hYzcas!Z_rVlOeidXy{mo;vxf)UG^i+{nfA+p8D;Me%1KB9hOy`Dj4SAsB)`bB?Og`eZ%rW}wd0^Mz0ln?=+4{9H@2jv27JDmXI*;D zsvll_`P1=#SbWvY33XpNoyLEIMM6zdZqvIMUsjGfGQovyaU{w|A)!|x?@6F4=z`x- zilJsbR(K-lPO>HGSo?9m5* z&mDa5e#0D2$8_0dn<)s=6hRcqXq1cTgErJ8*>>xH+T{yg-f!y6|1olke{Ywaf1(UM zbGxPySjZWD6h9^bYAkp`wxs?HlQN;?3K2w>ZW4F`BB{e;a)z}mPM648)&Ng{SuRJH zwOK2gNpmFWG0-Q)s8e!tnukf3$vM^nbXFFlHL~{QF`}UJ&2hwyB6v?zRnAb;58n6N zUrzCVa?5Ilj+=d=?X1=!ES~ftRccw2@q6SYbhN(0g5y_N@W;D zvX4j?1NJO=_sQq=sY0PIC)A2uQV_~{$lnKpC19EnbC7)<)*NE}5DvQJvSdrT02O4d}B4#)7?a&+zPftv2Z?AbH1u3_o6 z{y6@C4cLHv{r05*L77-L{7@?hBHQV1pW2>7!2 zbX^o7=esyy_-Pn6i4_2z!jAv*E?*Z5X*(2bjyZvL5n z9FSeI97QI_!*B*6$}C)b0%sm5p^}WNQ%2&vbdPCNGKxwf=Y#M*6C<_rv(1e1oYcjxji z9DCw1JND)Hwm_+3^ZPJsR0bN8fl^X`j9#S(5)(tc9)XQ5LV2zST@}MHL9oLXTZd)J zI1C;%1g@TLP${lJiG+%P7lxwOw6u0FyZ72_54!BuTffy@WRG8dj&~5d={Qr!Ow8qF zU!o_<2^m!r+<^ur5Lnf%dRJa>{~PJgJI=eWKV=&_tY(be<(|xO{1lGkjuj<;x!B5= zLD1jx~^n;dChg@8oEQcqGf#%gz+06C5PjV^gph$>LQXOk|2 zYnEaTPY@(s>IQ3C5l@<%S>UgKWDDTal5FIx2)?44G-^656=^+a|H1xoZvQZeVI&y2 zHkk3(2;wB~M6MD{!bU(OXMsqQ9G9FFRA}0i$lqnrDkd@*s%+9sPOJ9aZ$Z_^v_LcM zH+}2(G@Fwl*J!qYF$r+iNWW6a=Q;XG8g@ZN&LN_MAm+Hjp`k%UG9m$gK?5>z0(H&F zI3(^g^b?>|P2P}Q#jx33$iohuu^|#CVBF*XMtB(qY`_L=-)*k}A?Sd8h4c@%IV6r{ILntan&lVeU85fMAY9vKJJYqSj>`7E5n;}Pfz*Ka>+?a!HM-v>E z`B0YLgf6uL&N3cKCIy#lM=qGSORGRb$)=*F-mxCpMlSVMfA^*JR*c+C=HQMWS zoldY$Je5{H-QCi@Zq}*ieQhM$-?WjQeX401LZKK&wTf(i3`0aV6DR$P04Jvtf@qR9 zC18(BK_sBk&{6~#rpfn&g3dc>Yg!wf%N0N*jba*omEMvhSU{34g%@NO3(||Ug4)mx zD?hWagkGpEVW|wKr47$OqF|6C&sa6cv2!fPsK*3+o)XShNlsEZ$coZ?W<{$|i0aN;`ILRS z^Rym^VSV82$SZCl&4&9Fq?`t-qXIWK=FR1>rs@+})^O zn?tC7AqANX>f^`x;P!K560QKpmRS{(4xWLV)8P#OgUH0A>Z}zJqH{%3A(N8Edb4?B z4tVzwr(ONP(jQ)P*9W?iS+#!UlC8I0cHXz1_U5>w4?m@J`SPoBZ@o=$Jc~?U4wi#V zG!8O*rXP9q2$ytXUen|AooWo&%cO;Uj6c&a=PnOwep zP*-V1`KMzrs$^Ug^(sX&4Bi}9LH-c7C8+4&suz(rOkEDQ+ z3NlhncWqBDrD<5Xl{va>POG~6bP+_l6i&e;g`pNXI{BR{uFxuP0s?KaU>(DMQq>`V zP#|!ZKI=>-Q|xdJa>Fn+sGZ)>O#YO$I@x zw;OqSFDeJ2EC_*1L*z)iIcR-C`hiwGYqp}6EjH7a)ZX!czzIcx|R4ICx5Q?jcsTd7StXZ$dGz`lIbX4TOMRS4 zMca_2+=T@E788eLXmJv8(x$gRwiYY5x8eTthGArxoiw=@0X;P%-qLshIn@98iUN0V zk+{fIR3fkDp{SY_6-#H+&~hOpBb!j>iK0j+fLt5}Q+8o{_Xb3h?WDu!Q5+~mS>Pbj zk5%|R93)8|^udCErvpdMJUcwNrgDD=%a^2|coA$3c@IuM1$L+8u>s$Qsej++_aj&m z?C5A(zd+3^AH`ycxl*mT_ucYNy{qu)OM$qBojtj&@M>&Bld9 zd;OnyNfJ#igFG2vi$^7K#Oxvn={#0Gn!vhH4nxcQC^94%9Vw(*G^D%IC??MI6xoJh zE*~nYDo{+kZ9bO)Hm@SU#_455`8*-MVRrrWnOAIw{i%~adHFvsD_?Z)Uu=wR=+zs; zMZal(-@1k8JGv0831Z6eHE@h8Mo(JDgrf%|vZEc!?j)|7>%o2_4fK-1GfF)9RJtA; z!ac(=OY3=bw?x?^jwvEOwfq~O z->kmku?0W={rNM$QK_|mX8}#UN5A);G9jIRuxLUwYe|(%dOCxgK&CF0+@x%W(ALiD zPyFR<*Li2J!k5UADstO+$yb43pbb$y3vG=ZD-s$~4g(P;2{A>^MJA;{kjL0?4iQd9 zFF7wGF^J^ds4Oc+F3-c@RPvKdsN|W*lJt#(9GA_;JbK$vhxv`3-xLYjVY|9TY}&Se ziQFe(_c&2Uz=B86z!lr@)WS|IS+O0*9aMr#PMJWQEgy1jaxdKtq@C>uxNS#})_#cN zctu~k0a`-~x`$RHP!t4bBp?x>lq6GqOXoHW3Ra*w6Gi>bdElcq$Y~8lvW#R@!LCRe zMc*$*ws^D!5;#F%D#|OzlFMCWce;*$HMTX7i?btfxsNX%Ie8khGkoEZS3mOV2Y1aSSk9E_@-xMHdDXCg@(*1E z7|}>&o~8_#y7jwklSnf;EYJv=2T9(4jyRGk0e-|kA^=gabelE35M`ubOw-K2k%;S7 z5e{d`G*TUJ)yl6dbXm7kv_K{=2v(F+?^^;dM5HQ9 zZJnrZioxZyK@c_AZ7N+khmG8`B-yS0Ao5zwQZ>Id-CoSjhKYciQLJ@fFPOE;%NuKfIrOl^*oi%6fy!nqm z@|}pH57>YW*#EaL1Srq?#eu_@zuov!R?#JoD57F!3bT*5Ayi+AS8r`cxtGO+Di@-X zj5Y7{LhH=p5Hf6?=<#6O;5s<#>R=Ytk%5vxwNw&J!)5|-c$kSO*ibteOl;uF2YWqc z=CM&mhUV#9|L?Blgj?Q!@@?<+U%zvk?c!3glf7uV8=Fd5e7ZG?&Tto;%_%f2ugAtk z^>BNGxajAHpUFos*FvUL0Hn^B;L4z{m8!Ytbtu&4n-c_0+I&V9HeEu zqKTAINUR^^H{c#;;;mIOmhR9{?B~(h8#q&8%+`w@TYvMs^Cx_Nt3YLCWhE~LK23p2Z71>-&IEK_N2Vfc=AutSF-`^H<4k2}_yJdL;Cf>W{&{xauEN9w0(oDUn- z3M&$na){vk4E!z`L0XVNCTx+?tq2UlN*5G1fpD*c9GUQ)MHK|>c(HQbD)b~pcu70k zL>WZ^$2Xds|K@{#rySxmL%;NTxnsK9%b8dIx(ohd7K5v7DDjn{NY9XoTEQEeqj+cj zR*bLm;^Ci==m~Xf-K6QpC)up>$%>V$mz;6VPrlZi;j3?ZrQ+?S-j_CPX)19A zS-1uj5irC1R&e&lH3 zO@V%gWkriZhhjQWq)Xq#={2bAvOyPvL31Iq8A*KK*=|1$kf0P!89){sO6q6DlNxx4v zT6jaQlgX2PM24K|iWCk4MN*6ze_ z?|B6=G9J?Csz3m!Br|Zj94IOd;FjyZhf%c>Scyl0Qj>s8Gujsc4nUyA;JgGOZ?~eX zx?m7zkAP&ce|)c3FaFuCzxDbc!OV~I0y}EI{f1%n>J`WmT+5Sjs=B5UYd-z-kVq&x z??;#X^wKBp|G$1^0U59X8?dj|{v)6qJ-S*dtqmR%jx^2Ny)7cu9z}fMP6ZPuNN9YI zc&|AIgJHw2EeaMb>_xe5;CM3Foku+3!NtYkMvej#f0SX4JO*Y(oi$)FtxbUJBr|L$ z8OeIV5Ko;+gpk=qfM#_aBRkk@Hy?F;Xw3U>-~UX;nRjKwxK!M4JkmRMfgMvv0142Wj$-x3XCZ89!XcxlKsqpw_NFF>$487t9PssibEeh4D3hCkoj~i z@abwW0S|n?zZ@Iidk{OCO&oe~2{`vee>kcRgPR=B<1U6IiUfc0Wjt>yBYo#+yVI3B zbjEZ_zJ2A_)%KTN|9f$3yLXvSWE7b?7%rcItC}tIsiike~%>td4^nrWUWBVJZcIiO*ss=-}wMueC{<1+*S^% zBll(}->pMQ(FkxRYtbWF$~vsgB270L1)?o$65+JpG+oiJ;Lz+uL2e_1`_=v9*zzqkCKuWR|bm8JBq!&71}^xfM>k z50i#x!IssczRiwW!wZ|pBTKeMeF73`0-V@9beoAS-2%cnAVDzg)M{AE-YW6<(|M{p zO*X!u$IEag1TsUk#dRn-6T3U}7*uRSl{bx1#XP(Y9;y=N!;1Zie`G?(O^>{G^9^%P z&V99y?2B14nKU_`z_-_5h4bdyfCnCinn{z%jkO}KN+JncNhyRt0BCJR_m(XtPpcUA z(tKqTCzX#F&#rv`W%Ta)6lI)@SV;yG#~0zk$w?SI51oK|y@hi2iAbdcylu+p+z>%; zdkn2!6XQnghvN@Be;(cGPUNBj0i^%rvMJbXc2tcC z;N6vRFdYeaWT=K|xY}AfR|JOC8u|A=CarBCKY9puL>jPRf5}4_Mf%W?=_9c_(S=W+ zY(e9$1V(sFXk_yBRoYQDBsfaETgH=^*KYE{bZ#4<1}Kg=y&);=jBB={Y|{ z*-?ig`Vb2vr@(o}>5#`Ch`&BpLBM=FHmvM~#&^Ku{D17d2b?5Tx&HrDS9Q*DdU|r$ z+1=Tkb0A2Le*yxc2%;jGP(jgax{89=fT&kcynrAmC_!>&Sy(pbot*P@Pv_iS>HnVU z#cLM$UHRYp`OMK_!ghC^syg+a?|aVsKJQc5vet+cP2_1|H8R#S(bBS*fXzmRfj3%h z@~7}F0wwR9zxLox<3?Mp3bQ|etmMXYl3?6eNsJLCe-YVy5!HbpN(upw-ww4@roU&A z%DNXy4NEto@PedmOLLqCcoJJvQ+a~&3d~6|L8IA9plPU7zEMg@r&7q%fD^PBMM0Ac zVl}cAEm-pSR<*Xx{ok40Ebdj3D!Z~OSCJiO|JOFXSsicfbsR*QtCVv@rHrGAj0@WV zA^t;|e=T21ieB6DCYV!sg4t3fvzskVDteC=^Q;$K2zUf+-nbOcJ@GnyHV22xg)2XJ z5o+i1OwepEZ=CrKz9Vuyo58ZU5CCmrZIe|2WRT^SV2ap ze^%hM_$7{MvN5R(TMbQsWSp5WFX(rp1BVBCF*w`@QznCgsNzC0Tt^5ry*UDqp<&2# zo9s3{_v6<;`qhma@BG%E8L>>!Y2{sh7;;f4Hku5N_QTy!hs7-fulyWHz7RGCO_&~6 z5E+sYsOL1BJ)kawBRvYME{(MfZcLOpe+s-*(Ww&F$WJe3{K6U zWsV=?@hnaHC6o%~cLgZ7J#lM`snGFdkACO_sZ>tCr=MltCTY@DwMknbkXTx+KyNqU z_9q9>N9TF!>IR&?rkS8!#Vg%0e`I9|P4lWzo{6Bw<3Qu0I&@EG@uNq3&`J(TYn7<( zi1@^r_*8b&doD`Fc0ALc`QDG(gv&0%p1w|uJ$nl_cxqu?W?>&BcMa?WCw-$)8sjF=1IPd> z^={mQH``#sc|kZW=xhN2*@A#vPKMLU66F+#20f%~hOLren(m3e$_TUFh;f?o5e!Pe=M_Fsl+f!+BURYDS=ol(ihuJRgPz5%P?Ea1XD&W*0BPE zm7+In#gK`YGx%gNl$BLTRg0O#@pwvd+>TeZsqAQI8R2Y&lC4bgIxRtm*HwO3wC(PS zjilFcf?y_!&C&hgG+}g2u-xQe^%W~6x1}^VyF`s&34hXA6grmocY>VF~bS;{I|@l!Ro~;P+#pu zDm8${Iw#E5YKWzFu+$OA=&LhW|TwwdM6?s5mZ+@kV;yR%4KnaB48mIIGku&7khghZB!gAXf9EhQWpGfikjJiKeJ+jB zfibi;xK>!kyHBGJ`oo|0&EPQU3^p?iP7$e07L8R&=z<|kb@yZJ$T8GY|E#SxIBgc> ztTK#(9(f|f*PofhhK*LtF;76U*|0odqSw&$K@$~A4l%Lr(szL<(rr;uI==ZEl{gG1 zbqEtQmFXM}e_R}DJ_}Ly%0OabBmZ*?=V>`_A7NFGA4cY5sISH`TcrEFCI{9`FR4V5;wl`Se zf*e}tU}J8 zm>NrAf2mnU9f4_o-h%Fe^MP>USjp{nnbfA*?Y^fTYEujXMt1%hHCa1~3yK&U$fKJ8 z)k%P&*K^=YSxgoTn8^a2eF=Dr7WfS{&`rDwt33(Hnugb|XscjWo9$%IWQO%~pTOYY z42((<#yh`H=fi6y`4m}zsVvd8wPAj{4|QA5f5RIOJ%c@O45DGf2eESVh1hd&P=kH@ zBAcdvK*00*Te+65lfv&M@cO2rs8LQW=k!uu){7;xB1-Ojo->w3Ly_YJkvs|m$8$zP zDmSkeB)L$`E23PMayb>{jQ**gkJrh?G%_P*xVJ8*XPqD`r=S>(AvZlt&pg3pbsY-& ze=3Ym7tqpdgp*!lAoxkdQb=rI!<`nYGI{Pj+QthGhIlQ5W^PZRjmd$ z&#KrEXco!wWh}{HjjbxOYBwy#Qjug$kFu;~c&pmSGB{)_nJku3l@#rB*mgHNmKH0i z>NGfF$6?w0JOQJ@aNOLg6_rX=k$6rOf6S^X5Hts%GI4aX4LZG>K7&D|sL2dL&XG-Z zKu^ao5ZslDp^s znT4EyvroAIZifwfj%JYv)4iA~Kxdq!>mic8wj$sT!K62!bN>O14o;bk`p(Po58~=) z+iaU{|2x{>v=F`h6X&S12gqKg|}LbWCjzrQJJ0n1N!BCK8*iG`wN` zy&Z@4y{!!IORo5s!6+9Oe(0Z8%hzGi%e~NBO&DI; zfYYNgTAq0ZCW{UGO*PoN;6wyCn#@Z%n(QkQC*_g~3k&%A7qmz2{F1@%82OMsJn&Vc zUSHcgX+qav8jI)E()}*MMKiNCPcYcdW6y9IH{RPpe=p*yGu!A~f7}>|h%%4lzyix)d2JkvXfY8uD${57gOGs5kS6tO)WdUR-_<0r*pNhy`eN+Fki z)-tE@BRbxKrRg&;EL+h(lh9VNs_We7dT}?#XCwrwvoPBOm@LciJ@p$rYI2~twGkV< zwOH&NL8&Ba2_S6ef7N6%uuWbhvjzHZ2_*(jEJ8(apgTG5Ck0dX`sgN5^hn%*JS>P;i)r`tR(7;e!c(3lG|~OYWrYx@(;Z<#;>vN@(~@Aw zXv|x-70cF~2#+sFPD=?ReMj-q(+?pwGf~lwEJ`@xwD)4^sx8_UY$7&;*IxVsIuGs8 zRupCJb1HF^f3l>armh7ay!r+@W(q&}=JlEskwh@*@&<9rSr=mAk`)wZRf6hFMjC?|~#hT!{Ob)TGtcka? zY#>f&px^0BEorN{tYQxf^R-35C=&YJ5$o3V5~nP76y2B7kK8UN6+b`u-~H=}uy7bh7T99CxW!sXz0*1%@aV{g^l3g1kY8uAGXL*@uzh8U#~)$oC&ZZTli*gU03uwoCVY{@#wWe{lJNnScE) zfBc(GoBQs3@ZPU~?2}hF+JEq~Q_7u(Xm*t}86@y#O-P)r#K7%Qvge()cSkyY%U!qL z_O@0iS1w()Bod3*!edGBG`Twm2wvK&u_Ck?f*3^DVn@*BgYLekk-y?nOim7C)rkwB ze)4hTum3cvUq6T%WddEMIxUW^P%6V{e=#CY4n;mC{*PvOZeBfKcl|kwP6|f%e%F!_ zmkug)@5oy)8YMJ01d+=W;o!2Uck_sg27Kp{33N;samJb;-n%-0Oi4l~ITe%PB#k{g zqBA0Vt`g2zZbr$_jBh;IgKTOBH98gbEEWzT_r#1XJI*cnGR(ryVl%I6L3Ioue`2x3 zPLJP5>}=sejqPyK^Cd||g4G%9>-#n4v{l2>#G|QJ#Gykm2pK1wRRmV<5`^>-=%(58 z0pw?5xj0kMc+^nf7N6x_TpQ)wxf^uSpDTc)?j9X=_>;1DED`t8v!*J`N*6OPZWm7dbtFO{Z(Mz3=?Vx3%o-bz9zpf78ypT#MC= zMW#{L*oOCh;98{OQH%|DX)Bzpw4#=z7tR~;3h{yAjgMU3YLV#8C_6HW7-zFPS4X9Q)MtfRwEGD&J*=dDZDdn zSW!vqZ59_fOnQvRCtxI}+-7oXTB>ZdU!`LTLQ#{oQVFCLmbh26e`>Kuc849YxaEJ1 zChcsSZL{s~x4#0)v#(fg85thE#5qqStYchL9v+5KATW7P4p} z13N6~FinQjP6otEf5v)TEWyhvf)q-j_bxwCc;vv#e@qrJ2olzA^r3f04^mPUe(`&n z90y`Bn5SXP1+k?)i)VTS2zDcE&GV4=Sg?a^swp)EZ^(ui8T!GUhsaQ1L^L&x4d$SQhRJv?&r^(c?UQF`McpvH&(`WzOo znUBHmT!MhPe-7a%kD$0}DaLNT5nihq#lZoX=FCMZJPC=$LwtG?E>8;vV_{7$@PFpA z06T9z>vSa@`HGXDSUV_NxlGoEY_^0@z==#Iiw2ttE2o3rUX4e0j^p(MeQ2w7<3B#! z0FP5Z&xDL}nXOot$%)Y+J|4xgRx|1vn(#so)CXTWf5O#xOQ_=&G_Y-K$*OiH>R)xv z+j#YX`@Zm}E7cn4FIjWeR3d!1%VLn*T~@kgsX?ut{Lh|$7`B1^_<=uzmoOLGw|USq z6N8T{!Z#toA*smv6%=Pmn5pukch~L61RJnyUW1lQqAEp9rNT5eqnO!u6a%mCN8IH= z=fNI$f9x%2yYdnOb`u6m5g7GGnCV<%u?)C$7gEDTl*#e)u_P^4^siK$yyKU@9sPUP z)JUG@`_4bVx~aCt<9E4~od*sMJn+aP?>K3L>2unx{1{QwDwB|<{t=)_9P;2{cA4RE zyO1mK1oPy;$|`+j$pKU#&^WT_n64v-Do32lf9Fd%R;!!E{4oGzj_nDjU#zWE-u2UO z)3w+Ro6U+3e*CLwU%D1ea~5J|dW>FkA=#S(eoSNY(7^*(y>1IW|JCo}^b4-U&%gf# zEv}NSPO>fVEhnFYwgtzL#F5L3%pTiey#D>ia@R@5rOxI`xT;8J9D_4cIR%wUHDRDZs0xCksYI@T# zAt$wCven9pypaH-*$BO(#N^(=5wJ2ve~hwJct>EDj;X4{Xh$MuKv9Z9UskD4DR^97 zIBa^Y&U#rj!XVS!VKKvOa-dAkWhq?7+__%5??s{eoer$oHrr;~yVm{+D6`Y3H`}Eu z28h8r4(Wbi-sT{>$|IQHz5z!b??RM7pkdAm?0veE9()->bp$g3n;WG~2?~e{s;q zXE22#&h*z}xLm@DP!kRh^&qd1{VcP@hZG8Agm=(u&EzpV2yT-3EDB^S>zN3*R78QC z^3#@W@Dor@z1hFoCcEsf74gbbdf4Zh5jirYtuD?a(uhCt3O0ST9u0N_yo)U8DL9c# z>yV8oD95vyU+cmJ*PV_d`-d^Oe`gdco93h6t;0x^!^(h)bXLVn9Wth~I{KM?rlQ4X zH8*l-oo_};(IGdQgM%X=)=31w4lJ%$v1h-4hBiM&Upk0}_Kj$<=#9A3$V zn~ENKp96|Pekj3H{Em3&-bO%f0?%}B%aR2 zx5Q&brD9MMa@{)WWi8ar7_C{m#qXO8RTMF1Os}k zJE;lbVnF@+U5B{bOqyHkhH7HFk_I!LpE9NN&6~bdU045$2kyGz?uU2fHzyti#ykB6}yqmkHczVl~eL4=JVTsddDySYD_$E)3*%ks;f>Gb;eVbVrhXAoAF9I zePPw=joTJloOi!Cf7Cni@{S#EyLR|pKevaH2AGyO*+eGgCMQO=s+s!enhOJd$=tcaSkL>8;v0gta*+j2g7;5B-l z%gCgP7#`?C%e*D%(|J@|>D|5aRg4bxf1$ogawtHaKG z0GZ>;9Nklv`ppqkRfHicvOyeggQ|1V^Ey!}P0C^&kNb@*>8>b~Ga|V0%=1U^^xIk`M?4;d0rv zPzzDyAr`5>1ea#B0K1!q)A2v&T+X)HHrxJn?XQ5+e`J@>o|%@Jo-RD|RjjEGVyrlW z+U8ZrO&vw#P!T6=@S$VxK6LDlY30ONHegK2W0;H_t0Zg8lc6tVu*YhJO^qT*huJ;c z1-IFTjU@@cD-isZ^6-)EERa=AlaVXtb10K{&MVC0FJpuZSe-1X12bdAKkc8z!B2Nb zd^HO;e~TzYyI~1gamEEpV5>6Xwf%A2^qDU5+|8&tc>_Ei9?NQYn9F56`H&H@o(Zy< z%{bxWMHrrt&^Mvt)F$A`qKw{g2|ZK17C*@{eA$xdA|Hoo|x)K7tI3 z%CfD*@X!RZi5#k$Y*@81fT^w&-nhRH^WGOge>7v-disCt_CNE5HShMe_nXG|k1+6w z>%SiPkMDfrTwSa0wBhmGmydLewuJopC+k$hPiOY;+HvGq@7vDaT)bqFZaf)Ys53f{ z&t;IIdv`D@B6092q77AOt|BN8k7DOg7R|{VYRo*wvQeDa{4!F>I41l~?B5r|Nvvi% ze@le%dk{@aXf|u*^N=qU-ti=|?R)1mnE9C>%Om|~O(*r-P(&g}r-=1SYY|Om5wZb> zWCWWQhj3_y$2Wg^2)aTZSDiB#8`jk!Je|Rd`)6Qx+E6SPVa%iMti`intUY;Cph&$*!G;Re{S{1Uwq_;e|KdM$BBR-W3RRnMYm}poj_*v zFuVjV@#zv~2rwS23gE*XQlMC$_N3iLdfe2iS+DrZp~%Aq)EMya)cYDW}<2cJSKfm@Bue-1~> zTy6D>b+Awvvx^0&0)dpvyY`fM3$9(}^nLI2 zOW*&%4ZnHd?e2P`%9{SI&&~gPE^c;m`7qLXCyd?z^h}(*oQGFmBKx3+)5)p^&A>rm zA}0nhFzAHIz)4k&o=;0X>PH2Mf51&&5g*Uz@_6v>?_+v$Tr0!Kl4Y2-VyLb~i`$N} zy6eFjEhaHCJyofU!?w3&6@z`&a(oV5lgS zmCL@KPK*u@VAY2AptrXlgZ;fY^ZZMw{{|dAxJQfSWFqI4vff%HouZ_uf7XiL5WyTv znqgVj9IMrBtmsv;*hWo~h^^{XYA2|WHCdx{(MV4HE_~{mn^7u~Q|>Wh-TDRanBw#{ zR$j3ppQQ5i*}4+-k$o2X42!0-$@C^wf>bTDo1FyfifY!jy;(nWrUW^LwUEUaOk6zy zy8a!lP`2r1u4;=1I)evBe`kQkz6mlp@VqpHQo4tn{!#SwSrLixNaQ&By^N+1olo5) z49;e_JlWYT@7Xrn{tvW21IqJ1ICp+lOx?(a4KJ^;irl9zn}b{L zP9SVGpnj19r`1?sUhTy%eldX5sE9QeTd;8+D@LY6wWk^P{6_{8y=lB>nVTt>YZ;v{ z46A4mBs@pwt5sdCGo7@v3-Q@r&-bD zWfoQIF*Gub`Bef!b{l5Q9^CS~PIUFBarTC4oWH4AlWIA9U;_Q&B z6jaZx#z4}i{_4B0aPe>k^IIC>2}qC#4EFSz;$xEQfAg;&ct_@{}{?E0$7Wa@y^ z?FFwhqM>RYE=|gC>85dCT*d3W7wuUIQxXr4PC|BW8>Yw!>vzX6W0J9}B*H*_NYE$M zEm^2(4YD@&#&%e@W-%&zk)9AC)|cVQ7GWV+4C}lw_oa~^Qjnb6fTs2;Opgy>$DS-! zE?*DHe;>fIs#dM|fFg@ZG(5fSPdk0@B^L$fPfk4+dF8d$>4KW*f7wmm_T zBe{IdR?JAvpO=Jt=+I!fFBujQ-U-4KRZ@l^)1Hg=1`hLD3@FQF>gkXyi=8|;xYP|;QIjLDp!QwWq@8WEZMMC$CS3Dx=lEdK zogDJ4IJAH76PFu|5jV@OOib%gdc4mv3Tr@aw&0?l7NK7p0(UM$<}f5qg1 ze&~;;VI(g&P98Q}7a-plZf)nLjLt$4E?L6I$t}w^UunCov_(=&*8qpx*ZSftXsFpi4R^Q3!K<|{(SuEXL-z@D8s+Xe~9_|GA8F*;b{wE@2(t9-Ry+f%_F98$dk?OjPS5G z1#!Yk0d)Z$A+n+42@ySmGYCrEIH$>g53LU2SUiY_UMgY7;~fZ(N1pV{Ply6w(5-bvx>RWs^Nj*Qyear*Jxm6f7v9OG%T2! zPLn~`so?@mEx9tMPZM|>Wts$ZkYu(sCMbHHTh#MhM6sBToqNHhPxW{2c=qVgfw4kC zep3UpqDcHF%~#!Mnhr;kdVwq3Oq|NG5+CoNz~R5$aCI#>%hQGAn6T#LHE`N^nhc6a zjwaDSlS6HB2BU{MA=ZUZf22NV%Ne*^ov3rQ!RB%y9?f91KZZHW8gXnOi9pbW_O@0e zGh+2+(pvt|;cs>I^sOq;{i!E78O@885`oDHO(;K59fG@_L3S0U zMh54Zo_OYw``-Wl>wkD~|9#KDw&N|2vUP2R`=@5i>&GV4e~%hzu-Cc^NEpfl8YWHT zyO1w~mr9sPWRb}E2#~yLeO>NRpK18JELc^?ab*T~#ge4S^sr}&$zl~sidH4(oJ&52 zjVGRtK|23m|JRQpiY2Xr4tHFCQrmInxQaZGR`I4H1H=+~*y`lbgS&8G&vq>_hy6QC zY%5E$w&J&Bf9Xn`bHV$Oh{y2cW52^pWEyKXY{mM`C*bT0K7jl0zMU2P(JZ7a%37Q! z%S6|_IaZN}0FO!d$Yq(Ju1H_(_(bk(r&E81J$jodGRedE^f0ARXlsZ;4lE5}f|7Ow>DYa6R ztnh(}j!Vu$nU(gWbF}gX0%uF(B5;`K&YvIVjQRXEl?f+@1QCAo~g zo-kH^dI74dt7xp2F_YG#TuQ>>C;Ob`;Bgtv@8r0%ZMMy}cee@MeVxB@wzy9dU{7*3 zoo=E>e}_ez>S%%qV{jx7r&WeG=mqbl$tdB%E;0m57gk~82}=>}8HcZ}2Dzg#f*hWC zur$%ih>^);CM(1#h>^jbAlOg|5DhGol^}B^*`*0ig`_G-u$)pBSIKnR$i%UIvSnms zjjUP(geU&8!*_hV{n_h(JM^7Ydi76kz2gnxf3g!2@U_gxBX`VT?R6L8g+>QnikQeK zPa_^P5d`vRbr;d#GT`J(8*%WJB+}t-$i`Ysm0ZZDRb;{<@ivHwsN ze-8CU8~?KZzqsqRwSl_&d+bh6TVHn%maJWXrsfvxd2I)Qln3?A4an@+i3jid4JQWY zpoW0PWs_kPqsV1I=fuP859y3Pr%_Br>U8l`ox7^>w5mncHzeh?FZA~GAIh@yNxZ2{ z@<*stjYhqi&F7;;ktI&2Dw_0&^j8|}e}4s{f7!-+N2~pfH4Y1M*t6>xR0Gqal#wYh zC%^}@N)v}YgmSt7yC9>c%B&?Xq@v>}=aS&X0#+}dk0)OrMr%_8rXw@Zm&Y+p;A0Lg zpz9ET+v$AETizc&X|>c37P*$muWv3y-zUCIqXRu(zv-haY+df|BJH)pM{L zEXX8^=qdZd14{LEdtZC#!MEDaKW#UD^?S;Puek6#CS*_SRXC+KM3QpB?&)F>E0x$X&1^lTIV+YStvem=>TUNzeXi zUoFwtM`q*kDA&#^bZfXfBl_3w|@Ps z^T%rf)i2)t@bBN!O69+Q{6zWcn|^ykPhde)M_=*8XhxtzC@>NP>B;*^rHc?@Mo|sG zV3E{%PjSi^+nW*`?jVGYL zw-cLBI#pW@{?T{8h3B4mTm#NmUwH{%|Mm~?p3~39qYwQWRnfUoT;z_z+W&NuI7I^hJ1N3 zW0K=%_d;UZ?rb|=e-+<$N!Zyo+h*Il--PUBaZAA*;o_N++aPBl@L7xx%a}Zxh0D$( z$}$^c63+YL1sFa07}l<@g_RR9F)#!*Q-;}O!idj_)~N)tgoIf|MoKMXicFKAdBuu^ zJ~C2`vWP&?Yq zuV^)$HWlA=?tRa`fTsE=k^}wdzJEUoCoDk&!NXJ|0Uk|6kvJJdZx~x#F&O68BQ;{d zZI6YpdMgj3O~lM3aBx=wu|rYtei!b2XcV8nrXEd#4slB1V-~ImR6=&9D%kld{ z^|dWSy~8vir_dN;TdNUdh!*EAX@PHm5_=!28?nA427v1xuz>b3nG)v%EWZ5Q-^_eldU~^@W#Hh-OA$k9tr=6UUsn zR=TEx2nOxYiD5{58hWb*v6&HAeGM?U_2}C>Nx)#k+BI|WpSM4Qd@KcF^NP0wAguIy zoj3Q@e;SUf7jq_zmeSaC$_7kz51@@Nz(oM~M%jyR+}??FGKNo_8o~)nY5=DndyYnt zAfR^ERB5qly*(3HR%^$cRxi?A4gT}@J8-za7js;IjVZXK4H!_&>WJjO-_x?_vwI)> zN$jok@$WTRmfuii=?Ye6Z%ZJARCg8@Umbi?e_Y=xelD`UAlSL4y4mSD1!<_Quw ze^?DVI0POZyA^f^K?#9@exirS%!THLW*qM9aWt%0eaop^HlI&G`H$jC|E&G|E0<)x za?g%Sg5L7kJN8E}O_#juB-!Z@1e>LA4>Qn!Qn)+t^=AJw7fBX{)jzV$&Aiv`?#%OhxS3t|BcUV-<}`;(ds5yy5? zw1ZeGS>!r%g~GXt56V_DIXX`U$|Z#(pkpmqq1mC+@K($|W(!Ti~Q?X|8s` z>8-}+Kg46({seNOpT_Va_yPu$f8q%w662_HOHj#4&lNJ-VndcyyqImXZMOZdZ$f*k zwWBW;U*!z>;B(K1c%TExq>RS(7L-OykW)7FbjI-N(>u_%%!*AX8}ZPu69@zo@c2w9 zW^_mf^fZz2a4|u1ZTni#vQo!cxji~aEhH@y+yJ)KEh0{ajeKOxA@EEwe=%kYHj0WB*@w`qSsm&wcZE-PbIM^L5AgQgl)fGk|r6NL;?6XhPWLU+)8#2RDZ9^eb4ewkVb{^=% z{(TO-f2&7}1ud6=?XM=#f7?kOyekO3r3mrxQOuufLYt)tKfkL31y40<=Q>~|7#YgY zWZ`$fV$s9v(@($I=d(^dLFgULf4y#lsb$yR7jblFH$1gDWP1-G(o05M;nC4ELf0>f zTrL2!z+qx?3ekiCPJJ5l=^V;aH1QSPh$&{2`^Qn^$iZx!M7rQWe~}!4_GK#<8#(T7 zPw$>zGzL$5zIP%r*4urc_f2qgIGu(-z+a;mBD}$16vT45GBdu-_LcA4GQMg3=4~~h z_LBlNE47%{Ca(;|mV;QJ3E%F}NRK0M%)pIxn>b`sMPzdY%xkSeI97%#STGYyAn0qx zcKZHgZx?nS7{CO4%nS+e=XmL1#Pu>ZCf7uyONj* z)uFn#4`#m^xnY9KjW(E!dFY1extW;6gE1$zwAyh-olDauWEr|gU#90azY>%EM-kT> zk;+S0wtPN1BYL=;Rs_7{_$UDc>;>GlBTEcwMx)Dx83I+F26|QFDs4MdEak=sBg`AaPRjui>uQs9bYAF4u_ z-nnZ|;EGExq>uXH+qpJ3U9llS-|oHOW1suYWI52BF4@}c{yK}n8A@i8BO~>Ok;&}Q z?)2C0yYtVs(`7}~v5aU2bfpqY!r}3OkA5D(P(2>LfB!DL{LG^j*dx!7X-i6C5ffvB z80hWL0CLXUh3M`$MBf*Y4Qa>7U@s!!DLnbe{cvu3UQ5HVEpxMUe@s~lLpZWE>^#x*ISfWHchmMlfFP$tKbT_eIswX(I&aXL3WCIzj;j*elX zUW<3+e{wmx*mPedwNlet=Kq-dqZ0%z1KQzo;}h4MkG5J91YKF%F2DX$7h?PCoj9=j z5GE%gxcLXq;m+GW1S>(LqSy$|qQsQ?3QVd@=9SX~*`a3W{q(b}Cu_`ND9sgJP2xB` zIrprLu8ypCF<%z{_TBo&jW>A84elJedk3+2e}0X&oAJmKJ0RN$VhKpn>1 z^Xp*^)*&)of|(@`8Fi>@x5LwHK`@}hf8Mb=Jo-!o?^$Ap#i2)jri`bbj9}T82E4k9 zK&U*1Y&wozuW%SUI*IUjo(!=Y-bM!^V_C!(a%kSN3dt-PLRp=7v%kU6oKunmqgRwO zGkEpz5XJ{4;FySlKNg3QZ-dQNg`OcB(&-HR78xFg5yCWqrZ|cn&*sqSVPRBcfAIBY zn7jo0Yxp>BDGmUv5iBCqG>poBps~;oopoH+(EHIm|RB)!1~j z>~y#sVp-vmB^wKK{Zp8H(`dgXz_fWynPj{Zx#=AUIvjACd@x(>Fc2tm#DY456=L3m z$T-vLb7(QPCC-G=z7mW^JLc5Yf6!z+3WLdvLLo;0ZpZj&1XTo+4!a3vgYhi|;-9!~ z;W9xGy+Y6ohTt zZ_k0FFPFR+%`MHvy=PRDTNf_s7Tp#Ul&aEHq_+)-NVm~@FQG{9ARQ9m6&0mO3r%Vi zhyg8Dd;fm>&w78XcdTd3XSKQJm}SD}nIsGV z$V;{2v_-kA9Y4Ac{crm?+(3W!Fg?n>aL=~ZbP~#X>qMIHbnsqE&ri))LKYvB;|z6o zrS6D);`sXG>lO^Cs4^5+*dlSo(%M>$IUMg*egIAVE(TfKh=q!oq48VQb@<_l4MpF% z1huClYZv)o?19gf)RuprhOU%+FDsS>V#Awn{9a24BJsuliN{5hHvFEFQWm|n?{#ue zFKL*TPH+G_$Xn7>U5TYDR7wNIea-6?Q+LS>|#5mmWHxxUp0FTTqD1{puCCtC-u39=k?d4wL5aE-uOYs#`%>T<<}w=AMY#5 zBycGt&Y3fEf5VE;KEVd2C=LFIc?jHfK8GC2k|De{-nC*XDoYcQ>9EZ6dtDd5V)UJpowNAib-7{iphjo>0hMR}$BWVEa(?X&PDN73 ztE}$##o+R?;(>Nt&)@$EUjjZ~5&uBwh;<`^{SCxgp4|E#ebFiU{MSOsUje{F-t_Eu z6;7Q_50ZZNJY;LUFz1`wK9gx}Vc^=X^Xx_c!jp$xjO=T0f?F zvu`57^*#6D_uWPF#QjxYz{Rx(kQapCO%d=7F#UdWZhOgx{#U?dv~AuS=*r8>c!%+| z_?O~wp(jFY@y@TcQuTF{c|SAPUD-|0`MdS_=Rpt7zv-|A9(uC-x0xO~tG$$>7Zf~iHFDtgrv9!{%JZhXMeT0$N%-elS%a>!zP5mX$@sGy z*{k863th|5)zt`3YG)QTuAS2Chp-on9N=_m*I*<@+OVYcA;L zFD_EuJ+D8%Eiu2t^9DZY@-z>K@6Ymn&M)=5GVbMM%F}}(%g3H84*vWX1B9-*ei}7< zS8yR!O82Eb{v%U_%A?D54G*7*o+Vk;`f~|6_o(^d{Hyqsyh+edTMme|W6pqu{+U=Z z3zx2rUp9pPv3msr$0YmwMl@L7l{sG}?Ok`p-O95fl}p$Pn+S^mEyt#d{{R<2+pC2? ziHi!s{`JcKp;Dr=@4T-}RF{Kp>s=W^QW&|y?P&(1DqFuN-7+IrYnT6wp*R0d4a~rE zx2F>#xamY-uR~7wK2=~YS8{)J*!lAF@jsUBLVYe{seWF0uI>9X=RZE;IKh*xI(_+b z)bj$E-tw{A^02=mxzK4P%6tMga^I;isZ+D1b`~|?!OiZ-3X4X$_`h?x0lM-0%&8pT zrh9=w{<`3meA}ZTn$2Fcp)Q%j6a` zqfZ+Y9Ms%#jQiU*>#GXI@jTrog%<>uER*B)c#uQu%#?%po(D z)c0$yViI^aJ7wP8=g63m*dZ>hq!nA1bk}20>2ZE@pO&b{cAD2s6Z<&#C6gKmZ}kIi z)XM8x2;0eWuGokeK%{O5B{j@b@a`)aYTD%%x&JT18|k!N3PS?H)#@4 z4cR4wyTw&ccvHkKu&;(J`ZeEo@w|E=n2(s9&`CEL*O>g)?OkqC(M}hv zTX!R5{bSf(NbP{HU3^2d5dD&CA?{~uI~aQ{^75T{Xk1&*4-~6Koi6J|v!lwlbGR2Y z(!)OneVx`8GRr>`7#ugV*^u3zuF2zvuQ#3^%Q3^KM~lD*+RPOe=o)sVZ#RF6&q5-? z+x3}>YvN7gMVIzCwWiC$eNK1Hy@H>Ax> zekxM*F-`*j&c7MTFo+A&jo$)!>Psec9*uk`RJ+c^+eVeZh3sphq(?9sRv_8cZ;paDw`K~d@-?%OGyi(gCv-j<%>?beC zUpl=%==#1*;Ma#gxHorg&`IRGtLyrBsP?4iq`*AHcqFj=a^Z(7-E&$I48s-ErL$Wcqdu zx0;sb)q-j$+18do|9Q0!qb%jgoNpR6frqoDGVUnw9nAk&O1q-FJ)MkVcwlzH{`Pf8 z(WmF^wtl{Npn34}S=Yo1$8LC3*WOD3E02#Ffty%Yz^CbaE91w4S8iA9=|0Tc*>4Uj!-N6L(r*B%`mBcJkg-)r0FP zDGX8B&tCHmqNK*UV{0btwGw`MNj*add=pzXfc8{zShz^piM#siXQO6(zEnr?7A#&} zD=J{AfdY49`IP5yyJpCu_QfTTP=|&*Xdz6G-MSh&ba=uPRrHzVs+td8IJKJ~Yo*Ii zWI!M=>&d!I4_7XRCC z?+)rebr*ivpC2PAGbCZ+Y?O5L^xWFhTb^ed85Bv(w{3y75 zf6J|R((NC(*k*YbsXJx&)6YvYtrup|n_&-(Zntf19Dd^D`Ox9@Jr*?nxUN74UGyzI zIbLq=a!i#+bo>8|+nmh#Z2`*M*t!Gm0*W)0iI4m<&eWe9ea7K$KFsxfPFtw++QNHo zYWQ7z0d^YWWO@^i_%p_}At&oGKH+R=O8&dnfqW6JvP9ppoK;j~CZ65r$X6XD(D)Ht)NW{;2az{Lesh$VQpOjBqJK#i~V z;f6O)3yEv4C@F5LWQL-Vp`m$Icm>M!&Z(0m+;qlNV+u#}tpqBEMr9pl|~KI!zM0topy%Y4EW zZ5P_jtToXdISCMdI(@eD&Qo>b)0B!TjZ|=|IJ?N;MA=LlXb;@!7ZyHS)V6wPvomqs zgQGTY=l8ser6e{*hW=+wfWGCv5;WyR$FdDwwzO-1dlqZ~#@Rinw}=Nq0tn;$y}Zctpy9_9VHXt`aQmxVUjDCRP0-Ute@s)wTOXDjzDg+K0O z3_C`xn0o%GOyacp({c#Vvs3Tqh+H6}`>MzC%o)YZR-Tl8vp zKI3vZASa@Q2OhB+n5l8a4Cjwn%`kd%>Gjdel>p5FP0JJJ;sBd~O|n%rDEp0v08CRe z;6=2By%7VaU{AJ8JReM__oz0T&rZJ!TZu9MJ89_wi;#A!1iyVfFHb+-`IYd)8*8M9 zT_wu&;pdH`>$2O*Z~e!oMhpbcN~MUxW{oq8Wbc(DAH@W0Jl!s(iLnQFeKWy$X)hOj z(v7WDxQDYNWCDC5nZ7^6z_D9&~3-EU7&^VYDA0Q+{M(tVM+pep_tz=Z9w?A%0 zk{k7YABvy@gx?ZWgn?5cAv&PBjl)sC?F1a*=Ia>8!{x7x@GJbFd{9G1rP)pN~+itTL{5f$;+=GgF+x4 zq%Lw91R3+VJfVIR4}%C_tR9ZC1R1x6?+0w9AZ?HT3Yt^oP4b!G2admNb(n?Jr=YO__c{r zQ=5MOZhmqi$t?Ex!_pBYe^c)!f3QIXL>;!|;)4I)VrP5Y6OTW2F`1Poz7K7_m2tV& z;5=}n4MzLH?!lfP^1XWRV9%h>RcsedWg1w2$?hdrqadzu2}-)tsm{PsRI9*W3rNdl z?W@BBY;-d6^3&!W`84&8A8^KYw>2vbPO_H6Ysp8izF3c02^Hc+%GYp^Ne zBz(8YYn;>-Np@-E&rkW8q}RRK7;18G5nkRa;F>=vW*GEBC9TGJauW+U7gR_!TcvCH zd#%$oqQBYjw30hAD|qA{3)<0k7>iIy(2?1%)Hr?I_uFO)*>O(V&ud)ujhOB!rd}TZLPJ>AE$-XU*tMc|2kw$}i1Drr z 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 oW$z(N0UEsD|wWz9J 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 T= aiState.solution.length) { + return null; + } + const placement = aiState.solution[aiState.stepIndex]; + aiState.stepIndex++; + if (aiState.stepIndex >= aiState.solution.length) aiState.done = true; + return placement; +} diff --git a/public/src/games/geniussquare/GeniusSquareGame.js b/public/src/games/geniussquare/GeniusSquareGame.js new file mode 100644 index 0000000..b9cbc92 --- /dev/null +++ b/public/src/games/geniussquare/GeniusSquareGame.js @@ -0,0 +1,600 @@ +import * as Phaser from 'phaser'; +import { GAME_WIDTH, GAME_HEIGHT, COLORS } from '../../config.js'; +import { Button } from '../../ui/Button.js'; +import { MusicPlayer } from '../../ui/MusicPlayer.js'; +import { playSound, SFX } from '../../ui/Sounds.js'; +import { api } from '../../services/api.js'; +import { auth } from '../../services/auth.js'; +import { createOpponentPortrait, createPlayerPortrait } from '../../ui/Portrait.js'; +import { + PIECES, ORIENTATIONS, + rollDice, newBoard, absoluteCells, canPlace, placePiece, removePiece, isSolved, + rotateOri, flipOri, solveFromBlockers, +} from './GeniusSquareLogic.js'; +import { createAIState, nextThinkDelay, getNextPlacement } from './GeniusSquareAI.js'; + +// ── Layout ───────────────────────────────────────────────────────────────────── +const CELL = 90; +const GRID_PX = 6 * CELL; // 540 +const HGX = 80; // human grid left +const HGY = 190; // human grid top +const AGX = 1300; // AI grid left +const AGY = 190; // AI grid top +const HCX = HGX + GRID_PX / 2; // 350 — human column center x +const ACX = AGX + GRID_PX / 2; // 1570 — AI column center x +const SLOT_W = 165; +const SLOT_H = 92; +const TRAY_Y = HGY + GRID_PX + 28; // 758 — top of piece tray +const MINI = 16; // mini-piece cell size in tray + +// ── Colors ───────────────────────────────────────────────────────────────────── +const PIECE_COLORS = { + dot: 0xf7c948, + domino: 0x5b9bff, + itromino: 0x45d17a, + ltromino: 0xff7c4a, + square: 0xd45bff, + ltetromino: 0xff4a6e, + stetromino: 0x4af7ee, + ttetromino: 0xf7a84a, + itetromino: 0x7af74a, +}; +const BLOCKER_COLOR = 0x2c2c3e; +const BLOCKER_STROKE = 0x4a4a5a; +const GRID_BG = 0x12122a; +const GRID_LINE = 0x252540; + +const D = { bg: -2, grid: 0, piece: 2, tray: 10, ui: 20, overlay: 60, overlayUI: 62 }; + +export default class GeniusSquareGame extends Phaser.Scene { + constructor() { super('GeniusSquareGame'); } + + init(data) { + this.gameDef = data.game; + this.opponents = data.opponents ?? []; + this.skill = data.opponents?.[0]?.skill ?? 3; + this.playfield = data.playfield ?? null; + + this.blockers = null; + this.humanBoard = null; + this.aiBoard = null; + this.aiState = null; + this.aiTimer = null; + this.gameOver = false; + + this.placedPieces = new Set(); + this.selectedPiece = null; // { pieceId, oriIdx } + this.ghostCells = null; + this._lastHoverR = -1; + this._lastHoverC = -1; + + this.humanGridGfx = null; + this.aiGridGfx = null; + this.traySlots = []; // [{ container, pieceId }] + this.opponentPortrait = null; + } + + create() { + try { + const music = this.cache.json.get('music'); + if (music?.tracks) new MusicPlayer(this, music.tracks); + } catch (_) {} + + // Roll dice + solve (retry on the rare unsolvable config) + let blockers, solution; + do { + blockers = rollDice(); + solution = solveFromBlockers(blockers); + } while (!solution); + + this.blockers = blockers; + this.humanBoard = newBoard(blockers); + this.aiBoard = newBoard(blockers); + this.aiState = createAIState(blockers, this.skill, solution); + + this._buildBackground(); + this._buildGridGraphics(); + this._buildLabels(); + this._buildPortraits(); + this._buildTray(); + this._buildHints(); + + this.input.keyboard.on('keydown-R', () => this._rotate()); + this.input.keyboard.on('keydown-F', () => this._flip()); + this.input.keyboard.on('keydown-ESC', () => this._clearSelection()); + + this.events.once('shutdown', () => this._stopAI()); + + this._renderHumanGrid(); + this._renderAIGrid(); + this._startCountdown(); + } + + // ── Scene construction ──────────────────────────────────────────────────────── + + _buildBackground() { + const pf = this.playfield; + if (pf?.key && this.textures.exists(pf.key)) { + this.add.image(GAME_WIDTH / 2, GAME_HEIGHT / 2, pf.key) + .setDisplaySize(GAME_WIDTH, GAME_HEIGHT).setDepth(D.bg - 1); + // Dark overlay so text and grids stay readable over any playfield image + this.add.rectangle(GAME_WIDTH / 2, GAME_HEIGHT / 2, GAME_WIDTH, GAME_HEIGHT, 0x000000, 0.45) + .setDepth(D.bg); + } else if (pf?.fallbackColor) { + const color = parseInt(pf.fallbackColor.replace('#', ''), 16); + this.add.rectangle(GAME_WIDTH / 2, GAME_HEIGHT / 2, GAME_WIDTH, GAME_HEIGHT, color) + .setDepth(D.bg); + } else { + this.add.rectangle(GAME_WIDTH / 2, GAME_HEIGHT / 2, GAME_WIDTH, GAME_HEIGHT, COLORS.bg) + .setDepth(D.bg); + } + + // Center divider + const div = this.add.graphics().setDepth(D.ui); + div.lineStyle(1, COLORS.muted, 0.25); + div.beginPath(); + div.moveTo(GAME_WIDTH / 2, HGY - 10); + div.lineTo(GAME_WIDTH / 2, HGY + GRID_PX + 10); + div.strokePath(); + + // Title + this.add.text(GAME_WIDTH / 2, 36, 'GENIUS SQUARE', { + fontFamily: 'Righteous', fontSize: '38px', color: COLORS.accentHex, + }).setOrigin(0.5).setDepth(D.ui); + + // "VS" badge + this.add.text(GAME_WIDTH / 2, HGY + GRID_PX / 2, 'VS', { + fontFamily: 'Righteous', fontSize: '52px', color: COLORS.mutedHex, + }).setOrigin(0.5).setDepth(D.ui); + } + + _buildGridGraphics() { + this.humanGridGfx = this.add.graphics().setDepth(D.grid); + this.aiGridGfx = this.add.graphics().setDepth(D.grid); + } + + _buildLabels() { + // Labels are rendered alongside portraits in _buildPortraits() + } + + _buildPortraits() { + const r = 36; + const pY = HGY - 52; // portrait center Y, shared by both sides + const depth = D.ui; + + // ── Human side ────────────────────────────────────────────────────────── + // Portrait left-aligned with the grid edge; name + label stacked to its right + const hpX = HGX + r + 8; // portrait center x + const htX = hpX + r + 14; // text left x + createPlayerPortrait(this, hpX, pY, r, depth, 'GeniusSquareGame'); + this.add.text(htX, pY - 3, auth.user?.username ?? 'You', { + fontFamily: '"Julius Sans One"', fontSize: '18px', color: COLORS.textHex, + }).setOrigin(0, 1).setDepth(depth + 1); + this.add.text(htX, pY + 3, 'YOUR GRID', { + fontFamily: '"Julius Sans One"', fontSize: '16px', color: COLORS.mutedHex, + }).setOrigin(0, 0).setDepth(depth + 1); + + // ── Opponent side ──────────────────────────────────────────────────────── + const apX = AGX + r + 8; + const atX = apX + r + 14; + const opp = this.opponents[0]; + if (opp) { + this.opponentPortrait = createOpponentPortrait(this, opp, apX, pY, r, depth, { playIntro: false }); + this.add.text(atX, pY - 3, opp.name ?? 'CPU', { + fontFamily: '"Julius Sans One"', fontSize: '18px', color: COLORS.textHex, + }).setOrigin(0, 1).setDepth(depth + 1); + this.add.text(atX, pY + 3, "OPPONENT'S GRID", { + fontFamily: '"Julius Sans One"', fontSize: '16px', color: COLORS.mutedHex, + }).setOrigin(0, 0).setDepth(depth + 1); + } + } + + _buildTray() { + const trayLeft = HCX - (SLOT_W * 1.5); // left edge of 3-column tray + + for (let i = 0; i < PIECES.length; i++) { + const col = i % 3; + const row = Math.floor(i / 3); + const cx = trayLeft + col * SLOT_W + SLOT_W / 2; + const cy = TRAY_Y + row * SLOT_H + SLOT_H / 2; + const { id: pieceId } = PIECES[i]; + + const bg = this.add.graphics(); + this._drawSlotBg(bg, 0, 0, false); + + const pieceGfx = this.add.graphics(); + this._drawMiniPiece(pieceGfx, 0, 0, pieceId, PIECE_COLORS[pieceId], false); + + const container = this.add.container(cx, cy, [bg, pieceGfx]); + container.setSize(SLOT_W - 8, SLOT_H - 8); + container.setInteractive({ useHandCursor: true }); + container.on('pointerdown', () => this._selectPiece(pieceId)); + container.setDepth(D.tray); + + this.traySlots.push({ container, bg, pieceGfx, pieceId }); + } + } + + _buildHints() { + this.add.text(HCX, TRAY_Y + SLOT_H * 3 + 14, 'R = Rotate F = Flip ESC = Deselect', { + fontFamily: '"Julius Sans One"', fontSize: '15px', color: COLORS.mutedHex, + }).setOrigin(0.5, 0).setDepth(D.ui); + + new Button(this, GAME_WIDTH - 110, GAME_HEIGHT - 46, 'Leave', + () => this.scene.start('GameMenu'), + { variant: 'ghost', width: 180, height: 52, fontSize: 20 } + ).setDepth(D.ui); + } + + _buildGridInput() { + const zone = this.add.zone(HGX, HGY, GRID_PX, GRID_PX).setOrigin(0).setInteractive({ useHandCursor: true }); + zone.on('pointermove', ptr => this._onGridHover(ptr)); + zone.on('pointerdown', ptr => this._onGridClick(ptr)); + zone.on('pointerout', () => { this.ghostCells = null; this._renderHumanGrid(); }); + zone.setDepth(D.piece); + } + + // ── Piece tray rendering ────────────────────────────────────────────────────── + + _drawSlotBg(gfx, cx, cy, selected) { + gfx.clear(); + gfx.fillStyle(selected ? 0x2a2a4a : COLORS.panel, 1); + gfx.fillRoundedRect(cx - SLOT_W / 2 + 4, cy - SLOT_H / 2 + 4, SLOT_W - 8, SLOT_H - 8, 6); + gfx.lineStyle(2, selected ? COLORS.accent : GRID_LINE, 1); + gfx.strokeRoundedRect(cx - SLOT_W / 2 + 4, cy - SLOT_H / 2 + 4, SLOT_W - 8, SLOT_H - 8, 6); + } + + _drawMiniPiece(gfx, cx, cy, pieceId, color, dimmed) { + gfx.clear(); + const cells = ORIENTATIONS[pieceId][0]; + let maxR = 0, maxC = 0; + for (const [r, c] of cells) { if (r > maxR) maxR = r; if (c > maxC) maxC = c; } + const startX = cx - ((maxC + 1) * MINI) / 2; + const startY = cy - ((maxR + 1) * MINI) / 2; + const alpha = dimmed ? 0.3 : 1; + gfx.fillStyle(dimmed ? 0x666666 : color, alpha); + for (const [r, c] of cells) { + gfx.fillRoundedRect(startX + c * MINI + 1, startY + r * MINI + 1, MINI - 2, MINI - 2, 2); + } + } + + _renderTray() { + for (const slot of this.traySlots) { + const placed = this.placedPieces.has(slot.pieceId); + const selected = this.selectedPiece?.pieceId === slot.pieceId; + this._drawSlotBg(slot.bg, 0, 0, selected && !placed); + this._drawMiniPiece(slot.pieceGfx, 0, 0, slot.pieceId, PIECE_COLORS[slot.pieceId], placed); + slot.container.setInteractive(placed ? false : { useHandCursor: true }); + } + } + + // ── Grid rendering ──────────────────────────────────────────────────────────── + + _drawGrid(gfx, gx, gy, board, ghostCells, ghostPieceId) { + gfx.clear(); + + // Background + gfx.fillStyle(GRID_BG, 1); + gfx.fillRoundedRect(gx - 2, gy - 2, GRID_PX + 4, GRID_PX + 4, 10); + + // Grid lines + gfx.lineStyle(1, GRID_LINE, 1); + for (let i = 0; i <= 6; i++) { + gfx.beginPath(); gfx.moveTo(gx + i * CELL, gy); gfx.lineTo(gx + i * CELL, gy + GRID_PX); gfx.strokePath(); + gfx.beginPath(); gfx.moveTo(gx, gy + i * CELL); gfx.lineTo(gx + GRID_PX, gy + i * CELL); gfx.strokePath(); + } + + // Placed cells + for (let idx = 0; idx < 36; idx++) { + const val = board[idx]; + if (val === null) continue; + const r = Math.floor(idx / 6), c = idx % 6; + const px = gx + c * CELL, py = gy + r * CELL; + + if (val === 'blocked') { + gfx.fillStyle(BLOCKER_COLOR, 1); + gfx.fillRoundedRect(px + 3, py + 3, CELL - 6, CELL - 6, 5); + gfx.lineStyle(2, BLOCKER_STROKE, 0.8); + gfx.beginPath(); gfx.moveTo(px + 16, py + 16); gfx.lineTo(px + CELL - 16, py + CELL - 16); gfx.strokePath(); + gfx.beginPath(); gfx.moveTo(px + CELL - 16, py + 16); gfx.lineTo(px + 16, py + CELL - 16); gfx.strokePath(); + } else { + const color = PIECE_COLORS[val] ?? 0x888888; + gfx.fillStyle(color, 1); + gfx.fillRoundedRect(px + 3, py + 3, CELL - 6, CELL - 6, 7); + // Top sheen + gfx.fillStyle(0xffffff, 0.18); + gfx.fillRoundedRect(px + 5, py + 5, CELL - 10, 9, 3); + } + } + + // Ghost preview + if (ghostCells && ghostPieceId) { + const color = PIECE_COLORS[ghostPieceId] ?? 0xffffff; + const allValid = ghostCells.every(([r, c]) => + r >= 0 && r < 6 && c >= 0 && c < 6 && board[r * 6 + c] === null + ); + gfx.fillStyle(color, allValid ? 0.5 : 0.2); + for (const [r, c] of ghostCells) { + if (r < 0 || r >= 6 || c < 0 || c >= 6) continue; + gfx.fillRoundedRect(gx + c * CELL + 3, gy + r * CELL + 3, CELL - 6, CELL - 6, 7); + } + } + } + + _renderHumanGrid() { + this._drawGrid( + this.humanGridGfx, HGX, HGY, + this.humanBoard, + this.ghostCells, + this.selectedPiece?.pieceId, + ); + } + + _renderAIGrid() { + this._drawGrid(this.aiGridGfx, AGX, AGY, this.aiBoard, null, null); + } + + // ── Piece selection & placement ─────────────────────────────────────────────── + + _selectPiece(pieceId) { + if (this.gameOver || this.placedPieces.has(pieceId)) return; + if (this.selectedPiece?.pieceId === pieceId) { + this._clearSelection(); + return; + } + this.selectedPiece = { pieceId, oriIdx: 0 }; + this.ghostCells = null; + this._renderTray(); + this._renderHumanGrid(); + } + + _clearSelection() { + this.selectedPiece = null; + this.ghostCells = null; + this._lastHoverR = -1; + this._lastHoverC = -1; + this._renderTray(); + this._renderHumanGrid(); + } + + _rotate() { + if (!this.selectedPiece || this.gameOver) return; + this.selectedPiece.oriIdx = rotateOri(this.selectedPiece.pieceId, this.selectedPiece.oriIdx); + this._updateGhostAt(this._lastHoverR, this._lastHoverC); + this._renderHumanGrid(); + } + + _flip() { + if (!this.selectedPiece || this.gameOver) return; + this.selectedPiece.oriIdx = flipOri(this.selectedPiece.pieceId, this.selectedPiece.oriIdx); + this._updateGhostAt(this._lastHoverR, this._lastHoverC); + this._renderHumanGrid(); + } + + _updateGhostAt(r, c) { + if (r < 0 || c < 0 || !this.selectedPiece) { this.ghostCells = null; return; } + const oriCells = ORIENTATIONS[this.selectedPiece.pieceId][this.selectedPiece.oriIdx]; + this.ghostCells = absoluteCells(oriCells, r, c); + } + + _onGridHover(ptr) { + if (!this.selectedPiece || this.gameOver) return; + const r = Math.floor((ptr.worldY - HGY) / CELL); + const c = Math.floor((ptr.worldX - HGX) / CELL); + this._lastHoverR = r; + this._lastHoverC = c; + this._updateGhostAt(r, c); + this._renderHumanGrid(); + } + + _onGridClick(ptr) { + if (this.gameOver) return; + + const r = Math.floor((ptr.worldY - HGY) / CELL); + const c = Math.floor((ptr.worldX - HGX) / CELL); + if (r < 0 || r >= 6 || c < 0 || c >= 6) return; + + const cellVal = this.humanBoard[r * 6 + c]; + + // Click on a placed piece → lift it back to the tray + if (cellVal && cellVal !== 'blocked') { + this._liftPiece(cellVal); + return; + } + + // Otherwise place the selected piece + if (!this.selectedPiece || !this.ghostCells) return; + if (!canPlace(this.humanBoard, this.ghostCells)) { + playSound(this, SFX.PIECE_CLICK); + return; + } + const { pieceId } = this.selectedPiece; + this.humanBoard = placePiece(this.humanBoard, this.ghostCells, pieceId); + this.placedPieces.add(pieceId); + playSound(this, SFX.CARD_PLACE); + this._clearSelection(); + this._renderHumanGrid(); + this._renderTray(); + + if (isSolved(this.humanBoard)) this._onHumanWin(); + } + + _liftPiece(pieceId) { + // Collect all cells this piece occupies (board scan is row-major, matching normalize order) + const cells = []; + for (let i = 0; i < 36; i++) { + if (this.humanBoard[i] === pieceId) cells.push([Math.floor(i / 6), i % 6]); + } + this.humanBoard = removePiece(this.humanBoard, cells); + this.placedPieces.delete(pieceId); + + // Recover the original orientation and anchor, then show it as a ghost in place + const oriIdx = this._matchOrientation(pieceId, cells); + this.selectedPiece = { pieceId, oriIdx }; + const oriCells = ORIENTATIONS[pieceId][oriIdx]; + const anchorR = cells[0][0] - oriCells[0][0]; + const anchorC = cells[0][1] - oriCells[0][1]; + this.ghostCells = absoluteCells(oriCells, anchorR, anchorC); + this._lastHoverR = anchorR; + this._lastHoverC = anchorC; + + playSound(this, SFX.PIECE_CLICK); + this._renderHumanGrid(); + this._renderTray(); + } + + _matchOrientation(pieceId, cells) { + let minR = Infinity, minC = Infinity; + for (const [r, c] of cells) { if (r < minR) minR = r; if (c < minC) minC = c; } + const normKey = cells + .map(([r, c]) => `${r - minR},${c - minC}`) + .sort() + .join(';'); + const oris = ORIENTATIONS[pieceId]; + for (let i = 0; i < oris.length; i++) { + const key = oris[i].map(([r, c]) => `${r},${c}`).join(';'); + if (key === normKey) return i; + } + return 0; + } + + // ── Countdown ──────────────────────────────────────────────────────────────── + + _startCountdown() { + const steps = ['3', '2', '1', 'GO!']; + + const dim = this.add.rectangle(GAME_WIDTH / 2, GAME_HEIGHT / 2, GAME_WIDTH, GAME_HEIGHT, 0x000000, 0.45) + .setDepth(D.overlay - 1); + + const label = this.add.text(GAME_WIDTH / 2, GAME_HEIGHT / 2, '', { + fontFamily: 'Righteous', + fontSize: '240px', + color: '#f7c948', + stroke: '#b08800', + strokeThickness: 8, + }).setOrigin(0.5).setDepth(D.overlay).setAlpha(0); + + const runStep = (i) => { + if (i >= steps.length) { + dim.destroy(); + label.destroy(); + this._buildGridInput(); + this._startAI(); + return; + } + + label.setText(steps[i]).setScale(1.6).setAlpha(1); + + this.tweens.add({ + targets: label, scaleX: 1, scaleY: 1, + duration: 260, ease: 'Back.easeOut', + }); + + this.time.delayedCall(steps[i] === 'GO!' ? 560 : 740, () => { + this.tweens.add({ + targets: label, alpha: 0, duration: 180, + onComplete: () => runStep(i + 1), + }); + }); + }; + + runStep(0); + } + + // ── AI tick loop ────────────────────────────────────────────────────────────── + + _startAI() { + if (!this.aiState.solution) return; // should not happen with zone-partitioned dice + this._scheduleAITick(); + } + + _scheduleAITick() { + if (this.gameOver || this.aiState.done) return; + const delay = nextThinkDelay(this.skill); + this.aiTimer = this.time.delayedCall(delay, () => this._aiTick()); + } + + _aiTick() { + if (this.gameOver) return; + const placement = getNextPlacement(this.aiState); + if (!placement) { this._onAIWin(); return; } + + this.aiBoard = placePiece(this.aiBoard, placement.cells, placement.pieceId); + playSound(this, SFX.PIECE_CLICK); + this._renderAIGrid(); + + if (isSolved(this.aiBoard)) { + this._onAIWin(); + } else { + this._scheduleAITick(); + } + } + + _stopAI() { + if (this.aiTimer) { this.aiTimer.remove(false); this.aiTimer = null; } + } + + // ── Win / loss ──────────────────────────────────────────────────────────────── + + _onHumanWin() { + if (this.gameOver) return; + this.gameOver = true; + this._stopAI(); + this.opponentPortrait?.playEmotion('upset'); + playSound(this, SFX.VICTORY_SHORT); + this._recordResult('win'); + this._showOverlay(true); + } + + _onAIWin() { + if (this.gameOver) return; + this.gameOver = true; + this.opponentPortrait?.playEmotion('happy'); + this._recordResult('loss'); + this._showOverlay(false); + } + + _recordResult(result) { + api.post('/history/single-player', { + slug: 'geniussquare', score: result === 'win' ? 1 : 0, result, + }).catch(() => {}); + } + + _showOverlay(humanWon) { + const cx = GAME_WIDTH / 2, cy = GAME_HEIGHT / 2; + const borderColor = humanWon ? 0x45d17a : COLORS.danger; + const headline = humanWon ? 'You Win!' : 'Opponent Wins!'; + const headColor = humanWon ? '#45d17a' : COLORS.dangerHex; + const subline = humanWon ? 'You filled the grid first!' : 'The opponent finished first.'; + + // Dim background + this.add.rectangle(cx, cy, GAME_WIDTH, GAME_HEIGHT, 0x000000, 0.6) + .setDepth(D.overlay).setInteractive(); + + // Panel + const panel = this.add.graphics().setDepth(D.overlay + 1); + panel.fillStyle(0x1a1828, 0.97); + panel.fillRoundedRect(cx - 340, cy - 190, 680, 380, 18); + panel.lineStyle(3, borderColor, 1); + panel.strokeRoundedRect(cx - 340, cy - 190, 680, 380, 18); + + this.add.text(cx, cy - 110, headline, { + fontFamily: 'Righteous', fontSize: '68px', color: headColor, + }).setOrigin(0.5).setDepth(D.overlayUI); + + this.add.text(cx, cy - 26, subline, { + fontFamily: '"Julius Sans One"', fontSize: '26px', color: COLORS.mutedHex, + }).setOrigin(0.5).setDepth(D.overlayUI); + + const data = { game: this.gameDef, opponents: this.opponents, playfield: this.playfield }; + new Button(this, cx - 170, cy + 100, 'Play Again', + () => this.scene.restart(data), + { width: 280, height: 58, fontSize: 22 } + ).setDepth(D.overlayUI); + + new Button(this, cx + 170, cy + 100, 'Menu', + () => this.scene.start('GameMenu'), + { variant: 'ghost', width: 280, height: 58, fontSize: 22 } + ).setDepth(D.overlayUI); + } +} diff --git a/public/src/games/geniussquare/GeniusSquareLogic.js b/public/src/games/geniussquare/GeniusSquareLogic.js new file mode 100644 index 0000000..348457e --- /dev/null +++ b/public/src/games/geniussquare/GeniusSquareLogic.js @@ -0,0 +1,177 @@ +// Genius Square — pure game logic, no Phaser. +// +// Board is a 36-element flat array (6×6, row-major): +// null = empty +// 'blocked' = die/blocker occupying this cell +// pieceId = placed piece id +// +// The 9 pieces total 29 cells; 7 blockers = 36 = 6×6. + +// ── Piece definitions ───────────────────────────────────────────────────────── + +export const PIECES = [ + { id: 'dot', cells: [[0,0]] }, + { id: 'domino', cells: [[0,0],[0,1]] }, + { id: 'itromino', cells: [[0,0],[0,1],[0,2]] }, + { id: 'ltromino', cells: [[0,0],[1,0],[1,1]] }, + { id: 'square', cells: [[0,0],[0,1],[1,0],[1,1]] }, + { id: 'ltetromino', cells: [[0,0],[1,0],[2,0],[2,1]] }, + { id: 'stetromino', cells: [[0,1],[0,2],[1,0],[1,1]] }, + { id: 'ttetromino', cells: [[0,0],[0,1],[0,2],[1,1]] }, + { id: 'itetromino', cells: [[0,0],[0,1],[0,2],[0,3]] }, +]; + +export const PIECE_IDS = PIECES.map(p => p.id); + +// ── Orientation generation ──────────────────────────────────────────────────── +// Enumerate all unique free-polyomino orientations (rotations + reflections) +// using the same normalize/deduplicate approach as BlokusBoard.js. + +function normalize(cells) { + let minR = Infinity, minC = Infinity; + for (const [r, c] of cells) { if (r < minR) minR = r; if (c < minC) minC = c; } + return cells.map(([r, c]) => [r - minR, c - minC]).sort((a, b) => a[0] - b[0] || a[1] - b[1]); +} + +function keyOf(cells) { + return cells.map(([r, c]) => `${r},${c}`).join(';'); +} + +function computeOrientations(cells) { + const seen = new Map(); + const base = cells.map(([r, c]) => [r, c]); + for (let flip = 0; flip < 2; flip++) { + let work = flip ? base.map(([r, c]) => [r, -c]) : base; + for (let rot = 0; rot < 4; rot++) { + const norm = normalize(work); + const k = keyOf(norm); + if (!seen.has(k)) seen.set(k, norm); + work = work.map(([r, c]) => [c, -r]); // rotate 90° clockwise + } + } + return [...seen.values()]; +} + +export const ORIENTATIONS = Object.fromEntries( + PIECES.map(p => [p.id, computeOrientations(p.cells)]) +); + +const ORI_INDEX = Object.fromEntries( + PIECES.map(p => [p.id, new Map(ORIENTATIONS[p.id].map((o, i) => [keyOf(o), i]))]) +); + +function transformedIndex(pieceId, oriIdx, fn) { + const cur = ORIENTATIONS[pieceId][oriIdx]; + const next = normalize(cur.map(fn)); + return ORI_INDEX[pieceId].get(keyOf(next)) ?? oriIdx; +} + +/** Orientation index after a 90° clockwise rotation. */ +export function rotateOri(pieceId, oriIdx) { + return transformedIndex(pieceId, oriIdx, ([r, c]) => [c, -r]); +} + +/** Orientation index after a horizontal mirror. */ +export function flipOri(pieceId, oriIdx) { + return transformedIndex(pieceId, oriIdx, ([r, c]) => [r, -c]); +} + +// ── Dice zones ──────────────────────────────────────────────────────────────── +// 7 zones partition all 36 cells. One cell picked randomly from each zone +// per round, ensuring blockers spread across the entire board. + +const ZONES = [ + [[0,0],[0,1],[0,2],[0,3],[1,3]], + [[0,4],[0,5],[1,4],[1,5],[2,5]], + [[1,0],[1,1],[1,2],[2,0],[2,1]], + [[2,2],[2,3],[2,4],[3,2],[3,3]], + [[3,0],[3,1],[4,0],[4,1],[5,0]], + [[3,4],[3,5],[4,4],[4,5],[5,5]], + [[4,2],[4,3],[5,1],[5,2],[5,3],[5,4]], +]; + +/** Roll 7 dice → array of 7 [row, col] blocker positions. */ +export function rollDice() { + return ZONES.map(zone => zone[Math.floor(Math.random() * zone.length)]); +} + +// ── Board helpers ───────────────────────────────────────────────────────────── + +export function newBoard(blockers) { + const board = Array(36).fill(null); + for (const [r, c] of blockers) board[r * 6 + c] = 'blocked'; + return board; +} + +/** Translate orientation-relative [dr,dc] cells to absolute [r,c] at an anchor. */ +export function absoluteCells(oriCells, anchorR, anchorC) { + return oriCells.map(([dr, dc]) => [anchorR + dr, anchorC + dc]); +} + +export function canPlace(board, cells) { + for (const [r, c] of cells) { + if (r < 0 || r >= 6 || c < 0 || c >= 6) return false; + if (board[r * 6 + c] !== null) return false; + } + return true; +} + +export function placePiece(board, cells, pieceId) { + const next = board.slice(); + for (const [r, c] of cells) next[r * 6 + c] = pieceId; + return next; +} + +export function removePiece(board, cells) { + const next = board.slice(); + for (const [r, c] of cells) next[r * 6 + c] = null; + return next; +} + +export function isSolved(board) { + return board.every(cell => cell !== null); +} + +// ── Backtracking solver ─────────────────────────────────────────────────────── +// Always targets the first null cell (left-to-right, top-to-bottom). For each +// remaining piece, tries every orientation offset that covers that cell, then +// recurses. This forces row-major filling and collapses the search space +// dramatically — runs in <10ms for typical Genius Square boards. + +export function solve(board, remainingPieces) { + const emptyIdx = board.indexOf(null); + if (emptyIdx === -1) return remainingPieces.size === 0 ? [] : null; + if (remainingPieces.size === 0) return null; + + const targetR = Math.floor(emptyIdx / 6); + const targetC = emptyIdx % 6; + + for (const pieceId of remainingPieces) { + const oris = ORIENTATIONS[pieceId]; + for (let oriIdx = 0; oriIdx < oris.length; oriIdx++) { + const oriCells = oris[oriIdx]; + for (const [dr, dc] of oriCells) { + const anchorR = targetR - dr; + const anchorC = targetC - dc; + const cells = absoluteCells(oriCells, anchorR, anchorC); + if (!canPlace(board, cells)) continue; + + const nextBoard = placePiece(board, cells, pieceId); + const nextRemaining = new Set(remainingPieces); + nextRemaining.delete(pieceId); + + const sub = solve(nextBoard, nextRemaining); + if (sub !== null) { + return [{ pieceId, oriIdx, anchorR, anchorC, cells }, ...sub]; + } + } + } + } + return null; +} + +/** Convenience: build fresh board from blockers and solve with all 9 pieces. */ +export function solveFromBlockers(blockers) { + const board = newBoard(blockers); + return solve(board, new Set(PIECE_IDS)); +} diff --git a/public/src/main.js b/public/src/main.js index e4b9474..c297bfa 100644 --- a/public/src/main.js +++ b/public/src/main.js @@ -80,6 +80,7 @@ import Game2048 from './games/2048/2048Game.js'; import RummikubGame from './games/rummikub/RummikubGame.js'; import GinRummyGame from './games/ginrummy/GinRummyGame.js'; import RiskGame from './games/risk/RiskGame.js'; +import GeniusSquareGame from './games/geniussquare/GeniusSquareGame.js'; const config = { type: Phaser.AUTO, @@ -173,6 +174,7 @@ const config = { RummikubGame, GinRummyGame, RiskGame, + GeniusSquareGame, ], }; diff --git a/public/src/scenes/GameRoomScene.js b/public/src/scenes/GameRoomScene.js index a7f44f7..548f40f 100644 --- a/public/src/scenes/GameRoomScene.js +++ b/public/src/scenes/GameRoomScene.js @@ -22,7 +22,7 @@ export default class GameRoomScene extends Phaser.Scene { } create() { - const slugDispatch = { backgammon: 'Backgammon', holdem: 'HoldemGame', blackjack: 'BlackjackGame', parchisi: 'ParchisiGame', yatzi: 'YatziGame', skipbo: 'SkipBoGame', phase10: 'Phase10Game', chinesecheckers: 'ChineseCheckersGame', gofish: 'GoFishGame', uno: 'UnoGame', craps: 'CrapsGame', roulette: 'RouletteGame', mexicantrain: 'MexicanTrainGame', hearts: 'HeartsGame', catan: 'CatanGame', tickettoride: 'TicketToRideGame', nerts: 'NertsGame', bingo: 'BingoGame', baccarat: 'BaccaratGame', dominion: 'DominionGame', checkers: 'CheckersGame', chess: 'ChessGame', wordle: 'WordleGame', scrabble: 'ScrabbleGame', ghost: 'GhostGame', wordladder: 'WordLadderGame', wordsearch: 'WordSearchGame', hangman: 'HangmanGame', sudoku: 'SudokuGame', othello: 'OthelloGame', go: 'GoGame', battleship: 'BattleshipGame', mastermind: 'MastermindGame', connect4: 'Connect4Game', boggle: 'BoggleGame', oldmaid: 'OldMaidGame', blokus: 'BlokusGame', spellingbee: 'SpellingBeeGame', minicrossword: 'MiniCrosswordGame', forbiddenisland: 'ForbiddenIslandGame', solitairetour: 'SolitaireTourGame', splendor: 'SplendorGame', tectonic: 'TectonicGame', labyrinth: 'LabyrinthGame', videopoker: 'VideoPokerGame', farkel: 'FarkelGame', stratego: 'StrategoGame', kiitos: 'KiitosGame', monopoly: 'MonopolyGame', triominoes: 'TriominoesGame', freecell: 'FreecellGame', rushhour: 'RushHourGame', hexsweeper: 'HexsweeperGame', puddingmonsters: 'PuddingMonstersGame', shift: 'ShiftGame', blockfighter: 'BlockFighterGame', mahjongmatch: 'MahjongMatchGame', mahjong: 'MahjongGame', jewelquest: 'JewelQuestGame', zuma: 'ZumaGame', bejeweled: 'BejeweledGame', minimotorways: 'MiniMotorwaysGame', slots: 'SlotsGame', cribbage: 'CribbageGame', canasta: 'CanastaGame', dotlink: 'DotLinkGame', '2048': '2048Game', rummikub: 'RummikubGame', ginrummy: 'GinRummyGame', risk: 'RiskGame' }; + const slugDispatch = { backgammon: 'Backgammon', holdem: 'HoldemGame', blackjack: 'BlackjackGame', parchisi: 'ParchisiGame', yatzi: 'YatziGame', skipbo: 'SkipBoGame', phase10: 'Phase10Game', chinesecheckers: 'ChineseCheckersGame', gofish: 'GoFishGame', uno: 'UnoGame', craps: 'CrapsGame', roulette: 'RouletteGame', mexicantrain: 'MexicanTrainGame', hearts: 'HeartsGame', catan: 'CatanGame', tickettoride: 'TicketToRideGame', nerts: 'NertsGame', bingo: 'BingoGame', baccarat: 'BaccaratGame', dominion: 'DominionGame', checkers: 'CheckersGame', chess: 'ChessGame', wordle: 'WordleGame', scrabble: 'ScrabbleGame', ghost: 'GhostGame', wordladder: 'WordLadderGame', wordsearch: 'WordSearchGame', hangman: 'HangmanGame', sudoku: 'SudokuGame', othello: 'OthelloGame', go: 'GoGame', battleship: 'BattleshipGame', mastermind: 'MastermindGame', connect4: 'Connect4Game', boggle: 'BoggleGame', oldmaid: 'OldMaidGame', blokus: 'BlokusGame', spellingbee: 'SpellingBeeGame', minicrossword: 'MiniCrosswordGame', forbiddenisland: 'ForbiddenIslandGame', solitairetour: 'SolitaireTourGame', splendor: 'SplendorGame', tectonic: 'TectonicGame', labyrinth: 'LabyrinthGame', videopoker: 'VideoPokerGame', farkel: 'FarkelGame', stratego: 'StrategoGame', kiitos: 'KiitosGame', monopoly: 'MonopolyGame', triominoes: 'TriominoesGame', freecell: 'FreecellGame', rushhour: 'RushHourGame', hexsweeper: 'HexsweeperGame', puddingmonsters: 'PuddingMonstersGame', shift: 'ShiftGame', blockfighter: 'BlockFighterGame', mahjongmatch: 'MahjongMatchGame', mahjong: 'MahjongGame', jewelquest: 'JewelQuestGame', zuma: 'ZumaGame', bejeweled: 'BejeweledGame', minimotorways: 'MiniMotorwaysGame', slots: 'SlotsGame', cribbage: 'CribbageGame', canasta: 'CanastaGame', dotlink: 'DotLinkGame', '2048': '2048Game', rummikub: 'RummikubGame', ginrummy: 'GinRummyGame', risk: 'RiskGame', geniussquare: 'GeniusSquareGame' }; if (slugDispatch[this.game.slug]) { this.scene.start(slugDispatch[this.game.slug], { game: this.game, diff --git a/public/src/scenes/OpponentSelectScene.js b/public/src/scenes/OpponentSelectScene.js index 0fcdf1d..92e0136 100644 --- a/public/src/scenes/OpponentSelectScene.js +++ b/public/src/scenes/OpponentSelectScene.js @@ -403,7 +403,7 @@ export default class OpponentSelectScene extends Phaser.Scene { // Skill control: pips always show the level; the +/- buttons appear only // when this opponent is selected. Enabled for games with a 1–5 AI skill. - if (['nerts', 'checkers', 'chess', 'wordle', 'scrabble', 'ghost', 'wordladder', 'othello', 'go', 'mastermind', 'connect4', 'boggle', 'forbiddenisland', 'labyrinth', 'stratego', 'triominoes', 'mahjong'].includes(this.gameDef.slug)) { + if (['nerts', 'checkers', 'chess', 'wordle', 'scrabble', 'ghost', 'wordladder', 'othello', 'go', 'mastermind', 'connect4', 'boggle', 'forbiddenisland', 'labyrinth', 'stratego', 'triominoes', 'mahjong', 'geniussquare'].includes(this.gameDef.slug)) { bio.style.webkitLineClamp = '1'; const skillRow = document.createElement('div'); diff --git a/server/games/registry.js b/server/games/registry.js index d9cde8c..0823561 100644 --- a/server/games/registry.js +++ b/server/games/registry.js @@ -96,3 +96,4 @@ registerGame({ slug: '2048', name: '2048', category: 'logic', minPlayers: 1, max registerGame({ slug: 'rummikub', name: 'Rummikub', category: 'cards', cardGame: true, minPlayers: 2, maxPlayers: 4, minOpponents: 1, maxOpponents: 3, hasTutorial: true, iconFrame: 68 }); registerGame({ slug: 'ginrummy', name: 'Gin Rummy', category: 'cards', cardGame: true, minPlayers: 2, maxPlayers: 4, minOpponents: 1, maxOpponents: 3, hasTutorial: false, iconFrame: 69 }); registerGame({ slug: 'risk', name: 'Risk', category: 'tabletop', minPlayers: 2, maxPlayers: 6, minOpponents: 1, maxOpponents: 5, defaultOpponents: 3, hasTutorial: true, iconFrame: 54 }); +registerGame({ slug: 'geniussquare', name: 'Genius Square', category: 'logic', minPlayers: 1, maxPlayers: 2, minOpponents: 1, maxOpponents: 1, iconFrame: 70 });