From f0e7533e659538c67a586f851ce91742418d22a6 Mon Sep 17 00:00:00 2001 From: Alexander Zhirov Date: Mon, 1 May 2023 01:22:58 +0300 Subject: [PATCH] v1.0.0 --- .gitignore | 3 + README.md | 50 +++++++++ data/o.png | Bin 0 -> 37953 bytes data/x.png | Bin 0 -> 10416 bytes game/CMakeLists.txt | 22 ++++ game/ai.cpp | 118 ++++++++++++++++++++ game/ai.hpp | 20 ++++ game/main.cpp | 211 ++++++++++++++++++++++++++++++++++++ game/map.cpp | 256 ++++++++++++++++++++++++++++++++++++++++++++ game/map.hpp | 53 +++++++++ game/parse_args.cpp | 53 +++++++++ game/parse_args.hpp | 38 +++++++ game/version.cpp | 3 + game/version.hpp | 8 ++ images/game.png | Bin 0 -> 34177 bytes 15 files changed, 835 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 data/o.png create mode 100644 data/x.png create mode 100644 game/CMakeLists.txt create mode 100644 game/ai.cpp create mode 100644 game/ai.hpp create mode 100644 game/main.cpp create mode 100644 game/map.cpp create mode 100644 game/map.hpp create mode 100644 game/parse_args.cpp create mode 100644 game/parse_args.hpp create mode 100644 game/version.cpp create mode 100644 game/version.hpp create mode 100644 images/game.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dfb20d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vscode +build +tictactoe diff --git a/README.md b/README.md new file mode 100644 index 0000000..fc47743 --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# TicTacToe + +Крестики-нолики + +![game](images/game.png) + +```sh +~ $ ./tictactoe --help +Использование: tictactoe [option] [arguments] ... + + -h, --help Получить информацию об использовании + -s, --size Размер сетки N*N + -w, --width Ширина/высота игрового окна + -m, --margin Размер внутреннего отступа от границы окна до игрового поля + -v, --version Версия TicTacToe +``` + +## Сборка + +```sh +mkdir build +cd build +cmake -B . -S ../game +make +``` + +Основные данные, необходимые для запуска игры, находятся в каталоге [data](data/). + +### Для Windows + +#### Ключи для сборки + +`-lallegro_dialog-static -lallegro_image-static -lallegro_primitives-static -lallegro-static -ljpeg -lpng16 -lwebp -lwinmm -lopengl32 -lcomdlg32 -lgdi32 -lole32 -lshlwapi -lz -mwindows` + +#### Статическая сборка + +`-static` + +#### Дополнительные библиотеки для сборки + +- `jpeg` +- `png16` +- `webp` +- `winmm` +- `opengl32` +- `comdlg32` +- `gdi32` +- `ole32` +- `shlwapi` +- `z` diff --git a/data/o.png b/data/o.png new file mode 100644 index 0000000000000000000000000000000000000000..761cd674256b1c19a6c77e79caca657eb2913047 GIT binary patch literal 37953 zcmc$FWmlX{lr2t>;O;aKBv^0_5Zs~BKyVEn+%>qn6EwI5cXxMpcXzuF@16M#!&-cx zS5b9j?_*URtRN@;5s?590s`Wrq=X0<0s^Yw{r3YL@JUns#~%<7kiUNl3oA$p3zON{ zS{whgFoJ-fiS~%*m*^5C>d{dWjSdkm4&pK_ki!uXC8|LbEkHB#S0$EVeDVGCQ8FYn zXI;bQ+@SJseY2$4ubAwEr+0k=H*KRt@S8LugFYYEXe_*kICzGUw;shV_5#tQ5vP?D9n9I7pTy)n7iR5L{sWQl7CN#AP8V zPOIZG-=Q;KjcsF&n^H??kh8->pw~yh5TPl^{>@_1Z8{@a8I}D~AL-S9BfSmoSAnAF zgQ6QJYw|o7xL+xa|C4qe^X*sWRnM=lV%}w1nTmF4X9j&g(;zxb)}^c;K0D~{#$Ibk zhmt^gEVcJINGsiX4-xC04@Ai>#QU=OyOTHzP+QdSgx2MQaR5Vtzd0B{=wzP+fry|A^VrID3Ags`oVp1qMFnbS{u zQ!;T$Sp_v86kG@hG6+c#A!X;q;}xf*bcgh}x4oxU`BbI9`FA8B8oXRXu%JDzgVyK! zm70Jcbv3OyU!-K1in7KKbG>*N)j8kSX)RnQOKG0WbCo!z07}7c9}Z#%uDN$S-(Hh4 zqhrL3chgwQ`y6&QS-AUHuUZB6T6OOBUa`>7|IdG-L-go;f<83wXVh9`G2xxzr0SmL z5ci_p(_Cdj-ie_WK#%!S*?_Hbp{P%z?D>q&RJ-Gq@a{8+1dVGqM!edVS{nKbnRAL=PJD;UROCh5OTinC56Lj^O6f|)%jt2YcOTIj z!QJHBl9HO!8nlVVAB}(@n#_RzTCD_RM$nspcrz9ur?XZtf@e=)jlJ*pQT-JU?n8WNio*9Ixr&`^gQxj@N z5icWxr68JH^uu0F9z=&T6=1a7&y|6cc3>rhBw_+R<)f%et74uM`+3#c25lb2@lS)b z?R?0Bo?RpH8H#>o89Q$7RZ+sbN)n>Z8@;z8!I|VB)6SNKFgVuKgVVia*0FHOh&^Pb zNYkC)s+=W5X??_N7D6_4O>dA~+w(#cJa`m5*KG_p1b1{G!~zh@GmfQ&bRf>3WAs?& z)DK^0HY@@c+PVCQT={guL77W>ksTaeXLiTrb|h8aeITjGGEIeYYgY9)5rd}=+j5ULCA;I(Y3zRnR(rwf<%Z?Ao8Cz$25il zA~gJ1p{uHVT-xd3dcz_(`Ws!vcalW~QEece^(so+p-(+^VBV~^IyGQb(P5R*qqj7h zYx%`=uRd5H%yYLB>GF;LHl7-)+7gE{C#*o4hkH(-Srpv9E7i>YQu3}DNc9E?uHhzNeX;9 zvk3xpORj@B)K3}M7(Fl_hB~iLsg*@{HfdQ~=B@T{HBNC5R8f#}DuAoRbCJsjxpUWb z|8|)5;1dCdjHrK2;XHH|r@t(;1P_`L&UD&#Hzx=X$=Mr0KErkwA1=m}?YKgOAhVx=E;{Q>LF8sd(zA>*%S9VjZ?iu5LIp5dbgDm7gu}^+V z$FbQ;fvu@4rhHcxY>Z=lsG%F(wie!IsQb%3Iy!eQoISw9amDwTNd@KIfcW~M9QJw0 z<>BjL?Z;B*i7XWotwDmg#&3k8o=OmRJoaKFx0XNRW<@@~ujWqIc2*P5R;Wh6WA#ZS zXio9j$z;n=-ag>2z`bYc^Zfmk(C{dteVD=!p5Y5TtZft| zOwX^ldmOte1c30-=#~S$rzKm`?K%iQAY@E*AwAIXc|6)t*41?D2yd@y81OCY-nVA? z*L?1U%7Ke{!Kr&Y*KX(isrsy?-zL;sxZQa9jhZI@m49NcZOg=qTh%~C6yR;q93Zp_ z=B1;bwD*Nzcxyh$=%AmYxP*Fh=m>Y`6fF5p?xH}q3TLIgp^nv&KcDz|l<}fN6rdV? zo_@VeHYO}PF^|0BDhgs3D&VeEGMxlZuZhjOAsa)|dQgkf-Kk>sLq`%U8$PV2&i>$Q zlr}+qbLN8J3omSw41dC&mlY97% za+pJaFz8u?#~fW{I!iGwB0FfnKKPEIoc5oX%{t1Uy;wCsQii#Q@SY!PiSCGxaCWOR ziU7Fvqrp$fribSx$s%99l84PfNvep7ctef8#ckHI&_9eq*DOGzrWH!6yo1iqaP@_R zjrf#c%Xkmwo_F~H$?rEE1xS8ZfyKb%w?_x)ZKUJzSPoX@-6vDKow6j|2N~-XAMV=t z{{{S%ibs#eRIr&3T4;kEZEQ9oX|VJ0{ZEFf4}Zy9Fo$yz@n6k!A)^$HM7FW6q1zmf z;geRhDO+TPQ~)b)=hD|V<#Vgjx1b!?tTQPvV@FTrqTVx{chOXz)f%z7UNZqA+FDeh zVCip>9((0%S#QcWeGLvuvubJgi0~**`lor8_UAxB@*RyC`WFEaYPz@D>kopZtpXqx zm`3llt=Am~B=fdH+jky9*i1Z*_9(WCzvE9=XN?dYUkb$@y6q$AYpt>3sh2XwyM?oG zN{`ZvvTA(WWIB{Z2B`}c378&cj&S!*)!xrB{H8*gaFW_>Gt+0c2j@(1Vl|Rdm1#34gaWDiRHkFf)F5d?l41RRSq}J zccfl;BAi2BGSCcx(nn9fCF&ezjk?#)#TL3?K&H6l(9?YhQOQww&44SjYWBjQFl3jo zH`}^$D*cHRoeZ7-Q4e3ey3im&^wu?u6IyBdRMZe=@#AyTR$ZBO;ml*aU6gzvs^`w+gmg^s0` zh+(_l`rhtsvc353+}jH{^#8j>M4H1sw|#ZJ7vASUP(}qE-6aI0Vk)iN*UR#xbCDzd zowjftNS<0|B?EWv#PwJOilQPS5yhnHI*9sb3(k5Y#___y8o3-QLLQwxV;u-m|5_Ss zbZ&fw~W60M}CqCs*1Z)1}WPQ(^6aTvwO+5secp+S6v=oMuG!)>QPd2?Gx1gK|= zh+}>1%5b0PqgWIW)c++lM$+Dhor9qU|m zds_oW1Ns~7iwR-IkD-A2Q{S5_KcC=e>0AAQ+AVqkDx5~G0FUvDrMa4Ip8p`gooys6 zPT&41`2uDAL{JXU8lT0Zy=}|=lkHlqo}#596~IgU2_SLEY&7HDla2ct?}r8|x6 zcXrIR1kyxl#*!!kfj~w%5G7sDJi1+tur-M9UY$Alx5PKkn{|Y^PU^j2mIEvq@F8vw zH*hp+J8v11B?m~I$5UgmPeKec(KqbEpimB+71v_5ej5XSwp7ntrMZI!t6WG2xKe9< z_Yd?a>}F9=kVH?AH~jF4hdHjXSD|hHK_>nLOY^cH6(MiA&D9wcE=^iUkg{O{*VIT` zi=ptIzLfL3 zQW)lIHc=r@!5VVl7NT zRI7xPF=kF65Jdp)ucn1GdAwG;5fH;MQy;Dpf+4fk^df=%h{sH*e)8f`m&hSs=+Bte zp#FaSFJX0%tjos)>sB)&5ld#uQ26vF&r?n*RZ4p;+%iUqeS|6IvRksEB4UjUC~wXc zj88f6qt)5(O0eYazD(WW8vY%2wWim6J9M@bmWj<05!nuMGsudYoE2#eilnkRAgK7(Z?EYx6~YG`V`C!L=Cu+G;`}@EOXOm z!IAp`YblOM%MVIF|67WW<)hQM5ID=!|0?(HQ|=bVCWa*Lx}#>psRF`D%)g9M9O1Gs z1Gy=QK|w_FFw5|-8x9OL0&4I3%7t>5a^{14+a%e-%tmBVzR*sv@qE}sz!nn`k&A=o z9e!Dyh}>(v0U$M`5DZn6*7$u$ZBA2nuKOr;EjpcpI^EQ?_gm?YPashKws(`(TI`_v z&8i(kxh)XG(y9wfbxI>OFX4k9|5DXdWe|3o5mt~X=mFMP*yq?Xs2qQLNZgwPm<*7e z+TwJkZj^>9Cw$;>_lv{TF6Q5=6l5x3ojS6qEMGtfzMkpX8KKVXFC?&ks+{i|QzkG= zPQxD10_Y+D@)^rKpo~7vG7O)pFaQzh)wEZjObTsldHh)#NBV2I@h02Q2p=YEI43rG zH2L~%TSS}3OXspGwlJj1?}bv%Io?~d!1zjKSAEw>dzM%egF|j$Vb*ZLXbViU`HS!J zN>Kp7d0p1T@)X0~Cg!q`ne9W?SQ9X-Cn8R0F&7BLLd3Dv?6uOl{8oSkfTwfVyoI5E z%HfkuX@^daokQX9_V?Ug8D%bD+l|_lipYr7_=hr_Yc(K9=mYlZ&33MC9}$3UCexn7 zGtM6dE%3>0D2s>;Qq}XJl+5cSYQ3~4t11K4R$j=6b|nwob9|E*T-8DFBHWNny70fB z^f*(e3P7Gxz18oySqZ+Lt3HYYxN6R&}&`BM2YIAtyFGEs|S42IO za9psgOddOUtOW|%PUqT)#Re11a_e5Gl_ntci0(6Aq4r_+sI+m_De@Nr;b5S*yuOfQ z>*5dO9wbij0N88RrTd7WW11eIefFkIU2+>m295g@P^p@2z6+h*pti=tC>1x$H4OJ* zQ<7kh38cN0xe4r@CzjGm7Q`6Y6Z+nth%pG|dDF$~@7Cx<`U`OhbXr4yg8n@~Krs4U zqPbQZ76Uz6Dw6$02(9HGYsS+;%br>KwA5dp01B!!MxFTHu$F8`xNS&K_%CA|G^47*YssBY}hsKK_R#6miC#`11=^wn?7=eH(!;s-z{CDfI z#NaazrODGTjyI_96of&4Qo)d`>h{|BTH!z|h$bJE!50g#;C&?sn!nI#>o&pxsj5wd zdoa;ep_naA0}ssVh>=YD-vV(wo3Fd1I?a{lA%j`obbf}9f!1cj&h9G{8(6F{vIhMl zJfUQNZRkLt%iJheTAPzi*_FjoF(44u;j6tJ?K8*U)7o%|f1H!pCMZaCDl2@5Ii>}y!kGH$2{Ae1D-tNn!l>rZM&)9@`kT`El z^fAiJM5O{)=$)X83kvEVV6lyUIP4+hWmNcrrLaS3C?WUdn3ap^>tj7^FlF*Ul|*=k zH!M#YVAA{~FtztewW-n^-^@3_4(-)mKlm56xf z+<+YT-BoU_h|RnEHX--}iUyMMDMBTm{8W)J0V7y`TaWk8E=_Z4>r+O7Rd$I1fNllj zHTB0|iA-@x&~+18e}RYDUkM#OdWs%_-jZke#_B&ISehJWZs5+GZMi<0v*c3CQBQD5 z#byIOfRj(}SYuk4e_(lE=MC()dUme2K1RX-Q^|F3p(GKW{u?$65y&ts^`E#)>PS3gve%Zm5@u42$E1eMyJ~GuF=`slGHMBa!D!+%len zkRg2oGO5zdzv4pP#diOfq!sz#0u;Hbo?yXJD|SWqj8rca=TW88IeIdFJs$S0{30N_ zgSxCk^hi-hdf#)5in-WP(NE)Lh#&n^VeoPhB=U}nKV;0)-|NHB9z~JQr-KT>$tJ2t zBRSCbnH|#3lN$LD!Hu76r}p$Ne!m|K{)&7Y(v#X)rc8^aP&|0NQ7d$~Q0|85sT@1=5AoQqud` z<&89#d6+zg#Rlv&T<)Ps_4@6?NCl2mL4 zORRIPT;wevADuXq^V+5?@jIKQLs;z|ikJv$&wpCC`9=+I<5Lof3ug)g<^$^y{Cb+~ zyg3Q~Z?mKo*DFGX_4KjpGe9nYNX2oL3Spwmo;b4}n2`deFu(%GK~ zLoU!ez_(()=>SCcbkTo`so8qxTzY1$ps?0QiXjdq4HEIB{J zkn8$FNR5NX=QXAGO?}K^rqBjh)XCa6l#_k17vfP*Ex* zF5zoJ4`I`FfexgD^RPy%Ygoq`^p#7%P7^)yz=$)79#63^;6mj#yz|$7sWC-B?ZD-< z*;J*ZHwGJgw69Y~ld;AzrqeNCKspKu;q?v^pbMNXF@>GZ!gjGK!zYD}8M{t#wuD~z zX;&Rz2t>sGs{XXP0%XJjVdL3L6@&J-f%IJy*Kkk^F^hd)l;9@&x9zA+`2*~*wtI$T~)`z$RuO4*(D*la)T; z>P$UmwFu0|n)g?Uc`qf^+{c>ub6N`Qbl4xM<}#u8$RLst#n2(bcS1?vsS63IcGu@jwBMle$3oj_9e~Uw>>13BAU?1c<`~Qv%Td zV`y8M8Cc}9cFhP}yLGJxpADvqX`qp9V4w)5eYOXJ*>zGw>qzaD+M6ab}s=>s?q z;!F)q!b_Q7KT;K7vU&E%2KS%v__0RZG&hb&*msFVSXqL1jogb{z;rwy0r zDTeo&%jV_fC~2#>MUUSqkjcX!S{ugZ9OJCBhOPqiGTbsX+vAH=FVhyqEDXXrbgmSv ztP2F|penXT(yWOWwxKd@zhQ}l_W0U|S6cW9(oAe$JGQO?u0DnN+KY29UEIy7@yS(PKhZ(dm z%KQaliXgpGadvQAVL@A>z7uuNDWepBI@XhG(B+GBB{Q0cv}m((r*xhV$(Y{AD0&>I zS(#5YgdaoKKphX|x}sMf=7Lg>PL@8MYIr*+&+a!n!R{yU-KO=Xjf_f(j?kt_z}pxHM@oV6>yV5`trCB!cPNrq?tDLmYGi1{r6)X?nF8X9XG)l z>z$Zh3z8c)OQh6B-}!|2)a0}Euz~}O^^-L$2k2Sck)2htbOj(iGi^CFg1 zHpU}%CL&clKKbNj!}J30IOVl3Xe5x$wDj38y1<-lfiJ@FO1;zGDsxU{NGBM%7OHni zI(R)He9u_y`Zq2ArdOjm`By?`R59Yd`rGel3aolXorV3n{*#mK^p9Y9&WBnb1&w_^ zzJDZhs7fbSCzjhwOZ)EokekWNg6ft8!bt-!zpx?wRidXDBd%5}*5;r!#jid7Eq4A% z^*EWUvU2=rOuEg*YuRIW!#1MBcTOWCA}7y5hZBVO68GpjPGwkm^{IS06` zp-)VZ!fN7$o29W7kl3&x>}e$#=`0`3l}eI8FE^)DToY+-4R)?22|dV4@0avU_N*+)CNc@RzduYoXbs}1T zimWr@*=b#en1;kfi|A?VW6MT2UXlnt$%Az!;cL$4BWQz=yA#k_ZKQf_g0mLpK(8X@ zp}5{fy&0vgzRq81Mvb)xTyvZq&%fS0P$Lbu3DOji+P^^MvhqoCNuvd(pg!JGG4uy$ zxBaEMQ1?D^sg{+#RkhdaU~j(h6ZOCb(oR#SI%wn8xfPTY7u<2qbDl9j?1Ru@F@nv`8br$8^c(^~ivN*AY}Wv?l;E74K! z!I$Q_^NjwkS7w?Ud#CNo$d{`fznD1c*0)+RrKMy#F+HAYFa|xb9y=a;K)w%~9K}6R z->$9?}JJ_-T%^IDoa>gg*lpR) z@a>i*RgEu% zM=`wJFOwlOk|c>(1RAq=YJ^?DPYO@ck`l8QOn18}#mp8tKt*ZTYT=j|ms!CdqfRKD zngd3Q9c*5vq*_a)lxv>n_Vfj$dbeEn{Bifcu;M)ly1RsTaW=HWhO;d{C#vp9x{4h! z2<Xeqf0pSC2LOdR?~MRImImK%=(T4({1bUK2u;fYxXVbSBfWk+J8(q&c{|L zULKxR`QrBm!^p2qO#h*Pck2O&6}|SGSdi^G82+P-#XYHpZm@-JZyyT0fILnPj zJ(D^`jbj$KAv2*XIh;ZjAKVEP*rB-@J^whOVPUo6zcf8b0_XHbr#d9K%8TNuXSPgF$&MMIPBpppwdXuz-gSpPaM-mieP}hn zd3L@US2dbn3yahj`^g(=TW?Pbr->N>Ig)Hdum`oakN7n&Uz8KI!x z&LgQL%eYe+Z14#~+Jya8r`v@dQ6JY*UEwMU$}B$l{&mSWW$`qAozzfwAkjc7oJ8Jg zH~El19^L($y_5$(z^uuaeO1K3B{|Bt-7k$RFCFa;_3{$?D z*D3wZ4ap;21CYT|d}n=tCqIo)PH=^&%c`~%vczB$HPH^6tTyd#9-fL4|604mA5!~+ zndF6<^s9LeE|{_b|EeIFS*sZ(24ny=n= z0Y&B4{m9Q2ml%U`yJPV19`X0tqU_EhSjd6hN?^Vq)?Dku{5=QyGez~3ci{3#{1L9v znVMi}f=%P*8rTQ74dO=!!tifd_DCwuqlRwVcU>J{L#42IQQv;?Pl4B1zm76N!uyoA zyGGu(iZ9=d_m$BUg%~-bJol;izz$b=4|!9y6J;hNYT%OvQ5WEI`cEezbej`aDqyM^ zbr0~mU+8Mx3ZtfdZ)qu@FcXwt?+Nuz%;-NOri`IX=|vmbzE+7s&zoM7ed}nsK3U+d zuu#6PuDWXSwuE!yevR#Se-Zw?x>$A?Ul;h*Q50qwby>imXRgX;399RLaO0aUhZqXe zSwv_-RKD9D$7LWYFtB1N+^zi0BR|w1!|eQXYva@!s;zWZ$F}=AbJRj>#`N51okdPJ z!2I7&wi>(9i84hNedj`vjdLMaCjqH9AO5&Uw?CH{x}3dYX>T7vI(Y`)wh{nGFbR&JMq5aJX1_Y;|Y>u;1Po_`Npu#{MsZ{B|y3Hzp-PAKH-N4R#bd`Qcff)0mvA(^>Ak!@Xq7Uu~Es(qr)m z>yU;Q*Q>$2LxxfeaVusLD3X+=#>ZOF*R=|q^F-b>1Ec0qGv)rNI&0jXG86#I3anO$ zdK!C{_~@H(UNg%R4ut2aMZ=a98#I8z{G;co-id$470bwH3ci;XYr~fWY%vX5>xB((CvO{P6z0j~4p#jX zIWveHZ?QwlTg}KZ*>{2#fU;u0C%%7W_?$?a6roV1sTS^Nz&J|iGvxEH#f}r{1DHLR zT84uEC!7#p7BtPwDPtOExn|N*wzr0!aqTK!M}dx*`sPSU?#P!_NM7#5pabL`L z&p8r8y7F(csHG^1XzUo9lf9|04APB|`rOd09_9kZVax@xaAM10JU8Wq$l{ns%Y9+uL7%`#k7PByloAg^{wj(T=7*LAl4e@3ZJlb<)mMGerfGgcC2f;hiX5!s zsByT7!+UjM)%H!?Ls1#%otPf=B+=u@M^Fa)A3wpVm0Awes*G4Gmj;^kioY=s_J%s~ z4)bPxgCUpQV|lFAv}mEOTlJ3h6$(+YEl zvsO+@y>fU#Tjc6W-FIsVMTIAi(9Ad8MQG#Ba!5eH zG}{C}EYsdNPSo917MRT4_J#0k)p0M^Tkc@mGg zmwX?L4o~X~WkP?N$y~|aT&@WvDANCDuHyOG{GXN=v<&ye9Q7fA1X~z*Dq(O8a75M> zb4ycg-QBVK{@Z6qru)+Gr#e-B+1_G(rWXvS-H457?klJ^u@JwsAzmEE}*9En06QI8)~ zfGq7X;^yXgzW!0oOd5>uXjk^2Q5v`*O|%ME&CL9@2D!}pwr?drW@M{ET?Ss7ZspVg z=^y5o;`@bXl{-uNaTlujZA=djJ~hBi)hX4=&O8nwflG}*3Vh9bny{?<>U=`TQA`77 ze0KuMdQ+8JNoyZP8_|}Ot_HWe^<^Lm+Rjznr3X-f_vrs3W-c@|NVGV1U(vXC%zFc= z+yr@PA6X()pxR;ZcL5PpH)Vttn?z1}CEbh0!HNE)`K+!KF&|u3TcZA`FuwN&(+qjf z3Fp{>@7QyS(n#tORd#}k5s%2D03H|~DJu=p$xVqE1cpMdkXx~7>$=a(--WjtLW7N} zOAD3FI2`EdJOtKi+iuF#Mm+_wqoux7IXF<=^vukHx5h>a4bnIz7=Pq__QX9&2Ben6;OCj@- z-nc$qJr{a^3b%WpTAE1nURrsBAD920PS#~XOmAsxj4Ke z-3*o2#S}kwOTC*4%yjZ+tBB;KCT~o+)Zo90z|?y&@jIO&WPUu&^Yx>@gBD$&a$}&H zcCwfA4t5=Hb^QfvnBE_sG=b&btf$l5`4z}A*q6Lb$|shCVr+%LH9{YJ>Sr@nGcj2* z3Cfw@d7bJ^qam3J&%=*B_zq_hDlVowlYwdTM$YFyb?2>HFNp)W+~0u44}~^Ysz-~S z`AI;U!x5-d0|$=H)lBf`RnLCI$M#k^ykAi(n6FBT9&lWZeFFQBl{VC8$?rrJAs2pL zovw7)(Jbq2fN~Dn__4f}?k-N4uIVNJYC}jO$|DGt?B!~fgLJ4LC52>S<%-4Bif#{k zp93gs$g0sv!uOhN1$R<={<6yHEL3hOozuGDk9?kKCq~}0RX)8YU6h}zeWI-0otqNZ(87vmD$?Et4xT&5mw*qEtwvg~#bg{g3piry<<6 zgo&cJ_9*dXwB(#1tQU>?|M@FGTlHX5$kQwN-8*2oi(&jP zg@`IXdnt^G3d3K1*{y6x1qJ_SZApERNAa06=e)SLcp!Uj?MV(0E3vNYb?C%r`PGZO zd4BKKc+$fCfD7Z<&lH>PluW`gDqn;;v2wS=GT5 zRC=nL9x|O~U;t{^o^X^Oyj+M~5giTzi`iZQ5_E<1Sc@z}+iap*YL zCI^MwWutcOuWuyf1$m)#EI<*~;(}vC`z}%x(8ODk1(}~H(YkRqiqDnmq)mXHLGoLu zpA&0fVK^a3;cii-#lk_4D93;8hR%W!2}l@?M!ffoA9?nGIruHAWi1-lli@1n&@4u| z<@h!YtmHRM;hu#+xaFloNQm9E;?PE{LNkXVFO zQ;ogx3b!4B$l069)~CE5;Ve0M zMjrB_hHW8;1rN?YV+g(6z;mx;lo`d;GA1)@dB^n===h}k3aJa3Wgk+V3Hs6UjIF(O*CZ9O4hY`p?)hSOcn^@$r16OIFOZWsog z3BgxQ$eU{w`-Op4D%DsL^)#Jacl%9u+v}|bodPV7-`NGW+6_#G7vU&s08eg$YtzBP z&4-6Bc=AbRJ6cqf?}1mqyEZA>%&*b_7)Rjc%6J#UM5avXag@yCY!zWzPtn)zS9emd zs92Oa%H7=p#V6J_gx6v<_PIpHMlG@2s_iP{(6^X~Nprj(kC9wHLc0xQhYWl06+kwlEEycXFGKn-Jx$jJz zDz}ghK$jzh-@I+O27oZ=;G#7ylApw8W-&qI1du`|M5vXNxUuhFL z+_iL+Stjp==w&<6<%}x__!*~|%{09j1Yr@SOfR}=^8d&ZoFTOndi@3CQ z2><4iE+_(Qq^G~B!LLMG%$9iKTj57iGb#x3CzB3m*KMZR7s<1QPaJ#Tucm(H(yd^j zF+?dK0PURl#3$}OJ;t21&-bG-3d~&HJ6>A40phDS_@Ai=@(Zz+w-^!GkmNJJvd!?} zuquVdZh&FliWD22MtT+*q;kQ0j{|dcO;@VAM+zRs%5;-8FG5l)i$+obGgS47S|s#i zWxZss>^75A=Us*&z&#;N=HU55d>7{|eaRHIcy6bKrb~~iofq#o2PNsgTvkqcMjz=! zjwim{N2Ie;E^)}4?$(-eD4;F&bN0XlUUC%<*!;A6{!DeY_7@za{Fh;lp$XcVDT*|v zSgTNCtyOD#sd^v{*#M6ob_h!$(%`hF*aXiJF8^P%a+fLnhnY!3t~l?dFP{H?ZO{O= zE7a9oxL_D=Yex$gXSi{ks&a$RTeZU02^i7=Zd1-e3C`!zI=4KKzHK^$r;t%~?Vy9+ zCLdvIECJv7Yc{ZSzD%`yvBFUF@`d!*o#cDHSuw0Lbs1fTp8hmf739BFyAc&UG+e_T zn!%uqA@HK>${GtlLleC#!UD~7AS`+Ba4iLHUS+!rcsw~Oa+SFKz{jZszWJd6J8i=3 z)^qs19e8AR;n`eA^Mt&pu{r$t#jQ0u|OV!JJcH?|8mv2 z%!jP3?}=qvHsS5ZQcQz%9$KL%f5IF2xvcIud{DyU)BaLbELbNJkx4iWp;Q#|h6dm{ zmaZpb6z{^F1{#pYF-)HekxMx~C#V)6gDASTK9>z@8tTA!_MnwSE_&&5K6F_+=Mw)l zl#tb_Z_Uw$ya{d+m5+cP<%$0TH2erLw9MfG@#I@vz{~;s76jx0TZ;zI1B%mE{D5^u zFJ=1iyL-p%*RR;x0pQ*+DnNF3bOz_I%vZ{*ghM3X-;@mtl1?sY?$Z#-S)hmyUzygI zkUMf-fh&;#(#3LZWqheGtZvazhonsRY5u>Yc=5Vf9AJXuQsR(Rxcr0U%YiDWcL78( zUd!~VHBmVR)n*b!dgE3I#QVStcWwW~EDWeUx=g4l&9>RFC-<~iZKJi$C?LWC?y^tQ z5+Z+W1P=BUJ{-*B{iO<_<@fU4KSKDLbU6qAg+&=T$$cU{us7`98*xLXVlRD?SLvs( zveZ)QAex8e$IxdAbH=h0@D~xW+RQO8MEAswQ_-8C)AXh4ra0uhAGC7PgT^J=>vx zml_I=%*F-hb#4Gq%+Vl;JoZ=RfPK*RA5?lXB`T3^(^NIa@JAlja-$Ck>4%H0_}LPo ziCN=lFziftm5|s5EMil%FY5yYow>b#2BYTp=H=(;3qAuRzBGKl-Z-iE(ytK6pPv#1 z0uWt2vcC+P=w4XAH_y{zd46y+tU%2l@`NICnY@|bhUaHF%U)RhoHd(OU=`nHxF~aF*8KNDy!^t)o-XI?Fu4h%c*{G9Wb6`lQlp7A69~ zn5^^64MI|`sc98*P+yJ9&ZPeDa!3x8-96x5be}i#$r#@r{~VvVT{h@5h?Ze3TY;9X{Vnw02e;H}c(kz$7tGnLOz3c5_+J~{6ARCG!u zm|&pENB;ZL&NTO9J~KT>Wc#aG@@+#FdAYsfL0G}UlGL8FX8G7F<1n@FY zYxYPacd6f2)h#mbl##B7)*ILSbkhgPK-8cAM4rKU_Uqne-`;^u1t6#xxT*ZizA4ko z5r2VX2f4n`_B}Am(Z?&sMt4k`?3&N%B+ZN}f@~*AUbc@YXkMt#i#r~X0pk##U^Su? zud^hH;d9VOJ_MQ|)6sM9kaA^^NtnzS8Zw`7)V(R-i)&ImQ^*`v? zmsmVY!IuPdOn&x4-LVn!c<7K0w=(>}NsHY{!cs^+C9j?!>6b6|{wlWscSR$JH?e@yQS0 z_lq9*bx!w=$BJX6?u=N)v=e= zGtdG){F_?5kjP*2x7s;U_^)iTCEoaygZa^;<7WsW$_taK7#&Tpr?0MyyHNg-8jXWIUxHCeL4vrELegXe&{MDbwt^ z(9n2NFg8boas|l}V;PZXiww;@=oS-Vg|4UyE!KM~ z);8D%n233_tHJS zvfBbR#sWS{a7}Yukm2U5Wg7|Ash1zRk!>LVS1GnH0o1`E3X)~obAZJFtma+s%B#^vKaYhg<%c({_z(>X^V=GX31dMzs`CBz@KJQ2HgFk(a z73n%i=O37T>?H?a+4mv&PhLV|=Gm&^fkB^*7#5idrO!`cm}*P~YihjHU;Ys41ws`W z>U+I4I`XgLMh|`ua8ykN7QJwRyYKnsJ8=__GgKr6_II#cK~lq**F<8(EFhkbvS#lVSF}V%2~kJ3>M59xj)RxsBy~7I7{m zCT7!YVrvJN{sec3A!80Nqx0Xh!twO<%q7MK41SBxXfKlotqBQ9F*2tg(wPbnL16PptEN}I zH0pm`jt=Ksr-%hHjbELZs+9#{HThTO5JQ0vI#9`M7?`L)H;tmNhM#~ZwP>Js3F4VG zis5H;52~Tfnn*6B4?oqF)AAPpvTAM8z9L*g=0E=LTL7{f_N*8)e^Yl6*o12AEZ~ir zsOD>9m)>f%XSXqo<@=c)z_;k9L%W351#$YyP*6;><8m1iVP;oYAZw(4!7`WbT?u6c z!DgidFf=GLH$#(ekzcbl{BxJ+^#1tG>Y+zBYTzA{BGW(A(MMrC}yDX(Y*+z~&`by1O;g zUOi=`ZmN_M#nzB4P~qkQ06%D2D-K4U$DQJa@ZyqEdq%-c^6F3$-P-5>(e#yJQFdLU z(nvSbN=hT$E!_;=q985ZB@Zni&Ctpa15(o6pmcW$0@B^}ZQgU8|1x~}~g5iz-9c^G(KM0Oe9QKmIDWGy((Dbi2rx~plUO)80s)BH=n zpun06VSz^l;RD@5&hqwPsll_3g^%J;8E-|P$MYe*(TR1qzo zV6YgPvl!Bz2&bONs{etnn((gq)Z9ZG4Z<^wP|zX|2OO9bgJ6iHBTGJ}^=zJj|06(~EcrR*hNyJ0x_4&%_YXM?Q+_j=(KEk4VHKZq552u9 zT(&5he#x9&ypK#>ECQZ&&UTLXb^b#AAXX1Z)u|x8MEQj|u{BR0=qByG_MrwKyW;go z9{^jaw<*3!Np+&C#fCcS<5*t2o{}g^HpmdMwbUdkY?*T~dco4ieqlEjNqz#8Q0=?? zT|(I=P7yz`Mj?1LN^tsTnAdvW?|8qAMnYLwyx8+@c-G|_`l61G;;yt|Vr426)<$e3 zZu&Cx?F|AO1U%Gx{qMRjXO%4AF;sC)D*7Ji-NEzh?&1>Il(^l`2Wv(IK81dUT%Kg% zj|oXICJWnd0r=pT+SlunKI%S;$3?}BO2R|W%YWzXzswU@!LBZJ;fj$;c0(!#uD60E z&jK1u;L{{k9KbR&pZX7PnqwxbB}pSC2}lj9B2R8H1%QvpGuiF3&>f7T@&CA=7yX&M zn&3~?BWKTT^o0R&CxbRwOheaGqfzLi;l4wN0wKTz4O*{|ilN(V?6lbX-*8P+pCL)w zY9B7~2|$Q6o)`FNXd5uG{@OTaS2VQ#$8ta(!a|EZ^2HJk%nl9k=2_7U{@j~MtbifM zgx)5qiJy(MZ>{ziL_&ggvVt1L^DFDW5w=F~{=VM9W9FFV{2qjnriok~ z1m{if7S#aBrZDTPKWB&lb!z_KgQA3lYEzwR@E4kT<)Re`Gk=Iq$=?<5^}IzOUi{6PtAvE1Dx)q7dp--1RQ<5iLWcJ*feoXG ztEM~2aR$~geC6m^R#hFr+lY25;{7zT5F!geeuVBHD3EdzM@^39K{=V7pp1nU^4Qhy3?3oCn{AI?;ye zmvm_b6GqWCwLsJvyJGtO&s=~l9tAr~d>%UVC$6p;NLRt>cY(s)Fyf!6r}s&G*r@4S zS;EdEBnqh^fGBNM#ZdWLVAM~niCwf0czf^%kJ+1}Mg zCb#ENKALY~WUz5<;=e8cu;X?~WkJF^=%pbnHk;bk9sJ7-O zlhYV2VpNQ0&Q(K+QUEH$L9>cd&+~HxuMFNtwP9F%902gz7wP5Morh!s-l%83UCv8p>1=3yu?p^Kl z@L9PtS7xMH7FJmvsEy!m78wscy15!^Xw-)*nMmAaBLLsreoi`DidW;O{xj z2lY>~JwV>&_u*5^+u|n_TszJmKxD~h*6LQW>0+oShaHKvwTK!2NKT+aGUg=&YXU}K zqHvN|HnpP!Y17hx$8_v-_Ie82plYopuy;!7v|7e+_$I=XHf0C~o*t0~Q16n1q`>MM zuc#Zl{zv&TbNY>ocjx!81?A%BP6W-~NX4pRYjN6`MNdy>@Yv{Gq65lXmi&|`l-(+Q zA%07w@ztn}nwF}UrMc>2i0yWa6p8{1p)FxTEvaCNHkm98ALRfu%?j7HY_ddJX&%A7 z2#&;ZkO-R%NmogkVx(WndGUka*aVYy{3~UKz*129Av9lFssA_@;d1_q)KC!`^9v+( zhaLYP0GaoHM}&Ag7YC)*{t$ZTkl7QaTrFj)~b# zUbgdh1>v#@E=?+T7IAh}g8q!90!QzY;Q0mP&!50xA7IO=g)Iw{I#*@NtxZ1jGUKkd z4f}K7G=0hMglj806_Rc!c~1Xo%&;ioL49ASI5>hgUFWc|0rwwt_|1t}RfkGX5-)>P z0@n0S&rh`yJwg;I0*S%@FO&YzhbOv}Ayop%RT;jJReou$gI4G35{l~9KgkPeo?(S_o_@L+WdlA@qha_$cGb9;cv6T4Q}4?G^A zY&xeXt86s-R`_LLFvEE+Z$kv(bL)G9h{YW*@j$B|>j%-Y;!p(=(*gp3Cv-7WoI&A* zHgKPgPL0r{YN1b``g*fBv+3P;s<05Z_xZnecN3=n=7iRJO_*dq5#cfx$FpId>n6Vu zd$z&}D2&6UDzV0|V~_f{3H$4sN8y1QtnV%%X1Lzrj1+j=Z~*~bge>dRx`tSe&I=p| zXBLA+;TY6e1!ZJN2%)5pNk{fq6&B$BwIM0r3Fx5W+dSJsvaX4+X`PhMJy&PQFe*%p z#jTT-bl*bff^H&MmWHyBEvZB2gn^y5V>2h>xQ7Vf#H2ucv-vt#NjFxwS^?K~RXu*~ z-Mx0)6`?Nc|$t^Wb-6T}g zqtBbv+4(lg!f2tqb7@C>Ko3kFs?Bjc+svGL{-ZE1R|A60kWug)H*QPBa2@~gejz}t z^My){q^1raA=Xz{n>9_nZegVHH|X|4qyD{t)^e@Z{8AZeW(f#Yv#Z-JsRodV9GPCv zkUmA{%78dakc~7jq)fNl1rtmfbc~#s*IFrm! zl|AOFgMknKt;nQ6LY8@qtcvOSx5*m+-*M~vLfhGI`x#pdH35HAkZfBCsJq6Oyxa3w zj<1T+zr44B$2ZFY;y3(Mb;_li28B1op zQ%~45EYj5Bxn?+(!!({25-R4?d`qv*S{DEl2rg02@>F|VGxbh_f%vXob6K*At_8Fx#n;z8w+ZD#rH!jFdHocH^Y`+Dw_ z4!=Qsj?M-Z5>&4>4enIJ+#TU+ji<2;_0@H@!QaN3_f_wUF(`k` zL|ap95MF|8a(I21o7xtuhzflxpflKYUf-$ljI)cE!dHBxo=w2{lA7~}CVrPCK8H^pCFuvY z(1ZB^>ZFX(ifF8>=u(j3D<~zJCm+r43&gbtObY@tm{NoS>T~y36>DEO<}G4ty`w8M zqQ59?#(ELdIZBFskYMKE+fbAi6_V0oFS%BjCV}2gWq9C_0-P(Rwk7Z^im~kd`!1*# zcgb+u`|%%K28k!? zl$4Ojt&I&@lG*Qg-gGtnPtS|fX5?>9=1UH{?@5#0p=sqy)z%6NH4zFdx*+7lFbfr1 z#>IR)KO&^wlW6z?t##rAf$!zD&kjNjx0Dv}xh7@*IXWqdj=pEcR}A$&y1jy$gou!^ zy#nlY3?m66xT9dF(U4)K;ZktFWs0L+`~4j7aE(g?(}gjRN#lw|7sWh{`dgUQId#VF ziH6?uEq9Osw8`7L7KToR`;gxCJo*hqK05ese-eZRAR?h<8%7d85d`zxzYCLaykaZ9 zgxJ!0czwETY|tD)g9LRq75>;0=e<7Za#|`Qr@Rq_43su5s@Bb*h7oFGN9yiTOzUQDi^b%_u(h z?LdWOG>AP>&IL^U2)9;|^mki0$3=vDdV=`dR5VM?x?^?~#mr?KF$4==h*0_QiVh`w zWz&u3Fk`I23qCEDY^W4;$k#~$-)Dz9bM4E>S$559Dit}4v`!8NYKG#)^E9radSG8& z7v8RH2{*nTmLMIlG17)Zi<_Ksyb-3v&LPxsaS4$A)iNuF8r!~Cn}=p~t`&Mcc<~d? zV<`(rn0uGbYOD^1c%zj^enX3?h8b>K13VnL=_v5R6Y#{CxHab=Rt$XhgU04kM++?f zMP$Yn$BB=C;_cJpfL7k<&P>+|V^csK!awc&ZC1Wu79ISSNIa2c4%#_-2?Q7TY!c62 z>Fy;KI}ogY4ax(1AJHQjy4&e zNFR?_Jh|wdg6yOR!u8e-t1We9y!EK)>RUhw59M>&W%p()mG*4@wzhsRiNduPJjp67 zF2^l|kX_`h$iBg4+Tc9$iyUM$0@CTv^pG&scE2x9t2r;zcE+j^tJykqT0Uy!HACk) ze{6c_?S!kmEAC=aq%93+;qz2mdqC6McV-u1pp~$=PKje{zc*B~-q+@davlCQDu9bA zO{{LaAO8^3g2W?`+xrm7hGRq~{0-$cpQG(n7yrhKd)24!p3qX0>a6wX81k)dhka1lL6xlIIN#P@jWzz^D4;~v;p1_tOa zT-oczf#8XGav`(yx5t^Tpb;Ps#(~<&{vjY%+v!DjbgaIFqz0w0uF!`#7mZ!L z9_xOsZ8sD(`5@qU#43bq)@U>HHG3j*P~)J3a<$q=-E}|9jl(o{qXsWxQq{dLJyrw+ zOUl;qXM?eZF_PkFdQA{?b_y0&9n>mR^6{YF!z(Vz&;D3dkc#gnbD`UqRs1KtA__kJ z>*C$?Cql0sK2$z#KWmac4jKt8Fym)3t}Ea1qG{JN#wJHPo{X`3OZbkYu(H(Vn=npQ)Cj_N_g`O8yjrez+|tN(i5SExsaqsK zu2^1uJ3{_`A1*z2L8qeFTZ??ZCd3_PTt{D%wapbYM(s921%iGioRZ&)E$+}c zwC~bQj4F|XcyE@`no+LiSobr=+#gVgZZ?ZQYB|L@u82D6Bb>{Jz<3ZvvwJEBlQWqazLi%GIqphb;_Tb)-nU+52q{Ic;edp<5*%wE{PD94G5^>w?I=TnI+2C~ZGn z!KhD_W$wP*NTTcTLms?0Vk*6;>`z<^6n* z19}f0(!!Sm{oh?#wwsgmR%VR>sC!IsTx2OEwFmAIm)crnTAn6;A_UpZcC9TM6YFXN zra^Tq=JF|Ss>sDj&iTsUd68|wM?{w_LvjQ1-hfp}y0(r+)XBbwyCGtprj^`GDd`U< zR};A=`7mc9=O*X-;dmXEP=!;Yn)8(JTb*%_KkRJ2a*o#QNdqHDbO8NXyx|SE74}lJ z-eoXXbFj8gJZ2;WDc$* z=2Au96=k@J$j>gzx5*v{o7j9&b9w(MsH(e7$|Leo!np^yiMf?l0D($tp%bf9|-kJZaWe zSuU5d5mc!Q%4L0d;J(xq^B_k-o14zGf_MS46ENcf(N8L>TI6Fws75aT*>NQot=1^$HMAgZ~nMLJ`&@e)nSP&frO(e zuzcWCwvjDyez3n7oyAC&hE7hS~G> zFzaTI^fB>3e5$Rom#?eg=Hn4z!D3A_o+{ulZ1R6Gd#~~~3f6u*7t0{orjP$>>(Udv z7(Q>3=Uvi+fe8?QB!W%QMAx0FM+H*LHb@Cc7IfHbAaM*=CPQu(_UK_^zb0!7;pIOL zHD%r3e+2=8A#HM<;nhpTEmc5vmIkdGDfz2T0{UkFHm#G&BX3g)YCVhf$BW*DICXCV z&ddIWR@c({ZrIVBHhNt?PX;1C8O?&te%NbfKg)AN001M^xjh|6g0zlpWxqydwZ8>8 zpy4lu%l>>XgnVAn^D(t)=1dl&$okxIFSLq0sfH|ETWdimz&Hf?_C<$d4X z0VE7HLN0ttC4Y>#_&+m)HrKst@T&VC&3_6u@ci-am>T7~q$yfbjip+xQ&JKW9i1s3O{QO!`e4G3At$>_0*Azq3?Z5@-GKdzpmx*n<8+$9Y|>iK@s>5A>LJr0ly9~SF&rIxM)!K| z5@M7+RY>o_#$P|4KC_!Rlvs7Otmm zuj%(}NW6V%~+QOo2)}bT6*=Tq{%K1sUYM6Q6N?v z>oF47!a#q(s9$61+`c9qZ3Pmjxt1%rfSag(Y4V3tt3_Wm1NGu(d~27zBBkqY{ANSV z(_|}5_(0GjzW&w8`Mu>%KfYqeTO-F29rOpHt<>vy=fZ|q03#FGTOm;FuiDq)>0mZ< z9f4>&pUihlt7c^+ksK$X$}6NMmsL$`5H`u+cvt@Ni<$HJfmA3Y-X`kBt<36qJFfP} zvX;d0;;pQ7y!=lrLo+`JKR-?n(&Sno?N~nLl>+p1`{D)?A?lPpbO71~D)3XP+ooSG zZH*QqMOK&5nfb{^jsZ36PH4h`FVsYYw;TR(W4I1?NXHb!7o3gC8g0!GY48wqnjy|% z5xHBh{UW3X;e%!$=eFMjphFQ)$d$Er`AmA%zkQMBuE`Icy1Z4IKPsTNo2fK$@?YDm zFO<){-R3B0$9Kq!yJTHYKD-Er8V%IS*ciSQc(A%ZhzDhkzsUZZxLm$7cD+?zy#vPp zgT^PPF3itUaUoTShob%ZeN|vY7*5g3%0(}|^P_@C-HYMb#JE4sKQ`G^??w3QExHc= z#KDPZM;x!G<1+0K9+AA3aUV>8&7F3>$ojj+^TcxZG@6%K`L0Vuz)j#j1&aO1+Wh49 zgp+Q{fBH#={=PSJKp^ojt5lbLXqf8OFbUU85hCPrnNBT6j(7crwQjNc*`@}?#lw9D6V**sGc1nE581ftI{(@!6T6MY zET%Tx(T;zgdJHQto~F`ofcm9jY5{; z6gFH5?=!ry?li;N>L?wA3+6u4I*S>Foc>pc11qlDIUP+y*A7)LUnf~<8lD>qldw-6 zXpFObe+hSVNXDHYLO36DaGFH{DbGj7H|uCLIuj|nF0t!@k;exyO>!wkl-!A>vnOL^ zFDodpmfu-$e9Wi{I!GS*CKyE&Yaw@ zj>59&Qp*o%#*+1|GJ)n`LnV29ZsqhG!=WMet@5^Ez?;xk?{qk4DLwxwE?Sx)+4%pj z1&~_gHhRymD(SB7h|+IBB>_)@3c5+E8XKx2tf!*a&qq&|8bWeDE zd3CrU+~l$}zyWjJM)}+13!${(TXDrbcycsTpp*-|2z=-vOu;4wtzkZz`EOC$8QRT| z1b#GG!(VYKo#OWkhZ2L65DO4=rI%yDj=7 zkT^B0B`Nww?)q1v?ap}drtrl@?jRNC-TXh=WEsP$Ya>VI(4I~S)s8S=br{<+neGvdi%pjg(V7aFgd{49sNuFr5k1V#0nJ&nfg z3gS_|Dr-rnLM;YkWRFSpE;y%I3M?IRt7Jva2ZhD>g`$Un`rOXt@=wu~B~PR6&s%2Nh5?#soI{<6V&kbPn~r|3Y;g}9dT>d3m+BB! z7}vA%zmL88pAnr3efdl`1I=u{!uM>1e`#aKF`>Zq51RP#-Ngr1@g>)>k@7=*uK>L2 z8oTGr(C69wmz;YI)viB@C5*KnKI_>xTo1LIk-e`KFu4_q-flSBs%)-pON6=#IDRVk zK52@dTQ;#%j#Q$J*(>Hez-8%+y_0U8yv1!;p2Ms*fe*q?Ybaf&`3mi%c{ct+J(xj%(RYs$hW2hS?fUwF_AKOVol?jGh7LxT|i9`9YU#9T}?>+vG~#GLzP zjC%sR9;JM#q2Ltr>9m_Z>PCmS<3mI}YvS7V$TuuZv0pidXxVlOOsqJ%5LX*slnjQX zmaT}LXsWL*c$OYgX}Hs?0`R4XVu6uCWnJ|I{~$WD3ZFdWr;qcY&OU4;h? zdUQRH-cQnfqy&yqTBBSvIv3Vr^yy_ba?V1-H&+Nl{5HU*ZuQGKd>Q z(XKxC=P&5I+svm5=dE8GBsWZ4P1x(CK~Iw`C6a>tkG} zO{>V)h+?EBatn(n`njf%_#8p+^q4=34wY?v?^c@pt4MBAC(sKQ!c!TqS2?*%BYXwe zN1bUCf)kxN>Rm3Av*HGma2HvaKF1-V@wD9NvZ_$dt7|duTGO7WY!O^K9+7$vdvu4c zp6=fE>B8AgCVm{!7`0kl{$om%{zP-d`sq+pkl0(!@jze%_6dXi?CO2bbjGrU;~`U5 zq!|hFnW+nk!zl@zROj#9+xG1CgvUmI)e+NVnP>d_WR3L4t0O_ANGNA7%>K?{>8~k! z{NNlaa(-Y>{2Au|ug#Kj;EaS(@rB3{7q!m0E55gfkh#oShk(EyS%c@q@EzU(nuarrQ~h zED<^hZ&v@b=-NfoAKX4)u}BZlei4g6{WqqN9p2u1$PN!HW~zrg(o~?Wb9uhM)Y+ex ztNCr>6Ni?SnCJS&%(0hsai6c1?3Rr3pq6yZJ^+#xl|clR;qZaDEAM zX}xSq5$%LFYU{?V1Zv9SF7hRCW5+umRjoj-!j!Jz<*WMHMKhEDV*Mr-I_@mD{<18) zrkRn+krkKi9SG+Rg1Koy=)eZl|C;e+spW<^684FM|1|HQcFA1is!ptbX{N1GCi+pp z_Vv=6Ws8P?(iJ(b`c9jAO$)TVWf1zT3{Pvz$Hs$l*4)~!z;5%Qm^J%wFT8&`lE0NO zP{}o^u1MdKs5SNH+0nW7<6fkgm-%Jmu(M8K>+}IR>whUf5T_CK5cSB}F5%DBX%n&+ zf>yT87Q`%_#*MiDR~{ujC5O8<7wi9%>;1H=spLX)=nZq^drL|$f_mI5pP&`uuYQLm zcD^;GMlr@MzFetzKh)66vVGh}T!R=SnReKTe|I`B1~dek%*zZx2$5(F<~B=8hf;D@QR&!0_(-b7dD~Q7*)j@!`c(@_=WLGf;*~Vf~P_LWk^HxI)dg=K&DGClmK|+NO2K%2J@Mfp6o8)nX{1#RR zg0E9+%bBS(;n{NqVqN}`3yk5U6vh~tm~K3L*$|}Nx3*3M^~8Gt$=`bpqx2jbKHy)G z25o&X?B;@5j&V2YiOUlf$nJ1j*k(*UKcX{VL0Nzfyv@1YNp6W7nfz|-I?{fp)Ntf- zbiOKqR*UyhVoDP~*HkOs=Qe7+e5IlG>_4TkPO+kA_+#;3SKC6C-jiLRdr@kOJEuvn z7)Jq~)`^_dYlq<4A^bqofBwL#N%XK0wnUeQibmOLM{OThk<~O)d)W0O-=oT~%GXbE z*k3Hgp4Y3jYg`FR;Kijw!@kNkZmw4E>PmE_&C-*UBB5A1>oP&maXPw13q_|*znyQwA=u0L~jdvHW;QT z*dfnyb0JeANqn45^r~3-BA@WmtHQS9o1ZaM)IAt_LwDId*nU4bd>Yp9M=kHwn{}la#MOZ7}L)W7_hAlzqglTTkGnR1z9P@|%2fq9kmY%kO zq5p8VpPTXJ(X6MdI0dtOV2l-i+gcdc{1naW#P&O$lsN6+aDJv-&}f?Y-(4Hp+|{JS zl=fq{imKO>7#H za{eHT(*0QU8Q67xWG%3QTj`Cy%-y}4a^oe zUo7#iNtFc^9r^Gy!Rj3P;^KTT@e_U1@0&mDlwW7fI>Y(a1?S+(e!T9F9(BiEYS5fP zo2lpdm2`kneg8esD{~mzmF?-h-SX z-(gq?Ih4Of5X?t~GApuqIRJ6kq!VRLIyi}Ya6r>{jY`HTf&zSbo}1Zw@@Oy`np*~X zS{W(bM+$k4GMTeIcG=?0+Z{M!{+*;;!27QvBaV$|H5e(1bw+;_+mZ@RxzLpK_rP^* zI%tYrQNi}n6jOZRbG1Of@w`U(>7#U&^bO13Pu_sp!spduE`gT|!Rs|%?B%*-0joyy z7GSLN``(HLQS`Q2{|QQyJ7SHI_QC)$r7tVrP+N+gB{JdgJp5fJj{_GQKbcGNPYWyx zbePGF0uvm2FC6^4BrNR9d+fX^c|4BrL5fDl3w$$Ws6Zv?eop_}uDFg2!ugNTjU%0Q z1$I-`>=%}M?Op%xuylfOb?8D?`V04z1{H=h7rz;*JXijf!Jr{+0dX=HCV0~GPReU7 zPLhA(QefhGsNYED<(~e`d6AN{N79!7SxVAJoccP(I^AS$!tk72my`P5JTS<&IyTXq zrq*`G6ug&@__{*)<802eyc(~TkM?Pih15*s6q?6i@@cvm@s(Qw{iElt)x?i`n^C$4 z8fU*gDsj8@8hPxDIA>-)?@5WsP@xkOG5xfO)R*A(nUq(IS2PF4dOk`U8j`A0?Xet;hZP+tCu}uZxx9an5taLkRD4VtfTmnmF5a5lIuz^8#Kn zt4pr|PxASRxBqiMdP5yU_dLkFwQJ1 zmX*Nr3&H%>^sWab&#UMr&co?1)+m$dp_7H1_Kmej_UvE%>k33b?*PyrbZoUD&{kxC zz+RnLG5x?x;;eL{WN!BfG0cqBu6DHotE~?laNQSv{}#FlEm>N@$l>*qmlZ1upoc>$ znbvfgmOyJD(W^%3n-d4g4l5Y@Yg7GcrxsrkA(<7%TJN<6h+)g&BX)F@f!y5*meKorDwQ&}{L~eo|(i!Pos|U(g`j znu*LL0a)0>(ay2heo*$SbmZ@J9g1sM%7%KD`}y;9Ck|2}iW; znrn41BEVaG=2vLd7DaEhb|l4!v){L_|G$GB{6{L-r5bjFfXJAypkBOa%v*JO7G`&z zu9!b~r5(rPy~oUJ1Go}qg#$fp9sS(0AYk_nQVNEQ8j#OAZ~ZZ#Fm>kQ3PjOJWY0Qdw%|ZnuTV;#yUtZiU>u?cId8AliG5 z0)+5;CYLMv-W7W@vvi1%t+H6r1lMe!Jg@KiKr2%73ro{dQvqt4;Pzjhm+u-fThRds z-GnM!n_Kqz%$mN-@LUjUWQ?@Oj^K7>Bp`~pPfL)40zI5$&o~5k&T3|%8 zQ72$Xc`K*pi;>i?@;g^uBHLkn1DSmnRl@Y|W><#H`v)EFsM1M0^lRdz9*2?l1y zII4H{k23U$gf|4>muhC8kAGi>H?F|7cmews?9IlCBSYlF+X*qm zswy?iN`d6A`jpApTWxa5+4fZ%HxAL(PNZ^ucua_*-2YisO}ig>D#lB4vTm*uF@ODB z92WrjoL=)nw1=jqX%9+WKJsV+6*=mM#NF2D<3|xn_;#sz0@uY~@!lLSA_508HlRDT z{V?xvrK4%|09>q-iWf{)10ysi`cM^XI%f&vxF04h>zn?E(#LU$-!9kfM zvoY`6S_ALBa5op4b+x;m2Y}}lSDKwxE2}ax3yX*tyc*!{73px)6LhdQoN5WvwQtxK z@8T#s-`!NMdR^+r5juBz#sDCr!ne~)b7(wqFQF6FTll7k50ZO}QDIpVu(WfeC`S_* zw6p3wng+qghk7#(-pODTf_(*82P+r5>r(b@?USZ$d^*&E{lC_6HL1uzARK5vnEk9O z$U)XVjh;Wz?pb-WRXXWa$Q*Q1Df5NO3lNn4E3n4L>NCsmBlHrowV)HV`CUsB^}jcQE0wy z`vdL^W5i6o-6VY~vd@CFD@#06iBI}g_|I8wW$m!Qe#>AlfHXvC{p-z~r9Xw~1A6ZU z>Zu*ImVEe8krF8Mc$qpw`lJ?U)MC`X)VQ~JAAaEf24)}k8|>7d>8NjDB=-&JBMlax z@5<+O(I=lk6oyz~Q4tEKVcI<6_+h^Tmt5aE>jO=aZ1dt_zR+(u-E2<%pE{ZSvqsxn zoJ=pj|6ttSEU+DCFa)3XgW!EV%ERzJ=Rcuh@C_x5*uzFTXw&va9OHrfnEqF!s2OM}Huyou=RmQt&Sa}S@#Ux9(|I^$Sy5pjx3hx&^EL^%f**z`q{GZQrp zT{dN&#ty@;x@~1ZXJNR7u}kUy{SonO&E1UvGox9^Ui@q0IaoOR>GVSC*W~)ceA(k) zH9%^{*|6NcdjPT7cYWfzzw7QFmh?!_bYiE!qi|777E?IhQ8g5otixutVZDS(qDSzk8Gh8c^MU> z1yn$n!ZabD!~>cOPd(di{a8yVOPMvElh4ovx-6Aoi{p9?nJs2TcBykU9tHq&$XWd? z6ljwcRq_kmQ(SkGz()pMO(8=)HHMEz3*GUdZRv*rH)ibun&H`#zw^|k2qqfb_^z|( z^mBd5!Ib>yH$0C=u_cWUFL=(=s|E98Q0pFLIN{y#Eg1C_MFY4lAT%gPb1$Bp*e59l z2b%(XWgPE*$MWTSGG`8Bk%!D9s~t33x?OCh9(L4I>dR93Xs!Qt{(fxnSz5$Gp0wc2 z(|;)X-Yi$Ts$PaaZB?=1>QQYI{K|9{3l*c$*NFR?p2QR>hx!~8?`AQmW`dpa0p)!(q>WChkm!e!Kp<{Gr#J^vJBj z-1Bk1OrHU)C1XT~SD79us~h44^bM9FZ%#A7df$xw<1%GW+&y>&no~A_1aa$W-+B}1 zi`Ts}S6Kl2R2;-IwD$L4#P?9A?J5bn7^1OHYv)4Mi;RZAumZen5=UI>~)rw74Sx<1>z0>1s!frkkZl8 zTH6v_;%==k-nRX$wA2S1uqH_=KJCWjbDXTWS?h?c$OG;i@88n+mr+Re0CZ5J9QI=u zm7Q{6p%%!U*@aE|E*cn&T;hAUjklZ#5pA)J{$&PM4ZnQw%w_rh!*?ane!@KH#X;j^p6~TrqOF_~XMjB5c+HYFwYgk2j(h5WRe=u9qz(-&`XAiTK9RW_Z%uc8 z9X{pEwfu7pqO~_*fyiI9cdHcFnQd#VdMU9*lqV{@(QQ4H3&-%Hv(I`D+G(d?RH-{A z`~ZR$w?4&UQ5gbM=j|&XZ$H)F%c{?m2dr;J%dmvs@hV}l+iv(u@UMK{SrKd|D%z#Z z4>fT8XXx`Pw6y_HFD-sN*^Xdu;I7%ky;QPvc1*3XgJxXwA)ox>y+i#Y9T#}BmXLSm zAGE^{YoiDWwgzUg5x)l4+Cw()9Pw_$Avi)*JHxgXNFoQ6(5mAPE8RZ`>tDQ{+-;$s zVgcsrCni06reAg^Nx%`pLl7CL$4x{dq zrIYF2Q2bm=Yf(uR!wpPP1Irh62!|LfCYKIoW}~(FF7rt^RuRNTPCGnXHRgv1Rx>qY zD4JrUAp9#{ z$Z%%j0LfV_HL;V!f1NHE08Q-eOZQDL+Cr|WfI*3>Lm)%}Ofw5zrv`>pdSkiO95=!8 z18lC;LjPr2kcDR4+nXk(ryXy8Cm>E7eiz^OTidgITk&c8VKUFpGpf3w5#j+)1k&j? zVscOb?Ze?E4z9_?r;H!ZsEvbodp~=>2|RaJmT;f|=5A{iTv<7&?*&}>1v(di0#ho< zRt809U<5ZA^eG{ZVMyCgX z*|&ku@$pwc$>^Zw8{;qvkCCJmyQ6w+CR(F?82wzT1%f#2?zAMJ}l z7q1UC!J7}jeY-6urg1oJ!f~NRPol`iSD2~j}9V_ z_68G}d&mvVt!()5hFM|jzgi5%*PPFh)SBIArcQC;ED3z)x&1tb4I2ehX)T0Te3`Lf z^%=Hyg`iMiA2UVeya2VajR5~Q2b7V1N+~mG;F5kLQi3x@cd^00YCFCaXh;9jd6x-4 zf#v@e7J`JZ$IQFFN{`sjlX84>IFNqwHj*L~cIJ2)$;r~sif+dGkJ`fz{m+Rn;VfFp zJD(GBcDiFl`fm7JKapvR)Q6`i6^G_}Aj+5L#NeLO&rWz7voC z64%mnGTDmjzpJW81JV!(I^_MpPS;V+Fny5xxad%UWyy>^dU~Llyz`H1>Q7=C$WSUh zmbdug)}FE)iahvFH0;L@DHXV}t&t)?TGAU)6|w z4fXn;K2g|LMjLYJFY)%_jM^`qF%r36VdEw8M>3ZYl2RB5>;?!43tv__9p07|2JTrZ z*7K*>|DNCacL^1mH%fP%Gu-uGxfii3y)<}YlX4BqJ@lCM@V2a>k-O+fYfnF$KF+qn zGTr!Ssl$IR)BIoT&9EP&`VO{XW{%Qu=?`-s&P;C&r5lQ43GjvFE2qo@R@BtD3Lmxk zMQ#^F4!lPKYN7xS&|<)IN|5(d@mu$1CHp9Uk)S7I_|MqGT&{_CUgO7CO;U<<{j!^B#yzZIrOMT9 zqTWzmI3_IlZ?k^jVXbG{TsZ=T$UbR~v>xt~-Hf(rYZQ2j264PH8&udkPtES#m+O!w zOJSaCtb<33RH`eCygZg>uzUAswMo^7TfUAt#6_$#x5;2?#ElOnMP;oCT8~`cAme{H zX_ZY?j9^vTlW}{6&UYG1r+ao|_0}UP3!X*putb|Ev*C>2ZFeW{M~ob=4ZnSz3EB;M zh*byMOT3a)oA3>;8LP7T5xHvOz-{Od}NfaHm4PAZYBb!V6r!4k)~ z`^ZEcm_qd0?OemOGQDhICLYo>Dp2pppfA1e*^i?i{XO>!328S~KZ!s@ad!g2ANv-q31d$d^@ zy;VfHjt2`%*VyW_ZN38qD(qnR6D?;~m~S01?OnaW73V62$hm$s-s=nOao=<7q%b|( z0SJD>$8mV#;K4OV>2GJz?Ben^k;av*b^(v&LUR`I|E-=4ql3epi?!FiOM+8s0i_!s zShriO=t7qRmJ}Fh%P}q$#03TxmkZ%E5^kGKo|s$TypaU#zC_J)m`rds|!!5@-{27A{#P1{dYptOFG^&Plyz|W$wyT2bjn` zkcH5ovSj&Qyilx(-ua-XVOkpn*z}wJ6Mwp@7IgD6ln;%izsU1&lbE|>tCzTZ&K}N$ zNl&x*#-{}1;AxHU+h+4{Y@^yoJI`Cac0*zB>Xk3jHR1gqN*0U?FV0wtqJGVpZ2wFG zVrcsB^PMM@4`q_6(0%G2l*pI~7q8h$lvvV;1~u5f-g?}N;fCu+P>3GmXXYTIirl2} z<&7>Wf4JUA3QN)6qoPmh-%-H#{$no8qiAQF**j}7KDW&i0!QL`u~Pk!2G_>RuaC(w z#+DDz(Dut2hk&BKp+|Ve3QF^H;akVYtVl%Hy>z~{i{kmZph-O*r#9g9!u{2eD~<%Nu{zVre%s6Koo}KQU&cpW zlw?>HSWI>l;+5Z|@l#YYs*eId3GqGL@fD0x^DS8(p^e>Ndal$dE+m01$iLn>gXg85 zybGY~y$#Ai3M1{>Rbw$BxGC~@$w2nqF z$4Xet$~#l9xUcN@O?iQ}?mxSYg-*<0Bj_>31Z%LPsUyA&Ms_Ou`_I#|)wUvkvW znC%_p+YRwSbj=iB6HR@irDEG88?p>9qFQ`wx5;3&HDud;wcC9KH=${Al`CZefJ%L* zvDEBeN@n!N@!Q0JR!fiun`Vn2l}X8TyxS#*eSR^+Gg{LBYwpb7q3+%|PS$Kuwk*R# zlC@B_iIHL~#gJ`A1}Pc)mP~3;CVL(w+h8JNmnBQ~iI|=;B>OUBY@xA+iHPrK`YXQY zI=_C-IiGXi@7H~w>pItcUV%X&KYw2a=wB*54yBfK3^`s3Jp7pJI^MPuM#%z71}Gn+ zLmS$JRv;3s$&7~5#2=ZBg+^#Ej$wQHImQX01QS&yuhUVV%B3tkCggCrMVM_C@=H?O zvL)4PI&fEe_dDecuAT5q7;wxzjJ&+N0iBB4P$4GQLG8pGVf9A&#TlOyhF2e!4f`9{ zBq_xIcAPh!|0W(^dA0@~5O7sLEY8>S2Un$TjyT*8EFSK_QPHi7o0zw$s zYB1Z-T;Cu_+s6{G#dZ1kA=U`Buk~gfce5PGu@Z80Buzn}z@K%f$@NR0qEmX zd;l2H9-#iMkUi}|@#)Sz9)DLA#IKoRXutqJ4A6sI)pMVQNB$-o8*hl#;MOm0dj*hz zmoc!if9+b7!hYGT$P``Fof0UQvxNB$p>CuMX6u`4>kJ}2CVXk=Fso^jdnc`&DAUwU z3JYkOD?vCi7h3@DxI4+>KZ@J(fAZ(pTE_YKmxk=dHP_EMo?~p^l)7b#ayyNE3reo| zJX?R^@pQI?Vy={8F79l=P&{hu7Suw_N*H`)`{+lHeCGOC+ugzU5^!MHLJ!}u1Gfyt z3e80s)7kT9fTSkU3~DnD(AkLT<3s6mp$etg%w9CKdAg-l`7q#=rlQ3qSng&v2S` z_a`m+AzYQ2EZn{Ic)fu?eq6CPycj%8_Mj@VH6>&3H)K(EzVr<(;i5Cq)uIIOisR-AcK~?$j zBP3+cr$ap=DwjH;NZgxCm#*j=Sm}cwt8;Aio3bN_>JN@6h)=-d2@C3#YD~E{)d41> zr9{libfUo*Sklz7TWZ3V!V&wEE$|(I7oj_XJRGV@Clk6EeGUlGz~e)PCPpM-73xQ7-u~&8cM9-@`icCy;WOprmt^w4 zebz6BJvT45!61fQMbQ*p*JKo9+yK8D<(?NQPyO!gxyj#?LYK8==2(`xa0^T<_0GM5OUR_M)gg<`kBGqANO)Y6_MHDV> zXhxxFEIl3qk#SoYEzp3`i|uhhxsKK}9SrU8LQ8G+#HoGK_tvhN9U@|aZhxMf2(y({ zay0vFZ(NTvCM3L4K0`R^;L9~qXm?ilOY?Dh!C9Mt*sl&-`)sK4E7TGoTbn0Kpx-^e zH(tI|mQ8ejsz}-8Y>KR34`-~*;oB?~3YeQVzYtFTw5Y7qFi_LzejwhL!s7EjCY_~q z39ED_#BKOIg*s>kJRrZ!64V;>&T z3y^+ji2P^FCW#bu$azp@v3rE}-hTeH`ao6RkCV=4!2yj83{(aHyJfa2a1if-1hDn-0O>nCyw3X&P0KeFw;w3 z*(cwL-ci!9jEC=A?K{G_k6tAZ&1o7NP)gUSfzG)IXh5!Q>|cYGyZ!kdn=Ul#!-x4q zQX*gJ|bs=T-%_QFJ7>0rBzXLT+%JUfyEy;Tl!r-JHO6@q^?pJor(DcpkNF=MU*V zF_GyiCc%Hcb3K*3>fhco!`bB@cCbpU?xTc|t5~1Z%c!}15CwIWLV3+wYK`*0g7Vdb zxy^-C)YJY$l&o8rP2h1kn_jFu)2_xUIo-8v{aOb}QReA0pvfy5-@`$hnYlcv8m{LC z(>y-ila;2gFr zE7@>aJg`}6oqw!n>EQBr2y4X<`VsQwN+)(e6tU9_1yjBjKPk!e|Ff9fJ^>F+oa;Y| zT|Cq^$Zg+PD$d(q?%&dCCw1d65E(1+M_twZ(1Z2fECnaOMNzCRa|U>*zxdvELa$24 zl4qmaEv(P!DAj}qAd;TfTBKcdk0Kt_<~+!dWAaAW<k2tNN}X1tp(MB`$#HWGEi@I)!}Jh1X`ritFVo{6hwIqfOv7^u{duD* z_VVG37LbEwWJCXoL6wc(p!4wddgzK8ZItz@kr?dSLd85+gnwwA!1X7q+6Pr?zwrj| z?hj6vp|3H$8d(FJPgW9kPe2dOcKNf9uziU}zHSyoEPQ*V7Bc{+v2Rq&Maon|*%%!U zlBh+f2qA!ksl4=N*9nKs;9!FfksmilkBuJl>F2H#k+rc@GuQjd@;xeucA@%9^^s-W zx|3Gqk1SV8p_+*ab3XNUA813RHm^=IX(!VK8^Te|`JPYw;!-enq&sZ0zs*2XpF@gG zz+LL&<0|;r0;r?KCv*@~pBBe-$%1OkeDujNZ*E6iOkEF3XYj)%f($zHaC!J1-RO|7$u1xCmR6U4pQ4e}o_Szl;Jxi7irS^DzY9@7QPR0A z6s$SP71NuT98i*BA|IQiR7am`MVONS^~6XrT4;1<8SUspQsbzKz9E^^Lh5?9%AU7L z)a_FpOFI2-%`i)-7%$y+^-TfOljMT6k-ui9dC3-tglP45u&|P-j1S708Syikq<{+t z5^nt8zi3E?7N1zE4U--vX!1yk70u8+dufK)$>X$tyO3RZX9L-bS*a{O5_MA^lpIq6 z()aS7Plw=ryLcv+KXKH#Z!KOu!|Mr>dXmM}`vlC&J@R%`LKg0!(WaSQ$?1?a{u8Uf z`SkgT%mELp({Glnx@9*RoE-mkhD4kmy#|@%othk^56Fgm>h+=(`d_4E>G(=yvdBF6 zr9txwg#2&_7u|YF%W9-2nrg|d4NwX`bb6e8;AhVQJVO8f()Kf)`+qnTe82`Ju@8VIp=ww=l}V?Z=X+}ZufoN*YdsY`~F?mH-Ux}-Njf* zECz#FyjPE8guw_UqQ5`Qhnd_*i_I~ZIltKH=os$R(UCvv>||@_V1vOZGQF8Q^`2`< z7h6)v%pjd)2Ju89MVv&I&cu=vMeG9($?V%WadFM!y+OfuKAD~U-8#MF6Zc;7rDXY^ zeEc5es3|?x3!E~*Zm`lI_LSsa2+wu%GgRJE*0Ey2*2eABz(?0!rUqH0iM$IJnJ*F* zZS!WY(XxV;PT4sHO~vj}Q#qQtY1bdF5D^JH8GXF2NUEqRChMukE#kAF2l`$V4ckiL zK)IY$_wg4wpB_BfqF}pY+X3lS;)@*bWvHyXF4-qar`5Q=lGrSp%*rO7ZY7*4PEMa}HYgB$)$gnQvvFOTwJRT*O$e9Q>dTGYik^9d^NB7A;4A=U}e0 zR>0%}*S-763tEN5eqOP;I^@e|m|E#dHg(l;a&)vgOM@&+9~9rf9ow|o#el`KtS62uHUk4Hk}+D3goA6}a`xs<3O(9-H>>TYr5UW{Ia$PS4{S=0ISD zLs&tda=&YJXLm`4C#7V)*fHWw>eSI{HA$6x|{GsbWS^0G` z29NI-GYNTdY|4qeC0sYiGMtg__T#{~@TPO)NlnSJ!Eyy|KVt>)&DHWfMN=XAEw9^?vo(%y z7bfJ7YWI&M`>eVisg5uCwa&Hl7HMmmLA_H!bC=NIyNNG#r^CZfjejlet9K-tE8r(j zuYW(4FJtVlUp}#6_!afe;Tu7WbKRQmlXtE~kJZ{)-9DZ$N8d*?XS5?3-#R6ZE6Esn zcR)9uUeHMM4|aI#}v3BcihdG1VbF#argwSQ;I~;y4q~8YbtvA?SnBv4C;=vp1f7OnBTJ^ zj-FT|gUZBeedf~cVrlTRaO_z+!AO_@KMOIco)u3^$Ws;>2qZ+O)cXe+&%DN@u0(xNd6-oe={ZKPoUs9f0Fu}DPzz< z57HAZ;t<6+LSm5lIYmlfA&5!>3%scg=Rlek3vVQx1Qt=kgS5ohjQ?Ru3_$&316Ndl z=3k~}>kvr&^OV3SZ?#zIFKS`R_^!~*stC9RQEUIZsdp~m5>hAFfaBoBij;VJrxBxL z|9*-fgI?}hBLlfa@E*&ceoNKcaE^z% zJSA=npP3=ZUO-Pswb6VY@?6o!szwG9(;Is9Ht^GgHYj8oMXj7nKH$@Trx(W_45PwT ze|2l>&B6qsA|>g#a~1a}t(~bF#<3eOsVg^}?WpsgbXpP!IhLnp*56*aSe_M&iEq9dbZ4AKRxhwn#3qR}`L;iO3+Ec_?!k2UZoFfAB8A?LJYMw=H+Q z;gOK4c-yMYLde0ot8C?k)#BW(c&pTk`@dS5JTOq7o0nK_agGEn^~oU z=Dc4gFA5f4&Y+2~-z`znR7A=cjK+Zh!CaEG@{7RopQ^JPw(s)UXHRo`f%D3qT;$?X zQTp+=5HpA<#(rlO*YsNf(O4qUNiwAEDxRCK+h6DTaHaB_w}+|nMmRQCG_1jEP<1Lp z@lv~cY}3wNKAxn}{6k@VUnVD_#2D~|0O*mGzI$t%`)_M`Q^Ur~@welf4?p&`Q@R-w zo%u-XE}r85eAu;mbV`Rgzq&#z-~0JxYnLK+J^fx`Q*Q0jo(15E@R9>ztkk`=mX?V( z3c}{wryLqPLHaqf#dJ~V9#NskC320SRXqiq*gqo_+J)-blc_82d=-6HE_ zV+MI6vxGEd*!9^5B)nrIH(Lrb;WE>)t|qMWTMc8>3fCC%ZYAC9npVn^jT&wlZ&$+% zo}$e)_|df`a8tnf zxR^Jpl4&&R&^-X=xX?Dd)xg^uQ|ri+@Nq}cOE>JxFGx$T{$aSXCBx8P5~rg2xNWIX z(MJAqUjE#n(T1jx;-Pf~-!rei9+jn5%y+H-@k8YjQ!a!Ne$H8XB2u5_(oknw^VLPv zY!Fozm5Z}?IT6sYjB0V6Y=zBi%07*QZNrC^>in|0Kcr{Bubm2HjJvNbIlfk`?gb?Y zU4sOo_wn7&=|FAb8D?Nfh@fU9y%t-T{m>POE zwx2A^5};pqgl_gjON@uKJmtbVN-o}zOh6}+QPuR1$2PHeF%p3*TEqdFSwoZ<5Lcz- zZk`sW`V))`qhq;ODut6~a!*D>0%Z;ygISwlSS>sJ=6y=xgY&13 z)f#4+ZIP0vplu}kl9s_oasC#Uz^V3wG^I|d+#dyF38%g1N-6ZW+>kD@dbo0F;bxh! zsHl6}Pn9WEB<^o5_wEs;u7dLzb%Zb`l@WoB=aq(c)0+B!;fO#Wpcz3>tRyg!#5&J^FfLY$yt*hXCl2 zV$pGLiDtKE*A%B?)+C?2h!#_a?Jb{863|r*7D_oRQPx2#=y^rG&>gCoWAi$p=23P2dvYGtK!UqbO7;Ku~h|QR8?( zFsSpUF=0^sp`c;b8AG15Sy&o8|0sj+;oo@>R|3dH>0f?B@nND_g zZN>RxwS~UU{Ux?K04P+oGT~M26IKpIJ*)4`Vxq6u8*OQXvB-|IxRweW1qTC9t+Ez481 z`Idj8k>JGe{ewUu^>AIL{re{=xV8|*j1&|v5Cz{kUd_$dh3=sU^a7%MT}UTL(XoL3 zv=l1KK?+&^Tb)cS@<1Nd@zYZORww8}(z7fh4`x|L9-xK*!2(GI5aFZ3hXo)8$l*~m zn)7EVBt1(CNyC?z4+|LzPwiNEPoP2JNuf}*;ZzHx5Ipj5r1(;(JK% z`$?I@i-xZgm9)YrX1)jT6<`UWn5T8hQ;K;AO-n=9fux!6u*@R>+Pv5SM>-baI4$+> zbo$%SRD{pEqi?0#F7_gPvBC{$-TaRsz59B@b_NG;gw6l~5sc%^jnw~{mb~$&jHj>6 znhU5e4lTL1@S8^Xk2v8QUJaT?$;E0VDWR+UvE74+Mc{ubFn~Y2<9ZO6t2KJUIP!-6 zy!V6&`Q$$!|G`vhS7-3U_hEtj{cm+UUKJD&zdp)TG3(b;dRf_5S17|)u z=MaUPF3Yto{q@Nb!g?LnP2%RQt0?}L?neM_MN0BUaCV8p2u?U9criE#RK7MiQwUmt zA+9JAfun(ZfTdYJa7AbN@GqB`aIxsv8FMHC+qnX>0-eZQkrFR1zB%w{#@wtW=nasw zf4>CJ8(R9q9G)^qgoDgsP;^`xT18P}rp=LO0U%f+5vI*SnLNuJ?E3p9Fb8I#G(*@R zb45yE&L3_R=3ja;z2v6{um6mb$b*?(f4@WkGXhWOSY$@vBx<{mx&OfvSem61oczPw z%u?Jbx0--r24jWPH`SFWBxvcqSi3gwl)>Rnrdq5+^(C-P??#A@U!-xknkyuDJdo2t zIJOfiVbBi6eXJmOJP;6~8-e2COJF5{PeBOMu>rwURIY>X0f?A`h6McHji@_ldH|0& zMBO1v#ZZ$^ONg;~(sk9C?izz>7(K^fguj^Uj~L_3*6@6 z#drH(;APATq6z~035u*~M4@V&M%0)kG>s@U9RDF+I3QqVspV$OU=CI7vt_(gqH>j2 zp(Ahw@t|TdH;fk=8uDvR2p)zg(Y#`oSD>Pk32B_eBa#@vuR=zFnT2Ye2@eV4w^-l# z2L>^Y}tUOrjzeEX^7MnF!^uzz@L?>Jvce^W%!523Fr(x_LHI7lFhRfQE*ArxES>$58BB zk6t%NZ#f`^oaG^fN}rjbFe2mR98igj7h`x=goL&$PjV~HtZ;xgfqUgvriZih_RE)* z_v3PRsDPcBuxElgK@#OPHajuk*;tm;)&iA{g9MfF=M}IgSJ^%SJGcK?|A7Kc! zvF5ts=yc~VOM`b7EgSj1`YJ2eXDGed{9v+i$}SOh#?_JuLxP&oKy78HswS=IX{7Cf zq13*4Ztn@*HjR$n!MtgCQnlF!Ji$93b$0fR%pKUt4HZ-Kmv;5t$TSN2FA&|Z( zEf*B2V6w0ps0e2DaA=io_{xk*#P9k)53C+PAl$LJ$S(e{$ES%B+1v+hQs1Guf~9kN z3fht$&a;ncaW%GVPFjBX*Y(PXft3&rBc+P=sQ8-9?>Iu2#3fVAaw?w*0m&-HIeXVg zRwB_cq{=LQ+4%!V51EibOJuhur}<=SIqCpicuz(;Bq?ntw1pu5?z;WtYX7>+@LH{q zT5&%XIR!h$H7Pr^W3yHP=eTD=9EYqjvE7Q#Cao5;4O)N%yx(zkk3a8NC|WAJ*@4=h zX@pdH1{Lb;fJ3cqKv?QPUV+Otira6bvCgnwls&}Spvc#h@)DO>BHZzm>+0p@9e+4y z?ULhPT@#LG-xZi|>vL@h9TVAaNijqWX!r@LY>7Ji=VlUt3sj^10l;LrqA;g6k zrh!PzSspZk!&pwy7pB5VGZd;A7xhkHeTh#vRz+;oPw%bh(W~RR< zG%i|{dn-Cx{V*?J>3@he>#H^ndi#%VU!&?cdV}FQ!t{Egp}yrb{b>w+bi8X^*=I0J z{rk1Wq>i{oodWfpGRkEhlDbP@mnn2is4sCCixW z&OO)vY+#o((>J%KMZ^1(-%@czxihi9O0p~RN2Ok0uEEx>ud6|cYI7J^%msn*KHuvkWc3+L2 z{gsi9yuxic{k|yo*ZCHrMRx2-&93Ues~w9ZvbMlk=qR)GI_a5x1726xRqD_YsLLiQ zRVK6&Q-MQ7-3fe|>MFF#)ZUtnvgfK*0PnSICr#r6Moz>T8J)i0$@67u6lJ4FRP7LU2rE9_#c;o?YGJ%`X02~1h z%Kw0-(5h$iQFfqir`N^M&AtI$fI0#^6@;L{DvfpC7?h$8 z0Ef7-S-C=q1R9c~)%|vkLkeFErsTcLP`A9-Aw;0$pDjs(%@ z`q7|#mP8Qv2ezgq;It&c;RJWk8RhwkVnZ_mE67)YqvRxF{MWxzM@K{nKXSf0h#R^u z#HS(%Ud{JI{xqpzAn%WWo`vSzzOm~ z-L|I^0m)KD7TY>624e%?$g%>4|Pg6X0G{XnjSc(IaJcB8?XHR4}Q(wdg3tx;DC zvwhq5EjjIlfy)4(V|H0@zs~a(C9A7Eo5n2Xv$B11Jlc`T|ebpXqj>&$I;5FB65M^$-80I_I;mg?xfoui``HX!>Nra zFE8`?KH=*zmXeyG6|bu>Wc~X0;vVQUS{7XRzAt}M9(Ok#YdER5A4lhw>aothNm_C5 zQ1}mGdD)wdJGX7Q@cHtEo{z2AMKn*M5&Re877b}RqOI}Iwe}liPR4xXk`B_&ttW27KZ_$ zP=>0HYw6?9pWT~-m@B$9^GYU>V>!_u-Fd%@poZ_4Cyzx96f!<2`-D-WAUb zA=5!x@m=uq^rfI2+(CKR>A}XPG1T?!~pRnv=H5bXlA1DryCO^C7Mmc zJr&m3Y(_a^9xbFfBUvLA+f2~0D8;q+45&`9SuK{lH3^PVrCfPv*yPi!z`)DV3ly*B zzHR=|UfN!$Tf_kMm5Z5=MbvzzBGlb{Y8>WX`QhU{IZ}Ad#rgtiv~{~oKZn(#y0JcI z;DYT{or5aEt?ASCGPB2iI30?Nb&(yKz(4Fft2y#Qb@F?K9ZMPal=a6HIHUlmss24{9iSDCpt9NX%3Di-+HMuapntgV3XyfX_!~b z?tG7`EDmR`?Q%bLsG|(^J*r@xA z%1|vaSJiPxPITpJrB)Z0qR~>i73rSmK=?@oZVs#ESEW{`HkRz5BKj4<|EoVfbyEve X9;Qn9jd`M9T*K@oQ%I@1k6rw4&qhQq literal 0 HcmV?d00001 diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt new file mode 100644 index 0000000..accb2b9 --- /dev/null +++ b/game/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.0) +project(tictactoe) + +set(SRC_GAME + ai.cpp + main.cpp + map.cpp + parse_args.cpp + version.cpp) + +find_library(ALLEGRO_LIB NAMES allegro) +find_library(ALLEGRO_PRIMITIVES_LIB NAMES allegro_primitives) +find_library(ALLEGRO_DIALOG_LIB NAMES allegro_dialog) +find_library(ALLEGRO_IMAGE_LIB allegro_image) + +add_executable(${PROJECT_NAME} ${SRC_GAME}) + +target_link_libraries(${PROJECT_NAME} + ${ALLEGRO_LIB} + ${ALLEGRO_PRIMITIVES_LIB} + ${ALLEGRO_DIALOG_LIB} + ${ALLEGRO_IMAGE_LIB}) diff --git a/game/ai.cpp b/game/ai.cpp new file mode 100644 index 0000000..2ae61c6 --- /dev/null +++ b/game/ai.cpp @@ -0,0 +1,118 @@ +#include "ai.hpp" + +std::random_device rd; +std::mt19937 mt(rd()); + +void aiTurn(map *m) +{ + std::uniform_int_distribution dist(0, m->size - 1); + + if (aiWinCheck(m)) return; + if (humWinCheck(m)) return; + int x; + int y; + do { + y = dist(mt); + x = dist(mt); + } while (m->cells[x][y]->p != EMPTY); + setVal(m->cells[x][y], AI, true); +} + +bool aiWinCheck(map *m) +{ + for (int y = 0; y < m->size; y++) + { + for (int x = 0; x < m->size; x++) + { + cell *c = m->cells[y][x]; + + if (c->p == EMPTY) + { + setVal(c, AI, true); + if (checkWin(m, AI)) + return true; + setVal(c, EMPTY); + } + } + } + return false; +} + +bool humWinCheck(map *m) +{ + for (int y = 0; y < m->size; y++) + { + for (int x = 0; x < m->size; x++) + { + cell *c = m->cells[y][x]; + + if (c->p == EMPTY) + { + setVal(c, HUMAN, true); + if (checkWin(m, HUMAN)) + { + setVal(c, AI, true); + return true; + } + setVal(c, EMPTY); + } + } + } + + return false; +} + +void setVal(cell *c, PLAYER p, bool draw) +{ + c->p = p; + c->is_draw = draw; +} + +bool checkWin(map *m, PLAYER p) +{ + for (int y = 0; y < m->size; y++) + { + for (int x = 0; x < m->size; x++) + { + if (m->cells[y][x]->p == EMPTY) continue; + if (checkLine(m, y, x, 0, 1, m->toWin, p)) return true; + if (checkLine(m, y, x, 1, 1, m->toWin, p)) return true; + if (checkLine(m, y, x, 1, 0, m->toWin, p)) return true; + if (checkLine(m, y, x, -1, 1, m->toWin, p)) return true; + } + } + + return false; +} + +bool checkLine(map *m, int y, int x, int vy, int vx, int len, PLAYER p) +{ + const int endX = x + (len - 1) * vx; + const int endY = y + (len - 1) * vy; + + if (!isValid(m, endX, endY)) + return false; + + for (int i = 0; i < len; i++) + { + if (m->cells[y + i * vy][x + i * vx]->p != p) + return false; + } + + return true; +} + +bool isValid(map *m, int y, int x) +{ + return CHECK_DOT(y, m->size) && CHECK_DOT(x, m->size); +} + +bool isDraw(map *m) +{ + for (int y = 0; y < m->size; y++) + for (int x = 0; x < m->size; x++) + if (m->cells[y][x]->p == EMPTY) + return false; + return true; +} + diff --git a/game/ai.hpp b/game/ai.hpp new file mode 100644 index 0000000..405bc95 --- /dev/null +++ b/game/ai.hpp @@ -0,0 +1,20 @@ +#ifndef AI_HPP_ +#define AI_HPP_ + +#include +#include +#include +#include "map.hpp" + +#define CHECK_DOT(X, Y) ((X) >= 0 && (X) < (Y)) + +void aiTurn(map *); +bool aiWinCheck(map *); +bool humWinCheck(map *); +void setVal(cell *, PLAYER, bool = false); +bool checkWin(map *, PLAYER); +bool checkLine(map *, int, int, int, int, int, PLAYER); +bool isValid(map *, int, int); +bool isDraw(map *m); + +#endif diff --git a/game/main.cpp b/game/main.cpp new file mode 100644 index 0000000..76a31b3 --- /dev/null +++ b/game/main.cpp @@ -0,0 +1,211 @@ +#include +#include +#include +#include +#include + +#include "ai.hpp" +#include "map.hpp" +#include "parse_args.hpp" +#include "version.hpp" + +int main(int argc, char **argv) +{ + int countKeys = 3; + + ra::key ks; // size + ra::key kw; // width/height window + ra::key km; // margin map + ra::key kv; // version + + ra::key *keys[countKeys] = {&ks, &kw, &km, &kv}; + + ra::parse_args(argc, argv, keys); + + int size = 3; + int window_wh = 600; + int margin_map = 20; + + if (kv.isset) + { + std::cout << "TicTacToe " << version << std::endl; + return 0; + } + + if (ks.isset) + { + size = atoi(ks.arguments[0]); + if (size > 10 || size < 3) + size = 3; + } + + if (kw.isset) + { + window_wh = atoi(kw.arguments[0]); + if (window_wh > 1000 || window_wh < 300) + window_wh = 600; + } + + if (km.isset) + { + margin_map = atoi(km.arguments[0]); + if (margin_map > 100 || size < 20) + margin_map = 20; + } + + map *m = init_map(size, window_wh, margin_map); + + bool done = false; + bool redraw = true; + bool isdraw = true; + int FPS = 60; + bool move_ai = false; + + int mouse_x = 0; + int mouse_y = 0; + + ALLEGRO_DISPLAY *display = NULL; + ALLEGRO_EVENT_QUEUE *event_queue = NULL; + ALLEGRO_TIMER *timer = NULL; + ALLEGRO_BITMAP *img_x = NULL; + ALLEGRO_BITMAP *img_o = NULL; + + if (!al_init()) + { + al_show_native_message_box(NULL, NULL, NULL, + "Не удается инициализировать allegro!", NULL, ALLEGRO_MESSAGEBOX_ERROR); + return (-1); + } + + display = al_create_display(window_wh, window_wh); + + if(!display) + { + al_show_native_message_box(NULL, NULL, "Ошибка!", "Не удается инициализировать дисплей!", NULL, ALLEGRO_MESSAGEBOX_ERROR); + return (-1); + } + + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + al_init_image_addon(); + + img_x = al_load_bitmap("data/x.png"); + + if(!img_x) + { + al_show_native_message_box(display, NULL, "Ошибка!", "Не удается инициализировать \"x.png\"", NULL, ALLEGRO_MESSAGEBOX_ERROR); + return (-1); + } + + img_o = al_load_bitmap("data/o.png"); + + if(!img_o) + { + al_show_native_message_box(display, NULL, "Ошибка!", "Не удается инициализировать \"o.png\"!", NULL, ALLEGRO_MESSAGEBOX_ERROR); + return (-1); + } + + timer = al_create_timer(1.0 / FPS); + event_queue = al_create_event_queue(); + + if(!event_queue) + { + al_show_native_message_box(display, NULL, "Ошибка!", + "Не удается инициализировать событие!", NULL, ALLEGRO_MESSAGEBOX_ERROR); + return (-1); + } + + al_register_event_source(event_queue, al_get_keyboard_event_source()); + al_register_event_source(event_queue, al_get_display_event_source(display)); + al_register_event_source(event_queue, al_get_timer_event_source(timer)); + al_register_event_source(event_queue, al_get_mouse_event_source()); + + al_start_timer(timer); + + while (!done) + { + ALLEGRO_EVENT ev; + al_wait_for_event(event_queue, &ev); + + if (ev.type == ALLEGRO_EVENT_KEY_UP) + { + switch (ev.keyboard.keycode) + { + case ALLEGRO_KEY_ESCAPE: + if (exit_game(display)) + { + done = true; + continue; + } + al_flush_event_queue(event_queue); + } + } + else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + { + if (exit_game(display)) + { + done = true; + continue; + } + al_flush_event_queue(event_queue); + } + else if (ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) + { + if (isdraw && enter_cell(m, mouse_x, mouse_y, HUMAN)) + { + move_ai = true; + isdraw = false; + } + } + else if (ev.type == ALLEGRO_EVENT_MOUSE_AXES) + { + mouse_x = ev.mouse.x; + mouse_y = ev.mouse.y; + } + else if (ev.type == ALLEGRO_EVENT_TIMER) + { + if (isdraw) + { + if (game_check(m, display)) + { + al_flush_event_queue(event_queue); + done = true; + continue; + } + + if (move_ai) + { + aiTurn(m); + move_ai = false; + isdraw = false; + } + } + + select_cell(m, mouse_x, mouse_y); + + redraw = true; + } + + if (redraw && al_is_event_queue_empty(event_queue)) + { + redraw = false; + isdraw = true; + + draw_map(m, img_x, img_o); + + al_flip_display(); + al_clear_to_color(al_map_rgb(255, 255, 255)); + } + } + + free_map(m); + + al_destroy_display(display); + al_destroy_bitmap(img_x); + al_destroy_bitmap(img_o); + al_destroy_timer(timer); + al_destroy_event_queue(event_queue); + + return 0; +} diff --git a/game/map.cpp b/game/map.cpp new file mode 100644 index 0000000..01e7ff8 --- /dev/null +++ b/game/map.cpp @@ -0,0 +1,256 @@ +#include "map.hpp" +#include +#include +#include +#include "ai.hpp" + +map *init_map(const int size, const int window_wh, const int margin_map) +{ + map *m = (map *)malloc(sizeof(map)); + + float map_wh = 0; // размер карты с учётом отступов + float cell_width = 0; // ширина ячейки + float cell_margin = 0; // отступ внутри ячейки + float line_count = 0; // количество линий на одно направление + float line_width = 0; // ширина линии + float cell_sym_width = 0; // ширина сивола внутри ячейки + + m->size = size; + m->window_wh = window_wh; + m->margin_map = margin_map; + m->toWin = size; + + line_count = size - 1; + map_wh = window_wh - margin_map * 2; + line_width = map_wh * 0.0036; + cell_width = map_wh / size; + cell_margin = cell_width * 0.0538; + cell_sym_width = cell_width - (line_width * 2) - (cell_margin * 2); + + m->sym_width = cell_sym_width; + + m->cells = (cell ***)malloc(sizeof(cell **) * (size * size)); + + for (int i = 0; i < size; ++i) + { + m->cells[i] = (cell **)malloc(sizeof(cell *) * size); + + for (int j = 0; j < size; ++j) + { + m->cells[i][j] = create_cell(j, i, cell_width, cell_margin, line_width, margin_map); + } + } + + m->grid = (line ***)malloc(sizeof(line **) * (line_count * line_count)); + + for (int i = 0; i < 2; ++i) + { + m->grid[i] = (line **)malloc(sizeof(line *) * line_count); + + DIRECTION d = (i == 0 ? HORIZONTAL : VERTICAL); + + for (int j = 0; j < line_count; ++j) + { + m->grid[i][j] = create_line(d, j, line_width, map_wh, cell_width, margin_map); + } + } + + return m; +} + +cell *create_cell(const float row, const float col, const float cell_width, const float cell_margin, const float line_width, const float margin_map) +{ + cell *c = (cell *)malloc(sizeof(cell)); + c->select = false; + c->is_draw = false; + c->pos_x = row * cell_width + margin_map; + c->pos_y = col * cell_width + margin_map; + c->width = cell_width; + c->sym_pos_x = c->pos_x + line_width + cell_margin; + c->sym_pos_y = c->pos_y + line_width + cell_margin; + c->p = EMPTY; + return c; +} + +line *create_line(DIRECTION d, const float row, const float line_width, const float map_wh, const float cell_width, const float margin_map) +{ + line *l = (line *)malloc(sizeof(line)); + l->d = d; + l->height = map_wh; + l->width = line_width; + if (d == HORIZONTAL) + { + l->pos_x = margin_map; + l->pos_y = (row + 1) * cell_width + margin_map - line_width; + } + else + { + l->pos_x = (row + 1) * cell_width + margin_map - line_width; + l->pos_y = margin_map; + } + + return l; +} + +void draw_map(const map *m, ALLEGRO_BITMAP *bx, ALLEGRO_BITMAP *bo) +{ + int size = m->size; + + int swh = al_get_bitmap_width(bx); + + for (int i = 0; i < size; ++i) + { + for (int j = 0; j < size; ++j) + { + cell *c = m->cells[i][j]; + + if (c->is_draw) + { + if (c->p == HUMAN) + al_draw_scaled_bitmap(bx, 0, 0, swh, swh, c->sym_pos_x, c->sym_pos_y, m->sym_width, m->sym_width, 0); + else + al_draw_scaled_bitmap(bo, 0, 0, swh, swh, c->sym_pos_x, c->sym_pos_y, m->sym_width, m->sym_width, 0); + } + + if (c->select) + { + if (c->is_draw) + al_draw_tinted_scaled_bitmap(bx, al_map_rgba_f(255, 0, 0, 0.3), 0, 0, swh, swh, c->sym_pos_x, c->sym_pos_y, m->sym_width, m->sym_width, 0); + else + al_draw_tinted_scaled_bitmap(bx, al_map_rgba_f(0, 255, 0, 0.3), 0, 0, swh, swh, c->sym_pos_x, c->sym_pos_y, m->sym_width, m->sym_width, 0); + } + } + } + + for (int i = 0; i < 2; ++i) + { + for (int j = 0; j < size - 1; ++j) + { + line *l = m->grid[i][j]; + + if (l->d == HORIZONTAL) + al_draw_filled_rectangle(l->pos_x, l->pos_y, l->pos_x + l->height, l->pos_y + l->width, al_map_rgb(0, 0, 0)); + else + al_draw_filled_rectangle(l->pos_x, l->pos_y, l->pos_x + l->width, l->pos_y + l->height, al_map_rgb(0, 0, 0)); + } + } +} + +void select_cell(map *m, const int mouse_x, const int mouse_y) +{ + int size = m->size; + + for (int i = 0; i < size; ++i) + { + for (int j = 0; j < size; ++j) + { + cell *c = m->cells[i][j]; + + if ((mouse_x >= c->pos_x && mouse_y >= c->pos_y) && + (mouse_x <= (c->pos_x + c->width) && mouse_y <= (c->pos_y + c->width)) && c->p != HUMAN) + c->select = true; + else + c->select = false; + } + } +} + +bool enter_cell(map *m, const int mouse_x, const int mouse_y, PLAYER p) +{ + int size = m->size; + + for (int i = 0; i < size; ++i) + { + for (int j = 0; j < size; ++j) + { + cell *c = m->cells[i][j]; + + if (!c->is_draw && (mouse_x >= c->pos_x && mouse_y >= c->pos_y) && + (mouse_x <= (c->pos_x + c->width) && mouse_y <= (c->pos_y + c->width))) + { + c->is_draw = true; + c->p = p; + return true; + } + } + } + + return false; +} + +void clear_map(map *m) +{ + int size = m->size; + + for (int i = 0; i < size; ++i) + { + for (int j = 0; j < size; ++j) + { + cell *c = m->cells[i][j]; + + c->is_draw = false; + c->select = false; + c->p = EMPTY; + } + } +} + +bool game_check(map *m, ALLEGRO_DISPLAY *d) +{ + int answer = -1; + + if (checkWin(m, HUMAN)) + answer = al_show_native_message_box(d, "Игра окончена!", "Вы победили!", + "Начать игру сначала?", NULL, ALLEGRO_MESSAGEBOX_YES_NO); + + if (checkWin(m, AI)) + answer = al_show_native_message_box(d, "Игра окончена!", "Вы проиграли!", + "Начать игру сначала?", NULL, ALLEGRO_MESSAGEBOX_YES_NO); + + if (isDraw(m)) + answer = al_show_native_message_box(d, "Игра окончена!", "Ничья!", + "Начать игру сначала?", NULL, ALLEGRO_MESSAGEBOX_YES_NO); + + if (answer == 1) + clear_map(m); + else if (answer == 0 || answer == 2) + return true; + + return false; +} + +void free_map(map *m) +{ + for (int i = 0; i < m->size; ++i) + { + for (int j = 0; j < m->size; ++j) + { + free(m->cells[i][j]); + } + free(m->cells[i]); + } + free(m->cells); + + for (int i = 0; i < 2; ++i) + { + for (int j = 0; j < m->size - 1; ++j) + { + free(m->grid[i][j]); + } + free(m->grid[i]); + } + free(m->grid); + + free(m); +} + +bool exit_game(ALLEGRO_DISPLAY *d) +{ + int answer = al_show_native_message_box(d, NULL, "Выход из игры", + "Вы хотите закончить игру?", NULL, ALLEGRO_MESSAGEBOX_YES_NO); + + if (answer == 1) + return true; + else + return false; +} diff --git a/game/map.hpp b/game/map.hpp new file mode 100644 index 0000000..f4c0f52 --- /dev/null +++ b/game/map.hpp @@ -0,0 +1,53 @@ +#ifndef MAP_HPP_ +#define MAP_HPP_ + +#include + +typedef enum {HUMAN, AI, EMPTY} PLAYER; + +typedef struct +{ + bool is_draw; + bool select; + float pos_x; + float pos_y; + float width; + float sym_pos_x; + float sym_pos_y; + PLAYER p; +} cell; + +typedef enum {HORIZONTAL, VERTICAL} DIRECTION; + +typedef struct +{ + DIRECTION d; + float pos_x; + float pos_y; + float width; + float height; +} line; + +typedef struct +{ + cell ***cells; + line ***grid; + int toWin; + int size; + int window_wh; + int margin_map; + int sym_width; +} map; + +map *init_map(const int, const int, const int); +cell *create_cell(const float, const float, const float, const float, const float, const float); +line *create_line(DIRECTION, const float, const float, const float, const float, const float); +void draw_map(const map *, ALLEGRO_BITMAP *, ALLEGRO_BITMAP *); +void select_cell(map *, const int, const int); +bool enter_cell(map *, const int, const int, PLAYER); +bool game_check(map *, ALLEGRO_DISPLAY *); +void clear_map(map *); +void free_map(map *); +bool exit_game(ALLEGRO_DISPLAY *); + +#endif diff --git a/game/parse_args.cpp b/game/parse_args.cpp new file mode 100644 index 0000000..67898a9 --- /dev/null +++ b/game/parse_args.cpp @@ -0,0 +1,53 @@ +#include "parse_args.hpp" + +[[ noreturn ]] void ra::print_usage_and_exit(int code) +{ + puts("Использование: tictactoe [option] [arguments] ...\n"); + puts(" -h, --help Получить информацию об использовании"); + puts(" -s, --size Размер сетки N*N"); + puts(" -w, --width Ширина/высота игрового окна"); + puts(" -m, --margin Размер внутреннего отступа от границы окна до игрового поля"); + puts(" -v, --version Версия TicTacToe\n"); + exit(code); +} + +void ra::parse_args(int argc, char *argv[], key **keys) +{ + int next_option = 0; + + do{ + next_option = getopt_long(argc, argv, short_options, long_options, nullptr); + + switch(next_option) + { + case 's': + ra::get_argument(keys[ksize]); + break; + case 'w': + ra::get_argument(keys[kwidth]); + break; + case 'm': + ra::get_argument(keys[kmargin]); + break; + case 'v': + ra::get_argument(keys[kversion]); + break; + case 'h': + ra::print_usage_and_exit(0); + break; + case '?': + ra::print_usage_and_exit(1); + break; + } + } while (next_option != -1); +} + +void ra::get_argument(key *curKey) +{ + if (curKey->isset) + ra::print_usage_and_exit(3); + + curKey->arguments[0] = optarg; + curKey->isset = true; + curKey->count = 1; +} diff --git a/game/parse_args.hpp b/game/parse_args.hpp new file mode 100644 index 0000000..b64c4bc --- /dev/null +++ b/game/parse_args.hpp @@ -0,0 +1,38 @@ +#ifndef PARSE_ARGS_HPP_ +#define PARSE_ARGS_HPP_ + +#include +#include + +namespace ra // read arguments +{ + enum keys {ksize, kwidth, kmargin, kversion}; + + typedef struct + { + bool required = false; // Ключ является обязательным для установки + bool isset = false; // Ключ был установлен при запуске программы + int count = 0; // Количество аргументов переданных для текущего ключа + char *arguments[1] = {nullptr}; // Переданные аргументы (до 10 аругментов на один ключ) + } key; + + const char* const short_options = "hs:w:m:v"; + + const struct option long_options[] = + { + { "help", 0, nullptr, 'h'}, + { "size", 1, nullptr, 's'}, + { "width", 1, nullptr, 'w'}, + { "margin", 1, nullptr, 'm'}, + { "version", 0, nullptr, 'v'}, + { nullptr, 0, nullptr, 0} + }; + + [[ noreturn ]] void print_usage_and_exit(int); // Напечатать справку и выйти с кодом ошибки + void parse_args(int, char **, key **); // Прочитать все ключи + void get_argument(key *); // Получить аргумент ключа +} + + + +#endif diff --git a/game/version.cpp b/game/version.cpp new file mode 100644 index 0000000..259bcbc --- /dev/null +++ b/game/version.cpp @@ -0,0 +1,3 @@ +#include "version.hpp" + +std::string version = "v1.0.0"; diff --git a/game/version.hpp b/game/version.hpp new file mode 100644 index 0000000..f7f04c1 --- /dev/null +++ b/game/version.hpp @@ -0,0 +1,8 @@ +#ifndef VERSION_HPP_ +#define VERSION_HPP_ + +#include + +extern std::string version; + +#endif diff --git a/images/game.png b/images/game.png new file mode 100644 index 0000000000000000000000000000000000000000..af04779ae834e6593225f06cf59113f9824ddbb6 GIT binary patch literal 34177 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