From 51fb7f81d3065a6b1dcb9ad5ed8c0e8e8a226b2d Mon Sep 17 00:00:00 2001 From: Daniel Lehmann <3004405@stud.hs-mannheim.de> Date: Wed, 27 Mar 2024 18:02:45 +0100 Subject: [PATCH] v.0 TicTacToe vorlage --- .gitattributes | 2 + .gitignore | 2 + assets/sprites.png | Bin 0 -> 34480 bytes assets/sprites.png.import | 34 +++ assets/sprites.svg | 451 ++++++++++++++++++++++++++++++++++++++ assets/sprites.svg.import | 37 ++++ board/board.gd | 65 ++++++ board/board.tscn | 70 ++++++ board/highlight.gd | 22 ++ game.gd | 65 ++++++ game.tscn | 64 ++++++ icon.svg | 75 +++++++ icon.svg.import | 37 ++++ project.godot | 31 +++ 14 files changed, 955 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 assets/sprites.png create mode 100644 assets/sprites.png.import create mode 100644 assets/sprites.svg create mode 100644 assets/sprites.svg.import create mode 100644 board/board.gd create mode 100644 board/board.tscn create mode 100644 board/highlight.gd create mode 100644 game.gd create mode 100644 game.tscn create mode 100644 icon.svg create mode 100644 icon.svg.import create mode 100644 project.godot diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4709183 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Godot 4+ specific ignores +.godot/ diff --git a/assets/sprites.png b/assets/sprites.png new file mode 100644 index 0000000000000000000000000000000000000000..ebbfc166562d5a4bc705abebe2f74af809a5eb0f GIT binary patch literal 34480 zcmeFYWl&sC^euXZ!QCae1QH;)1`Q#B5G=Ta;O-J2=n&ik!6mr6yK4yUuE7~3xZlI? ze{bE-uj+kyRqq2uF*S7e>E3(oz1HdztSB#qh5ig30068H(vnI50Qmv_oS`CvpAgKu z!@yr?cG8-T0D!6R^aCm3u;~LoBy)PF;iPP9;^d<5U<|mpxUiYqSUMW&+ZnUjI+!LO z3O@q?8sLNE8x_}-gQagCDpS{D$0Lr1viQ!QnUhuhj5-+^VB`$a2bpw6Z#vjyT&(Zs z8&&q%LT|^*YMM&UZ;NzP6s0>2YNpB=%y@s4qZ%>NFo!m=>VGiV5^WQs2|+a)PIcd2 z7CLR#Eo=RPbR>AGZ^M<=l;V!f$vwa1x)H9EaQ%#~5wl$!(8QIW!`4HCxl_6AWYkE_ zujVG(?2$+I*)nDZ1M*1eN}77eoRDTDy;h|?9~3HAy@e>g=#3~Y2jS+;{661#=--?D zvLjQ{UOJ#_sescE&Xjp1dbR31LU9w%zvMKLIQV&Juw{{%l>l$dJ=a{`?P@JhSM2O) z)3yF>L|`3-mvB%br{mUOaa>$n4ls-WQ+5c3@#nfHCjKP4TH8fRcKiKrH>S@q`bO2 z;fU!>%)q^&@@{T=m)BrT?HxALsoyO}ATWIb*qPMX>?Fq`T_f3};?>sFtkuL3cjI{U zrcp%#Ky`KX=WyRO&dMDROg4%QgPKIc)m4e+&cUCizX6U^4kolwGH(@GWL(=z%uz@|@u!F_2Mh%@U^YG@N+PXcU-DnGvYyJ%0 zx6!=TWxtmHiA_C0lX!Z@@Fa=1Jt{&flB&MkR3V;akQGDh8Zp!bj(|;tQ{#SlSOy57 z0RiDu+ZOhTJ28tHJJY9r7h+z2IKnh2|yXRimG-XUf*BOt3 zY4K>t38MozB93s-ogGR_W#4rSD~jOUQ6=PF@1Bs(Hu1kUHEq(=dcPO_(-+d>4iz|X z{rfk)D%!NVVEWxlOo1zRy(E(g1P)9TZ zC}tO-V`O>8Xo~{Sd*0W@+nd*y_3`!*tsjm*V}vAnuXAf%d?uRR(K?kAp!|lXJ!v((_Ck+F? zTP}$p`TzgR|JQfS;~CB1fe9se>K^YQvlzgM#^k0Fmpbdb^A7bT1dtV^Dh>8_6V|dj zzNCK^*`y|)YZ=-z|9E8D*HvR7xnN2{{wgF$6cKjsuDw|FqKook&KnU}WbW&FwdlNB zWx9m}@jwNdF5!+<*;{HcEW_P8sK>BcHu8y+(%J2Tg%(WC2T!j zAfc(QK}{i-+r{%{u1w@g%<6iFerE5tQ=rF18f9c{ZI%st%GZ9=HZ_O_GEj1RvF>Ya z+n}bBYhcpcV()oN9gjE01q69ElTpN0EvszoeCc+fxDrv6@pKdBvssB~DJdzPjtjmx zSc#N7YQ9&qzMv8&ATFrtTjRYe2=E`LOTRWW4pzCswYqT-d$uD{ zV9%SJ8?-+oYc)GEt)m>O^u#JD6zxvr^~p|n06=Y93*J6?T$8pw^4$6FKv&P-ofl%I zhs!Ou-vhzwCrf@ z-L25h`R0T;Ls_tZ@kprxuBLWm?esk`ioDu4k*B~95r6shr+JdDG54~&?uOWpDO(1W zy5%2ID)Rbvf0}}9EP+`>7`#H`VC&*>-b;8rckVX$@eai_Kw`)J?&L5wc`JczLG*#N zOp1;J=Wdkx+LhzdYyJMx{{PlMWaun$`1*MqF-5ca)$U391ct{|mYf7n! z7Gkg?;j_`VRXF#5$ZhJ^Fmon7Ob$1dbQ1S;awfCE{viEfv@K?1?U^9e^1p_SH-Qn& zjVHb2O~4fy><{o4q2D2=d$1g<-2k{00mqSQZtz)UCTVhrlPK8!k`d1u znM3SZxae^|eWaDx_+zEbzYC$ znW7&XqoXMn1#tb_`ZkSGuApG$>=MH#=tn!}dY$EOa|U zU=H)y^T91r*gwc$=uXjC4-?RdXa$Ug2n@z=D`?e3a2svaj3Z?!sMtFq;3*ibN&q@b zrN8Adt?1T~LO4vjLsb9dDVS<9tfz-u(|ZpLaziLw`gOhg+e=h)u)Lj%N>vK;St&-) zxgmtm^pSh1UM4QPeu;lt?T?Qbeib`a&Z%5T) zX;+i$TQy6ogM*irV$MzYOmeB*Q)Yi6nth;9IebY=bn<8D;_MA8b+O%KGm3u4w|Iq2SNhCC30D z+LDoOS4of5pyw@5gYzMhC;QEb_`xQaShWsYhp*i`p@6G~R2%opYkc-1s>zb(#?_a& zB9PT?m4k`*Z*W&84QC>Va!xS<8g&LUo(>!JjNvtfF&*Gh(>JW}FaxJcao9|Ik0RGg z8TX7}Bth_Jv$sS%U|cEJHEFK67}T~?x1eb}MgLFEmzaJRT##bC2=!N?Y2=8<(HJ&T z&gfC|=i)1NZo1gynF(LOV7#kc@CQ&@IW*SH0iDIt9{wONEl%&h{x2G} z)BF%o`-Xx9zt^KF5SEOjbP)#=Kn#nc^lS(YKJr;= zd!%Yf-E6lmaz29IKFp52uf^GTRrc%~chFH)%>*=w)HN|79P2+H(2Z{L5u zwzy&>Tb$w%j6@|MOF#@|dTCTRb~>P5T;9+e!&1gvk1ctDg{^m&Us=3nzi{LDLGx?J zIpR$YoYH;A_-$UPFpz**n9r=Exil6~i!9x97ZuNas;j?{PveFX=G}|+@aHZVE6T{d zD4+EJ4XT{TiPcUztHK2JE@QJ!i3{O(W7l#rInrZoB)ZW};Y3(!&T@~GQYLeje|^<^ z!VO3?T9bLGtD0w(*+PFkt_QKDUKE7`ZgaEn1?!Hu(M$~bh%X&^5}IGvj?k`x!9~$X zQefh6Ty2ARiA?b`A{aJZ_x=Sy{!h-XMWbzJone2W(J ztF7O1u4TE|*{Us*gk>>1h_#1Pj)d{rKzX zK@^t4F(T51q)Tz#9`Tp(9!jhfP_I;I?$0ZEt9lk4?9%j+GCVI`0xZ(c6 z=^f(D$K5-;ygAi{C>M#w_+nYcYOfb}xrNmgK9Hp}^1a$yLj@7ssj(!=dg9?B_vt)d zcU`R%JB|dfMtP&Jx?EiTn&+QxA*O<1L82+)7aXKn(L3vMKNVFpYaQZ}FLk!%w60Zn za9L?a|9o(on9w^9%c9rRxC{&g*I_$*ApMF;Vvtf!*UOJ@;6b;W5PU8t9JRmP+os6#C83SZK*Je)x*7Y+&Y z;m(}Xti>!6MlYdOL9lfw#I^lI{)*?HF|2yCyA)-^)$~%Lg{ZI0!I`>XV;lFx!WH;{ zC=F&Lz;eUO8ewFxdepMQJJ4Kdp63^jmMkB6=ff*Ef%WXw)B6O=8#I zI`^?D0(`_&;`!uH|4E2}fzT#YUziq)yGs~K-d5YhNIUOly~Iu%q-XX(An1DiHG zJnXJbSsme7a7{{+=-yw0Xkh*bB~G2YUDfKECruCmyCDm);_qsz^H(nAo9;s-V1FQA zUPBW#CPNY?iYGf?7nV2$ugV*Y;J#vmr*hd8gK1f?G~9KEOXr1(({2DmG#uO4ww8k3)7w3rJ43vV+8?%rxtcIx=?&S4EgUC$M1bv$_nMMv zX6sd5yuT=Nw=xn3C9e4Sn`h4b&CZ=8MgYE#)oMe`u!@Y+otL{~*(q;aP8s=Bz8@!T z9lBQ=BYBt3^^!Cb(s^Ovh;xgV-c9V#XeVoL*}~(;yv`T@s%p2_&q+)~|0`UJLncRs z0ANMD{k{{}2*=D^h&;O-OvuqeTzgg~Z~BXs-7ko`3p$GV*IuF!UIS-4|qs6aKI(+;Z>1~JbyQ;+B6f6y&)adUzJyMo}|Sl zZ(QO~J11g|i@usJAOV9cx)lhLjTjC{8S7-+Gs&iJyL-Te+|fQ)qD_@g{A5}};r&Tc z>(sEq1UGb0`3vuz6LP#IUud$CM&r#@3|SLa(nk^wJI&qiV`Pp>e;aV^1%+XVP(RJn zLCq87k5gBec)JnZ&s?9{!_YEswGS)0cF%knb0%N4S_W66{qY0l0|u*iiYoJtOvjET3;S4DOuqEBQr z!Jci98&72gEL3>6*@;LB<5P)es?)%xE8}v1+iJ4(>6$2L-f{vZB+m_f@|P_f=nTu( z-P7A7&mP?`GN)>b-E~C@POxC6mVC-6+j|2qO8tWZJE78dN}858&c?{jn)y9t)ej{D znAtQ-qcf7tSLp2kymVuB@@RE4rIV{qH}=?}c^HUv)rmxkLk`uo;v z#9RyOiqBC;7ck#u?vdcrN63WEMI(++ETCz0!F?1(1?i(Wl&yX;Nb+I z{1AsVa~he^M8UCRmj*ulA-cx&)vBpw8g?!uUQ_rTfW7&!QzliJAqV&13NX7N`6zisV}Y1vmw9CLl@t>tK7Hy&-{KD)%YM#n>=qGH z&eGp#IzjuNhtt+w>0+Y%-=>I}_7c^$N0RBH z_s&~13lJ$~suOF~Wyd7Oez?5mg)*=~=tNa3(pUEpQ;O!SsKs#vl}6tbBUAxqIywY) z`roF43<72TF-YYZJyJaT+k^XoRb1ofO+|qL8K=ruu**hm?yT_98XIRY>&oc3R-b+eV&DslFMpe-%s5b`7SUF1Vk?Z* z72OFNYnl|Vj(tWKos*k|A!3Ny&Bzx9mR@yZ~H(h1+y0TL1Bp50R zWPu_3tr%Km=LEM$`Od!60dfX$L{v%i1e=VtEJqf#mLu^Gy2p!uZ{Rc!RW?Fuqh7fi zOo#qbLPvhmnUG9gIRu~g8Z3P-XUpxzEhC?@%PI@;HZfB&=B!MoA9fzW**{5!7vBO0 zQ&xPnAZ=4m&F`~543rYG^^=x>7+93G_PtZy#++!W*$`?BwZfA|kc5eMOU|oPV+uRi zUHHam3ar(*bX{uR z{b3&%dn#f_s5$+CrJ^&+f$ppb!b!*k2Ni59Mg%kElW5y9LZFO{;1T#7E^iq!fZrCO z{Nj(#6P4~A?&z7OH!XqJyVaaA%V$S)_p%_7)!S)f?`Ze65fLl;rSV7$X`8a{TWuO& zWA1KR8yjxH{qRB@OtJ;!Azo3`dMofi18ORp*@vAPOnxru&gbq?zI=c6-qQIhSr2pC z>Vmdh;TB_2jgiXl5LKc#|HCPUhbP_c{ju4$d=P`^yWnwcPaN?Tv%F(TBPteyuUH(`nE?>xqQE(3O);Q@Xqg);p0HxHvv(g@J&7kc@9-t~8V^OcBBHMM~d?W~0` z!uRF39-ZX@-#dR}$NnWX?Sj^+%2|*?r5N>Ot%DdSXjF4p_91@fjoYUmw@GrRy3YP1 zdSo*eeB3@)RS|>?9&1kwkV~`vM(?ZcdAHk=esx5GNRAhi><$h+|EI9FJ4>)5S-7xB3c`J=yO8FD*}iTRHOtl+az)3H7EK1 z3Mbky*B8#Tnc<0Y?{1zNdg36PX=|zUCQ}8?QlZ$Otf!-sfL*9COD24(tY=u2lym-I z3}%^okQq`xxVJ+9vE@;Bch+{BK!%>sj~UOI2wNc)rSV17NM|o>y!+eeK^(I>+LZYM)%*8Nsevkk z)YnkteKAaiJLij-8nSAMECH1#?)u%o2q#lBlr79mF7Fp}RUYe#6e4{0FIvJ{4;k|! zCO8@v9vmoOwe;|T&D30WUwr|&noIS9G zz6IBDXWNyF#j%oYYRC?o*%U~`cM6UGc0Va0v4EhQD7-T=XEZb4 zUJB1&zmjA{l2)B7l!28rqfX2jeNlYfrk5XkpR1*Lo^B)Q;}1Bz;#ujSm}pyK8h@Xs z*7!`EJ(Ukp66|D86ar-`Rl$=U0hTANoMqIC_ih?o`u(t&Oqakhld%a@ zCTqhX_f2?V3wgt2S-g=csm&Br@H>3EINienW@{^;YKq_JHp#wbuxOu2SJ=ggS}h+k ztK^BOl{gi5Db=+9x_@#$X^x-W?m4~9-lI^W^ikC$?$B_f{H-VLYIqbDRu$#Tep-;` zJW#{JlZI|29WQit#RVz<0=2g6p$508d-dpo)lCLuiWd@mi=h~q*yi3uP+oa@$N(_eN36Ya(}^mc7yTR znP&XU5{_h2n(=q7Dnl`l^9@-{6Bb(~Y)gvBV;qj$lJm?o(yo3ind?XsP@P!2Bc*~j zQ_y`_S+4#K3}677+C6vJZot{0O?^|JN;JndZR~%$R79D=Bkfd4MgP??4gy zFO^(3$}sMq`{B#_#Lsy*p1$U0gD$*!wN^oe9oX&Xz^W3~JzSi-*Mb zv4AsC%g&I($|;P4(&w>HBn7!#t7;CdJJoATQUpE@>bT!HC4)3=EsC;0J>4m?_Tb7u z!`s=8)GIcFYRG1&pwdw^{Ygk?rLZqWxcBo3)mI4e%EWYBTntq!smUla1jUaRv_B5# zS%K4!)|!GpNp!CE*iZ%>Ny4uZ%|AQ)^~_rXi&*~+dSUNe%Q?$HK07Q46{CeQRKj`k<`;?AF; zb%2fw)c=oTVV3HzDHUnV0_-w}q+UB&C zJGv0z8BMl`VXj(>24PZF{VFFUU%emE5(LYt^#f9CK!@bu0Nt>D4<`bKk7G zLLmnl$@h0u>C{4_o?WdJRagFHWqWpHj@nQ}V4zTH6My{=;9&5tQ~)-GSj^|c_^vrh z?!2PF)l@w3R^VBG1bGEj_j~pBL9p95p^|J*9R1uT{N@v~j*@C)<-AX8WMOmR>W3d7 zs0GeLMxVh}=$GbVb$Z235hO7GJ|B}~E#jTG1Tot!l%BGy$5HAs7-fB^oXgN>Hg@Wn z$WZA9rz2xQKquZ;Ak|vRJMf=`YqcYnB%S^ZilrgM~~bZa?wJrP5>N&yHSq_UU;ng&zah z5gznON4>2R;xTib1F$|tHIYj8ATKj;)#%`>}*K_hu7Eq764&4Fr?Oik zVh4pitJ^;YsYLWA&N_qGl8N{jRV*Pg*sHoPT$B(fBO8U+XNQ&-UB4_=_Y`$lC|ni% zoG)e_2g9W2B;7$4`C!RxNJ^Q|GNGVOKk|&z(GH~hx=U<-?ILwPQS-)f5BvLGu@Azr+{S$q`2sd#M)7gWBRI}H@o|#o^YE4lV!B))hq?Sm9*HQC$ zfVP}*7?|w^i*-o)N*-RINEx%uSXTL3KYIftx87#Vh6oIj5xt0Oy#tl85yi(Ok;#>M z37!I^;d^q#ZVA@}9#Vd-M(^slF^$8FKxwZCo zM!L@pRqi7hpq$gX<17-K|4XCoO;6Qu`B{LQn@WCW@A$aJ0?TmRhBOI1b zJyWz56Q;0DL&eC`1h49{M^W&#Z}5LuQbjWg$#^AHG4?jNJvr}zQRpbe3D^=no2;uX(S}=^>hp)=;Uq{G5>k? zGevIkcA)6Jyy1FaWQ`IdM73jj=aL{*t+xu|P#-eT`5>DzBIyhKCAi`NL^>vk{7L~g zU>0hJA^r+*hE*V?Gct0^7W09V(;w7ngRJkhY2jGh6c4f@3CxZe%0y64B0gVq^{xF2 zppEJp@AC??*`~XSc(CN^NXmwU@9S`R=~F?+Uo+s4N77sQG0xK^E(=M9xG|PaQiD-> z^wmHNF>`$HJ6d-=q8~RT1+`O(;~V8mRied}i!dE^5igFl>#8PGsfAYS?@VJp*MA#1 zjzu~5V%~VC3E6M5yuQC?e7f1>8d`)i=8r3J761R{btl9{w)PPCf|Sd01Gl9fO?o4T zvii@#Ux-t|KKC>SxdK`-AxGwxUD|I0SQX5^+zyIcENz`IA!S*&K+d>7oGTrar9plk zqb1JD`&p;H?x{=j`1jBA$?;F-kN+!~RYCW&o&4D$1|bG z;1LLYnvVxUYgo7X{4K5@qk#<<+PRT~+>2@t-=DnhzXPyLQ`1$Z-$@Eb`CtG}j!lfo zCG^K0CN(sKg(YvFvE$~lEPnPNN;pEWyQB5KhY&2Kq&2b9$E{%nhK2-lg!lpL(Fwn}8cEP7=O! z3xbhHG(t|o6m6CU3FBf6B-geoTwt6~$}}rBCBj=1o5P|eCB+1mq~sCNL_x*h?fIa= zkF+tMn14|ge72tm%+=e=+6b3|PMZUemt!|01pFGxJu&in7;hvzoWYZmd*}H(olNh6 z%EK*m9J#2YUXZZRa~UqNh>K04gW8#i&1Z-ZIr67SJ1II-i51)$?u4TWvr2S|JBt@8 zrx}Lt8jS999Z$ntn~}xa5R*9|@qag`hT&#!XQ0^y=8JZjS6DPR#EW9eHb$B5r;e6s z=Nr$hl_%;evIiRgd50!q+f_06@|4?o{-^U#bu1q!mDc)ak%2CuMSP8@cy*TmYVYaD zoTrhLOrU2dXeG!fZPD`oWAk%uj6r;nDcuXqX5Q;t&uR!WQ@qrY9&mPeViR z2q@WJZUzl5=)s$;1zy}J34C_QT;gq@4L$~7hXHuaxmn>#R5X^$Y@%!wRJTIL|11GU znv=k_0-lsNBLVd99&Id`2V9yGBK*4E)!}d01DZB7>u+@b*lf-ZqDB=U`yP#&>mytO zF??OuGbQA4NS%HRjilHiuXMmDuCspEK=T`9G#rZ4V|*{~JIpPp+%=t9Y=JS=g5|n* zy3hTmeG%%W;nWV-w*u|#?|VpqQ-3j6HoJdvk+7C73XLz}K4k|1ijfKsf@ z&x+9w|L|2JVQdVJE;if9d&~!ro2DK2!C6tj+YG$UXQHv7I}bkS5!W#$j3V!1?OEp# zm~M}@Jt1Rn_?_E~|0KvGHV%b*=J~9xZPB&qVu5!f_Uoy?+gU^}VWRWfKE}O5YB0OI zN+R`Pu|AxhsH;jr!-46G&W!OzAWAcEUGO2_Q!Aa)X{W#x+FdbFhJ}^5M{o?aW)1~M ztmn9Lm1Qnmf?95;A|axJQ@3*Dga4WGf3}963+gQzd^8=Lm@rKDX+#lE9!hol=NzZJ z23dvru6rMt(J$ySgh__j7_Gk1780T9ZQt+KkdQ12&Mzn#Ld79dnsB%Z*q_GwgO1pU z10eVUjvRy`9WUOGXK_csJ`tgxw~!`K*0mgEnS~I(Vp;_~`D8TL0ftHP_FGOm-4-L$ z1Oe=JAV3f;9j)9IKU+F{U`VHNe0fi)?4^Zc3d$s+dnrmQJr+3LP_Eg-O?ynlo)l9Gd}`{ z`pV(J+6f4DLXQ;Fef}h-h7)6C##ak znBT>YiRIF+4co1DNwYv6ovD>4v+Xeul6V_XTyu*ly4e|35eaefhw3y@(P0Ompw@G; zm+@ubh1McH9SR+?YG=TL8lnfnYMso9EedwAyV&)fsO_IP&eV%T)fMD56AkKye}b5; zLSkj|`_I`}I@dC(zaN_pnaHO9`S&mGej+OKbG3e#CKKuVRU!=9O6C}K?N#YdFV`nE z`JiIIM~dLb7yg%c{#}M%?#C_MO}AgDF_4GJ$J@4aZf`~TOuKw-L4<8$T7$z;e@JJ$ z0#Fuffua?Z&U^F<-5djx!KXy=REY2-7`&vvt`a~l`W^iF;yFD9n;V56wHdF$-E+di z`;52G8*I9I*FT|{@{KkyZxrj5SLvD>d}+D4V-rlhu=>t@q-wpt_0$fF z>0)iI2#sE@it}7J6jBwtzY+$>5xP;SE^%Sp(K`lWzNJ{3uaXne+Wrn1?N`w8Ury{tXtiLTMs|J0<+36glgIsxqVGIa= zS5=<1`JCga+roy{70u?Di+BZS`CWEVDt3m^05Rhl9OR|xNvBffPy=&09Rq|osnTmS zJj+KRqT~yledpPvy3k1Inii-?o1QHk%k59cULA73e*Nel6yF7vrW3z85B(B~I72D$ zUA^jiN2a1#!{)*}`Da{4*4i&@uZ=NfzbWAiwqU=W*qx)VyzEl6SaNupS_| zCv0C2UUCQzP}+8>md$i2C$n7O42SioX(>}gw2{zpp(vk`0FCB+?jnSR?o@z8M&lgd zWJ`8w75dIQcdi$unVilG4X0fKW;M^#i1PM+wzE|hL5^I&?za%}e4|PKj~Z*4lN_Md zlAn=kqPil#`=L-WSMbXCOso-(S`V)x!%sj<$Z2uR-3Q}%J}BbblEoIUXvoHQ6gAk@A;kK>|R1zhJ{CZmaPsgN?oHVkPiF z^~;wfVW4aup6X8ercu5uT-TLJ@(#R2Vgh6R@);j^`xq{t$-7W%bbVu7t7vxp5fCd~ z`eDC(6K)tNs2JUkyFU}T-$lIT#Pvo>;F~_)a5F#jCECf`=$m0UjjLno&h)@wEp{d5uup_;24U)xo-9Dj*vQ-2u?BQ%ucRNJ zv)j%g0A&_&V^ci#EhgmD_Ta-lds-UD>E=ySx~YR>JlmMZ<~cC&M}I`Zl;M1f$cf=wCE378fJ- z#y2<9Q)`5c_eeJrsb`^*wW**=N!QXN+X@x0Rip211CiIbZ{A4p@E-}lI>nmzk>^?c zhpON zLr}0|lMIU1bv?rH%oTWYs*Ub%>^%X@@x8_ou1zv-jK%1XtJRHlxT9P-M>lL6T zw)E4dp`qaqxzqgLZT1qw)psT9FjnJyZP1*G`KeBKVNd@wQa8sSXx`7!EK$qoq9I#~G?={*j|UwhedhbRL7eJlEZEj~_E`&99$-25*AaDZyTN;!_$~f9 zKg#B8F*!>o*!#qgK|+K!ik`|RJD---FFwcvov)HS=DxoEsIEPy>*ZxF(vHEKj3j3? z&Wf>&iN_BD&2eCi=4oi;XhNE9(}L1FFNyrA`ClK7_|p3Y$oawqQ#*e0CikFi>HI!W zkK&|EQl~}yH9e^k^M>i&GCE!zH~@z@ArG|MXz44;-ESU#vs%)6gPxsq`kJ6>J<>g! zoiCoa4^i=#GD>ZZ4GkaF5%MQN<384$Ti%^svKg03yi+W{n0GM@RZcDBgdF2>STB#D zF?IFHx978BrRr&C7&5Wvet%I67q5pV5d?4@4`Gq_rr7j7+;=VEp2)ZY!ONWp<|X&~ z_{)``sr!P+Rk>;CLBoZ~0`DO&;pqDz{+Qn*Iggpm{h&!3wMVXcZH3m0%we( z&t=g9L#1Xl1I4oWB%g#n35W#x%|34SBh(3iB4e8Q93D%>0eHGbph5VZVCUrS?)kiW zM<18jXe9@!f@OT>8I!3jP5~Mo`+u%I*qQSD=ywjx6nOVa{Vz+^#;Az)+t0QJ!ciBU zYwL8d*33C8u}_oJMUl<{`on&QBfQGr1cWaznf6XZO}NvkjB`b>;j6x89Q*9p=czH+ zzWPs~2~;C=sGP9HvHXkL+CrNH&fcpU_fI8CQ{ZXW->mjIIO;B~ONu~I*lZb(f6ill zkaGcTd+oN}MPZ`t_~6-sqZan(RlSWr@f#~?(%}>!ey#=DXF!D@bzf5OOY{wB z442@3I9t1VU-D&cFbMe6sN4)tr+E!jDo}vNGEUS3H?*_tso7icv1p|cYjY+?oyW12 z<2!N&Z$sFzgYE;9Bt8c2wC9Evkw$(`Cdo zUSy#=*=*5Vaejfhl@{CDffwjjy$@ozz)jWQ7Qgx%PTu!d>t(-!6SbE^fb0p~YYEAe z)yk?s12?1oADh$*x+7y)RLxF8c;;oSGTG5di({e91XS=voG3)7G_}RAv}|l!dnJFqx!Cpmg8|g!MRgE<|2w&1Qi3-eGWL zcq6}=Zf`Vmm13lAIoH{vXKvKAWp8?ZL^Z*7;VrhTlL}N$3M$6PuuvOLFo(&=;BTGG)g+N zWZL_nB249uI!Zn~(w-0UzF_Rw82n`%a3Oxu>&h{>EyZ)-yPTn3%2na)JiJ8VCVB~K z^qrNTvi7)*LP+e5l(CS(@N9?Lu#fVYje3jG?W{;}`?zBd=WPo`1fWzwnSK`FM0Mj7 zo3~~!H3eIa+e4l!ojJnaGd}kDDEUSDbuF+#)0>z#QO3-UapWhn{%~A8MguJiW`lWB zbcTN@nSXQ22cY;IqWZ_B!3Pn;3b3O5pbUgsUvQQ#-=O9>AN?wEFY24X4rAMRnKUHZ zg}PH(MKj+2r18+)Pu(Wi9sQu?)lx?;iL6(RQw@s=CT$ zljOl><_>zyZGs{%)qZpQ5Md)!7Lwen17McC_v-<3?pt4Ch#$4ne%!qd0Od`#K8iLJ z-4Yj!>&fbn0zA^^tjq+2O$whpdS1|Ze5B3%s;1XF*e2m}kD;fh&3c0|#P^FZIE)hI zIHwUFbndI39SK#Zb_#WVo7tow`mNzmg)ZV5S9Y#{uvfuC1ZovAI~$t7r=L1Xwx76^RD#fR;E5-q5R%dFw0hO$6DDx$l_?sD#)iyDWlAc96u*$@#4mD56T-BErd^>oqcNYn6_Qf+~OED+H-7H?>d(L(y5P>K{;de#! zNOKGm_~57S=706DmO-n0hhMu?n;RpSwFW+dqhy)AM|w3CuT-V^-1 zXha3X!}^qX9Se_tz0&S=qU#L@yGr5HRhjf(Q*GWuUI_bXxLk*y>ufaQpwG=u)xfk? z57I#Y(cIi917mGL?Mjz=k|5OPbLVg5wzoh=3#h4SEaGAIdVK47eo$eX2D|-#0vSz7*t!(#r5_J+KhJxd&5%1jy>|qx$ZM3|$zRV{F zn)HVYQeqC7zap;aLC_SFjJ|RBjgEK(ln)s=`ohF`-i17@=8#}@4fUwMRBl0Bbq&?& zCY)4lw_;H@4Zc#eb)1+diW$MJIE?271pawgJkdE)C-CkPV-lp?Fk{OPgoi9yC-C%5 z8jWu+#!^%Bcg^mIzzRW0_W?=ziN_EY*mlg9umYdnn3n#Zy8r-0%qH}`uDJ~;j3sJC z*F5oaNxFAc9d|;&G&G!31ni}~;Y9}+JkVtHmIs9RSA=O9D?!D-?kJR5r*~hQ{et0^ z^NH162r}*2YkAqEwIL*h=HR&2@&m%TSJ&7R9;v6>$rmxB?if#r-2XU#wkT6~v@19KD21Tk;7- zp{fgkm-BY<{wvFTB6`N$ETk#udNo+7=Z2$M?w1ApU2E%P&I&%2PuuL599kA4*;|U7 zc#6t19$@2AUcdln0 zWHLPfRKS=}B$^d3EbZyFGCdzt7ar zLM<7_9hb_P8JK0*JUFaax0D|#IXsyNwJx$#d3oQ3P%)Ub3CzwW$!*VR25NtIUx?xQ z{uTIF^9+9kb#wZ;JNca>wg<_HC9w%)hji>!#-j0jSG+Zwgnx3MC~_~3^%0rISk3-} zz30uOOMO^F2?PNk=OYY^>G%jatE|}=IY2fOnYA*=M8)$&BzRR^uE6;nXyiIYqd8Pa z$A!L47fa###95w%kN&E}DgTik?0X)NCAjvBJuoHcIYlc=@(DS8C|+~Ca^v!4GcXaJ zcOOlEoWD4F@&Q90}o*2}Qj5s06+*^rk(f zxmgSJ*MlT`A41;D+AUQq_mtO8e`BaH}ss>Q1~oZ{PW zRx$72$zyuc0st0huk#^@`V_PtzIO%MeHM)W4uJMLj|pkr+}zsJ8FTEQ3*8R#AT~O0 z^j6d^zNGnCTA7tLa*o#6DldMbbj){_&giW0DKB_W>UWO_>k; zm;}3;y}Qf#YD28wyHQ6Id}+%?e42)Wqk&&h^^v}xAF#8wh~OFHrDB4UmEpM9k)F>v z6P~@y)L#6i_v^(LNbVKhxGqkAc>@~l;h@ouNvhb!9iz@4^=1Yk=ygMxir#7itm3h_ zxmn#QkY(OxG=0-j{3>hV>(!uphn`1Viw?fe^}@wPVg~95?}#xoZSVip+E+$ZwT10& zKqN#!Km;X46hyik0YNG0ZV-^}E|mre0i_WTkuK>}Qo6evDd~p$?(=>3|NU{#IAf@= z_u6aEHRt<2HP;$Dsau(5h-l)qrya=37^PQac}?KpJyRkn`z9P?k#Y6dRQTr6``wI- z+6ieSnOk=j+;ZNT@*zhFoi1p4k{&XY>HOMue9BW*n1@^c(IAeD^Gh3T`lbTIsRub0 zv0GxEZ$}F@jl5In6U}V;8kakdcXrrf-UZHO<=&BqC0(RWlh4op66j3AnIn`#r1y7J zUyc@4FFvtm=;$4W0vnlIAhpugY=dxiuTsn6&V*vnstwrG`4y$k|B1+Xw-x!6HvY{s zZ-S_K>Hm<3ZEPbWi0h84A)T_8kgIL7X~S0}q}HR?enf4ryz-9u1D|y0dndn-&n9P0 zdi7zGBBhu~}Lj-Ign-j2_a< z8=b3|RFyPp+IqHtD=eut8Uko|YDte||#FF^cm_$tKRuL5A+9Wy&DGVPjNoqD+(Dlg+g(C!5t-RI?Fg zM8$VW*Po@{{Gq-r!Ck#8?V*0E`C8m7C;EMre!*GqSh>(^raHc^2JMQ&K~%7hz7RyU z^L{`vG8rhnbv~$y+C2d#gm}((3yuGkXgN@eoMy^pL>o2Jw==f*>@2LA?whlHM(|L- z>y~AiCBYuPEF?caqCi??dMH@EgXR750w!~f)wrXbyUM;~PYLKL8ZEuizxAM1-Z%<# ze2Zd0%4)t4qD#S1RQ{_$$;>6M%5AFZ``asgKdhp9k@>F9rw^lKE)6;`fEoK_W(SoWQ_CqokwLK|Lp;URc- z*R*y~*(uJg(+4kHxkQ8_%obZ6ZniEyz44FgF*d!t&toB!umXe=t?fONpYQub8|6$k zQHx@OxZ}S44pLGAGI5w8F??=%BTg0xRS!<>f2zkjq7bHHO9&&p+5^+<|B={WxH9-! z$sB0L&HD zpDhv2OJ~9&m7mKPcVAqTmlL1ozX(~l7ZDO7!ZnX6PrZQtvT_M?{?iSHM}9Ps_@6}D z=U2u~FRn1tiX@#~Oq@+4diQtN77a|DO>{SnR|VTlg(y)kAa#j~U&YSLfGv+2qaez) zp5Qs_vzE4Vf2)*MR7y%BeAO-CCN9?3H7OAb`sb{!CH{-3qcsy-=Bz!*5AF|*tYoC! z$iA_5s}WD+F8UE+NK(Dm@lNR*FD6A1k^ln|Q<@DiNBFbVsTlP)3r-W}Z*0sa791K( z1}dB;mN2S3U-%)*`=bBPzm)PQ5MX6hAiZZ z+m(xn88w?@V`BXF1t@Vvs9h+E=`ufBSy?TE;C0*H^v+X8M%m#^=`TU$<>m5Kr7xeS z$qzjx3JFokRb5}|dDuKv`AQrX^RZIqjehPmX7Zqhk*}G53 z8=fda?}aZyGPVD7^|5a#!Wq$SVQoG0B{4Dg3-6!~8#}v)qLh+bN~$;}Y0wetvQE8i zTwl4|}X5`J#(iWl4R-+v7MeTR6AFRF-gfHFty-{f~+wB1c=ebg^fAYauZ zhHt(vD?UD6%rzwyL503`o{`%XwV8Qegf!FfK_&!-a@~zU$cdj6N(A(8T_GkaX9wD|gR$of(N0u4WGi+XlaidVo45iSy(V= zYUX(l*}W_r%_`8TDW6D*=QHC-Xh9Hb?rVfE_GN~843Q+uVbsn1m3+rwWN4UDam>gl zim8x0+=lq5XnF5S6;n%-~r7;%DXLJ^LEfnhXO zWI)1ZjQNm;<_-x7rvGoRlxZ#wj;~NCvgDFQ4GgHIq@=pMKP#T?z!9>K+rSHS)iIAt|TxG5X2t^siqLUzqi_Hy3Rz$|goP z<0bP|ul?~$+NUlk1l{$KCoAB}A}S^ZC%eXV{y{M$k=tfrqRfKF`+_H&jQ4#=2zF`e z6Tb^y;KM#v;{meh;`yq0kNhqWRE@SNsi~BTN=i{NF*lf*d#j`_*0WNJ44Q7neEytp z-u^IO^;|8xA~7XpCULP6^=E}+O=v|0_owLSsHCJ#E>oou9+z!0F3T}rxS2{~5?pW| ze*W_p9#(q!s=_ZYPYE7t);MiV+*SH6^D84l2s_-NEg-m+E|bT836sluDyXAF%7Ib| zz80B>rCvtA3`)_R$0=9=0Re`8hq7Ilq9muj>#K{>xBU8mQEay;p{$lzOR|b0({Em; zm8X+6jQ$8JOPXS~9D(TBgPzckkl)hGb$)&Fy`E&h_XS4swE}G#E=PteJM5-1EJpHp z>6W=T?{`}xGHz!D!e?AvoCbx3#n?MA!JyUF3Ruq6jxP;k_U=d9+uN5*)lDB90AUkV z5T&ncv(>%6x@0x&Av-xgm#)+J(l<2~79o5^;_vVO-Go~~YNxlShv|!bBD+Z!rWzfQ zslkG=OM4`>>u$@v>6MYR{Dg#rfBlk_^GkoCznhG@xw*A?U!AUw=4pHx&Ju-L$u4_0 zVr|XrVwu@zcWeRW=WLtY>(_0_`=E6{7U*S;viC4Aa~F^yirAj6G3rl$L7^q!dt_=& z_(ZPRp;yp!uj|udrO%_skEOgRBk=bUvKLq_$5@`J7d0A%V)S{x5OCSnhTkS6Y<1ct zjcdt>+L0Zb#?evGNQO7Vm@O5zpqcsL^7&kOhLITT<%fQSJI9UY>wHl`4srgi%!9&! zK`~KL7MmG?h-%q^_?Q@?FbXS2Z4BQiC=G;}V-lL03Geau@S4`Wy}jdveS}a^!@Suk z-VXgxAQASi&DOw^c=1AzVYz(B-02bZ(lx1E!|{yA?(bX7mBZ{JX_(aQU0vc0-j`u3 z3R3LsY-~4QmN9;mAQZ!No3VAbw0!2hpE&E<#hBY;OBOhLbyN`)9L$;^iRosr(iPvY zn%|aycY1Onb3@-zGci6sI5HC7LUo=MYO!svpv05(Ii777#k|?h&J9+CgmC%W!SB=$ zABu*^R({M@%1VdAD=|o)`DrthU*OgURa-xNf#WF$`D~eTn}08%XfW6Qd!M}{{+vFU zasGQs;ByBZf6;g2rKUA1Gz7)9wY4lBN0v%Yc%G)L`dD=Hw3Y(BGB(>Vs^Mq^YG#CB^^SgHczEz z#F21D9w@FIw$<^%s5iGNUdv34DE(?aHe-;=?$0l3ZWgbommL@wcn|$`zV+jSIk!pO z2go{C?aaBo07X^n5UqGgHPy&2U~u~KxPNRcC@1IX(CFx7?PjIjqKxczY*ZAhx@7?= zyNLi|&bw({^hi=n3@s-or>~F7BZ7xG_>cKY&H9)4`0>$!65_(u`wt#aQu*DO<&{m7 z*YErKeB{Xii&Q278U}826piF|LXX{46XJ%8gMIFsKVAWYiwj}ldQ7jg1`XQ6$$1>t z@R@XLT|KIy-rU3`3$j~mjjv6$4#Iy=Ef%1^+LP=en-wF3qhB?aB+x62^T8zj*RNk| zgIN({D*VX_3HLoO4@Y_259rLz&8=VKVPlJGYm-6U%CG)70hnC;#f$lYOlcR{(T&3h z1P{|=nl?L$=~h2~|M=S2w^Ax9!&^R!A0KeTTd}a7dwL2eDk}EnCptKeXsM|9+ti=l zg!}xp9Bz!-yxwU~NJ_F)S^WOv2c2I)094+Z2fEW|lR|^zCB(Nd+w25!62&CM#a$h9 z2`rjhTkqe+m&$hXX)(bUt$rYP3lr0}#*{Mab!w|5rI%lIHD88XcXv14vuEPaXb1=h z{!KabYFIYkAtW?X7C{6}+#{#U6vWx76_=E(nf@@bHCbVFd3N~N!|+FLu9&yC(9!mE zC>9}X=vewge0^D5Tr7d^w^&JG=#apt+tRAJ%^sx~Vl`PlKYM+}Juxv6wxZYIP0sJK z-3*0g_h9ff4X?(`_I0_{WI%T!w^kRQ(_iIp-@d79>seanDWIgqXiibWx9Z&&ynRjb z{=Y5it=mwDL@8Wz~qEv8gt zZKOJd#oyCEqu)&M)U`essbr+fw60?=(5(ycx!lkzKgjaiU+pzo?ubqHZlyR+N6Q>q zqj<-^75)A_YHmnd^3mqF(XPH_p_eFTv7684bj@haf?d{5{W%EA0kQ&ZY&j^%h+_G^9A zNxVi^s`<%B{^N(0okHt8lf;JmE8S+69J3KW>W;87hrVB?4X#HfCNh|5J>aqwaVVX> zdCs0bxL#!Np-A!v{Alf<;>}-vwnLr!hOxeO5H_3P7#;RkslUGRz#3#h*e*0O{M)p(OnAZY!cf8K}EFD*_V8TTy>Te$ZdN0PKguZOJ!P~5rrZDd< z`lH}dhfJT0F)P7;jc5e4r_8D%Bw6@(@A|_6{M9ME*G}`_sTa%mg)>QE{`xmBQ5V9K zJl_;}Yg*;D<9aZGVvbz4$e?&_={xd8h0uNfz;z-?{ z&bJ*g^jx!NYyBC4meZb?yIt(Pb8v%=GrBG1otZjTs|gN%TDIQtk`nlOu?Gi^0;fyS zs$N_G8E@TVB68XYT~AWXZmxCP?`vr2Hye3;xITzcSa)>a)5~isNrvxfEH-n)Magil z*mlFU_cQHE`Om+8D?h!f>$ZG1w-n~$y~6slr?qu;Tb}}N_qOoFhVL%JU0$gzrz-Ef zdGkghRUup1b+fpQ#cj{n!Rsk2!QSz4+k5m|MW($JOUujC!?7NLjg2C(>Z$1I|IkWa z-onQIeSOh;tv_0zbF$aTyz{rCPVD7NOu&t-CS4>Ng|295XuEB~S9fN8uItA0pb)>5 zm2Dw>EnqO3S5T2f8o^>aCxS!9gRi2Z!sD=l1K@UUdD;KpKU)E~tF7e^bqpmsA`*5J z90Ec@yX`4n?P^D?+qZB3J3M@0Z2SlssdjyYK&E2ww{MTa9&qE*($dl~GfNs7(Og_y zz=dB{o<3k83YpZ9mX@|#AE4FvZ)D4gidg*oUk%tX(V&Q8re|c_Atz^aA*!MFqvGNk z$*~h(lE8c}BZC8nHy*FINM%Fv=Mn>SKLe70JI!xw49b4~oP%q~J%@Inho{@xn@a_koc>gftO; ztQ758_g;JZ%isZ)FbAw#w+ICep7qU8Q=WUVh*pZDp!lYV1!C)RQBjE;_#WUa=6QO0 zvgkJ=esvzN4+hp*c498Dp)dV;l1e0Sv-xCqQRB<)Fs(!$yY#tT%EvNsRCf1Ul`3UW z;Bw#LD6nyK{Mo%|$sU#)93I{Z9nebG`sCkyP-tkW*uz#rcpZu_%wAYi>X)Zbr!MC4 zd~E+vbCI^H0)Bq^@@3K4{^j{`8;p`on|N4_Llw;ifdBp)7n?k-iXLN|T9I?xhz!Yy zR`yvC~=W8i|-%4{wG!otdZD6rIiiVDfNkUfkHeDtrpdCQrEI=N(C@^WTzC5E6 z@fe&5r1U1i6TT>#QXpwvKRG>}-)*C8TZ|B9av^H{ST)3sj})fd{#SciD5)qSnSaW_ zV0W~sF;(kEsH>}sdHePYIPO@xBU@Tb`p=(4Uzl`6VF5!)>n}BZ4Y26_;uvpA#;!ob zr%wbiU%q5yXJggZ*9V1!h|0)>&AC`@wkVIl#cXbF=2@}{yo--#zqjPJbLz(9t2E@z@cJiHUJMBh6P0 zh2I&?)Vg8f;5h34u5nP0=6v!51J+a=w@u2l9QOEOF-D(xnJV6fmYP~1t@P(PK&Z}g z%T=0MTDv{`JC2$H+sdk{0X`RtlqRzq`py08j;`lh6%g;9UGIu#S1&QfN=QuHO6pRV zmcBLPwo0B`nj+{iQlO!MV&{Owt3Ap5R+DWRof|O+6VlAe>h8~HnM8rO5`CV=|9VDwq(B9)h-m1;sP9RKMRzJ8`aa5Hj+dx5U! zq@oEs=s}I$V!)4OP%s~n+9aMb7oUr7?sZK!d#A4OIhJ9VUQ8OGH-CJ!yN&R;7SS|p zcwH|1jrNEfEA7J+)_j-`Kk`JO@ds-PQBnEUB{Q)WpFiT@P)>h@Lv?jdR3l7Y#prRd z1!L0+bcHU5|HJbSH($jCp!mXlZeNZp$JYS-AwPX!*V;f1r>w58PZfYm{?zppFvUyc z%Ru9}B@}%Cz4+gJ6Rq6R_`>2MdP62T0m1u|6IU2JZpStGUm71ieAxOloPcULWF5BZ z_UA+81NQtc&E9qr=f4#hvVZ>Mc%H!)PQv=zs+zrcu%4wRrROLZ&;*nX8Z)ui!j~Md z<9^*ZBqs5i^D$@G9qJQj0c@lJojD+oULV) z`$spz9I)z108JT~qVpN4l255Xuhtahi1s^W5;=WYEJpTy@?iImarh6-^qN~*4Ca6P zW8&hLpNs>}Ta56z$j}lLsA#KSYuvBxch7q}5&!w~oMZo&|Cd~>S|n8H-(n%g7OLM(MCVmzUfuW>es@Iy5vim2!`aEUdDU=h2fVGy($J=|6g!hJ?~$uy?rT8^VqP%Pzw+0lQICqv-iu za)tx0RhzF`P4NIV0tqVu%WK)%6i49w$ZnK8Jaje3)3b0@q%Hyt&>QG-HSV0V-he>w zA~Zb`PV*R*c>!4{C`fK#K7zu!p;P0$rSeh2fw)lz?+LQMfEX0o>EYpFbaAo^Vvm5P zrl#%wiY#5M6aXgPX%Swv*4 zX(^5bgO``dd*jjBd7wc3+utvJD|nAdn`Qj9p71bubL}J?>w!UU+#y$N7=NF#KYYid;9xh z>gsVy#CT%l8di+|z0y%mF1)2)DbKuBnts}xCm&iONQooQwiTd+gJ`H1mk^tpoIHIx zsKS6R8g}&J%^O-cPD{bW);|H80`3JuUS8gNGTr#UhlF@-=Nfe?u;QJEhld|~&~Q10 z-RT&rcHWukc4y;COHW6IhYxUaT7+_TYN?38;TsOu9)$42jO5n7R5sG~1 z=lQ7REF&Z17=@);xE$2hBQ#dvpB4q&hOdrZV2HLqMKnzDepC#BBBK2Hd0vad%NGDAa5){P`>&qHj^s7vpnd}5 z02IaBP3uS^TJomzUng@zoMzXe=i#v0N^9TPm)Ka^KaA1bGp-+=_|=;5)BzUg{LEN7 z<~O7S?FLWJ>o7K3Lzt7ByYQ2}76`jlGMJ~rP3y?ZeT;U<6Qh`?TX+BZG@^f+7NK6} ze)!igySxnkP((Fe>!W#;kbiN=gX8#R-tala!{13+MR` z254wXQn$0aJN6=|K%Q>qro0hPT~QIf^yg>K#l$`gB|4JwCF5Qn`&^q^vwV9Tz8EGa z*YeQs;LEd~LsTrOtQ2=_dV2b`fy~gML}$&+%uG;F>Z(e$<)wtXdU{ff3b#y+jW0qJ&+Z~JD!7os z@0$*yu=|`+%GbsPeu^PTBm)A@iX00)wXuY%>SvwS0F~U~Xe{bP{RQzVtqSWnKBuP= zVI=b-A75^Z)3*S4^p#EInjSX3z!mWQqnXduJK;0|f)*7G4Na_KHM&WGF3@fkXmL=@ zsoB^Fon-CsnkCw~EUk$UIqU3$2KKEo)LFEPgpMmP2WyZaPL4$8A~+?RFvsYfb@V8Prv2TSqmwHjLH0V?&Q)Wynt zFn~NZFTZO4h-WuFT6ObA&2$v-HH$NQzWO)^B?jf>zDNpmmd6eh(H!@?seWDyDI%sY zj_b(v(7%S^mwd$kQ~}NbWu|8FH}q!cs0pHJ@_xC>IsZVjaH-6y9gQQiZXfaj*CqfMhlmD%IM_*$oGGYQ4h_D|$dh``qpS`J*#ofDi z>FDUz)~u^a^79$3$4lPawO=(PF?Ctp4O!$l0L=_g4JSV_4h=5#4Ngu@P^o0vY#S>g z)T9t!W0=O+5Q+#$T&$iawp9-9VZbKRfLQ{8#qfPMSz)6W z9TTJc#Nkr0C9w1Q_)UiwEyMpy-Q8$t6goQGD+fk*-oz$gMH zhIlVKd~7(i4{!M5_dm&j21y!i$Zv*2!XmQGLt#4C_->8|x6-M0!PWu?X*5=ly2Jj$ z)6=xqsX_=u%BtiaGI-PUOT^kt9Y5#^%RLKrfCusK+(ChdEVZDJAP`YeQT8i)X5_Pi z)W%=CKnWPXjhL{xX4_jk*~X$q<3*$)@bU4fOdm(A?Ci|$rf#bJVoAP*-njj_{fG1y zCi3g?k7#}9h!`msvb-M7AIdr5*9Xz;7)_PFObEX1CU&;U4Aqn3ocUH*DrCM`F$2F4 zzj?w#zr~zsY4*JMhbTb(fsn`5zt?7`m#gN zfjSq?tm%Z_w=?2nx+hQw>mG`aG?cxDDE2tsP-4afDQW4zT>(mI%wQ_NgKsg_Ete!x z+2Q#1%OlqvNY{x@ShzuUTRZF$=-gxQ%#?u@Il!n~zog%K>Ov7uhY*m%bQ6HyMcJ4O z6~x~@5EWVE^c190Z$@HMb&-djC0{?5qEAmxH;0No3N==<#@UL(Da+>>ny-`43NhqW zYTP|Md@$z7f2PKI2uQtsn0fG3B141D6!)V9`@)Dye+9xDjY_6RAY7cj4#PKLv69ie zteSm1H4_sq zz$Q^!TNY$jOGgJ`^;UsiLpUt`Bq6W+PvnwBl$4^YB6_VYEx#dj9mUJR6m$d;HxZ?% zfE)*3)O#96jhlwXNK{o-HGayC#11Z$0`v`UvNkLK_ytxFgn@S6uJbr{wqZ4yYxEV1P9Z=c*|{Gw657rAMR741}S_%vaS~Xb%hfIkm_LJ4FJw-7e%OxRM z<3rHlx4_4rDScsR`0(>HjrZ_;9T!Iu^B z_39Tm0duRSQ~l6`pqs`&6626S1?__bCMBkC|GE>%X*X}PRc9<0V^X`$``^PSAu%(b z$#ou^nf%TsaDA~)!sqy7DA9ozsb^lC?sp6BXe7nOwOeP^P^pS&NA!2Zd2!zl;65$uuP?DQ{E1 z8_6zACP6}+CjwU|i+L`J>`+r>y|}S66;ET7C#n2oxRZ!MH5nRG&gPouY7Hk31r;hG zq2;EM!}HCOe*dlnP6m=j{HFEY-CfnfMbKH1lpHCkgZ&C&Drx}%vJW?J{{{`>4iV9# zH^vIz+H+urnDtSS3Ap|%SQqGxK>2z%krmP>utPuDl1Gq}bC@R8P5rkW+2hwKVL;{^ zZAapuqh3!ksEer{c%ZNN$CU738I#k7Kwd7rTYuP>tVQbxBcrn6pC<`#rI@{!kH>`8k^I>o>m7VKqT#&Gj&~wJjeXD)63fK8hzTsM{f7S_i*qG8r+E@7n8@t{T4o^RJwI<9{j@BIl+D6HA3Z`xgK+XZtgLlW8R={^&I60MdKbWX? zVgP&DeBa*Ca=LnWN~<%uqq9@&&6~{eQE6p_l}f8B&ECn3feV4uEeF>f$I2|ee0_81E(n%4likC87_%2|ri+aN zn}hRA9BuwgPSy;f!<7gH%VhFr6dcK@JAt#DHo6gVU<$gr)`M(FuKjm7m;Vx+%82Yg zC|p)SQREC%)_IkcV@q{T7V(vmR@^UMyhtxe_Lm zbBkSebf0%p@H^u`03({`&Y~r(L?e)U@058uIdN)gk+b_j|M35@3@?6hmr9bJj?P!N z@Luf&$a1tYMs8Y$CB#HTpm*9yAoWx|@6#7Udohar8%3XqChe3}S({U0zkL2I71PY7 z*3r=pbCKI5+y65yw*PO#XqoJw?hd=8rjif?>09g`&ul^yxmylPycb(<2Y+Je34s?o zgR>Q)DfIMdhe5`@5b~3!@HfLy4paS=`QoO}75&3@tWNr#;aO|~u+<1RrJ^=*;qc zHB0(4rBBkQ02R!2 zt85gQdyE|AZwX1s#lulONkhYQw881_(b3VIJg>8ZU#V9IPc%xgVRM_$k74sfzT6~^ zx1XN*mq026G*B*6uM>lew0TnQWgpsn zZ{PP5@;ZY(`Zb&yVq#)QXFTiA(;aPcS(Y>Sy$%c?7^s^P5fodEj$ujgEm+`3B&>!vKuVx?Aqv%|&&3Dn{{>|6qQFxC zKWyQ*|1C3X>j0@tQLu`k&;4sAe9hBx&Im7Sfe|jU7-h=H6ZAL|_w=kCG=4({oiZRw z0qiHF{k61o^!&D#me%|-t%~HYfxX>byZF2?qasr(oJDc%b>B@X4bpRcHL9>j$a(-m zRyv41AP<4QAnNGI0pA`Y^V4NKYZ$*_gQY|aIG2V^0kK357a=Yf z$8H+lS^IC54tRp3t}caKih!G%%K?~bYp^c^JotWSkfelHqriP4zkCUVNZ?egO183L zqc4hFY^)s)QUEl!di>A<~ZSW;QX3mSaUot+?zDL&eC5 zDze%E!b6&3Fw2ZM=p|RulI+3QF&j zv~DyW;8_Mx8l0t;HHFSM*-J5u#Xv3o4RWi^u<4coL~X{(trArxdwYA^z&rc3UyJsM z)!qo*uXz0G@?1efgWhZ$X@%$K%Pxo)yn(<07v5bDfMXC$7^jbNJ3T!eD>aRf?IaWS z*8ZFqwg@9PCeu}v19OYV>+GlBTkTM}tR`?I&>3s2CbFE!HKdC=HlIoArKrYnZW8!J@LEdQN(TRH_LqqM=wTwAX`55)Iv=|f!S~ZZT z=ZF8${l`FGpM3B@B}Fk~HraUfpV$(%J$?Ar@o{NVSkx4PLvNu9{8-+pTBSf9pDTB4 znRK-c8`G#1Ts3TO1xqlKDZKREV1B${oGsK7hF7h?ZlE{3?yNa-(bvDeoD?akjn7p%@TxhXxd>$A^B&na3NTxkY|nXzCuA5eRb?%q@_g% zv{dpo9&~)b^xa?@O22wld>S9CtwGub*Y-{r{(HUav(b}P;p<>%vovgMd(MQjP(pDi z1W2Hav})PZ`Frftsm&D0`7QEvC353I{_%%OD(s&KEYkmls=-IM+0JLb^fFgS7?=a( zT77SGEmNz1i4QXaJks>@?Vxq4)89k)k;MXZSQ$uM8W|bsi=0Y%d0juoEtQptz_j;; zHuM4iq0+$7Dk*$!eexkh93Gd31DcNz*bB;o^EE{Giy~v77zqsx6@$ni#LDb;7hZ61 za5VPz;sFJgJH~*0)|$%)lF??^n8EYTW4o#?ZO1j} z4gtYJzie^*HMAR`9}y6F295AnXXmZ?`FTuC%t-#vuL@#f4Fqm8P*Hq?cpGGcL8=h( z^19qw_rsrpVS%nfCJ|1yPIO$PL(kCU`czd!pc!Q1BKu{j=nPCnDWE(7uZ2!;AeS1% zhVaSAo{4oh7sRMM1IHAI2^p{b4TybI!kt4=QBnH<;xxClEzSp0Iw#BE^4dvGAtEn~Os>MA? zydPp2)D}8o8C+z+vT1{V$g8Ud`COmRg0Du5^g@+7oFTGv0^veN6R)Fj(>J{xJh&cs z&D}bcwkROq7iXIeBSlt7h?f{W9rQD~{MUrH71tqzjg9>eyu7A0U&}QBGDs~PJP`7j zt}$>0{~b46PaBQ^mV2gCO$1-vUYB@1$vP{DIFt&K-5f?D=x-VA3%YMnp!B|+U9tv* z7%F@~<=qRb`0?YVvZ@;I;w3Da50Gwn-U*x-nUVzXu(O)#(+ci2IwRytm;3U<1dxEr zFi_aa+?+u0s;aEnWO&^X46YcukC(`rH?$WnKo>eq%s{mraTou)l3^gH(~>h;tO|}a zUOHp;j~|hA!Iu@w?f>^kHHrU@jsj9sQ^nu%J>klg%CuJpkfqztyZ2PuQdLr?j%^QV zdk2#%4n>K5I@+1lJJ>7ur|Pb+|Mkc6hxhLvNg2kExmYw`X(8)T(1Tlec#@C=om#OYj#y^J^YF;C!9K0{oPI4yo))6FtWyf40uT+@cR$*s|Hgu5 z)_XSh0Z$5AF&A7K{FK#?3IDVktd*6*z>+ou+BwJ5SyN+lu?LDA)-8HPbMvPlh|qSM z|K)$^7i58ZsMkOuS9GwD48~qnzb|Z=K*rI>KFgqrmYkiPX?B^f@Eg9K*1=(*V)9#c z%W#f@G^V(YPIAkeRQJF17neIeZGCBCvPW?+i`9_2htK)sENE-gvik3kuJ@}_-D<}_ zL&mQr;s`{;MjXIfk^2JU^NXRd*60fprRq` zB^fi&`CgQ*#Gr1s8Xs(-7um|HXq8?avh*#`JtE`c%9CN=v`QazZh zx!5l;AaM{lBYjWIa>QY^XMXQZ^pkS8_iFAKQg7o8P{5XYZe*0va;%6i6IiCRZ0-}Y)~sN2R?wY z2?K`=6y=WGfkAqb>ZusQ z?hc{o6{8rL#3K+^BIUBqi5g!A48lH`BH-(g-0zI+aJv9K3z9*>Rjk}s< zVXL)O0uTo-NV=S(QL_c$8AW8yY(KE6{e|W_ZCee42aA^3Rpz#fJ%lkY_EWE$nHxyz zxX?t~H(*C#D?3RRRFcpE*mH)cH8a-*`U`^+&~UkB)85-#@mKJU+6(#?D2m12m+rL} zdz~j|8-?AR?2OAiOpL<9vrKr8e`;>2`9)d<3?h?-BU&~FupXHDr)!5`Ymx070&Z+4 z>tIw**0=7cDY`w)4Aw_N;zy=t92MB77!0t!+~OEGs3??uJVmJ;bC)TIqr;n#ST~OC4G3cQjrY)B zxqxnh+~@^)_Vm&_B%QHR%S8FAofK15bjMc=M~Lz9aUa#(Vc|QXLTG(0L#A|@pjkR> zFht2E&AEAhQq8T?-?^QyS@u`L#AHPrfkB@sQ5dfWVOU_b6#pAf^a~86dGzSU)7Xxg zezJ5h2Z7j&zz~Lnggh(5wp?)Y9>`J2eM%l15k&#?o{FE}BVQte7jMo1aokDPrm=>S zXK8JH^?_!muu!9PMFw^yHevfe?ENS8?SovF800lG9`a@|2=u=0`SXW$`~_l>k7w#{ zW0y?m-By(CHT9m#Np%KrHPKjESuYXBsF67tB45Pmr?IGXbBB9AFV0)a$@OT|=?bGZ zI!oG2jw?vvp^_v-M=Md;-jzkDJ2;U}?|LhJAQ0j7)%{*wYeJT>Sd$f_8miHoKO&+5 zQvQRw+S*UxZh+tO6w#SXSjC0?HBzw}7>%_?oqO4z3Jh|3*oDbQz4WR~^OD220WBzs zKf0>}C-Kui-QnT%o-&d<+b7$hF@BL=F#}5j1Bx7+ zoWDj#)p{%`vWkoEz?4Bl*pgMe{(CsfH(7&<*N{(}h1_O|dV&dnRtVY#>_Wq_v9Y07>s9|cxGt|TKC}I9 zvC>OQYW*g{2PE;SnK}=h?@HV*#SjM$Kd*8RUmWR74lFK&lEa5cT`mU?&_d($nI==y7z|Y?sR=;N~!DaLZ}pCj>nq1ci-sH-K!ads~Rxhnwqyt#y>fl(yww;~9nJC45Y197e!@uU^QB J7l`V=|36un!Mgwe literal 0 HcmV?d00001 diff --git a/assets/sprites.png.import b/assets/sprites.png.import new file mode 100644 index 0000000..73a5193 --- /dev/null +++ b/assets/sprites.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://do2vfb2cj7fk" +path="res://.godot/imported/sprites.png-bb36f92a96c2b9ad48a8528dbf01963e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/sprites.png" +dest_files=["res://.godot/imported/sprites.png-bb36f92a96c2b9ad48a8528dbf01963e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/sprites.svg b/assets/sprites.svg new file mode 100644 index 0000000..048f98c --- /dev/null +++ b/assets/sprites.svg @@ -0,0 +1,451 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/sprites.svg.import b/assets/sprites.svg.import new file mode 100644 index 0000000..4f334bc --- /dev/null +++ b/assets/sprites.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ddkkkb6k0j8pl" +path="res://.godot/imported/sprites.svg-3de0a23bb576a309499d2855bd837d3b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/sprites.svg" +dest_files=["res://.godot/imported/sprites.svg-3de0a23bb576a309499d2855bd837d3b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/board/board.gd b/board/board.gd new file mode 100644 index 0000000..267fa49 --- /dev/null +++ b/board/board.gd @@ -0,0 +1,65 @@ +extends TileMap + +class_name Board + +var tile_by_name := {} +var layer_by_name := {} + +@export var state_layer: String = "States" +@export var board_layer: String = "Board" +@export var state_name: String = "Name" +@export var empty_state: String = "Empty" +var off_limits: String = "" +@export var active: bool = true + + +func _ready(): + print("Initializing board...") + _index_atlas_coordinates_by_name() + _index_layers_by_name() + $Highlight.size = tile_set.tile_size + print("Tiles: ", ", ".join(tile_by_name.keys())) + + +func get_state(grid_pos: Vector2) -> String: + var state_tile_data: TileData = self.get_cell_tile_data(layer_by_name[state_layer], grid_pos) + var board_tile_data: TileData = self.get_cell_tile_data(layer_by_name[board_layer], grid_pos) + if not board_tile_data: + return off_limits + if not state_tile_data or not state_tile_data.get_custom_data(state_name): + return empty_state + return state_tile_data.get_custom_data(state_name) + +func set_state(grid_pos: Vector2, state: String) -> bool: + if get_state(grid_pos) != empty_state: + return false + self.set_cell(layer_by_name[state_layer], grid_pos, tile_by_name[state]["source_id"], tile_by_name[state]["atlas_coords"]) + return true + +func global_to_map(global_pos: Vector2) -> Vector2: + return self.local_to_map(self.to_local(global_pos)) + +func gridpos_at_mouse() -> Vector2: + return global_to_map(get_viewport().get_mouse_position()) + +func reset() -> void: + for cell in get_used_cells(layer_by_name[state_layer]): + set_cell(layer_by_name[state_layer], cell, -1) + +func _index_atlas_coordinates_by_name(): + var tileset = self.tile_set + for source_index in range(tileset.get_source_count()): + var source_id = tileset.get_source_id(source_index) + var atlas:TileSetAtlasSource = tileset.get_source(source_id) + for tile_index in range(atlas.get_tiles_count()): + var atlas_coords = atlas.get_tile_id(tile_index) + var tile_data : TileData = atlas.get_tile_data(atlas_coords, 0) + if tile_data and tile_data.get_custom_data(state_name): + tile_by_name[tile_data.get_custom_data(state_name)] = { + "source_id": source_id, + "atlas_coords": atlas_coords + } + +func _index_layers_by_name(): + for i in range(get_layers_count()): + layer_by_name[get_layer_name(i)] = i diff --git a/board/board.tscn b/board/board.tscn new file mode 100644 index 0000000..4d13652 --- /dev/null +++ b/board/board.tscn @@ -0,0 +1,70 @@ +[gd_scene load_steps=6 format=3 uid="uid://dvlk7imglgpms"] + +[ext_resource type="Texture2D" uid="uid://do2vfb2cj7fk" path="res://assets/sprites.png" id="1_lagx3"] +[ext_resource type="Script" path="res://board/board.gd" id="2_vjb6q"] +[ext_resource type="Script" path="res://board/highlight.gd" id="3_m02pi"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_cta1l"] +resource_name = "sprites" +texture = ExtResource("1_lagx3") +texture_region_size = Vector2i(100, 100) +0:0/0 = 0 +0:0/0/custom_data_0 = "Blue1" +1:0/0 = 0 +1:0/0/custom_data_0 = "Blue2" +2:0/0 = 0 +2:0/0/custom_data_0 = "Red1" +3:0/0 = 0 +3:0/0/custom_data_0 = "Red2" +0:1/0 = 0 +0:1/0/custom_data_0 = "Circle" +1:1/0 = 0 +1:1/0/custom_data_0 = "Square" +2:1/0 = 0 +2:1/0/custom_data_0 = "Triangle" +3:1/0 = 0 +3:1/0/custom_data_0 = "Cross" +0:2/0 = 0 +0:2/0/custom_data_0 = "Circle2" +1:2/0 = 0 +1:2/0/custom_data_0 = "Square2" +2:2/0 = 0 +2:2/0/custom_data_0 = "Triangle2" +3:2/0 = 0 +3:2/0/custom_data_0 = "Cross2" +0:3/0 = 0 +0:3/0/custom_data_0 = "D1" +1:3/0 = 0 +1:3/0/custom_data_0 = "D2" +2:3/0 = 0 +2:3/0/custom_data_0 = "D3" +3:3/0 = 0 +3:3/0/custom_data_0 = "D4" +0:4/0 = 0 +0:4/0/custom_data_0 = "White" +1:4/0 = 0 +1:4/0/custom_data_0 = "D5" +2:4/0 = 0 +2:4/0/custom_data_0 = "D6" +3:4/0 = 0 +3:4/0/custom_data_0 = "Grey" + +[sub_resource type="TileSet" id="TileSet_exrha"] +tile_size = Vector2i(100, 100) +custom_data_layer_0/name = "Name" +custom_data_layer_0/type = 4 +sources/1 = SubResource("TileSetAtlasSource_cta1l") + +[node name="Board" type="TileMap"] +texture_filter = 1 +tile_set = SubResource("TileSet_exrha") +rendering_quadrant_size = 100 +format = 2 +layer_0/name = "Board" +layer_0/tile_data = PackedInt32Array(65537, 1, 0, 131073, 1, 0, 131074, 1, 0, 0, 1, 0, 65536, 1, 0, 131072, 1, 0, 1, 1, 0, 2, 1, 0, 65538, 1, 0) +layer_1/name = "States" +layer_1/tile_data = PackedInt32Array() +script = ExtResource("2_vjb6q") + +[node name="Highlight" type="Node2D" parent="."] +script = ExtResource("3_m02pi") diff --git a/board/highlight.gd b/board/highlight.gd new file mode 100644 index 0000000..9dea4f6 --- /dev/null +++ b/board/highlight.gd @@ -0,0 +1,22 @@ +extends Node2D + +@export var size := Vector2(16,16): + set(value): + size = value + queue_redraw() + +@onready var board := get_parent() as Board + + +func _draw(): + draw_rect(Rect2(0,0,size.x,size.y), Color(1,0,0,0.7), false, 2) + + +func _process(_delta): + var grid_pos = board.global_to_map(get_viewport().get_mouse_position()) + var state = board.get_state(grid_pos) + if state == board.empty_state and board.active: + position = board.map_to_local(grid_pos) - size / 2 + show() + else: + hide() diff --git a/game.gd b/game.gd new file mode 100644 index 0000000..73e2190 --- /dev/null +++ b/game.gd @@ -0,0 +1,65 @@ +extends Node2D + +var current_player: int = 0 +var player_states := ["Circle", "Cross"] +var won := "" + +@onready var board := $Board as Board +@onready var nextPlayer := $GUI/NextPlayer as Sprite2D +@onready var wonPlayer := $GUI/WonPlayer as Sprite2D + +# Called when the node enters the scene tree for the first time. +func _ready(): + current_player = 0 + board.reset() + won = "" + wonPlayer.hide() + nextPlayer.region_rect.position.x = current_player * 300 + nextPlayer.show() + board.active = true + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(_delta): + if won == "": + if Input.is_action_just_pressed("Click"): + var grid_pos = board.gridpos_at_mouse() + if board.get_state(grid_pos) == board.empty_state: + if board.set_state(grid_pos, player_states[current_player]): + won = _check_win() + if won=="": + current_player = 1 - current_player + nextPlayer.region_rect.position.x = current_player * 300 + else: + print("Winner: ", won) + wonPlayer.region_rect.position.x = player_states.find(won) * 300 + wonPlayer.show() + nextPlayer.hide() + board.active = false + +func _on_restart_button_pressed(): + _ready() + + +var _checks = [ + [Vector2i(-1,0), Vector2i(1,0)], + [Vector2i(0,-1), Vector2i(0,1)], + [Vector2i(-1,-1), Vector2i(1,1)], + [Vector2i(-1,1), Vector2i(1,-1)], +] + +func _check_win() -> String: + for cell in board.get_used_cells(board.layer_by_name[board.state_layer]): + var state = board.get_state(cell) + for check in _checks: + var same = true + for neighbour in check: + if board.get_state(cell + neighbour) != state: + same = false + continue + if same: + return state + return "" + + + diff --git a/game.tscn b/game.tscn new file mode 100644 index 0000000..21073b3 --- /dev/null +++ b/game.tscn @@ -0,0 +1,64 @@ +[gd_scene load_steps=4 format=3 uid="uid://dmahmxghpm47w"] + +[ext_resource type="Script" path="res://game.gd" id="1_g1ie7"] +[ext_resource type="PackedScene" uid="uid://dvlk7imglgpms" path="res://board/board.tscn" id="1_ym80r"] +[ext_resource type="Texture2D" uid="uid://do2vfb2cj7fk" path="res://assets/sprites.png" id="3_0333r"] + +[node name="Game" type="Node2D"] +script = ExtResource("1_g1ie7") + +[node name="Board" parent="." instance=ExtResource("1_ym80r")] +position = Vector2(420, 222) + +[node name="GUI" type="Node2D" parent="."] + +[node name="Title" type="Label" parent="GUI"] +offset_left = 28.0 +offset_top = 31.0 +offset_right = 718.0 +offset_bottom = 103.0 +theme_override_font_sizes/font_size = 32 +text = "Tic Tac Toe Rapid Prototyper" + +[node name="NextPlayer" type="Sprite2D" parent="GUI"] +position = Vector2(690, 59) +scale = Vector2(0.5, 0.5) +texture = ExtResource("3_0333r") +region_enabled = true +region_rect = Rect2(0, 100, 100, 100) + +[node name="NextPlayerLabel" type="Label" parent="GUI"] +offset_left = 602.0 +offset_top = 47.0 +offset_right = 644.0 +offset_bottom = 73.0 +size_flags_horizontal = 4 +text = "Next:" +metadata/_edit_use_anchors_ = true + +[node name="WonPlayer" type="Sprite2D" parent="GUI"] +visible = false +position = Vector2(891, 58) +scale = Vector2(0.5, 0.5) +texture = ExtResource("3_0333r") +region_enabled = true +region_rect = Rect2(0, 100, 100, 100) + +[node name="WonPlayerLabel" type="Label" parent="GUI"] +offset_left = 807.0 +offset_top = 47.0 +offset_right = 849.0 +offset_bottom = 73.0 +size_flags_horizontal = 4 +text = "Won:" +metadata/_edit_use_anchors_ = true + +[node name="RestartButton" type="Button" parent="GUI"] +offset_left = 983.0 +offset_top = 44.0 +offset_right = 1086.0 +offset_bottom = 75.0 +text = "Restart" +metadata/_edit_use_anchors_ = true + +[connection signal="pressed" from="GUI/RestartButton" to="." method="_on_restart_button_pressed"] diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..afd6a84 --- /dev/null +++ b/icon.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..16de692 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cqc52ufiirdtv" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..c7a99ff --- /dev/null +++ b/project.godot @@ -0,0 +1,31 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Tic Tac Toe" +run/main_scene="res://game.tscn" +config/features=PackedStringArray("4.2", "GL Compatibility") +config/icon="res://icon.svg" + +[input] + +Click={ +"deadzone": 0.5, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null) +] +} + +[rendering] + +textures/canvas_textures/default_texture_filter=0 +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility" +environment/defaults/default_clear_color=Color(0.203922, 0.203922, 0.203922, 1)