From e8ce216d8ca7365ff44c3ea605a034725fdd58ea Mon Sep 17 00:00:00 2001 From: Emil Shanaty Date: Tue, 15 Apr 2025 20:49:35 +0300 Subject: [PATCH] Commit after final report. --- README.md | 5 +- fitness_plot.png | Bin 18855 -> 31094 bytes gameobjects.py | 175 +++++++++++++++++++++++++---------------------- main.py | 10 +-- 4 files changed, 102 insertions(+), 88 deletions(-) diff --git a/README.md b/README.md index 63a45fb..73f5ad8 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,7 @@ 1. Install Python 3.12 2. Install necessary libraries using `pip install -r requirements.txt` 3. Edit parametres in `main.py` (Optionally) -4. Run simulation using `py main.py` or `python3 main.py` \ No newline at end of file +4. Run simulation using `py main.py` or `python3 main.py` + +## Note +You can see the generated fitness statistics plot in fitness_plot.png after closing the game. \ No newline at end of file diff --git a/fitness_plot.png b/fitness_plot.png index 8eae2dbc59b72bfc8c280a358f16977f8cbdd85a..1c6c9f3412b62ed7e5e3215409b23d9b7581b745 100644 GIT binary patch literal 31094 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%0DLD0zZK*n@$Whi8uZAI zA%5&o@+SsjO8Ee|9uaPVjJm7|JkCs4i@rA}Ds-aczi~PA0iGAMObsQQ_Ab5zUUxgl z8A1vQCkca)jsM?|3YLnV_xH=~udA993uNyLI-Ca19l&ma0f#@V1S=AOoE4C2;6JA% z2?IG;(Qv)}kAL0q2namlrV)N=!w}+?F;WOAY%n~D1jx!l_vtMjqlEEAUOumE6!8nh zW^ZeVe^Bi@w{?>2?y~-6AD&HXR8&-4TECV(QWg<88sc`?ZEAu3hDPn$`?|FEb#DMk zMomzqLa{d#78E35p1HTzOOcV0QOrV#(x*kVZ?Gh)Bi#+LGfX5Rg6iMv6*z56U8~ER z>g(%CB+SxPm^TfLjI7;@u*slOt>AD#YsbD|bT^qy2Drio;Vs0|+qnuB$|D3a5y^bb z$O9v=Ch|D>d(M8(Cc5mfh~#K&jk zdl4_(KfF^2n?t@yYWga=yD*_oVzKN24v~%oK1CtM53wgE0%!>P0e}r#NS3t`Ld1my zV|Z8kY$fMm*`S8g(nQXjI-m>?wP%3p_m@HVOgHnYDR!;ib3f>aAqY3@0n8=lUVn}$ z6`5#gtR-N>;@ben(0gf~JOtWQo(8qypR(}*T9;wo*h zgCV^O?g7jOQ7QB!;*J4pmWe#2oFXZJr9eU7OyQ+t;VZ=u#%|CuAJ{({U-uThJNNFj zbzj(XspC2_8{S;*5TV(z?%OWIYj?g5V0|CkV^SugAlh)%gWCN@t3W zgdYOy`Ev8Dw#Mgm1Y9Q95YM-Xeg2yCqM1|vi}1#X`OM7D=Dr=raLAhIj+2v-wN`*031g#)O%OYzDu zSt5PFr*IT2GZNxf7g|dMV;(XITX_9xIc70VQSq43zykC-D{EJ(FED-w5OIbeq=)>h zK=}W?Nthq?iOq@wzKv)aUaf}b0biST3V&ZD#^ecg&ignQXq)nN=eI7(!&xu zKw_bD3NrnOkV7gMGqB=-JV3Bl5oa?8&bk$BcMvBKn@f16=vi2DUXI8;yWCYwJZ0t{ zqjJB;zVQ<9P=vi&|G6imexn;p5zX<)c?m;wuH~ojdUfMUDt<61n4wf?fIdni@BW=Is Gwf_aeowsTL literal 18855 zcmdsf2UL{V)@7Mf3$}_V5>!A5DuN&xR75QhL82f*MY05mlIb?kDu|XSC`mxFfJ)9N zib@d4l2LM2LXlziwfpsZ^S^&)&8#(R&HU5r`P!z6ufFfzd(PQs?|tf)%IOp9*Rrgo zP$=uECy%L8C`-L4lqKz}SK=okmCc>_mxR6iS$j2WV|%9ywnh}C3-&gbt?e(HUEJYl zWNT+;ZFO+J;DP;udv}=H+uPVl2nbmI{f_aq$nyq=yZGQIDdyBh!zk!sXVv;bSf` z>^*{^1G+uI72>TO^TQIQmIsTsE}>8gg_?Esa8neky-RmcC|>V2Q1H{eHz}(rl=Fhi z595_PJ1I*kl(WAq*?_lST5*m5uCAr^^;(__V__3B1IYv5-rY&spIjp|-MLA6 zac-=>xj->s|Eq?}@~2lZvhTGGVK#6(lc1ICc>47glavNw$HB9+a~~hhplSBu-cFqt=YLBm-TUyR;d}GeT<7dM&qLYveG!}|?wWR&J-+d1Vz5C?BVN7o zA-`7V(2%8dvS#9w;hYhfecG?yY8#zVw_9+}!dL1NBa4A3b=$DJm-JeD!K(v{>OTzN~CYyB`-`UAFQU6;spLLza!t zo<7|%`%2KTxcB?lBApDY5HP!y314QwGQa{wY4rYO=_fy7b4~{CrnWPfWO+cmJCk>u#ja)0?all!6YC1z5Utsqpzi3Y)A)b9jYQn|qAM z{0#4b11hbpt?}nFl2-n*^{J1~FRoz~vWvP-tKpQrl_6)b$STT|;>)DiHt);H+k1Zl^au{ybHgKPK zSmc;Q*KW>nO1}Bawu=Q5J8{2Q(&~m36SlfAVKW*R@7}#-`tK_vPjEB2Gqz8*c_z<} z6c{X7vLs$L>h^GE$K9igJ2h-P5H^dZ#Xj4}lji2-F|o5J6?ronREsZtetmI#WpHn# zpN#6YmFsJ8q=gz5<|o^di+#5bykj=7&-^7QIQaQ*%T}4!#GYXhw|!=n)wM-0)8+`a zrta3JJ;LTSJhcg0%I7kyG%jC$emX=VD$A}%;jc6OGq>-Lcg%E-vT+0~34IcJ?0^(*J`SiKy_ z+qZ7r=MuU6<#V|5;=(-BmMzhb51N=)gi6m$7Az*}q?z}11sJ4HJ{B~*xm!8(`NI6H z#oIrA#kPfw7jL(YRf{=2gRIdtGLl>xAiysqq$(~h?lN9^f@$m4SZrT!ho7vbi%T{M zkaE$s-d5KUjnYT^L@XPHaa(;jT{n)NxsralA!4%CRk@?s_W_batJ|28yu7^G`@3w& z0$E(V`}Qe0HDB?TK2Y~uTP@6EChjI9M^ahYDIECL3qb<8-+z~qmY$gE@Z;aJ=R{~| zXuY~(b+i)s5b4QgJ3L~go>L1qm0r;wtrWDGjg6cz(-MDPTRXdIzb0{JRA zjzg^JS~Vs=kUQ(img5ld;bgSAjrnfbd-kby{`B#tbjt_j#%gW(?hd`5cjnCw=eP`| z)vHGyUr$vneedUl7w*N+Dfxo`cS=nD5dlOC3qJnXVFQaJeP^==mlP0-s3dw+^bi@jc8^5 zylR7EYSE_zX=R1KEn7FSe*Jn8TG`CR09&KM)vqhm(#$pNaAV%|m{6CJ%$%Gc!}oW^ zYtH1kIM@w0i@O$xSk!H$cH>mO%JAKGu-Lyd%=c4>O{EN2-?)2b8K8;ryp7Rs+xVbD_qn8r}^hS&0 zv}v4;r0KwQn^^~v^l}C*W#_(M`$4B4a-SK0nX#Tjrg`~_6*yy`#GcC{YjpJVnC#ch zJntj8TSlh!q|ka6;TIWtit7!FeO^|KG-suJsL=KB$Tw@we0j^qM|gUAnoeKGyg%^8 zivwc;1#|CO9n&fIs zB24tcg$vP0QM&~MDz=V!_QaS~NAKRV=Y8wsM7@D1tt{Vt_O_Uum&27cTWx5+D_)V2 zkugg5Ln2^qU`Kd-_;AuY9rdR_DQCD!Nwnn|9_35SAAhXw>gr<3-aK8njIlR5$m&%E zv(E1$B!R0k1WwMv_qG_sC05)qK-~Z25=>6rxbsEHJ#S~Is95g($Rz&P?!`Q{>hBrda}aAFFd$2Grk|D6Z-?|=Qyv0A?N z3W7u_L_&jK^Er?DWb#PD-dh|VQ%8oHG6ZT`Q_a+7M}IHvQ*Cg+`fxIl~f1n5=j|GS?A~Di&y82jXHBi=Dk~N`JVlzrfad&kg=gK|^q7eIj6IbW6cqHPsECwFal7tbl);*V6;hE?Q&Vly87nv~ z3LKHUG~!g>$p{T}bVTOnO2sTlGsR@uo%{aOH#yllZeR+L#Kg=T6Q>r_pVbqZlELi2 zpfKvh%EA)g+1Yt?XobK=#`Wv>$)`~=S8cF~*b{p7C~98qAHQ#5gLJ z;!Ia*Ix6Um;dicM<)R^~iYR{%0|R3bOq+Ecg@z{aYbE(#4O%hc!e44&6RVTf?_gPg zI&16XR9_RPw$68EtKncW*T=H5z4i<`sir#tCc8R2PtJ7Fx~-Xf?lFyLJ$d`~n73=& zT@KkKWZhWQar|;XPEHQ8bqsEbN!)f0M{|ByMj;}zpa4aQ0JJC4uIaB{y;9IP@%lrP zb;Y!G*r5U)Hu=8Ryd1~DFX6bR>p4fqbW)FSodlHsf}Hh~8-hz$i=Dwfq`6JoN`Eh0 zX5N?@S0wP;W$ZSd#Qy601}wpNm7;(d!i7Lb94C7$c1(?sSru2JUXCXAoS>ly0>30B z&mqNE1M(yz?>8E}zLL0>-E=DsB??p5@Nm+SWh=#^S`9`F5vxxQn%w>U+BJX&%}(j_ z@65iu2#;0{OZxKVESt28dYNfhdcu$>PJbe2QYY! zd+bfjXno}^M169|@(H=Q3h7B6VPW+c<*>RS>-@NEhXDyGf0f|w@*v=hs;?pkXu=Nt z>aJk{`Yu#tO!KzmY(o$b)VFeKXJmMIrGZe)vG@vt3IUBBCzLK zbKGAJ-{^{e@AsSRD}3Z*oX02F$L-3>${igYh6{5&vO%J)SBrGB?LW4T0Bjpieg9fq zQBi>y2}GI+s*X`+o@EJ)&_A(}g~farF|cbu3~=z4udj$Ni--{LPc#m8H0r)FeXyZ> zw5zl@aM5*r8GmxFs_A@N-IcBqrZM2sCr?BySc1ywImy?tU@2LEi+A+&Yb?$)uuGXr zIP_mabD`VGZ|LF5uth*0f0Nft)G;Dm2mu-7PxUkErh~?1TOR}mU-l8~#%U472|S1p z5(fC+y<t)FeBaDWvFZdZflaKemjTw4Y;0a^6SFxVt~Ib(esPg$uXVwE zIw|r$Mn{D_XR5L!N+(lq;v}%;X4gED^sN+E>1W)>F6SfNo2yDVK%}kD1fBW`r&>g6M4ya2hOvc@( zprGK#*w{e;y#jIP(M#bK_XP`bqhqnz#pUJYUq?nVl7AB{4n+4Eh>}tzJ!@p4o%1f3V-qubxr*v)O{C6I~ zhOyn@Lq$bB+UTy14m&vyP9_RPSJu$yQ$}a7~BPMqCP>>R#9L|P5d>DnK5&u^~#QBY$ z9_x`D@2iTsLt18Gm+{_&;rgwSJ)y3rj~qEds^+d;yT)6b+QetSJc^md^SnvH0o6s`5DyAW`sY->pQn@y_~eJjJWap z@4pk&h6p2-?{tC@Se_>m4)N9Lt0AP(0XDkRszJstUd5QjeR5Tsr2ChB`_!` zp}AQ%D@*)QAL#x9{9Z$pD{Vjv@%SE%&l%Vsw;- z;3@+Br&5_Yx6wvZ^HI@BJq3l^G#YL5h7C^vZR6~EK0N_qcT zvcS6Rlua8q)_?&qbq-qC|BUtVkRva$}BL{g?=zs z;awn6YQS2I6T%H$>&#$E#dt=+ywdB}ulpNPVorxj#XZ=gY>rBAUibX5$JEzVzUwxo-A{l>`SI-?-5HfIhJ%AbIqZz&x)q?Ox3~9VfHm;pwN;Fo0sHm1sDgrm zGxY@vQJ^nk(I67?g_Qh}wig%V$^!+_c8%Xl(#?uccz9d(7_Ns5CNXptx6ZdTz+mZu zG@(5j(<~eSp|%;4UIhRr4zTxK68fv11_o^jH)W}fxy~u(weeBstg_@uPIRCTYMTTw zBCdur-Ijl!%>7Zk9c|{BmTU(!0zYXI&&5g4S^)lCvtiZ+Lq%XMHMrd{D%p zzh*#YHy&T>)iy()ggZRvQyK`yjdvPpr9HdDEKpKWp^WY^93YL|wE&D;?|TkU5>rEj zh|s!p=~=vbTm<0oS->UkR!`I!(j@`K#ee9M_odvte*KGp_%e#ur~t~jhldC1&;EK& zFHlE-q7Q?DIudW=QSmVu6(+{Ue4yX-_4Rdf94+JCwBfR`DJB(sJUp>qWbk7tUMvBh zRDkSq8p`OiXW+WIsWiZHe}DgH0E-`icnS0PjQSuIkBN7fexz|D-#(rh?*q8_UY~eQ z)X2od;_I6mC1qvm=H~ILYHAMy0!-SJ(NB^GZ=4iIFM*a->4YD+n;MayVP05M|&%8Gx2Xm#s&{Y;QQM3>uY_s9YjSp zrB;PXyQaF&I#LO(&6*wpB#kvxq#I0B+~T`z327GfjkBi$4;(>Pbzd_{Hx41yi^7I1H=;2qX;HU#9$Zd6h=Me1HDQMC z-@gy>ho^bGhbnRP z`%`q4@#vjfuDoZvK{xa{g9e1%bx=@xVXA}njQj#X7deIiT}g4Re^)p;z~=fZ5JB6I zf1S-?^`R_;-er?C2kMcy^6k2h;B7y@da%Sbhz)Aha7zw?G67`Ztc21NVUVs9{(*sK zI}fQL%AP#we{nY~EUYoZ+F($E=8x=zPw`%Zhl}8yT=Lylv{eO_Lmi;r*~NvAkB=Z! zAh8fGYFu30==iul`jsLVtfQv6x%vI3y{5@}IdqX^PAV8ke_Yso?V2@NcR3MeHoj|r zrDRw(MdQuplfx}86SZ0*=+i8lGk@Hy-}o=MXuCe%UN{lo*}pWY8&o(EWF`>F{h_YI z_qhN~R6(Q?MglN;GbnvR@=Hs%T-ba7EH{9Xyj8|iY5Wynn_(aoxcrL?lp2s=4)d!3 ziQA8Mxhy{*DyoHy1$4Q$x}`-A$bshJyyGnz<||jO(7Qf<{3zi#7${-itJ3LM^yUpd zruW5ZW8>&_>o)yC37j#{&HFi)l$DfJeJ%1H8Uq`yprD|7_^=oHyBKiS7FExv1nC2; zrWuuP!MQpG!tnlhY0-AT!g?TlrVSf*7#J8x&-6wT^0a7EA$F${DZDmDnWN$IAtIci zt=0mUK@<@5VMrrizOK21L?OEiEdy{?99jbUG-MeC+Dbdwm49L)fZ&(uq7Wpyr_`<@peKa2 zIYp(O!5QPCCTJ#B8_g^luIQ3pu9R)mZabb3*M|Lp| zl)_1x%>1|-v>oxZ!?>OpbMkLl3{uA#{!GohCn%GH4Uqu!4L$YGwIh+$2OuWYb(IE$ zXtI)>3q*RQLs13ve%d&oy&m#{yXcrN1+7kLRy zTou4~+NF;hL6Mg{o&Z!W{HVZ0@fAev3>Yu9IKQ@ao_XWO2%<|QlQSo#7q|30v>sBA z^T3QWzB0N)$~d(kcSpA4P~+)+a0O64X~a{+oQ8FW8d6T6gw_%=2=$IiYxP`ocNqLq z8Mgu!g2Jre8J0kz3FG*)v$KC{yp&aJh@7G>1>|hIT!n@+Ffrn}c<$xPml96H!CZZi zb|l!vUetLFxptmxT$c4~d$DtndetBs~s&vW#dG-hX=F4r6 zf>|W&V?l&VLf&s`%5fS=x_*86KMx8DYz*#GBQ_6Yhk}w)-f#q-M#T|Jl9!w7|M;^$0@cRDPK}dlp*;lA(m-e;I8q&eWWWa@R$$&$Jtpzcx(;yMg-vj z0mTCXL*Bd(Hb)r3kx4!56_h=EwQ7YxGe0#-$cyG9t$E;+t1L5GqLDjI>dATDW7mJ@ zY2r<0>e9a=;Mc=cv}I~Q6{o{w66faJyp8T`*_S>1hTQof+&NNZJhU7_nXg^DmR4?T z=SUnLJe*N$y+Hld)3_DK!Cy<}u;ZuxFIA;ixJ{25kzHy?!%x~*@@P<41utHIBw#Q+ zsDq!_Ec5T*_#I++DyVSe&NE0Y{@&i+MWf)Z#iGRU7BPdkrR_MUwb>39)GE+(A=;=` zl#;VJJ#KEfDFgVA!u6{0t`zU}+oN$8%;puJKGnUrP?VIzgV+2+R96(@6Z(;RZ!`+% z=f)b9KGJhKgO_+DxwDrCKYq+>=;I?u^j^rzL#2@K$FbrsYOtFM@Aqf z?8cseD9!q8i@yLZOCJ#4?uW;meDb9 z$xcHX?IU<&2I(EjoSxm^#EkR#^G}QBz#Y}3S!juvem-0!5D@CwvIkYlqV9Pmlu^E* za>rVCtvJ=F&vayph2A7_O7yd5v0#?zvN=a}be@3QiNUUIX)+-|z?J^|CIj0{PLnJ0 zIBC@Qp&5e=Cb(qV3Ph#n)p}NnoSYnbm_2{-AvBLQ=RBuN4b-!2yM*|^*FV~?$H&1D zwo8DC`D~_5I9PVDdo2l81Bmcc+0<89Lh0$w2MVW8*Ae+{Py#x8$;Xc`3GRP1w*v=3 z_xUm9C7#n=0oiWTuiO{Hz1e~7Y4f(1wa=xR-UlJj`F-KF!7P}|v(Ml`>f_jN zKHDt8A6$ zI3~_l6fDSZpq7-DlB9}Y8%h0!*W2B=*Lq<^9*vhKyU)>?k4Q;LksP0}po>VO=q4Xq zasYxgZ8MM(`o(zE5hK;jc%|g@EzfmlNk4q8J=GQenzJoAw(WgkS{X609}O7A zC=#_CD^Ap&#&pXBG#3a}lX_BZgj7*h!JrUAi&1v&Malpk=1SYtN-11J&W4-8%V zsEq}l1w}&afLRotHY^w+mJWhN&3@VK;E?nEMpUXoPDi(|SJ7<&58u3De-E34> z;B+dDxKiG;yO#Y`^l`a8rvi5{GBSb}IR)F=%M4ivbEG-?yRNerf`U7>{m^9t zH$xvvNG@2=fs|wK=!=E5iP-2z>F)0S*_WW00_mu25g|A8%fqY7KLgBz(%g6FpJfwd z(KBf8e{Yn_>P}E#5K8Yul_T!DSU?1Z(w?%%9sYkFJM87`EmU}d!!u-$Y1v$x=Js0~O!pW>2& zOUuegV+Fphb6{YgAJ;AvX`jvU=k$W!NC(zXqQ{-j=lV~IqvfG<_p2eeT^vzE=o~GD z;U_9#coI4w%Ryrwl5_C%aRvn*3W|#SXNGViOlRWsmsMxk0nYy$2MA7> zfkmq(8s&({$UA!MXtoX%z;oa*)TjaPjg9H#j~~1>8DdC7I;cayLP;=joTH^){c#b7 zDs@2OYBrd$%KxnHxGeM!-WvLV>ypxb_CnC_K;5SS0`{d2Mg{0sfrlZ~cpu7G4G3>E z1eM+yu9H?>I7&pB0Nu2SnA~pNy7g{lAtVH7=wEuA+mQy;kKyXFi*qSOZb+y33o{l< zKmnk$Z4@rZYiHZX0aUKl<6{S-YLzo|2(ZQ!o(9s9;TdnwQ?qMo)B$s#{I-SX0kQ+< z?sHrO!mmM|Po5>$>)lSWR)g^g;8d_*&J!I5y{ViS<@dL2D8skkDw`YGz~+; zGhadQUrY=^&QWkMA#s+P&HDNJI(*SWyL$BK(cpAPudTkv<)I$w5)GNw^$% z#KpDIC$)~yEg@4A4i&O`|D$tOys1(E3y4qRk}KjlPxzJ*&hgPvTl1$t4mLNC-Elt> zW!nwy`)hdfpx_g5bFiQ95(|1B& zC6a&GBTkyw}8KhI#Fi1vjR2ylf1{t!|)U3$a4?W>hUskGCtk2qO9j4i@WhZ7I}wtT=I#S-ZlMN7e(SmKUBtP)ROuc_`}2 zqK?R`#fSY~BrwIh4b_)Dzd&(H%_iuOr7AM$ZMQ`|`0=drCN$lDykkDi4=I=ONh{)K zljqAS{^~>OAfz;SESYA9rAc5haeM@vz8VtLh~iE+|F=L$a2CVykz z%H5z`GFlvinp;{#hy%OgIh)i~qW-Dr>xV)Lhy=(9(0<*u#_#^JKij7_%tufi&LK_K z8Z6Fey(=zm^jz~6r30KXelO+J6ktzmtiqh)4ybiAoez}9VS*e${SzvVg$zXx)59AM zPitcB9y|-O%BE(tdE^|lKz1%%uM**X7`LYK1Ky$kDIK}m3vc_sXQD6eT5@3L&Le>4 zDxm++AZRA*54~tMPGJ)NvynkilEwpPO0BEpVJ&12rN=_@h|c_ej~o!pra^ee{sf`| z@`%DR?)8_J49H9zq3ia^qO=sv#e{jpgR4qFey2Ud8RkQMUWBp&EXg_4R$u`5sg5EG zSGIetyC18#Dk@1z1saZbYfj+OD*2H2jzh_ikjVbh1(uCr44ugt>>s$MWmHwTnIj@1 z21~aKn?6N!&%=T|*FrgqLw2+Y2xltNZkoHDc2ZHX8p5uy+tl|2dg+G`Du)jjj#!O^ zIJKUEz)+LxY==WY+}xk|U^jT$Y&*UBJaw;LwmJ-t^7?%HZKl3o$b%MBAUQMHevR?3 zZm|)_Db#J0iZ)>28lw!4W5_>p_Q8V(6+H+kvR^ZNX?ukH9bwbYJ3v1$XA#7F`}XZB zVt$6*Mc?5Zgr+}r74U{@85!&G(;D=EyXqf{+eJs84$+yxVWaS@;w$5B7s#JF3fhcC z@Zz!irOJ@IkRakw;fR&*Rt8qxm0IAlW6PdHhcr>N=zUW^I=EZWgnK1u1pZnG2ojHU zh-#}5ZnWogunJklXr=A@^mETzS#ejSf#0OT=>PQM>{VyykENvvZ<~;sc$9TzmInT* zlekh8L7SnM0`4>(dGPpg9Lnq#@fjz`TtwZ61XvC5J%Iq{6%o+@SKJd=m$;!nFl~`+Ucu+h1)NJ-)u(2BCDE*ky68D_PzbJ&VS!x z+^EAiMuh`*1#Q+@nED*f8vESmB8603ykWsV8I_4ZD z?~K=~ZdBO&r;>yYjhICeN)fR2ULzy6Hfy$G$wjyPmz;L_-%UE1QWSWKVxdw&{3BB% zppw}hHDUH5MoZuMU26{rG8SRedv5OT#M+Kn=I7^!1tbrh1vuVFygdP>mMm~pRaMEi z4OqnzrvK?0px@kpgnQ+aS?wg>1{pcew=_#&D?k#MGdlM9GKJr zu!0Y`NVz~*Xk5G)L1q~&;zj@USXi&|Lwl9Ew5_e{{PGuEctlY962!aR`Y14v$J5i( zb?U)0P<5aJiD_Nl$^-;5amPVN%_CzrK)9hBH*LDp;(7Y?-M_H5*X`(|Kgq6=_wV0- zRkehGh_LMXoDAy;OmZqeRSl|=(nB0%%!sfxf^pY_QX*{EP3#5@G57A>tKuNy-5vE< zN~US$E&$e(P)_$Zc*61kls;GuSCpPAa$w;^ERi&7!Ec8nMFM%bG7KS;5>i#J3Gqu9 zd&t*YvJzn`)5~|$hB=ral2q(>Nt{&3r6Ah)=8qsG{FgBqFSq$8*y{S+3IGGC(E`s* zPsb{f_KO&VZO=i2x(|YI{>VluVQOGhsew533cWny?+vOCKRvqXVLV*)RnVcux$U$@w!1NO!fMx(Agh$PPz|c!6BRMFoe-0?K9g z>EPI@sjEY+dFP0U5sY2Z^qTYd$lE1d0bWi+jZsLMjXlVIJX97~!5{6_-bK}UdGUsi zAPYQr_nWSQw;~1xNZSBWME9$1TU>CO9feVbBzhDHdO9SH@>bD*f~nGW(lwU^{0F6i zVgC~3?)Ktcl%@Y=hv)tm(#d~jP}^VA(_~#hCOyck6h>|O!3Eai5WxQ9$NsR~nBP{1 z3`)$h30*oFzCes04uLotT{r)OhC27*K4&%tqH56`S+?eC6Soi$A)Gk-s1W%oeM3taYxigNJyykt-^}O0t2C&As+1z3gB`EG_`T^HE+RTvnhkb8^5? ze!dU_Zbb!y2U=i-ld`P^1d@*qVAJL*v*5!p9~~Qm$|TX^HdcPy$44EsT@9GqT>_h! zzvQ`Q!1Y9sMO(`PL|BN$`^Y%g%z(jSJeU!Qmo7Mcqj9>c3L&c@bt($vjnjZxh;ud$ z6D1IRlQHz8+9?66nmW)=EmkSPN)nCk8K|AZMZWJ#RD(=qv$ z3M?^D!dM7boK~{_6EweEaVUsn@UXigEE$@hwSU!cE(FN1~^>;C-H^RHG|K!;J8#DPoa z{Sykg$spWf@iqzc<1gJW8XErePr>M||7{+Z$<)bWUot*EUPA`$kbb=Bh)Z~}QdJfS z9)Y!nbUU{uComn=59k27f-l_UJ}E238g$vDBshox>vSKwQc?THy8cTlqM+J z@LCk>W2@G2{v%JF?&#`@LaX&XK3J&OIbTq$LUd)%baA^>N5<9FK;?xOw=TiI{s+Uq zx+ze)e$oXK6AvNOleYKy^XCakc70Xc7_>T$R+_{aMsa1MqN11@pme5?`^2+C{X;V4 zyZK72g0zw%HtmP;+_AP@CB($9j}fa^GXAzE7>JEGD9DElR145M^yOto{5)yQVIBO? z)O2p2PAbp%xsKwkWabSgN);Up)33jVkL1rL?PUx~DKhQ2r&4X`m- zZ!JBO@!m?}&VKvu-D8O4k0pmQi|hx#y!?=l!zzT}#o!eNHvaK=h<0Ic;Rg|Yhafcw zTIWqXii31djHo3uHYL6o>D&q@d8E|?KwlYg$C*EomSMG*`N3BwsiTn(cAFG|=%HaA|g&j0w%WcPi|DgQ{Lgo^|=ERY53ui9UYIla5l}iiq2^d)>d}INWSz zJ&Ru6x7_$3DX6v~xM;`MuNR;?;1wi%UoKp?_wyufUl{!OA;?yb7`%+!Lp_JAJ!gaZ z8q*TSZVU8~4+fMp467(DJqQ`j7=nvDw2guSIQm^#8(|Z%MusuMU>t^cm#@QpI)?~JMS+681Ug5D`J!ti|Jh(`~1@wykDjWctc#z8n%cvUY_T5 zmllgqPn{wr6431y)_4B+;~s`_h{>W;0^NxwI5wC(1}*<-Trstl#6!b;7!4L(n|>l| zoqw0}LL$sE;M&BJr)&qoyMryuC=!RcL+#kHV=sGn1O+R@3%KNuA8(wE0m2axsSPI) zhsW`(9a}h|xuqwI2YnhQ$}!aDq|m~oq#e=&HCKA>dl50uf_tfZ#mnAxGp)e#N;w>6 zq_}veD?H@m1%-s>>RnPtU!Qg_2Nu$zsUDqSCB*UxGUx<*rID(uysBo;bVj;WOFTfI zGCIxEaXGn?m}x_%QinCpo1PF7SyNM!Ko^*5qg@{JOWONs%o;2vRas{G*-8dh9#}iICB4bl{G1^fh8~SY8Yv2pIY-U>+(vJ6P5qJkJ0|6^JfoBX-massMvI~tl_4pze(-Wi=>-PIut=p}0FQ64RAp<=yb(W=DHVu}-z;YQ5slm^SP?-I) zrn`fD(a@3UqH+WS>m!Us1_6`>A$)&M=U|`*QmOUZaDR(WQWY!0CL^K^7Cj4Z2hTe% z>|5H-5mX+y=vfVlin8~&7%#LO{~KS@q3aE!s0Gd>8JbbJPFel*%~pJyfeWN6YCncX z;IsEEqUXUE1YZrac^hmo*bu9;Y?St29+K||$*e-l+=YD8KY?ZMduxu)=KS&vhi@Fb z^kD98@ciE-+e(H%3R>)u_F%%N<5`znd2E-P@BI)>?82ed7%z41N(u5&N zromf`1gCNGJrorAAnh`iW4Vte;0(Y_ddT*f)Q1!Ij`vhIvAW0SgTP`qse>{Txz3FN7k# z$dnb78<@F1d;=rldw>Cucjb}h=ycDy4h~F&Ej&XrU)h=tXh2XQ>`B=;TijH{Cr0y9 zSktEmX4eeVCzHVm3&0XW_+#hLoXbL3_MV^DL|cJu6N9-JT;L?_(Y|xhWbhBJ7XsAx z_XRx7Bqw2N>LiWbW9q`Yckj$lq3fM4LW#$CWjkX>!Qy-}0)=evYz>+-Fpt?xrs!Y7 z9YjIBLHU68bOHpb%hXqIVr<9PIedLGxrod20VT07aK!<gStlX2l* zUKDrKD8d5lhceEm5igc@8j7>GGdw`3sxiaMC`tHIo2N%%AXP`=lxrd`D;&8vNF(v; zeT|FGO{m~#_9prhl1s{m0@iUZqC$B%c^1@S-kD9-Ll;Jl48Nu9Vm60Cl7L2P5UF2A zG4fR`r0_i>@r6uDay|}vBtDXWU7|4~)uh?=oMscZJqCUIGxjT)r4?uY8At`fE0Zs* zAm32Yz`-y*v4Dx!&6w(iI=9)`Ol;S#qkyvz->#*aRImf;%K1r+{(;Q$94SU(o|SUg z3{r#oNhIY=Xdp2A9wdfea4Bja_VZ`@`QiB?lLtgCM$8ESL(YECKZAZbip(9ubfyW_ zV*(>CWa@^&9S+o3tSxa9s~}~slRma<-j>%1e}&W>1if&N{IO%P@TL>DW3a~@#YXzi pVHl((n~noZVQc$8^{qh*94>Nid^|Z7skk= self.animation_speed: self.frame_counter = 0 self.current_frame = (self.current_frame + 1) % len(self.images) self.image = self.images[self.current_frame] + def count_fitness(self): if self.stopped == False: self.fitness += 1 - if self.vspeed == 0: self.fitness -= 0.9 + if self.vspeed == 0: + self.fitness -= 0.9 class Background(GameObject): def __init__(self, image_path, x, y): - super().__init__(image_path, x, y) # Initialize background + super().__init__(image_path, x, y) class Barrier(GameObject): def __init__(self, image_path, x, y): - super().__init__(image_path, x, y) # Initialize barrier + super().__init__(image_path, x, y) self.scale_by(5) class UI: iteration_num = 0 - horses = [] # List of child objects - horizontal_offset = 25 # Horizontal spacing between marks - vertical_offset = -25 # Vertical spacing between marks - mark_size = 25 # Size of the marks + horses = [] + horizontal_offset = 25 + vertical_offset = -25 + mark_size = 25 + def __init__(self, hud_image_path, x=0, y=HEIGHT): - self.horses = [] # Initialize children list + self.horses = [] self.hud_image = pygame.image.load(hud_image_path) - self.hud_rect = self.hud_image.get_rect(topleft=(x,y)) + self.hud_rect = self.hud_image.get_rect(topleft=(x, y)) + def add_horses(self, children): - new_horses = [child for child in children if child not in self.horses] # Add new children + new_horses = [child for child in children if child not in self.horses] self.horses.extend(new_horses) def draw_marks(self, screen): active_marks = [horse for horse in self.horses if not horse.stopped] unactive_marks = [horse for horse in self.horses if horse.stopped] - - width = 10 # Number of marks per row - - # Отрисовка активных меток - xa = 0 # Horizontal position for active marks - ya = HEIGHT + HUD_HEIGHT - self.mark_size # Vertical position for active marks - + width = 10 + xa = 0 + ya = HEIGHT + HUD_HEIGHT - self.mark_size for i, horse in enumerate(active_marks): pygame.draw.rect(screen, horse.color, (xa, ya, self.mark_size, self.mark_size)) - xa += self.horizontal_offset # Move to the next position - - # Move to the next row if the row is full - if (i + 1) % width == 0: # Check if the next mark would be on a new row + xa += self.horizontal_offset + if (i + 1) % width == 0: ya += self.vertical_offset - xa = 0 # Reset horizontal position for the new row - - # Отрисовка неактивных меток - xu = WIDTH - self.mark_size # Horizontal position for inactive marks - yu = HEIGHT + HUD_HEIGHT - self.mark_size # Vertical position for inactive marks - + xa = 0 + xu = WIDTH - self.mark_size + yu = HEIGHT + HUD_HEIGHT - self.mark_size for i, horse in enumerate(unactive_marks): pygame.draw.rect(screen, horse.color, (xu, yu, self.mark_size, self.mark_size)) - xu -= self.horizontal_offset # Move to the next position - - # Move to the next row if the row is full - if (i + 1) % width == 0: # Check if the next mark would be on a new row + xu -= self.horizontal_offset + if (i + 1) % width == 0: yu += self.vertical_offset - xu = WIDTH - self.mark_size # Reset horizontal position for the new row + xu = WIDTH - self.mark_size def draw(self, surface): surface.blit(self.hud_image, self.hud_rect) - - - class Spawner: - active = True # Whether the spawner is active - delay = 500 # Number of ticks between spawns - tick_counter = 0 # Counter for ticks + active = True + delay = 500 + tick_counter = 0 def __init__(self, barrier_image_path, delay): - self.barrier_image_path = barrier_image_path # Path to the barrier image + self.barrier_image_path = barrier_image_path self.delay = delay def handle(self): if self.active: - self.tick_counter += 1 # Increment tick counter - if self.tick_counter >= self.delay: # Check if it's time to spawn + self.tick_counter += 1 + if self.tick_counter >= self.delay: self.spawn() - self.tick_counter = 0 # Reset tick counter + self.tick_counter = 0 def spawn(self): - - random_y = random.randint(0, HEIGHT - 100, ) # Random Y position for the barrier - new_barrier = Barrier(self.barrier_image_path, WIDTH, random_y) # Create a new barrier + random_y = random.randint(0, HEIGHT - 100) + new_barrier = Barrier(self.barrier_image_path, WIDTH, random_y) return new_barrier diff --git a/main.py b/main.py index ea19bde..df35227 100644 --- a/main.py +++ b/main.py @@ -3,11 +3,11 @@ import sys from gameobjects import * from genetic_alg import GeneticAlgorithm import matplotlib -matplotlib.use('Agg') # Используем Agg бэкенд для сохранения в файл +matplotlib.use('Agg') import matplotlib.pyplot as plt import random -POPULATION_SIZE = 500 +POPULATION_SIZE = 50 # SET TO 500 IF YOU HAVE A GOOD PC MUTATION_RATE = 0.5 POPULATION_NEW = 0.1 POPULATION_BEST = 0.3 @@ -42,7 +42,7 @@ last_barrier = None def init_game(): global gameobjects, horses, barriers, upper_bound_rect, lower_bound_rect, spawner, last_barrier, BARRIER_SPEED - #random.seed(BARRIER_SEED) + #random.seed(BARRIER_SEED) #SET SEED grass = Background("images/Grass.jpg", 0, 0) grass.set_size(WIDTH, HEIGHT) @@ -96,7 +96,7 @@ while True: plt.xlabel("Iteration") plt.ylabel("Current Fitness") plt.title("Current Fitness per Iteration") - plt.savefig('fitness_plot.png') # Сохраняем график в файл + plt.savefig('fitness_plot.png') pygame.quit() sys.exit() @@ -160,7 +160,7 @@ while True: UI.draw(screen) UI.draw_marks(screen) - iteration_num_txt = font.render(f"iteration: {current_iteration}", True, BLACK) + iteration_num_txt = font.render(f"Iteration: {current_iteration}", True, BLACK) current_fitness_txt = font.render( f"Current Fitness: {current_fitness}", True, BLACK) best_fitness_txt = font.render(