# HG changeset patch # User Markus Bröker # Date 1229172043 -3600 # Node ID e0dbaef723620b90f9bfba8e0cd966cdcb3cdf76 svn copy of the chess engine diff --git a/.classpath b/.classpath new file mode 100644 --- /dev/null +++ b/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.project b/.project new file mode 100644 --- /dev/null +++ b/.project @@ -0,0 +1,15 @@ + + + Schachspiel + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.jdt.core.javanature + + diff --git a/bin/.keep b/bin/.keep new file mode 100644 diff --git a/build.xml b/build.xml new file mode 100644 --- /dev/null +++ b/build.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${ant.project.name}]]> + + Developed by Largo Enterprises in 2008]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/black_bishop.png b/images/black_bishop.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7408ed6dec65f655f57b0b15654266f990e50e5b GIT binary patch literal 854 zc$@)N1F8IpP)?CAR=56qOlF&#+C57<4XA4aV322xEW(mA;j9^Peg)iY<7h=$+C~n zxziFtP@d58&y%$1Y zwOX+RF4j2={2a76qcnTa+SPtmK`V+P0)V@_J4h+HhW%~_#~?xo@}4xC&5-B$)_$Sa z>EJ=j6G+n(^Z6WgU1Kw7{q&zu?j2O&u3ERZw~$hzX_`^i-xfp^mE=@e<2 z_WIr+hW*EA$wQJPh~v0d-$6--aAheaDWynC*}7(yWu&zxYb|+LYe{QOudlCr-TNeh zRu|4WXsz+_@qsvwk>@$Awa{9lswy;1!(s;;;j%2(A~F%d7{i_>2ARWERiP*fR8_UL zk1+;yU56NcCxR&4XE)`XV{_v!F7B9iG{V+ee13lR>PrJA5`z;aBGJddzH@j;vOvHS zkA0g3pE>OcY`_^2?u(Nl3>-&#Xrdl08;>l@+TU>;V=|cl0G7)onx;Y1G*~W|0MN_L zj{%FqTI=@RbUHFHbbkcilB_pn9j`}=!5KR=_c>zzkHq1~HJ z;mKsut9lq(>7x{Wd3kC7?AOw+Lf&|#RGSod_o*{$UK?)C@6mTXPM=9Lb_4kDza+ys zS5iq$)41n(pp-(JX+Q|TSMM*@;<|37Ow(A6JA83*f$!hHgHnnO-v9(a3}CCW#4>_7 zNQv%%FJHdk(W6HI0A1H%Sr&pMK(bBL$K;$>HrI7IA%v%5oO^$G94$K@h-k90W;F8b_=_HovmblD)e-q2^)9P-WnfB-w3E`R!(m zamE;LR3pjX_T2~}JpanowMLZ=!?5HlDWxz?69BTGK>DPEAZYoRcY|RV7z_pgQlpjs zsp{$qZt3*&lmmcm+aHo|nn=O}>hVSc_?zFbqR^JSpL-r?}m25k(O`efpHCkYO0DCTxqmwuNDc>+9=m zEnyg9G#a%UuTyBLX}4BiL{Ku-&&$;z-#3b)jNE#?MifO5uBr=K5grT%7>!2RQ_W8< zGhCz52nPoTux%UH*VmPcwJa+$KAX)3Ns{2~>?|{!;@)PnDXb-L#8lCWa9(|*C@K&* zIXS_}$w@)pbzRuD4cB$S7^@^anM^<_1&~_(#bVL8n}%UzecC{|0N^+d-oJm}YH;88 zOGalhnWRRJ0OgCI@i!kg1dkyYE9Gd#bSZQVgb0f_e8w>P(}QL(el&w49}GMcCK31MPGek*QiQ{TEf%m zRI4hU3)DqleW6WM)wya}2gh+>nkL@9eGAhxTW2nJaddQq7cX99>FM2CRv(736XCpD z5WD>C+qa#^%NrzFw$w)vzp)UX3FfMi|3#=4^Y?ywn8nfr!2Q(?s!><8t}Lc^XrAYB z&Uv8_-=(!(zp_dTbX9E;E%}k37SKC{<$$^>3+$b6-)Kv?^*hWt*BE19jKOtXc%BE& zxw4-W@|^QRwX+VkZR7Lj&!zHlTe3h8k(S6>^8Qhr?8y+vapunAI4(RW;f8=>g>t=K zgE5Bndfj!o?TuEOBN-X;@^|ILxQsDw+jj2;YbT=x+@4S{#xNKRN-3KtlFN{fmhNgo zeuqWH^KNA{uSpN0(z>pf-e2GM@$TKb#=dn)ylva1cUDAOozO+4Ip^H-yjFg5KA-c| zYQ~w7>~y|I5+?REH9V%`p?%^pHTEsQRzf@ zu~;Yv^W*Ut^Z7jc{rLCe^nxNy;uVJJ<5;%yJ3Jnbad>!$j~_qc{QSI9?)>~5$H&Kj ziQ5=DM*0avgOZHLW4wO-x^WH_bWR?I!y%qOe~#gBSSxpRb%o_}iRGV5EdO4nH@8T4 zwn3d$=TJeX9e(xd)$K17z;7tjzNEORL8)T3TD6~}2Av3BUS490EfOTSy0`-VYVMOS zwW@qBv0N^J0RSD!bJU@8;1ME(4`12vh;wA1#pe3{MWS=u1ExhXU!LTwd<<^fbF>jMdJuD>@UVl$O#w zaoo{_Iyu*MvxD@!{9ZqKxC>F1y&Dhr5g-U+d4hw%0ECckr1u?5cWHgZ(mN3rjZ(@j z%i0@Z!!S4@WGAAX@?n98s&DP$js!XpE(~%P3)ub++i<9O600007&N=LMI}lN8E;f?T0>GGIDQK;apNR;}j6BbebHRy+iVgI{?2zG$>(DVAg)9+?b56F~ZD(TY8uhb86ovTJ zWhqV5GdC{F63#h%eSLwMN9|WXtCVWRbTHi7jk|`mR-ALetvuPn_tFfE#U#Q@B@0X- zykxS#$ZpA(pkkp;c0`1-EWyl3(^P(cf3K^{_mH42jnK7ukW0sMgr|}vA~@%Qyg1Z*HTSzlIEW$u40&79T4TLlgPF14?_*rUi{Sk* z@IS*cGpw~BA}?uU%vonN2YLy=zrQ2Pvew0Xb3WvG4(A-iqjlwZj>F;5T5pU&Q55+6 z{A|r14hJyv+4?Eyb?Ge2T0LvmoDa<0sbVlQetv#hb6RU}#;&RgWm%%Cs@^kuF{buv zt;Jd^TIpp*)tJT^U~cG*7c_j~MiyQ|KR z*T?L7x^Bo}&Ap5<$N4bW8ZQf<;!!MHW3d*V zs&g%t@Kl|v_eU*DbLl?yrPsnk<(qrJkh=!|oz}f$u`xUqPe=F5+C00000 LNkvXXu0mjf4xo$= diff --git a/images/black_pawn.png b/images/black_pawn.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1483c3b75fd31976cf039703942b276006a9f33c GIT binary patch literal 769 zc$@(N1OEJpP)J&DuWv_sOX7unpJ_ZR><> zqql_bPBJO2A52Q?e^*+E!vX8{8dA!(f6z*6yv%lg&B&j?=r!|)J1xDl zwYVfax{&T2Vb_NTXM|rd+{f|I`Wm(+3tf@#T}Zoz^&+0u8dX&x&vQsAv0AOL*=*YP z@;rwz23qTzF}f-vwmof4T83eW#bN=iHRkgp+K(y z`6XC(Y&mgwkN3@Z21oyPwbG~EwQ!VD_)Qp`TY$dtSD%A9j#FArN-3vL8G5m><2Y(E znJCUVeBUpX^&x{sZ%cYO9D;~28jboI(g>$d()u+^x(a-Jrg?IJ^C z3!8|iZ^F@Ia?TM&QSshJj#f+BL_B>et;Zsw65BWKqt7LMEYj*_N&i>STH$jrYZYu{ z>15$^kye-XotN}ENUIC}-@{Gt6ZWyK4AvGtr_x=)Dj9<5hi;PFtpx`Ir z`)b(LXD`JQ1OZ&v?MtqcVKSNE;^G2Hl9bB!6rN6}Afls$aOZ-KrijR>FqBgG3LsPv z1d50h0QFg)gf>$ayt ztsZr=*~G$4+5k{Qq~bW1Q)yU6n#@9*!W-{0QeYTIdrZP4i!4`U3T=OGNkl0c5*l*{2hw(QN#4W`p6f*^o1bKq?~kR*g*i1Bz_8+@2xLt0jzmL{!3AR;ivAcTOF z5}fmY&SwJh;pg%lkH=t)*@)5_R(sgAujcc4>6l8>v{g80BB*0egq6ZN6x>x%2M4=Y ztyYjyf-wfybwA5}04{(8aHWfY0%TcM$;L#4;cy7obs?q1cDwCFWY(@F5#j#+zW8l6 zo8jr{$yi?>L9^Km-~b4~0to2SBU>yMczt~}wvFQ$p63;wU7qKi6t*I*ySqDFUtjN8 zWw~6Iye18OED;eF%LS5E0v__h)5@}}GK#9R@X0+b4IK(L^>~C3V2l+6h6Et~X|Y4r zI`%ny()-dTB71pxDTs_QhKGlTqO1?5?yRuy`^7cD@2Dd(6HE%{d4AN8v9rQa6k$G} z8_Vj5%mfot>x{>-6z=3{rD=-IW>ZO4bwp-Dm4#i`-TPwETX?9UJ+1M03?T%bpPy~I zDWUEx-VHaqgojo);?JGm>hjU=Uwco>7QOz@!%x7kySDV}6#g4;!VTu$0MGN_I1T`S5Q4>GfhdZQBuQz_ zZnwjFy{BTrLnol-8`* zYfwt_xz7m0Fkee4h2uC%&wd-0PEYGo(Yk9&0!Dc7(DHD8lb$@SNRk9;ngW1Q(GUCuysQYx z)(Ihu1+FPAb;bAnyalt_Y;ZgtaXOuFKA&snbIxnazBElsB_*X4*Xz}kneWNN03d|G z`Fw8dLkS^T`&2@R&NX!%qYGM-;Gy%Dp4Mu$0%Ht^!=W)1F~%wl`8baA=6*IOj$>11 zzOSc6DaCfX#d5iPy2iF`*tT8z?lCRdwvG9GZpzH}77wcZtKxjm^WIuKXnVNn&EKo1 zqpYNC`mOu@u66i$`K0v?FT;zxdiv_*;bMU5gU3Lo)12=lxEP@NpzeGPbZgGHZs~8^ z!fmu|ab*wp>CrZd6&N7|v)N4f-LbNVO}vaYMbQ?<7;M|l9b(MGZU3UsCv_fHWpvN* t=!%C{!6w=&eW7Bjk)GE7#I&V{&Od2;6-+1duz~;p002ovPDHLkV1h*Lj5`1T diff --git a/images/black_sun.png b/images/black_sun.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..39fd98c1ae1ff71bd74b54fef966598b5c06689e GIT binary patch literal 407 zc$@*30cie-P)vGk$=f!lOiMMv4y+o+Vl{LcB|Om1s?mxOz(OlI>kvCA?F%H-lK% zf-IrQA`-SFOGq=Zg)Pbwl58wt%d!MFV^i3JEWyco+{?qOu%~v3R%SFzcx;z=%Z`Rq z^4%`+A7eV`-;! z&)PU#+I6v0jt~D`^ppeQkBdbA3xH+t@(`Wlgnx_@np2a`A#VTx002ovPDHLkV1gn8 BsC57U diff --git a/images/black_super_sun.png b/images/black_super_sun.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..391439b869101db761ab561d811fd2425b06aef5 GIT binary patch literal 623 zc$@)m0+9WQP)e$ryiFSkOtbm$ebTsA$0!5jmcuzts+8>jl2MJ{d+z zDXKsrA|>3Hh@hnfoGIc3P=Q&XwV2=(;3&{q3~(247HBOGxH(F%g7w-q0k4Gh`Tzs( z0Q;527YKMK*soBZ)WAE!euem^iqZ_&SqF@bRujFaz#drZgC6)9H2o~inD^&C*k{Y( z8b(JqVv(bL&U~i*JdBKJ%)Yz8$mnK-Z^XvPclQWq?o|w1OSrw9qw>X&=90% z(yKRlJWU(ng;5q?E+Z@=g?-x6I>sLTR(>mNN?YFk`I)GxZ!5Jp+gI9n&(g=COlS|< z*r{5?_V4))gKG_!Lw9y&1}*P$8CD*4%WbJ&++c=M)^Nt&%(5{AMy?h_LL+_8e5OX} z2xxYnq2LI0E`un2uxEWm^)-FHj+S0BWO(fPpYdGUBBr4P=JZrfTw8a-&ohqRUrSR%Du{RwDgr-*6BF@I23Y zyPrmwbB-vAthY;SZyus3lJ$BWo12?R(-eDqd$_&5MV{wYgv+{0A0HnB02pJ)vJAGq zT@5LvwF`jcoJ%2u1RyD;QV1a_rShpO=KEkR!pqCck}-x>s|D9}K`GUuWmCMY5GI63 z#u$VUx{PzK?>n82t_PT1h!`iV=H6DTg&+uY`O?yozR&X7-ML++i+bM zS(afm8cpnwfTyUZX{v>aQVQ2~(QG!+Znv?puz)y@XR6v(hIF^v)zeTA1ZXy!6QZTC zy}ga1D2xt$Yu~WrI0%9Oj^jLgriQc)SR?HFK78NT(^3^t6oFD|r5|6;#QSoDjSgug zKGl`hTR1#C#P#*{zb9G`4-ZI^L@RO?N}M?7@I3ETA-lZ1L|K*qX1jZuIbqc~wU(YH ztoFXUySs0`=jiCjh#O)>rQaK(Dw;)67+-5!Av`?|O=C0~y<2ByFzsOhkV%qgAM344 z2q8J=M*S^o3lGopCYF((1#5&moenlOHr}i=7z~W}O^}L;9_=7=#e1vVsa{ zXJ^0MDbMp{qtVd6(=^56;v#NtZYJKby1FV)PELM%SQ{ZcUH03Z`o(uxi}1gUFPCch fCOq%>a)f^ZoA%=%+$}7S00000NkvXXu0mjf0rM+V diff --git a/images/white_king.png b/images/white_king.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..afbac3570d28203d3d645ecb14e9af6e72a9b920 GIT binary patch literal 2301 zc$@+K2m<$sP)|3H*Kpb5LsOK1;e zp$BWBm)@hWEpivKfv?Dvw9N;Va9AriL|#(6U83*c%q$IoAX4Ie-az{<+X z#KxaEVO`fj2*J;uhX{Z-;qiwORupBZSBv9#A|^SGxn$PxwQJY#XRC$I>(|iBWvIFi z+qScI2LO1Uhkt+Z1yHZ&>emlSDUOeiad2>e&g<9sv(?IMDN5S0B(CV=$B)sj)v*8L zk65f$K`4cyoL$Vc6;>1_rU1z4-yQ%vLm$Z)c=zrdoj~6dsWt@Xl!{Q*z z%gZR2%eZ&%UQfdS-1T*+wvB4F%KNOZufuiSL|@s!I;AiOLEZC!AOKuGilXqrtJNyvIELdm zuq-PfPn0Wz>^aM_;5ZKAIL7AYCKeVJu(Y(qw-F%(mSuqul9*fH{LYLk)i9+L^Yilv z!w{b5Aq+#l!T|VB08mvmv8q?DT;UpF&@>I*ZWmD$VS0KR@87=%JP&FVfe^w?H4H=E zXLfcLnx-XWtE$T7YMKV1cgz7jhseN=KCz82uIRJ`+ea9NsMqU!r5(qStxZCs?C*Xo zEG%$&tyT-2P6xZUZUKYc7rZ_Dj_u_z4Eemo zy?m~~gJ}c+W@ct!7zTnMKoms@@(i1so2l~F*Vhq6Q9{G2s-jRRB;@s5mN;%!oQtrk zs@$YBO#>kW^?E(As(DbW)uiSJ082|t()OvTDNIdGB^D_QauL=vEwRcXSi8)mMYBwt z!=49QAUbF}^g}fLycl~d%`^`HQ52!u?Sc@3D2m|wK2$=WXd{PlU|j<%*?)Ab@S#P*oLEQ&RwX+I1WU zmo8lba6XNU3sDro^E@0K9RcVCB2g3}2!hn3Y9L|Pb>X^hBD(QBkDJPe498QK?k$=+PrQeE2YN z{IPRglsU*74?^zH(lkw;jmWUO`vm*@zXAY`j*j>uWkDE*+${I^f5q-@`dkPh=ytog zNT=RB^t<)`q+5okPrt$T_I&_7$C4)+s@Lm0h}hn~kEc(+8Tc%lOB6*3(;r*aa#-{w zb5ONfjT26DV76^10-JuYF!I5J2Rwpe$5LL$n3?df=t~yF`@Ww^_Ary|cDo3}5IZ|N zd`#AsH+euD$C*9=V)n5tD|Q?w7TeN3S&>zq<2bQpS^Z;V;xSSIfKrMe2;jOd%H=Yz zFQwt&-~h+R$7sKJ0ae#gESLFrV!=>M{a8KB_kBcBgl4nJBdom0OjwMwSuj$qR$<#V zT-U|&@^WIrgYfFrEBL;T-CMU{P?{htmVMa~1pHOMvTYll=Ovt5-fN!Jn+ItJMTtdi zs;Y`&v52|3In2z=;BaFDdZ~o+fXFCK!y=wNdj{Y4ak#O8uBIU(glo87uXBy(C44TE zc7@vl(=>7W_H8s84eaghVSh+;G&3{P`{m0oQ=jW}I%v1s2py+a-6RCXVi7?0qQ4Be z3CD4)$jZ4lZrtc)Pv3rfrjP6nYJhD1`_-#gaq;3s%sI}PlB_tFyz?Kq#M5jx;W!T7 zym>RQ3NpwU_1CXN&57mLqoX4PK>%IXF+Dv!(tJlI%!>7C5H%+{qy9L2m?cn3M<$%x zX#sy#L@1@)X{FVa8sV+2EwoxK?CtI0=FOX! zo14R`XugyJgd|>Wkr8H)-5F)Y$nR-={P+>=b{qfw@LEr_({B(SWzHfzI|e$e7>kYcv{o|MDeZ+dWJ8)LuFZ48y>|!2tl^<;Dj7!?Gw{ z2g+rX78jwX##;h7%U0vm=AcJV$Ov9tRpFJ|+ z{3TLX`vzA-)x;e?x`jalLgvwtwUKJO2$}oU+HJ;r|zWcK@jL*%AI9 X^HBA`7`#*n00000NkvXXu0mjfDb{Ms diff --git a/images/white_knight.png b/images/white_knight.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..eece7b61345e053c4b9e09cbef551a49330a5e19 GIT binary patch literal 1284 zc$@(Q1^fDmP){Q!V>)7!t?Z<7E1n?hL+C@e522+m0KS831(g+>N~)wvD(Gn3TX;7H z3?v~xaMd%D8OSV~J$xr;zwb*dtu=lVI>%l>+xR2=)A2|6r{j`tTb89Q z%Q}ga?$<^5pSmX6j-b}s${Le(zD?8?VXd{5CbRtq*tQMMIW8_Pw2}BRq~4mO`~5yB zrRa9MZCx@OTI*U5A%y0fYXEzXedFq0Q~Idw9yU-)Aq+zR0HqX!kj!ze>q2V{O6kUL zn?~(~CzDC?nR5=tSmwCv>ub2K3(NZQFhjUWbE}oGF(67QIOiCRMsOTw=Xl$;;dx&2 z-Kb+aohEbDO}vq9i4X$D7#zphDQV!-$ol<$@;xo@#!!b5AZ0jG%H&{-CFd!nS_q-% z^SR!K`FyU05Smijh>=x}aHrErWK0M_6h-KEyXg1(ux%TZQn;=Q+qU7lE_%J*-ub%S zE(jqQ3A z%e0I-D5Y4fRtSOsolZx8e0)^8j|&sdGAPCvIOiCT$5qyV*=z%nzh0G|rr zoI@#vAPAtfu54a~2yYvdQVLQ^jK|~BkqyHTtJMks@b>nGr>7^3MkCzb-j-eaLCC#_ zvkWSZV@N5%Imd7~EOo)vYK1tC5yvqWiv^^Va2%%uK|2kR+LgqCKD*7D&^U^l1^t(=Hgk|(rUFz_S`6n zlJNlG`#zS-Wl}b#kv6QFp$b=9W3sz7Tu3KOQ3!uS1+0{`yrF8OSX$ZRipNJr2ZnaRT&HLx;epAbR=(Btt~>(2qD z`%&0aM(#osMOsR!A0Ho+H59$x!R4WGX~r1d-`_VPeF)M@7z_r5^X|$hQ`|Ggz7_T; z@h>Ao5lAWKBqE%(*S);Fl=@S*(^AtEFlfr4vQT^1G7pqeFvgOkqHS3JNv)a5Q;}ti zK?niYbq~H@ecw;qTq(8TBSo{WRvxu5#&CIg2|~!xAGI_l>2!335FmtX+_%Rm`p-&d$!tPS-jrN!l3Fsot+yIH*l4gg9z?SOujb zOb7v`wB2&9X5Sz*YcGJkm%{yU6Z8(c7)4cwN+4CLr?RwU@fji` z2qdTHtL?9cS|@2vKnyBTduZc%J7VgeaF*wl0_uqS7?Q<>e)! zC~C)xq5xwINs{2|>PkI7KRa=6tAh2OjpGcd!PC=|(>Ux*FmObPhj!`RI4p#iUK|FtVTmy|2uqAHaL&OPQ&m+t z5$z-n=XpMQJqQBK=W}FP=FHO81QSBk{rx=_iv<7-!ctKbpp+ttB2Y@(IkrVxweVuG zfG!w3&l|Y3@B8q5AD-v6W41*be@l-Q3b(hnqxVWFQ4|G)5Rg*#=GYQ#ya5o$aa$x% zN(WXw1m_%K7;YDKc4j4B8guEf7u49B`4CBxKnQ`dETNRL;@-wwx?34(D5bsqxl7YD zsOuVaUAOskUDqhfvc2cW3pR~u!N&HmQi|;R0o(nVrYSh*e?8YE&NHp+>+8Y3UM`nv zy>25#z5IWPc>DEW*(kH=F=OlRQ7#FORBCoHnNYfNTh`sj}MS-fS zdSh9Z;qmd&YOmT#9A2;2M2Dw+NGS(nhyFpPaQevuu(hm|a&PO_HdY0{yu2XKb3{>u z&(F`cSg7k70Pz0)K5*-Qws_D-rNFixetUZx9DG+*g)GZ@b8M|gW2H^II~K=r+rR3v z+rR2!OS}`o|AikfxZB;(?i)oBE-o&<{5SGEZx6{eriB~Z!>iQ_v)K#)+A|}@80Pc& z-Z|RMyX{>4p-WkogDqeJBZBp(NjmO^VfdwzP#?8)8}?xsA`C-hS=N?{fH_Nl%cTh+ zYPDM7?(VMVzMkiOso>YHuPxkti)#y;cJFUncs841H=}BrW;B!9MM~NJcF|`{UBM>! vwuKF@<&T)K@X=LEPQT*$2^^h;k52G!li~@oKpZp200000NkvXXu0mjfRu|Lq diff --git a/images/white_queen.png b/images/white_queen.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d454391231c5544edce9f0c91659a85c8445b82e GIT binary patch literal 1551 zc$@(b2JrcbP)r zvefnUH8|(+JP)>QBMd_%Ndn8V)R;<-cEZ!?6qHicps?Du=baf~-_-l$){ezjKo zB$L*}^ZxyN5JEBmI>_A#dM`>Tf*=4P1e3|+q%~Tfu>K47F(=Ei6k`m8kWQvOgbbsT zmTlW`9B1rpGn}k&U!R@N=b1b7MHg9mo$#3cJJg=NP5Kg~)d#PxTI!_mB{HO;Waxat zmsGmX-h-I*7=Ap|9+Ee2vK^MQ@4*=zPo??ut<#Jg&2Y^~Gmx?i_ zzJ2?qcDtQojAeT@?V;y-p4V#pF+Fl8+@;4fo6SH7K@>$t$4w>^5JKR29vsI3A*A(w zdTta&h~v0%{IPX2mhNi4j^lt*+UWawoa?%0+oK4jlvUL0syN_OVV<6zAcR1YB&SYo zjU-7Rguv6&)6sEPS67X(y3_zrN?Dq;np!wj1^GE3rG%97=z+8itF?&-Aq1RrtX3=4 zMxh`Gz!)1;dEFrif}n96=Nyc&#x-jd)_yacPFo4*dETIXF1>~(x~6fI(sqr7CW_~r zD6&j&Vo#Ax7*TbPbL%CwhbvIk|e1O zA(P1@x1N-;RsP%-ofQ7`=@WpL6VX|ai7JB91q0_CLWtTVK}wlB;h}NTcS~>IzE!3$ zbtL2aK5lMqa?cKj10EkAbI&}_!)mq4J$v`=UGB4K2~x_;s-B;pJLUc-o$$|}KP@vP zaLy}9#`pb_$!d}@VcT}4Y5(}~Bm3R-e<8%lBvnMGFT^!@057JheYy_!_xBl*t=DUv zb7!XS`+in7R;{Q1Sla)!m7V>Bt8h3RN~K}()ax#=?Du;}DY4)0F`LZ*0E@*USN9Ix zW9zMOnx-XFErz8!=)}PUr8JjOAWhSp>32mhh3g2!aU3wl5JgdD?ph%Yld5!<#u!5w zhWPU3OYORS74CJ5M+i~N(x!4vq;+$1ld-jw5?{Z5t=zkqH;+bIX2agL?GmdVE7-T2 z4UVPyRqJV!UMv;>x^-7IIw`Ch_Q1;(hNiG&;@`VFJl@^azMs$MrMlUS;YpH=uW%D| z>1M+BeQ?gP2}6WZf-wfq^Wgh_j_Iq)$RTkSg{xw->$-4V_oagYfcPx6?kt9iFxv8NuH_g(c#bLc6=R8xc3Tc|2Oh&WWEGs067~&Rv zryKE?xPfP4^jkdt$D08fqyEps-+)(lZRyo1{2$LHPc_l?ICB61002ovPDHLkV1mTY B{O14w diff --git a/images/white_rook.png b/images/white_rook.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..07adda81e9570d4ad002e17f992de904594dd04c GIT binary patch literal 1773 zc$@+41`_#+P)XP zCPb1Ng^+?M9~G!Vu}E9`Ne9}Qa^D4E!Uz>wM({Gtz?w#}Nz4y$VdksPe{w0jN z9l%brFL&j~(|Nh5>7uwlg^gfQ%Oo6X2bFo4x+rLnP* zv9U4yem}#*!x)W5vAn#TGMLKBO3t4@kI&~L91b%wGP3D&PM+9=j zX=$OauaB=^zwVx3zu%9;;lN_Ckdu=`JRYa7uaBXjp_Ef`BU1V1<>hhz{(Tfh!QpVQ zw6v6Is2VaB90&yX^5qL9B_$j=a)gT)FCs}2vMg)-;_*1iWD_XBKLKuujqYy&S(b2(&4<9HgDcR81@AtE~xR_~tM59qcp%AfHOnr97 zosr=PtBuoGt9r4kf?-8;QBe`suV1IUyqps!PNdb|<#I7QJDbwp*Vji+PtUf6u99)m zT8pA6{P^*MWHL!45=pDA$KzpsemN;L8qy<7KqtZZ`T5vvHhOz|0l0GI3YC?W)YQ}fEAL{b(@8WM1)#33j@sH<>gwt= z{rG%7Mn*>H>gr-t|gM>mMWLc)BrUqG- ziO1vQ~=dIk4MwSZnv|%ysSr98={NgSS&_&cemzVG#X`kdYWi7ilQj% z?5oVq&JqX&SYBSn=kuw4ilX3jI+>fB(<4Nc{o)}L%F4=UYinb0aFEf_QQF(vxp3hE zw{G3i_&J?U91aJaot+dG7V_xPBaPkdc4N2O>FMdg@AqS~*%%!iWnf@Hk1zq91n1@D z(cIjO$z&p#Op=wA#j#_@Xl`!S_#HiZl!b)_y1TnEo6YO&BO@bty4OIkQd(MyEX&BU%>4X3CXkS zVF8cFLvC&^7K?@4++4M!+^Ck`4!VqRb#=AoVC=zz2Mi7l^5Vq{UcP*Z&1Os4zN@Q? z-ripB-o4A^%a^%*`!=6He^#ge`}gm8`}VDFBb>J2jXpFA3k$h+?V5W1>C-3tem@fv z6Ern7QCV4;vOl-mjo0gCU|@ja;$j*a8VCde>fzbXpFh{_jI5H$pOBW|-8gCZ9hnGD zdkvdRCc@!xy3Nuikx20I<45(nzrPV`O=wa!gC<^1_ z6HH4rg18^I=#0v!j~>x;@-V`+ly$MIGs-7@i+i8Gc#%y|Muqau*>D* z&Ye5Jis0|xzyHaYHf4T(UM*D8-4XfclGe6AE&p%)a~lBrg7-TAoZ$ZeDOD4Nv2M&h P00000NkvXXu0mjfaA{cvCYl}*vSGyf~1@??ZoHp0IPv;biPYQNlCs@ z*J6g(wt+&evay|=tk!2q8VoIOz)-H3C8x0?LZI`L! zN5e$qzg_0S0}V$9!eQ1gQ~03a=s-9+5RMLnqXXgD_p{3>e9&-oAWTGY*71c08b0ve zawR_+KH;_Ho7`yl4{t3${ diff --git a/images/white_super_sun.png b/images/white_super_sun.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..957f65daf70373f8dfe1c90bb9b38e5b46b8d51e GIT binary patch literal 586 zc$@)B0=4~#P)o8(>e+R!VSv(u#yNuqTgjG-ywPXv-p;0hUPQ2M(MC z_7Uh02AmD{5#SdeI4kTUrhmt^mb@%&6x~@$HJd(*%)JKI);+;JYWNAX+u}jf4n6mJ zB#rqyEQoF)9jwV%6TeN9me;z@a@;X67+u#ztYrLw|HqZ3K5(+=itThb)LEKaTag+( zyS8+$N8~o8Tc@)0r7B>HsoZ-ItB0ep`wyIbk$|e}fQf(m<4>x+TcY!2jd2^c*-* zlr5r5WE^2HXv=Zez+lEk%8<)g3x9bL7L+LsxcFX%pYENObTi&d*g37tTe!?wh$SuO zldfU`e&Ja<8#L&TtSn`L7Wkn*O}pd0Ry=Th;}IQgrM-JV+)PLO0x-04!cQJab=-RR Y2j + + + + Checkers + Largo Enterprises + + Checkers + + + + + + + + + + + none + + diff --git a/jnlp/schach.jnlp b/jnlp/schach.jnlp new file mode 100644 --- /dev/null +++ b/jnlp/schach.jnlp @@ -0,0 +1,21 @@ + + + + + Chess + Largo Enterprises + + Chess + + + + + + + + + + + none + + diff --git a/org/homelinux/largo/checkers/Checkers.java b/org/homelinux/largo/checkers/Checkers.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/checkers/Checkers.java @@ -0,0 +1,235 @@ +/** + * $Id: Checkers.java 144 2008-04-25 13:09:35Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/checkers/Checkers.java $ + */ + +package org.homelinux.largo.checkers; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.SpinnerNumberModel; + +import org.homelinux.largo.games.board.MouseListener; +import org.homelinux.largo.games.board.Point; +import org.homelinux.largo.utils.BrowserLaunch; + +public class Checkers extends JFrame implements Runnable { + static final long serialVersionUID = 250408; + static final String helpURL = "http://largo.homelinux.org/trac/browser/eclipse/Schachspiel/trunk"; + + MouseListener listener = null; + KIBoard board = null; + Point p = null; + JLabel human = new JLabel("Human"); + JLabel computer = new JLabel("Computer"); + JButton neu = new JButton("Play"); + JButton pconly = new JButton("PC-PC"); + JButton back = new JButton("Back"); + JButton forward = new JButton("For"); + JButton help = new JButton("Source"); + + SpinnerNumberModel model = new SpinnerNumberModel(4, 1, 8, 1); + JSpinner combo = new JSpinner(model); + + JPanel panel; + JPanel fpanel; + + int search_depth; + + boolean pc_only; + + public Checkers (int w, int h) { + super("Checkers by Largo Enterprises"); + setDefaultCloseOperation (javax.swing.JFrame.EXIT_ON_CLOSE); + board = new KIBoard(w, h); + + fpanel = new JPanel(); + fpanel.add(back); + fpanel.add(neu); + fpanel.add(combo); + fpanel.add(pconly); + fpanel.add(help); + fpanel.add(forward); + + panel = new JPanel(); + panel.setLayout(new BorderLayout()); + panel.add(human, "West"); + panel.add(fpanel, "Center"); + panel.add(computer, "East"); + + fpanel.setBackground(new Color(50, 100, 200)); + panel.setBackground(new Color(50, 100, 200)); + + getContentPane().setLayout(new BorderLayout()); + getContentPane().add(panel, "North"); + getContentPane().add(board, "Center"); + + neu.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionevent) { + human.setText("Human"); + computer.setText("Computer"); + pc_only = false; + board.init(); + board.negateEstimation(false); + } + }); + + pconly.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionevent) { + human.setText("Computer"); + computer.setText("Computer"); + pc_only = true; + } + }); + + back.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionevent) { + board.backwards(); + } + }); + + forward.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionevent) { + board.forward(); + } + }); + + help.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionevent) { + BrowserLaunch browser = new BrowserLaunch(); + browser.openURL(helpURL); + } + }); + + listener = board.getMouseListener(); + + pc_only = false; + search_depth = 3; + pack(); + } + + public void computer_play () { + while (pc_only) { + search_depth = model.getNumber().intValue()-1; + + if ( !board.isBlacksTurn() ) { + human.setText("Computer"); + board.negateEstimation(true); + if (!board.doBestMove(search_depth) ) { + pc_only = false; + return; + } + board.negateEstimation(false); + human.setText("Computer"); + board.setBlacksTurn(true); + } else { + computer.setText("Computer"); + if (!board.doBestMove(search_depth) ) { + pc_only = false; + return; + } + computer.setText("Computer"); + board.setBlacksTurn(false); + + if (board.simu_debug()) { + for (int i=0;i<64;i++) { + if((i+1)%8 == 0 ) + System.err.printf("%2d=%d\n", i, board.getValue(i)); + else + System.err.printf("%2d=%d ", i, board.getValue(i)); + } + } + + try { + Thread.sleep (10); + } catch (InterruptedException e) { + System.err.println("computer_play: " + e.getLocalizedMessage()); + System.err.println("========================================================================"); + e.printStackTrace(); + System.err.println("========================================================================"); + return; + } + } + } + } + + public void run () { + for (;;) { + + /* is this thread safe */ + search_depth = model.getNumber().intValue()-1; + + if (pc_only) { + computer_play (); + } + + if ( !board.isBlacksTurn() ) { + if (listener.isSelected ()) { + p = listener.getSelection (); + if (board.move (p)) + board.setBlacksTurn(true); + } + try { + Thread.sleep (50); + } + catch (InterruptedException e) { + System.err.println("Schach::run: " + e.getLocalizedMessage()); + System.err.println("========================================================================"); + e.printStackTrace(); + System.err.println("========================================================================"); + return; + } + } else { + human.setText("Human"); + computer.setText("Computer"); + board.doBestMove(search_depth); + human.setText("Human"); + computer.setText("Computer"); + board.setBlacksTurn(false); + + if (board.simu_debug()) { + for (int i=0;i<64;i++) { + if((i+1)%8 == 0 ) + System.out.printf("%2d=%d\n", i, board.getValue(i)); + else + System.out.printf("%2d=%d ", i, board.getValue(i)); + } + } + } + } + } + + public static void main (String args[]) { + Checkers c = new Checkers (74, 74); + + c.setResizable(false); + c.setVisible (true); + + if (args.length == 1 ) { + if ( args[0].equals("full") ) + c.board.setDebug(true, true); + else if ( args[0].equals("simu") ) + c.board.setDebug(true, false); + else if ( args[0].equals("undo") ) + c.board.setDebug(false, true); + else if ( args[0].equals("none") ) + c.board.setDebug(false, false); + else { + System.out.println(" Chess: java -jar games.jar [full|simu|undo|none]"); + System.out.println("Checkers: java -cp games.jar org.homelinux.largo.checkers.Checkers [full|simu|undo|none]"); + } + } + + Thread t = new Thread(c); + t.setPriority(Thread.NORM_PRIORITY-1); + t.start(); + } +} diff --git a/org/homelinux/largo/checkers/KIBoard.java b/org/homelinux/largo/checkers/KIBoard.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/checkers/KIBoard.java @@ -0,0 +1,202 @@ +/** + * $Id: KIBoard.java 144 2008-04-25 13:09:35Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/checkers/KIBoard.java $ + */ + +package org.homelinux.largo.checkers; + +import org.homelinux.largo.games.board.Move; +import org.homelinux.largo.games.board.checkersboard.CheckersBoard; + +public class KIBoard extends CheckersBoard { + static final long serialVersionUID = 250408; + static final int game_const = 500; + + protected boolean SIMU_DEBUG = false; + private boolean negate_estimation = false; + + private Move bestMove; + private int desired_depth; + + public KIBoard(int w, int h) { + super(w, h); + desired_depth = -1; + } + + /** + * Set the current DEBUG-Level: + * simu: print all valid, simulated moves + * undo: print all undos + */ + public void setDebug(boolean simu, boolean undo) { + SIMU_DEBUG = simu; + UNDO_DEBUG = undo; + } + + public boolean simu_debug() { + return SIMU_DEBUG; + } + + public boolean undo_debug() { + return UNDO_DEBUG; + } + + /** + * This function flips the sides: Player A maximizes and Player B minimizes + */ + public void negateEstimation(boolean b) { + negate_estimation = b; + } + + /** + * The Minimax-Algorithm works for TWO-PLAYER Games + * Player A minimizes, Player B maximizes + */ + public int estimateFunction() { + int i; + int white = 0; + int black = 0; + + for(i=0;i<64;i++) { + if (isWhite(i)) + white+=getValue(i); + if (isBlack(i)) + black+=getValue(i); + } + + /** + * solves ticket #3 + */ + if ( negate_estimation ) + return white-black; + + return black-white; + } + + /** + * simulates and returns the next possible move for a Player or null, when no more moves are possible. + * The Turn is flipped automatically if "simulate(...)" will find a valid move. + */ + Move simulate(int t, int o) { + Move move = null; + int value; + + if ( validTurn(o) ) { + while ( t < 64 ) { + if (!simulateMove(t, o) ) { + t++; + continue; + } + + value = estimateFunction(); + move = new Move(value, t, o); + + /* Flip Sides */ + setBlacksTurn(!isBlacksTurn()); + return move; + } + } + return null; + } + + /** + * AlphaBeta-Algorithm: the Maximizer + */ + int max_alpha_beta (int depth, int alpha, int beta) { + int moveValue; + int o, t; + Move move = null; + + if ( desired_depth == -1 ) + desired_depth = depth; + + for (o = 0; o < 64; o++) { + t=0; + while ( (move=simulate(t, o)) != null ) { + /* particular move from black */ + t = move.target; + + if ( depth == 0 || Math.abs(move.value) > game_const ) + moveValue = move.value; + else /* best next move */ + moveValue = min_alpha_beta(depth-1, alpha, beta); + + undo(); + t++; + + if ( moveValue >= beta ) + return beta; + + if ( moveValue > alpha ) { + alpha = moveValue; + if ( depth == desired_depth ) + bestMove = move; + } + } + } + + return alpha; + } + + /** + * AlphaBeta-Algorithm: the Minimizer + */ + int min_alpha_beta(int depth, int alpha, int beta) { + int moveValue; + int o, t; + Move move = null; + + for (o = 0; o < 64; o++) { + t=0; + while ( (move=simulate(t, o)) != null ) { + /* particular move from white */ + t = move.target; + + if ( depth == 0 || Math.abs(move.value) > game_const ) + moveValue = move.value; + else /* best next move */ + moveValue = max_alpha_beta(depth-1, alpha, beta); + + undo(); + t++; + + if ( moveValue <= alpha ) + return alpha; + + if ( moveValue < beta ) + beta = moveValue; + } + } + + return beta; + } + + /** + * Evaluates the next, best Move after search_depth half-moves. + * When the Machine has Black, set negateEstimation(false); + * When the Machine has White, set negateEstimation(true); + */ + public boolean doBestMove(int search_depth) { + int value; + + desired_depth = -1; + bestMove = null; + value = max_alpha_beta(search_depth, Integer.MIN_VALUE, Integer.MAX_VALUE); + + if ( bestMove == null ) { + System.err.println("Computing once more..."); + value = max_alpha_beta(1, Integer.MIN_VALUE, Integer.MAX_VALUE); + if (bestMove == null) { + System.out.println("Finito"); + return false; + } + } + + if (doMove(bestMove.target, bestMove.origin)) { + System.out.println("Next Move"); + return true; + } + + return false; + } +} diff --git a/org/homelinux/largo/games/board/Board.java b/org/homelinux/largo/games/board/Board.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/games/board/Board.java @@ -0,0 +1,394 @@ +/** + * $Id: Board.java 148 2008-04-25 22:05:48Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/games/board/Board.java $ + */ + +package org.homelinux.largo.games.board; + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.util.Vector; + +public class Board extends Canvas { + static final long serialVersionUID = 140208; + + protected boolean UNDO_DEBUG = false; + + protected Piece board_pieces[]; + private Piece pieces[]; + + protected Vector stack; + protected int moveNr; + + protected static final int EMPTY = 0; + + Color color_black; + Color color_white; + + int iHeight; + int iWidth; + int xPos; + int yPos; + + boolean black; + boolean blacksTurn; + + MouseListener listener = null; + + /** + * The init method initializes an empty board with a history. + */ + public void init() { + int i; + pieces = new Piece[64]; + + for (i = 0; i < 64; i++) { + pieces[i] = new Piece(null, null, EMPTY, 0); + } + + xPos = 0; + yPos = 0; + + black = false; + blacksTurn = false; + board_pieces = getPieces(pieces); + stack = new Vector(); + moveNr = 0; + } + + public Board (int w, int h) { + iWidth = w; + iHeight = h; + color_white = new Color (255, 255, 255); + color_black = new Color (50, 100, 200); + setPreferredSize (new Dimension(8 * iWidth, 8 * iHeight)); + + init(); + listener = new MouseListener(iWidth, iHeight); + addMouseListener(listener); + } + + /** + * getPiece returns a Piece-Object from the Board Cache. It might not be visible on the current board. + */ + public Piece getPiece(int t) { + return pieces[t]; + } + + /** + * setPiece sets a Piece-Object into the Board Cache and will not be visible. + */ + protected void setPiece(int t, Piece p) { + pieces[t] = p; + } + + protected Piece[] getPieces() { + return getPieces(pieces); + } + + private Piece[] getPieces(Piece[] which_pieces) { + Piece[] p = new Piece[64]; + int i; + + for ( i=0;i<64;i++) + p[i] = new Piece(which_pieces[i]); + + return p; + } + + protected void setPieces(Piece[] p) { + pieces = p; + } + + /** + * needed in paint(Graphics g) + */ + private Image getBoardImage (int i) { + return board_pieces[i].image; + } + + /** + * getMouseListener returns a valid MouseListener for this Board. + */ + public MouseListener getMouseListener() { + return listener; + } + + /** + * currentMove returns the current stack.size(). + */ + public int currentMove() { + return stack.size(); + } + + /** + * returns the color of piece[i]. + */ + public String getColor(int i) { + return pieces[i].color; + } + + /** + * returns the current Value of a particular piece. + */ + public int getValue(int i) { + return pieces[i].value; + } + + /** + * Defined Integer Constants: EMTPY = 0 + */ + public int getType(int i) { + return pieces[i].type; + } + + public boolean isEmpty (int i) { + if (pieces[i].type == EMPTY) + return true; + return false; + } + + boolean BoardisEmpty (int i) { + if (board_pieces[i].type == EMPTY) + return true; + return false; + } + + /** + * blacksTurn = true -> Black moves + * blacksTurn = false -> White moves + */ + public boolean isBlacksTurn() { + return blacksTurn; + } + + public void setBlacksTurn(boolean b) { + blacksTurn = b; + } + + /** + * returns true, when piece[i] is white + */ + public boolean isWhite(int i) { + if ( isEmpty(i) ) + return false; + + if ( pieces[i].color.equals ("white") ) + return true; + return false; + } + + /** + * returns true, when piece[i] is black + */ + public boolean isBlack(int i) { + if ( isEmpty(i) ) + return false; + + if ( pieces[i].color.equals ("black") ) + return true; + return false; + } + + /** + * returns true, when both pieces have opposite colors + */ + public boolean isEnemy(int t, int o) { + if ( isEmpty(t) ) + return false; + + if (!pieces[t].color.equals (pieces[o].color) ) + return true; + return false; + } + + /** + * returns true, when both pieces have the same color + */ + public boolean isSamePiece(int t, int o) { + if ( isEmpty(t) ) + return false; + + if (pieces[t].color.equals (pieces[o].color) ) + return true; + return false; + } + + /** + * This function checks for the color of the piece at piece[i] and returns true, + * if the color matches the current Turn. + */ + public boolean validTurn(int i) { + if ( isEmpty(i) ) + return false; + + if ( getColor(i).equals("white") && isBlacksTurn() ) + return false; + if ( getColor(i).equals("black") && !isBlacksTurn() ) + return false; + return true; + } + + /** + * simulates a "valid" move or returns false. + * all changes are relative to pieces and will not be painted. + * This method sets internal variables for the rochade() method, which will be overidden. + */ + public boolean simulateMove(int t, int o) { + if ( !validMove(t, o) ) { + return false; + } + + push(pieces[t], t, pieces[o], o); + + pieces[t] = new Piece(pieces[o]); + pieces[o] = new Piece(null, null, EMPTY, 0); + + return true; + } + + /** + * Moves a Piece on the Board at Point p + */ + public boolean move (Point p) { + int t; + int o; + + t = (p.endy * 8) + p.endx; + o = (p.starty * 8) + p.startx; + + if ( t < 0 || t > 63 ) + return false; + if ( o < 0 || o > 63 ) + return false; + + if (validTurn(o)) + return doMove (t, o); + + System.out.println("It's not your turn!"); + return false; + } + + /** + * Moves one half-move backward. + */ + public void backwards() { + History h1 = null; + History h2 = null; + + if ( moveNr < 2) + return; + + moveNr -= 2; + + h1 = stack.elementAt(moveNr); + h2 = stack.elementAt(moveNr+1); + + board_pieces[h1.pos] = h1.piece; + board_pieces[h2.pos] = h2.piece; + + repaint(); + } + + /** + * Moves one half-move forward. + */ + public void forward() { + History h1 = null; + History h2 = null; + + if ( moveNr > stack.size()-2 ) + return; + + h1 = stack.elementAt(moveNr); + h2 = stack.elementAt(moveNr+1); + + board_pieces[h1.pos] = h2.piece; + board_pieces[h2.pos] = new Piece(null, null, EMPTY, 0); + + moveNr += 2; + repaint(); + } + + /** + * pushes 2 pieces onto the stack. + */ + public void push(Piece p1, int t, Piece p2, int o) { + stack.add(new History(p1, t, isBlacksTurn())); + stack.add(new History(p2, o, isBlacksTurn())); + } + + /** + * pop: undo the push operation. + */ + public void undo() { + History h1 = null; + History h2 = null; + int size = stack.size(); + + if ( size < 2 ) + return; + + h1 = stack.elementAt(size-1); + h2 = stack.elementAt(size-2); + + pieces[h1.pos] = h1.piece; + pieces[h2.pos] = h2.piece; + + stack.setSize(size-2); + + /* Reset the current player */ + setBlacksTurn(h2.turn); + } + + /** + * This method must be implemented in your "GameBoard" + * Return value: TRUE: the move IS possible + * Return value: FALSE: the move IS NOT possible + */ + public boolean validMove(int t, int o) { + System.out.println("public boolean validMove(int t, int o): Implement me"); + return false; + } + + /** + * This method must be implemented in your "GameBoard" + * Return value: TRUE: the move was performed + * Return value: FALSE: the move was not performed + */ + public boolean doMove(int t, int o) { + System.out.println("public boolean doMove(int t, int o): Implement me"); + return false; + } + + public void update(Graphics g){ + paint(g); + } + + public void paint (Graphics g) { + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) { + if (black == true) { + g.setColor (color_black); + g.fillRect (xPos, yPos, iWidth, iHeight); + black = false; + } else { + g.setColor (color_white); + g.fillRect (xPos, yPos, iWidth, iHeight); + black = true; + } + if ( !BoardisEmpty ((i * 8) + j) ) + g.drawImage (getBoardImage ((i * 8) + j), xPos + 5, yPos, this); + xPos += iWidth; + } + xPos = 0; + yPos += iHeight; + black = !black; + } + xPos = 0; + yPos = 0; + } +} diff --git a/org/homelinux/largo/games/board/History.java b/org/homelinux/largo/games/board/History.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/games/board/History.java @@ -0,0 +1,32 @@ +/** + * $Id: History.java 150 2008-04-26 01:18:25Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/games/board/History.java $ + */ + +package org.homelinux.largo.games.board; + +import org.homelinux.largo.games.board.Piece; + +public class History { + Piece piece; + int pos; + boolean turn; + + public History(Piece p, int n, boolean t) { + piece = new Piece(p); + pos = n; + turn = t; + } + + public Piece piece() { + return piece; + } + + public int pos() { + return pos; + } + + public boolean turn() { + return turn; + } +} diff --git a/org/homelinux/largo/games/board/MouseListener.java b/org/homelinux/largo/games/board/MouseListener.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/games/board/MouseListener.java @@ -0,0 +1,54 @@ +/** + * $Id: MouseListener.java 140 2008-04-25 07:03:13Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/games/board/MouseListener.java $ + */ + +package org.homelinux.largo.games.board; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class MouseListener extends MouseAdapter { + int width; + int height; + int delta; + + Point p; + boolean selected; + + public MouseListener (int w, int h) { + width = w; + height = h; + p = new Point (); + selected = false; + } + + public void mousePressed (MouseEvent e) { + p.startx = (e.getX () / width); + p.starty = (e.getY () / height); + selected = false; + } + + public void mouseReleased (MouseEvent e) { + p.endx = (e.getX () / width); + p.endy = (e.getY () / height); + + print(); + selected = true; + } + + public boolean isSelected () { + return selected; + } + + public Point getSelection () { + selected = false; + return p; + } + + public void print() { + System.out.printf ("%c%d-%c%d \t", + (char)('A' + p.startx), 8-p.starty, + (char)('A' + p.endx), 8-p.endy); + } +} diff --git a/org/homelinux/largo/games/board/Move.java b/org/homelinux/largo/games/board/Move.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/games/board/Move.java @@ -0,0 +1,18 @@ +/** + * $Id: Move.java 138 2008-04-25 04:37:08Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/games/board/Move.java $ + */ + +package org.homelinux.largo.games.board; + +public class Move extends Object { + public int value; + public int target; + public int origin; + + public Move(int v, int t, int o) { + value = v; + target = t; + origin = o; + } +} diff --git a/org/homelinux/largo/games/board/Piece.java b/org/homelinux/largo/games/board/Piece.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/games/board/Piece.java @@ -0,0 +1,29 @@ +/** + * $Id: Piece.java 138 2008-04-25 04:37:08Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/games/board/Piece.java $ + */ + +package org.homelinux.largo.games.board; + +import java.awt.Image; + +public class Piece extends Object { + Image image; + String color; + int type; + int value; + + public Piece(Piece s) { + image = s.image; + color = s.color; + type = s.type; + value = s.value; + } + + public Piece(Image img, String c, int t, int v) { + image = img; + color = c; + type = t; + value = v; + } +} diff --git a/org/homelinux/largo/games/board/Point.java b/org/homelinux/largo/games/board/Point.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/games/board/Point.java @@ -0,0 +1,13 @@ +/** + * $Id: Point.java 140 2008-04-25 07:03:13Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/games/board/Point.java $ + */ + +package org.homelinux.largo.games.board; + +public class Point { + int startx; + int starty; + int endx; + int endy; +}; diff --git a/org/homelinux/largo/games/board/checkersboard/CheckersBoard.java b/org/homelinux/largo/games/board/checkersboard/CheckersBoard.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/games/board/checkersboard/CheckersBoard.java @@ -0,0 +1,299 @@ +/** + * $Id: CheckersBoard.java 152 2008-04-27 02:04:31Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/games/board/checkersboard/CheckersBoard.java $ + */ + +package org.homelinux.largo.games.board.checkersboard; + +import java.awt.Image; + +import org.homelinux.largo.games.board.Board; +import org.homelinux.largo.games.board.History; +import org.homelinux.largo.games.board.Piece; +import org.homelinux.largo.utils.ImgComponent; + +public class CheckersBoard extends Board { + static final long serialVersionUID = 250408; + + static final int PIECE = 1; + static final int QUEEN = 2; + + final Piece white_super_sun = + new Piece(new ImgComponent("images/white_super_sun.png").getImage(), "white", QUEEN, 50); + + final Piece black_super_sun = + new Piece(new ImgComponent("images/black_super_sun.png").getImage(), "black", QUEEN, 50); + + void initBoard () { + for (int i=1;i<8;i+=2) + add (new ImgComponent ("images/black_sun.png").getImage (), i, "black", PIECE); + for (int i=8;i<15;i+=2) + add (new ImgComponent ("images/black_sun.png").getImage (), i, "black", PIECE); + for (int i=17;i<=23;i+=2) + add (new ImgComponent ("images/black_sun.png").getImage (), i, "black", PIECE); + + for (int i=40;i<47;i+=2) + add (new ImgComponent ("images/white_sun.png").getImage (), i, "white", PIECE); + for (int i=49;i<=55;i+=2) + add (new ImgComponent ("images/white_sun.png").getImage (), i, "white", PIECE); + for (int i=56;i<63;i+=2) + add (new ImgComponent ("images/white_sun.png").getImage (), i, "white", PIECE); + } + + /** + * The init method initializes a complete checkers board with figures and a history. + */ + public void init() { + super.init(); + initBoard(); + board_pieces = getPieces(); + repaint(); + } + + public CheckersBoard (int w, int h) { + super(w, h); + } + + void add (Image img, int i, String c, int t) { + int v = 0; + + switch(t) { + case PIECE: + v=10; + } + + setPiece(i, new Piece(img, c, t, v)); + } + + /** + * Checks, wether this move is possible or not. + */ + public boolean validMove (int t, int o) { + int steps; + int rows; + int dx; + + if ( t == o ) + return false; + + if (isSamePiece(t, o)) + return false; + + if (getType(o) == EMPTY) + return false; + + /* + * 00 01 02 03 04 05 06 07 + * 08 09 10 11 12 13 14 15 + * 16 17 18 19 20 21 22 23 + * 24 25 26 27 28 29 30 31 + * 32 33 34 35 36 37 38 39 + * 40 41 42 43 44 45 46 47 + * 48 49 50 51 52 53 54 55 + * 56 57 58 59 60 61 62 63 + */ + + steps = Math.abs(t-o); + rows = Math.abs(t/8 - o/8); + + switch( getType(o) ) { + case PIECE: + if (steps % 7 == 0 ) { + if (steps == 7 && rows == 1 && isEmpty(t)) { + if ( isBlack(o) && (t>o) ) + return true; + if ( isWhite(o) && (to) && isEnemy(o+7, o) ) + return true; + if ( isWhite(o) && (to) ) + return true; + if ( isWhite(o) && (to) && isEnemy(o+9, o) ) + return true; + if ( isWhite(o) && (t= 0 && pos <64) + setPiece(pos, new Piece(null, null, EMPTY, 0)); + } + + stack.setSize(size-2); + + /* Reset the current player */ + setBlacksTurn(h2.turn()); + } + + /** + * simulates a "valid" move or returns false. + * all changes are relative to pieces and will not be painted. + */ + public boolean simulateMove(int t, int o) { + int steps = Math.abs(t-o); + int rows = Math.abs(t/8 - o/8); + int pos; + + if ( !validMove(t, o) ) { + return false; + } + + if ( rows == 2 && getType(o) == PIECE) { + pos = (t-o)/2 + o; + push(getPiece(pos), pos, getPiece(o), o); + setPiece(pos, new Piece(null, null, EMPTY, 0)); + } else + push(getPiece(t), t, getPiece(o), o); + + setPiece(t, new Piece(getPiece(o))); + setPiece(o, new Piece(null, null, EMPTY, 0)); + + return true; + } + + /** + * performs a "valid" move or returns false. + * all changes are relative to board_pieces and will be painted. + */ + public boolean doMove(int t, int o) { + int steps = Math.abs(t-o); + int rows = Math.abs(t/8-o/8); + int pos; + + if ( !validMove(t, o) ) { + return false; + } + + if ( rows == 2 && getType(o) == PIECE) { + pos = (t-o)/2 + o; + push(getPiece(pos), pos, getPiece(o), o); + setPiece(pos, new Piece(null, null, EMPTY, 0)); + } else if ( rows >= 2 && getType(o) == QUEEN ) { + if (steps % 7 == 0 ) { + if ( t > o ) + for ( pos=o+7;pos <= t-7;pos+=7 ) { + if ( isEnemy(pos, o) ) { + push(getPiece(pos), pos, getPiece(o), o); + setPiece(pos, new Piece(null, null, EMPTY, 0)); + } + } + else { + for ( pos=o-7;pos >= t+7;pos-=7 ) { + if ( isEnemy(pos, o) ) { + push(getPiece(pos), pos, getPiece(o), o); + setPiece(pos, new Piece(null, null, EMPTY, 0)); + } + } + } + } + + if (steps % 9 == 0 ) { + if ( t > o ) + for ( pos=o+9;pos <= t-9;pos+=9 ) { + if ( isEnemy(pos, o) ) { + push(getPiece(pos), pos, getPiece(o), o); + setPiece(pos, new Piece(null, null, EMPTY, 0)); + } + } + else { + for ( pos=o-9;pos >= t+9;pos-=9 ) { + if ( isEnemy(pos, o) ) { + push(getPiece(pos), pos, getPiece(o), o); + setPiece(pos, new Piece(null, null, EMPTY, 0)); + } + } + } + } + } + + if ( t <= 7 && getType(o) == PIECE) + setPiece(t, new Piece(white_super_sun)); + else if (t >=56 && getType(o) == PIECE) + setPiece(t, new Piece(black_super_sun)); + else + setPiece(t, new Piece(getPiece(o))); + + setPiece(o, new Piece(null, null, EMPTY, 0)); + + board_pieces = getPieces(); + repaint(); + + moveNr = stack.size(); + + return true; + } +} diff --git a/org/homelinux/largo/games/board/chessboard/ChessBoard.java b/org/homelinux/largo/games/board/chessboard/ChessBoard.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/games/board/chessboard/ChessBoard.java @@ -0,0 +1,659 @@ +/** + * $Id: ChessBoard.java 152 2008-04-27 02:04:31Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/games/board/chessboard/ChessBoard.java $ + */ + +package org.homelinux.largo.games.board.chessboard; + +import java.awt.Image; + +import org.homelinux.largo.games.board.Board; +import org.homelinux.largo.games.board.Piece; +import org.homelinux.largo.utils.ImgComponent; + +public class ChessBoard extends Board { + static final long serialVersionUID = 140208; + + static final int ROOK = 1; + static final int KNIGHT = 2; + static final int BISHOP = 3; + static final int QUEEN = 4; + static final int KING = 5; + static final int PAWN = 6; + + final Piece white_queen = new Piece(new ImgComponent("images/white_queen.png").getImage(), + "white", QUEEN, 90); + final Piece black_queen = new Piece(new ImgComponent("images/black_queen.png").getImage(), + "black", QUEEN, 90); + + boolean white_rochades_small; + boolean white_rochades_big; + boolean black_rochades_small; + boolean black_rochades_big; + + void initBoard () { + add (new ImgComponent ("images/black_rook.png").getImage (), 0, "black", ROOK); + add (new ImgComponent ("images/black_knight.png").getImage (), 1, "black", KNIGHT); + add (new ImgComponent ("images/black_bishop.png").getImage (), 2, "black", BISHOP); + add (new ImgComponent ("images/black_queen.png").getImage (), 3, "black", QUEEN); + add (new ImgComponent ("images/black_king.png").getImage (), 4, "black", KING); + add (new ImgComponent ("images/black_bishop.png").getImage (), 5, "black", BISHOP); + add (new ImgComponent ("images/black_knight.png").getImage (), 6, "black", KNIGHT); + add (new ImgComponent ("images/black_rook.png").getImage (), 7, "black", ROOK); + + for (int i = 0; i < 8; i++) + add (new ImgComponent ("images/black_pawn.png").getImage (), 8 + i, "black", PAWN); + + add (new ImgComponent ("images/white_rook.png").getImage (), 56, "white", ROOK); + add (new ImgComponent ("images/white_knight.png").getImage (), 57, "white", KNIGHT); + add (new ImgComponent ("images/white_bishop.png").getImage (), 58, "white", BISHOP); + add (new ImgComponent ("images/white_queen.png").getImage (), 59, "white", QUEEN); + add (new ImgComponent ("images/white_king.png").getImage (), 60, "white", KING); + add (new ImgComponent ("images/white_bishop.png").getImage (), 61, "white", BISHOP); + add (new ImgComponent ("images/white_knight.png").getImage (), 62, "white", KNIGHT); + add (new ImgComponent ("images/white_rook.png").getImage (), 63, "white", ROOK); + + for (int i = 0; i < 8; i++) + add (new ImgComponent ("images/white_pawn.png").getImage (), 55 - i, "white", PAWN); + } + + /** + * The init method initializes a complete chess board with figures and a history. + */ + public void init() { + super.init(); + initBoard(); + board_pieces = getPieces(); + repaint(); + } + + public ChessBoard (int w, int h) { + super(w, h); + } + + void add (Image img, int i, String c, int t) { + int v = 0; + + switch (t) { + case ROOK: + v = 40; + break; + case KNIGHT: + v = 30; + break; + case BISHOP: + v = 30; + break; + case QUEEN: + v = 90; + break; + case KING: + v = 500; + break; + case PAWN: + v = 10; + break; + } + + setPiece(i, new Piece(img, c, t, v)); + } + + /** + * returns true, when the white king is at pieces[i] + */ + public boolean isWhiteKing(int i) { + if ( isWhite(i) && getType(i) == KING) + return true; + return false; + } + + /** + * returns true, when the black king is at pieces[i] + */ + public boolean isBlackKing(int i) { + if ( isBlack(i) && getType(i) == KING) + return true; + return false; + } + + /** + * Returns the score of the current position + * Every field controlled by [color] gives one point + * A King, controlled by [color], gives 10 extra points + */ + public int controls(String color) { + int t, o; + int value = 0; + + for ( o=0;o<64;o++) { + if (color.equals(getColor(o))) { + for (t=0;t<64;t++) { + if(validMove(t, o)) { + if ( getType(t) == KING ) + value+=10; + value++; + } + } + } + } + return value; + } + + /** + * Checks, wether this move is possible or not. + */ + public boolean validMove (int t, int o) { + int steps; + int rows; + int dx; + + /* Must be here */ + white_rochades_small = false; + white_rochades_big = false; + black_rochades_small = false; + black_rochades_big = false; + + if ( t == o ) + return false; + + if (isSamePiece(t, o)) + return false; + + if (getType(o) == EMPTY) + return false; + + /* + * 00 01 02 03 04 05 06 07 + * 08 09 10 11 12 13 14 15 + * 16 17 18 19 20 21 22 23 + * 24 25 26 27 28 29 30 31 + * 32 33 34 35 36 37 38 39 + * 40 41 42 43 44 45 46 47 + * 48 49 50 51 52 53 54 55 + * 56 57 58 59 60 61 62 63 + */ + + steps = Math.abs(t-o); + rows = Math.abs(t/8 - o/8); + + switch( getType(o) ) { + case ROOK: + if (steps < 8 && rows == 0 ) { + if(t>o) + for ( dx = o+1; dx < t; dx++ ) { + if ( getColor(dx) != null ) { + return false; + } + } + else + for ( dx = o-1; dx > t; dx-- ) { + if ( getColor(dx) != null ) { + return false; + } + } + return true; + } + if (steps % 8 == 0 ) { + if ( t>o ) { + for ( dx = o+8; dx < t; dx+=8 ) { + if (getColor(dx) != null) + return false; + } + } else { + for ( dx = o-8; dx > t; dx-=8 ) { + if (getColor(dx) != null) + return false; + } + } + if (steps == 8 && rows == 1) + return true; + if (steps == 16 && rows == 2) + return true; + if (steps == 24 && rows == 3) + return true; + if (steps == 32 && rows == 4) + return true; + if (steps == 40 && rows == 5) + return true; + if (steps == 48 && rows == 6) + return true; + if (steps == 56 && rows == 7) + return true; + } + break; + case KNIGHT: + /* works fine */ + if (steps == 6 && rows == 1) + return true; + if (steps == 10 && rows == 1) + return true; + if (steps == 15 && rows == 2) + return true; + if (steps == 17 && rows == 2) + return true; + break; + case BISHOP: + if (steps % 7 == 0 ) { + if ( t>o ) { + for ( dx = o+7; dx < t; dx+=7 ) { + if (getColor(dx) != null) + return false; + } + } else { + for ( dx = o-7; dx > t; dx-=7 ) { + if (getColor(dx) != null) + return false; + } + } + if (steps == 7 && rows == 1) + return true; + if (steps == 14 && rows == 2) + return true; + if (steps == 21 && rows == 3) + return true; + if (steps == 28 && rows == 4) + return true; + if (steps == 35 && rows == 5) + return true; + if (steps == 42 && rows == 6) + return true; + if (steps == 49 && rows == 7) + return true; + } + if (steps % 9 == 0 ) { + if ( t>o ) { + for ( dx = o+9; dx < t; dx+=9 ) { + if (getColor(dx) != null) + return false; + } + } else { + for ( dx = o-9; dx > t; dx-=9 ) { + if (getColor(dx) != null) + return false; + } + } + if (steps == 9 && rows == 1) + return true; + if (steps == 18 && rows == 2) + return true; + if (steps == 27 && rows == 3) + return true; + if (steps == 36 && rows == 4) + return true; + if (steps == 45 && rows == 5) + return true; + if (steps == 54 && rows == 6) + return true; + if (steps == 63 && rows == 7) + return true; + } + break; + + case QUEEN: + if (steps < 8 && rows == 0 ) { + if(t>o) + for ( dx = o+1; dx < t; dx++ ) { + if ( getColor(dx) != null ) + return false; + } + else + for ( dx = o-1; dx > t; dx-- ) { + if ( getColor(dx) != null ) + return false; + } + return true; + } + + if (steps % 8 == 0 ) { + if ( t>o ) { + for ( dx = o+8; dx < t; dx+=8 ) { + if (getColor(dx) != null) + return false; + } + } else { + for ( dx = o-8; dx > t; dx-=8 ) { + if (getColor(dx) != null) + return false; + } + } + + if (steps == 8 && rows == 1) + return true; + if (steps == 16 && rows == 2) + return true; + if (steps == 24 && rows == 3) + return true; + if (steps == 32 && rows == 4) + return true; + if (steps == 40 && rows == 5) + return true; + if (steps == 48 && rows == 6) + return true; + if (steps == 56 && rows == 7) + return true; + } + if (steps % 7 == 0 ) { + if ( t>o ) { + for ( dx = o+7; dx < t; dx+=7 ) { + if (getColor(dx) != null) + return false; + } + } else { + for ( dx = o-7; dx > t; dx-=7 ) { + if (getColor(dx) != null) + return false; + } + } + if (steps == 7 && rows == 1) + return true; + if (steps == 14 && rows == 2) + return true; + if (steps == 21 && rows == 3) + return true; + if (steps == 28 && rows == 4) + return true; + if (steps == 35 && rows == 5) + return true; + if (steps == 42 && rows == 6) + return true; + if (steps == 49 && rows == 7) + return true; + } + + if (steps % 9 == 0 ) { + if ( t>o ) { + for ( dx = o+9; dx < t; dx+=9 ) { + if (getColor(dx) != null) + return false; + } + } else { + for ( dx = o-9; dx > t; dx -=9 ) { + if (getColor(dx) != null) + return false; + } + } + if (steps == 9 && rows == 1) + return true; + if (steps == 18 && rows == 2) + return true; + if (steps == 27 && rows == 3) + return true; + if (steps == 36 && rows == 4) + return true; + if (steps == 45 && rows == 5) + return true; + if (steps == 54 && rows == 6) + return true; + if (steps == 63 && rows == 7) + return true; + } + break; + + case KING: + if ( (steps == 1) && (rows == 0) ) + return true; + + if ( (steps == 8) && (rows == 1) ) + return true; + + if ( (steps == 7) && (rows == 1) ) + return true; + + if ( (steps == 9) && (rows == 1) ) + return true; + + if ( (steps == 2) && (rows == 0) ) { + if ( isWhiteKing(o) ) { /* White: Rochade */ + if ( isWhiteKing(60) && isEmpty(61) && isEmpty(62) && (t==62) ) { + if ( (getType(63) == ROOK) && isWhite(63) ) { + white_rochades_small = true; + return true; + } + } + + if ( isWhiteKing(60) && isEmpty(59) && isEmpty(58) && isEmpty(57) && (t==58) ) { + if ( (getType(56) == ROOK) && isWhite(56) ) { + white_rochades_big = true; + return true; + } + } + } + + if ( isBlackKing(o) ) { /* Black: Rochade */ + if ( isBlackKing(4) && isEmpty(5) && isEmpty(6) && (t==6) ) { + if ( (getType(7) == ROOK) && isBlack(7) ) { + black_rochades_small = true; + return true; + } + } + + if ( isBlackKing(4) && isEmpty(3) && isEmpty(2) && isEmpty(1) && (t==2) ) { + if ( (getType(0) == ROOK) && isBlack(0) ) { + black_rochades_big = true; + return true; + } + } + } + } + break; + + case PAWN: + if (getColor(o).equals("white")) { + if (steps == 7 && rows == 1 && isEnemy(t, o) && to) + return true; + + if (steps == 9 && rows == 1 && isEnemy(t, o) && t>o) + return true; + } + + if (steps % 8 == 0 ) { + if ( t>o ) { + for ( dx = o+8; dx <= t; dx+=8 ) { + if (getColor(dx) != null) + return false; + } + } else { + for ( dx = o-8; dx >= t; dx-=8 ) { + if (getColor(dx) != null) + return false; + } + } + + if (steps == 8 && rows == 1) { + if ( getColor(o).equals("white") && t < o ) + return true; + if ( getColor(o).equals("black") && t > o ) + return true; + } + + if (steps == 16 && rows == 2 && (o>= 8 && o <=15) ) { + if ( getColor(o).equals("white") && t < o ) + return true; + if ( getColor(o).equals("black") && t > o ) + return true; + } + + if (steps == 16 && rows == 2 && (o>=48 && o <=55) ) { + if ( getColor(o).equals("white") && t < o ) + return true; + if ( getColor(o).equals("black") && t > o ) + return true; + } + } + break; + } + return false; + } + + /** + * This method must be called immediately after isValidMove(t, o) + */ + boolean rochade() { + if (white_rochades_small) { + setPiece(61, getPiece(63)); + setPiece(63, new Piece(null, null, EMPTY, 0)); + return true; + } + + if (white_rochades_big) { + setPiece(59, getPiece(56)); + setPiece(56, new Piece(null, null, EMPTY, 0)); + return true; + } + + if (black_rochades_small) { + setPiece(5, getPiece(7)); + setPiece(7, new Piece(null, null, EMPTY, 0)); + return true; + } + + if (black_rochades_big) { + setPiece(3, getPiece(0)); + setPiece(0, new Piece(null, null, EMPTY, 0)); + return true; + } + + return false; + } + + /** + * checks, whether color is in check or not. + */ + public boolean isCheck(String color) { + int i; + int wking; + int bking; + + wking = bking = -1; + + for (i=0;i<64;i++) { + if (isWhiteKing(i)) { + wking = i; + } + if (isBlackKing(i)) { + bking = i; + } + } + + // returns 64 false positives + if (wking == -1 || bking == -1) + return true; + + if (color.equals("white")) { + for (i=0;i<64;i++) + if (validMove(wking, i)) { + return true; + } + + return false; + } + + if (color.equals("black")) { + for (i=0;i<64;i++) + if (validMove(bking, i)) { + return true; + } + + return false; + } + return false; + } + + /** + * simulates a "valid" move or returns false. + * all changes are relative to pieces and will not be painted. + * This method sets internal variables for the rochade() method, which will be overwritten. + */ + public boolean simulateMove(int t, int o) { + if ( !validMove(t, o) ) { + return false; + } + + push(getPiece(t), t, getPiece(o), o); + + if ( getType(o) == PAWN ) { + if(isBlack(o) && t >=56) + setPiece(o, new Piece(black_queen)); + + if(isWhite(o) && t <=7) + setPiece(o, new Piece(white_queen)); + } + + setPiece(t, new Piece(getPiece(o))); + setPiece(o, new Piece(null, null, EMPTY, 0)); + + if (isCheck(getColor(t))) { + /* restore current position */ + if(UNDO_DEBUG) + print("UNDO", t, o, 0); + undo(); + return false; + } + + return true; + } + + /** + * performs a "valid" move or returns false. + * all changes are relative to board_pieces and will be painted. + */ + public boolean doMove(int t, int o) { + if ( !validMove(t, o) ) { + return false; + } + + push(getPiece(t), t, getPiece(o), o); + + if ( getType(o) == PAWN ) { + if(isBlack(o) && t >=56) + setPiece(o, new Piece(black_queen)); + + if(isWhite(o) && t <=7) + setPiece(o, new Piece(white_queen)); + } + + setPiece(t, new Piece(getPiece(o))); + setPiece(o, new Piece(null, null, EMPTY, 0)); + + if (rochade()) + System.out.println("Rochade"); + + if (isCheck(getColor(t))) { + // restore current positions + if(UNDO_DEBUG) + print("UNDO", t, o, 0); + undo(); + return false; + } + + board_pieces = getPieces(); + repaint(); + + moveNr = stack.size(); + + return true; + } + + /** + * converts the internal representation into normal chess notation and writes it to stdout + */ + public void print(String s, int t, int o, int value) { + int row1, col1, row2, col2; + + row1 = o/8; + col1 = o-(8*row1); + + row2 = t/8; + col2 = t-(8*row2); + + System.out.printf("%s: %C%d-%c%d = %3d\n", s, + ('A')+col1, 8-row1, + ('A')+col2, 8-row2, value); + } +} diff --git a/org/homelinux/largo/schach/KIBoard.java b/org/homelinux/largo/schach/KIBoard.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/schach/KIBoard.java @@ -0,0 +1,209 @@ +/** + * $Id: KIBoard.java 139 2008-04-25 05:02:55Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/schach/KIBoard.java $ + */ + +package org.homelinux.largo.schach; + +import org.homelinux.largo.games.board.Move; +import org.homelinux.largo.games.board.chessboard.ChessBoard; + +public class KIBoard extends ChessBoard { + static final long serialVersionUID = 200208; + static final int game_const = 500; + + protected boolean SIMU_DEBUG = false; + private boolean negate_estimation = false; + + private Move bestMove; + private int desired_depth; + + public KIBoard(int w, int h) { + super(w, h); + desired_depth = -1; + } + + /** + * Set the current DEBUG-Level: + * simu: print all valid, simulated moves + * undo: print all undos + */ + public void setDebug(boolean simu, boolean undo) { + SIMU_DEBUG = simu; + UNDO_DEBUG = undo; + } + + public boolean simu_debug() { + return SIMU_DEBUG; + } + + public boolean undo_debug() { + return UNDO_DEBUG; + } + + /** + * This function flips the sides: Player A maximizes and Player B minimizes + */ + public void negateEstimation(boolean b) { + negate_estimation = b; + } + + /** + * The Minimax-Algorithm works for TWO-PLAYER Games + * Player A minimizes, Player B maximizes + */ + public int estimateFunction() { + int i; + int white = 0; + int black = 0; + + for(i=0;i<64;i++) { + if (isWhite(i)) + white+=getValue(i); + if (isBlack(i)) + black+=getValue(i); + } + + white+=controls("white"); + black+=controls("black"); + + /** + * solves ticket #3 + */ + if ( negate_estimation ) + return white-black; + + return black-white; + } + + /** + * simulates and returns the next possible move for a Player or null, when no more moves are possible. + * The Turn is flipped automatically if "simulate(...)" will find a valid move. + */ + Move simulate(int t, int o) { + Move move = null; + int value; + + if ( validTurn(o) ) { + while ( t < 64 ) { + if (!simulateMove(t, o) ) { + t++; + continue; + } + + value = estimateFunction(); + if(SIMU_DEBUG) + print("SIMU", t, o, value); + + move = new Move(value, t, o); + + /* Flip Sides */ + setBlacksTurn(!isBlacksTurn()); + return move; + } + } + return null; + } + + /** + * AlphaBeta-Algorithm: the Maximizer + */ + int max_alpha_beta (int depth, int alpha, int beta) { + int moveValue; + int o, t; + Move move = null; + + if ( desired_depth == -1 ) + desired_depth = depth; + + for (o = 0; o < 64; o++) { + t=0; + while ( (move=simulate(t, o)) != null ) { + /* particular move from black */ + t = move.target; + + if ( depth == 0 || Math.abs(move.value) > game_const ) + moveValue = move.value; + else /* best next move */ + moveValue = min_alpha_beta(depth-1, alpha, beta); + + undo(); + t++; + + if ( moveValue >= beta ) + return beta; + + if ( moveValue > alpha ) { + alpha = moveValue; + if ( depth == desired_depth ) + bestMove = move; + } + } + } + + return alpha; + } + + /** + * AlphaBeta-Algorithm: the Minimizer + */ + int min_alpha_beta(int depth, int alpha, int beta) { + int moveValue; + int o, t; + Move move = null; + + for (o = 0; o < 64; o++) { + t=0; + while ( (move=simulate(t, o)) != null ) { + /* particular move from white */ + t = move.target; + + if ( depth == 0 || Math.abs(move.value) > game_const ) + moveValue = move.value; + else /* best next move */ + moveValue = max_alpha_beta(depth-1, alpha, beta); + + undo(); + t++; + + if ( moveValue <= alpha ) + return alpha; + + if ( moveValue < beta ) + beta = moveValue; + } + } + + return beta; + } + + /** + * Evaluates the next, best Move after search_depth half-moves. + * When the Machine has Black, set negateEstimation(false); + * When the Machine has White, set negateEstimation(true); + */ + public boolean doBestMove(int search_depth) { + int value; + + desired_depth = -1; + bestMove = null; + value = max_alpha_beta(search_depth, Integer.MIN_VALUE, Integer.MAX_VALUE); + + if ( bestMove == null ) { + System.err.println("Computing once more..."); + value = max_alpha_beta(1, Integer.MIN_VALUE, Integer.MAX_VALUE); + if (bestMove == null) { + System.out.println("Check Mate"); + return false; + } + } + + if (doMove(bestMove.target, bestMove.origin)) { + print(getColor(bestMove.target), bestMove.target, bestMove.origin, bestMove.value); + return true; + } + + print("Check Mate", bestMove.target, bestMove.origin, bestMove.value); + return false; + } +} diff --git a/org/homelinux/largo/schach/Schach.java b/org/homelinux/largo/schach/Schach.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/schach/Schach.java @@ -0,0 +1,235 @@ +/** + * $Id: Schach.java 143 2008-04-25 12:19:23Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/schach/Schach.java $ + */ + +package org.homelinux.largo.schach; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.SpinnerNumberModel; + +import org.homelinux.largo.games.board.MouseListener; +import org.homelinux.largo.games.board.Point; +import org.homelinux.largo.utils.BrowserLaunch; + +public class Schach extends JFrame implements Runnable { + static final long serialVersionUID = 140208; + static final String helpURL = "http://largo.homelinux.org/trac/browser/eclipse/Schachspiel/trunk"; + + MouseListener listener = null; + KIBoard board = null; + Point p = null; + JLabel human = new JLabel("Human"); + JLabel computer = new JLabel("Computer"); + JButton neu = new JButton("Play"); + JButton pconly = new JButton("PC-PC"); + JButton back = new JButton("Back"); + JButton forward = new JButton("For"); + JButton help = new JButton("Source"); + + SpinnerNumberModel model = new SpinnerNumberModel(4, 1, 8, 1); + JSpinner combo = new JSpinner(model); + + JPanel panel; + JPanel fpanel; + + int search_depth; + + boolean pc_only; + + public Schach (int w, int h) { + super("Chess by Largo Enterprises"); + setDefaultCloseOperation (javax.swing.JFrame.EXIT_ON_CLOSE); + board = new KIBoard(w, h); + + fpanel = new JPanel(); + fpanel.add(back); + fpanel.add(neu); + fpanel.add(combo); + fpanel.add(pconly); + fpanel.add(help); + fpanel.add(forward); + + panel = new JPanel(); + panel.setLayout(new BorderLayout()); + panel.add(human, "West"); + panel.add(fpanel, "Center"); + panel.add(computer, "East"); + + fpanel.setBackground(new Color(50, 100, 200)); + panel.setBackground(new Color(50, 100, 200)); + + getContentPane().setLayout(new BorderLayout()); + getContentPane().add(panel, "North"); + getContentPane().add(board, "Center"); + + neu.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionevent) { + human.setText("Human"); + computer.setText("Computer"); + pc_only = false; + board.init(); + board.negateEstimation(false); + } + }); + + pconly.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionevent) { + human.setText("Computer"); + computer.setText("Computer"); + pc_only = true; + } + }); + + back.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionevent) { + board.backwards(); + } + }); + + forward.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionevent) { + board.forward(); + } + }); + + help.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionevent) { + BrowserLaunch browser = new BrowserLaunch(); + browser.openURL(helpURL); + } + }); + + listener = board.getMouseListener(); + + pc_only = false; + search_depth = 3; + pack(); + } + + public void computer_play () { + while (pc_only) { + search_depth = model.getNumber().intValue()-1; + + if ( !board.isBlacksTurn() ) { + human.setText("Computer"); + board.negateEstimation(true); + if (!board.doBestMove(search_depth) ) { + pc_only = false; + return; + } + board.negateEstimation(false); + human.setText("Computer"); + board.setBlacksTurn(true); + } else { + computer.setText("Computer"); + if (!board.doBestMove(search_depth) ) { + pc_only = false; + return; + } + computer.setText("Computer"); + board.setBlacksTurn(false); + + if (board.simu_debug()) { + for (int i=0;i<64;i++) { + if((i+1)%8 == 0 ) + System.err.printf("%2d=%d\n", i, board.getValue(i)); + else + System.err.printf("%2d=%d ", i, board.getValue(i)); + } + } + + try { + Thread.sleep (10); + } catch (InterruptedException e) { + System.err.println("computer_play: " + e.getLocalizedMessage()); + System.err.println("========================================================================"); + e.printStackTrace(); + System.err.println("========================================================================"); + return; + } + } + } + } + + public void run () { + for (;;) { + + /* is this thread safe */ + search_depth = model.getNumber().intValue()-1; + + if (pc_only) { + computer_play (); + } + + if ( !board.isBlacksTurn() ) { + if (listener.isSelected ()) { + p = listener.getSelection (); + if (board.move (p)) + board.setBlacksTurn(true); + } + try { + Thread.sleep (50); + } + catch (InterruptedException e) { + System.err.println("Schach::run: " + e.getLocalizedMessage()); + System.err.println("========================================================================"); + e.printStackTrace(); + System.err.println("========================================================================"); + return; + } + } else { + human.setText("Human"); + computer.setText("Computer"); + board.doBestMove(search_depth); + human.setText("Human"); + computer.setText("Computer"); + board.setBlacksTurn(false); + + if (board.simu_debug()) { + for (int i=0;i<64;i++) { + if((i+1)%8 == 0 ) + System.out.printf("%2d=%d\n", i, board.getValue(i)); + else + System.out.printf("%2d=%d ", i, board.getValue(i)); + } + } + } + } + } + + public static void main (String args[]) { + Schach s = new Schach (74, 74); + + s.setResizable(false); + s.setVisible (true); + + if (args.length == 1 ) { + if ( args[0].equals("full") ) + s.board.setDebug(true, true); + else if ( args[0].equals("simu") ) + s.board.setDebug(true, false); + else if ( args[0].equals("undo") ) + s.board.setDebug(false, true); + else if ( args[0].equals("none") ) + s.board.setDebug(false, false); + else { + System.out.println(" Chess: java -jar games.jar [full|simu|undo|none]"); + System.out.println("Checkers: java -cp games.jar org.homelinux.largo.checkers.Checkers [full|simu|undo|none]"); + } + } + + Thread t = new Thread(s); + t.setPriority(Thread.NORM_PRIORITY-1); + t.start(); + } +} diff --git a/org/homelinux/largo/utils/BrowserLaunch.java b/org/homelinux/largo/utils/BrowserLaunch.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/utils/BrowserLaunch.java @@ -0,0 +1,50 @@ +/** + * $Id: BrowserLaunch.java 125 2008-04-22 08:06:08Z mbroeker $ + * $URL: http://localhost/svn/eclipse/Schachspiel/trunk/org/homelinux/largo/utils/BrowserLaunch.java $ + */ + +package org.homelinux.largo.utils; + +import java.lang.reflect.Method; + +import javax.swing.JOptionPane; +/** + * Cross-Platform Browserlaunch + */ +public class BrowserLaunch { + private static final String errMsg = "Error attempting to launch web browser"; + + /** + * This method opens the URL in a native platform browser + */ + public void openURL(String url) { + String osName = System.getProperty("os.name"); + try { + if (osName.startsWith("Mac OS")) { + Class fileMgr = Class.forName("com.apple.eio.FileManager"); + Method openURL = fileMgr.getDeclaredMethod("openURL", + new Class[] { String.class }); + openURL.invoke(null, new Object[] { url }); + } else if (osName.startsWith("Windows")) + Runtime.getRuntime().exec( + "rundll32 url.dll,FileProtocolHandler " + url); + else { + String[] browsers = { "firefox", "opera", "konqueror", + "epiphany", "mozilla", "netscape" }; + String browser = null; + for (int count = 0; count < browsers.length && browser == null; count++) + if (Runtime.getRuntime().exec( + new String[] { "which", browsers[count] }) + .waitFor() == 0) + browser = browsers[count]; + if (browser == null) + throw new Exception("Could not find web browser"); + else + Runtime.getRuntime().exec(new String[] { browser, url }); + } + } catch (Exception e) { + JOptionPane.showMessageDialog(null, errMsg + ":\n" + + e.getLocalizedMessage()); + } + } +}; diff --git a/org/homelinux/largo/utils/ImgComponent.java b/org/homelinux/largo/utils/ImgComponent.java new file mode 100644 --- /dev/null +++ b/org/homelinux/largo/utils/ImgComponent.java @@ -0,0 +1,31 @@ +package org.homelinux.largo.utils; + +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.Image; +import java.net.URL; + +import javax.swing.ImageIcon; + +public class ImgComponent extends Canvas { + static final long serialVersionUID = 140208; + private Image img = null; + + public ImgComponent (String sFile) { + ClassLoader cl = getClass ().getClassLoader (); + URL url = cl.getResource (sFile); + img = new ImageIcon (url).getImage (); + } + + public Image getImage () { + return img; + } + + public Dimension getPreferredSize () { + return new Dimension (img.getWidth (this), img.getHeight (this)); + } + + public Dimension getMinimumSize () { + return getPreferredSize (); + } +} diff --git a/schach.manifest b/schach.manifest new file mode 100644 --- /dev/null +++ b/schach.manifest @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Main-Class: org.homelinux.largo.schach.Schach