From 733391625220ab7dd7e8cb795feaf0447ac4fbb7 Mon Sep 17 00:00:00 2001 From: Peter Elliott Date: Mon, 10 Aug 2020 12:54:32 -0600 Subject: [PATCH] Chess: Add basic ChessWidget and ugly piece set --- Base/res/apps/Chess.af | 8 + Base/res/icons/16x16/app-chess.png | Bin 0 -> 7660 bytes Base/res/icons/32x32/app-chess.png | Bin 0 -> 8154 bytes .../icons/chess/sets/test/black-bishop.png | Bin 0 -> 931 bytes Base/res/icons/chess/sets/test/black-king.png | Bin 0 -> 961 bytes .../icons/chess/sets/test/black-knight.png | Bin 0 -> 2007 bytes Base/res/icons/chess/sets/test/black-pawn.png | Bin 0 -> 775 bytes .../res/icons/chess/sets/test/black-queen.png | Bin 0 -> 816 bytes Base/res/icons/chess/sets/test/black-rook.png | Bin 0 -> 777 bytes .../icons/chess/sets/test/white-bishop.png | Bin 0 -> 4705 bytes Base/res/icons/chess/sets/test/white-king.png | Bin 0 -> 6448 bytes .../icons/chess/sets/test/white-knight.png | Bin 0 -> 7535 bytes Base/res/icons/chess/sets/test/white-pawn.png | Bin 0 -> 2801 bytes .../res/icons/chess/sets/test/white-queen.png | Bin 0 -> 3396 bytes Base/res/icons/chess/sets/test/white-rook.png | Bin 0 -> 5938 bytes Games/CMakeLists.txt | 1 + Games/Chess/CMakeLists.txt | 8 + Games/Chess/Chess.cpp | 127 ++++++++++++++ Games/Chess/Chess.h | 102 +++++++++++ Games/Chess/ChessWidget.cpp | 166 ++++++++++++++++++ Games/Chess/ChessWidget.h | 69 ++++++++ Games/Chess/main.cpp | 47 +++++ 22 files changed, 528 insertions(+) create mode 100644 Base/res/apps/Chess.af create mode 100644 Base/res/icons/16x16/app-chess.png create mode 100644 Base/res/icons/32x32/app-chess.png create mode 100644 Base/res/icons/chess/sets/test/black-bishop.png create mode 100644 Base/res/icons/chess/sets/test/black-king.png create mode 100644 Base/res/icons/chess/sets/test/black-knight.png create mode 100644 Base/res/icons/chess/sets/test/black-pawn.png create mode 100644 Base/res/icons/chess/sets/test/black-queen.png create mode 100644 Base/res/icons/chess/sets/test/black-rook.png create mode 100644 Base/res/icons/chess/sets/test/white-bishop.png create mode 100644 Base/res/icons/chess/sets/test/white-king.png create mode 100644 Base/res/icons/chess/sets/test/white-knight.png create mode 100644 Base/res/icons/chess/sets/test/white-pawn.png create mode 100644 Base/res/icons/chess/sets/test/white-queen.png create mode 100644 Base/res/icons/chess/sets/test/white-rook.png create mode 100644 Games/Chess/CMakeLists.txt create mode 100644 Games/Chess/Chess.cpp create mode 100644 Games/Chess/Chess.h create mode 100644 Games/Chess/ChessWidget.cpp create mode 100644 Games/Chess/ChessWidget.h create mode 100644 Games/Chess/main.cpp diff --git a/Base/res/apps/Chess.af b/Base/res/apps/Chess.af new file mode 100644 index 0000000000..c2393a4dd5 --- /dev/null +++ b/Base/res/apps/Chess.af @@ -0,0 +1,8 @@ +[App] +Name=Chess +Executable=/bin/Chess +Category=Games + +[Icons] +16x16=/res/icons/16x16/app-chess.png +32x32=/res/icons/32x32/app-chess.png diff --git a/Base/res/icons/16x16/app-chess.png b/Base/res/icons/16x16/app-chess.png new file mode 100644 index 0000000000000000000000000000000000000000..e53265f12e0f785243115e328a50ba38e855375e GIT binary patch literal 7660 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 O2;9@v&t;ucLK6U?DZ7>c literal 0 HcmV?d00001 diff --git a/Base/res/icons/32x32/app-chess.png b/Base/res/icons/32x32/app-chess.png new file mode 100644 index 0000000000000000000000000000000000000000..835c7a72c0b01059c924fe6e1ec1bd2f6f679748 GIT binary patch literal 8154 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 literal 0 HcmV?d00001 diff --git a/Base/res/icons/chess/sets/test/black-king.png b/Base/res/icons/chess/sets/test/black-king.png new file mode 100644 index 0000000000000000000000000000000000000000..17c1ea8b1b3af0c3b5def2dd98b648e0426c6c1b GIT binary patch literal 961 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEB zNoL!%zU@(JQ1~TywBv|Rt=?3xL&Y_B4heLj+ywDHElBKFOb77FXB>^%o>NdXZ4_uHgo^dVr_wO6qW~(>+m)vpb z*1s&~89!C_-n*vc?r`6%pz!XsC$Sb5&^EW;&T6=f>R9glH2DT(`cNYdQ`02d6 zo`HdZv%n*=n1Ml08H5=tmfDvwFfg!}c>21sKjGjKFyqVdbDzw>z#v)T8d2h$pPQSS zSHj?2l$uzQnxasiS(2gP?&%v4-pD7;z`!`u)5S5Q;?~>9=)S`S94xEZZ!UgwcDH%5 zeVMjv=H#TfvR9It@uiKD&Agm~U`Mo0_@B=8f#H+#U;Bk?=k=ZDF3|S*u6a;g;r#09 z4KaqyO3cq!a|tN=RMl+f464b{Z^+)TU|VGxqs7D@_u4fcYuGAB8C9PB@Y&hrzRMR^ zm-5ALudEJQG+)>3;C<$t_Gu1XtLo>JI~w$By*}(5P{pA#;X|5E_0>sopY}TCyj9^8 z*KcU6QCn&JpZ#BmY@?$!5Bt516XYArg%=sGOp!=>HsOG- zWcp6QOYMr?5|T?pv>KL+RGo0=2sY!3HhL&~up`J@I6=N9zd7Wpz}A^%H7?nAx14f~ zFN{05i0{<1o1%iA@_lmOq>CAFCU9Cj7O>g)avs}N zXV)toGC7<57#^=!C3Nsd{J997X>+B2Ow)MYdx7=fG}ie}ajJ*7<{wKbW%P5+xEK6o z@@wa?2REyEKd~O|d^w}*^^|6pxK(o)!66JHbn6&{A3W~in!D~ki0kR<=d#Wzp$P!I CZk)>i literal 0 HcmV?d00001 diff --git a/Base/res/icons/chess/sets/test/black-knight.png b/Base/res/icons/chess/sets/test/black-knight.png new file mode 100644 index 0000000000000000000000000000000000000000..7f16e286d6dad67e240685ae4927ed0194a0b97f GIT binary patch literal 2007 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEx#|Jy)-@mhccaPC&@u85-*)jp9r#;jk zC7Es4`nE@@LE(^u+x#OwwR%&%4i(qjJ$(H7Zi(}s?7lyL5&B7uxkl-u&Sl>2isp){ z%a<(Q3%f^n26de8JkGOA;iK~P)amyv#AU@Q(vF;1^1M^|NYcjUr+jIu&Z_g2`m|QL z{dBsP+WJ{6eQQwi+Uif@ZJ%zPGP<70r`YJKqsS^~l%=tliQ6#BG{|R3rv1Bz@+E&X zi%ve#YMz+P7`kGDjQtP!Kku&T`1tMcTxfCOZ_;gfWry>67uMYV_I+cnxj(~yRhB^@4GO7;okWdvx^-5>k7maS7*O{ z{DtvEK=?`N2M+`!bc4R_I=-8E?%u!E%dXz%H&-s|Kk@#w3IhWJTavfC3j-MZblzRh zz`(#+;1OBOz@VoL!i*J5?aLS#7}!fZeO=j~aB%Uf$>}&Qe9geXAX(xXQR1ARo12PUQnb7h?$13dRrBHU}1e{qXSc;+HN>x6?NJ zGAXb%H>xmKu>Mt)^(a^_@F99v?eA{_4a!|^`CFrwA5~IVWUqafDXFPoXUvl$ox&%D zKE&vm|6n@s^@Ktl^98O20teU`dKfYo3}&BQ81dl!{r&!OwpCMfIJ=W}HD>KRcIwor z^^7%q3sf$BQEWJG(I>rP#flwuUtR>3XJ=>X!{2`wEm|bG^6rAQYuCn4Qjp-T@%24>;qC41UxPN=85t!_t$mf9o&A5R zwm?{DC~GQf{l7myt&7&Nq^71OM#et4wKcnNrh;qWg_k7>k!DMG9=UU8j#nOkho!gL zji4!+Br|*wlw(Wp>Oyb#9SF<{=zs{X_nM03_m&(B_iYJ%(1JzrG5I`gvUE>hBphaIGQnisj_|f z>eZ_WLN)5=KR+~QSL9%-{Pd(#!-b>CVUC}=Aj`v2`-|6QED917CBr>_tSN|$yxITv z?_c)&HufL9=J=_#yn=ik1l})LA;i=4QswW;b?iNF?(O}(;QaH;EX~>GY>O{;96IFm=H_O0 zv2Iqk#e!K|rLwk4nfM-l|6ToSOyA> XmgQ|?&D)wcpbEj$)z4*}Q$iB}JMybb literal 0 HcmV?d00001 diff --git a/Base/res/icons/chess/sets/test/black-pawn.png b/Base/res/icons/chess/sets/test/black-pawn.png new file mode 100644 index 0000000000000000000000000000000000000000..7e9d6aef14ad2e490aef622c526598bf8c2af42e GIT binary patch literal 775 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEB zNoL!%zU@(JQ1~TywBv|Rt=?3xL&Y_B4heLj+ywDHElBKFOb77FXB>^%o>NdXZ4_uHgo^dVr_wO6qW~(>+m)vpb z*1s&~89!C_-n*vc?r`6%pz!XsC$Sb5&^EW;&T6=f>R9glH2DT(`cNd2LAh=-f z^2rPg44efXk;M!QddeWoSh3W;jDdlHy~NYkmHi0^mw=_B1A7`P0|SF(iEBiObAE1a zYF-J0b5UwyNotBhd1gt5g1e`0KzJjcI0FO2eNPw1kcwMxr#lKY8}Kj(w*9Zax%b;8 zIj;rNw*F>Xuhd>3!@zKG#Z8;9Uvjck{!Fh-RjEIH#%S_=yX|L=Y(K9T{4@9S>4>`S z!$#BhpYfWuznb;b!DQKo0t}1-4rk^+yTP`ljw7?AiuWE%k=4Ri6&2cr@9$d%AFX5; zIIx*fgf~M*?y}vd$@?2>{~WP51x+ literal 0 HcmV?d00001 diff --git a/Base/res/icons/chess/sets/test/black-queen.png b/Base/res/icons/chess/sets/test/black-queen.png new file mode 100644 index 0000000000000000000000000000000000000000..8cbc65b98260ef209e1615a01fc8be43b4db7128 GIT binary patch literal 816 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEB zNoL!%zU@(JQ1~TywBv|Rt=?3xL&Y_B4heLj+ywDHElBKFOb77FXB>^%o>NdXZ4_uHgo^dVr_wO6qW~(>+m)vpb z*1s&~89!C_-n*vc?r`6%pz!XsC$Sb5&^EW;&T6=f>R9glH2DT(`cNd2LAh=-f z^2rPg44efXk;M!QddeWoSh3W;jDdlHy~NYkmHi0^mw*L>XsNpt0|SF(iEBiObAE1a zYF-J0b5UwyNotBhd1gt5g1e`0KzJjcI0FMCho_5UNX4zUGaUI?6ggOO|NT$@wyApl z#MXu|_2OA8A}%Gwa4WV5IIWoe=l4=?=|)@0=Z#x!Bp&DU{gpm&`GC!adF+pCc+Z=u z$8l=Dn*HDD;|N~}8Ce$d}{Ph)J2-URNCY!{_00sw+=Fa8GC|h`l3B+|{DllSTV0f|M zdf1i3f8vq>a~SWg-fzU{lUciKC-;jq?iGvJO0<@ JWt~$(699L2SBC%q literal 0 HcmV?d00001 diff --git a/Base/res/icons/chess/sets/test/black-rook.png b/Base/res/icons/chess/sets/test/black-rook.png new file mode 100644 index 0000000000000000000000000000000000000000..ff007ec3ee7a1e36042dedf30adf8a2d4fb4d51d GIT binary patch literal 777 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEB zNoL!%zU@(JQ1~TywBv|Rt=?3xL&Y_B4heLj+ywDHElBKFOb77FXB>^%o>NdXZ4_uHgo^dVr_wO6qW~(>+m)vpb z*1s&~89!C_-n*vc?r`6%pz!XsC$Sb5&^EW;&T6=f>R9glH2DT(`cNd2LAh=-f z^2rPg44efXk;M!QddeWoSh3W;jDdlHy~NYkmHi0^mw=JREq(SZ1_lPn64!_l=ltB< z)VvY~=c3falGGH1^30M91$R&1fbd2>aRvs4hn_BuAr-gY&I}YfqQK#N^!I(s>ZZFd ztrjfV_ovM3p{d8}WQ7(1Cyv-v79V{6&TQ8D+~2}9@5tpOxm9(Y#v6a+U*9SbZvDn0 zKc1Q4fXInh7UNGB+oWz;Ic#A70~5LCDo@$dd>yxCFI?m-eDmzE!6M%Y%mRyI7xXGD z%H5E}ktn={!HGwG)ky&__xB|)uSUxXoMX^Y_+ZY#@LudNBgm8}W&u7B4Z*QbH>gL< zT7G(6LFB$XT?Kabh`D?_^_pJ2V%Y6`$w1F;Dce5gy!^)N{gy2Pzn1bZjZyS|en!3) Oq}kKe&t;ucLK6U23`G3^ literal 0 HcmV?d00001 diff --git a/Base/res/icons/chess/sets/test/white-bishop.png b/Base/res/icons/chess/sets/test/white-bishop.png new file mode 100644 index 0000000000000000000000000000000000000000..321259a3eea51280bb7d403d5997d556a74573f9 GIT binary patch literal 4705 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 literal 0 HcmV?d00001 diff --git a/Base/res/icons/chess/sets/test/white-queen.png b/Base/res/icons/chess/sets/test/white-queen.png new file mode 100644 index 0000000000000000000000000000000000000000..fd38bb386b3c87e9101808f8fb73c4b244097fec GIT binary patch literal 3396 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 a_U_9TmI=<*yvM-6z~JfX=d#Wzp$PzBv|UU9 literal 0 HcmV?d00001 diff --git a/Base/res/icons/chess/sets/test/white-rook.png b/Base/res/icons/chess/sets/test/white-rook.png new file mode 100644 index 0000000000000000000000000000000000000000..e384732c995411bb6eadddbb29ae6776243daa19 GIT binary patch literal 5938 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 W>=OeRc^DWN7(8A5T-G@yGywqcADw{! literal 0 HcmV?d00001 diff --git a/Games/CMakeLists.txt b/Games/CMakeLists.txt index 96e33c0b03..02ffed9a9d 100644 --- a/Games/CMakeLists.txt +++ b/Games/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(2048) +add_subdirectory(Chess) add_subdirectory(Minesweeper) add_subdirectory(Snake) add_subdirectory(Solitaire) diff --git a/Games/Chess/CMakeLists.txt b/Games/Chess/CMakeLists.txt new file mode 100644 index 0000000000..f5a8746b60 --- /dev/null +++ b/Games/Chess/CMakeLists.txt @@ -0,0 +1,8 @@ +set(SOURCES + main.cpp + Chess.cpp + ChessWidget.cpp +) + +serenity_bin(Chess) +target_link_libraries(Chess LibGUI) diff --git a/Games/Chess/Chess.cpp b/Games/Chess/Chess.cpp new file mode 100644 index 0000000000..11e33de3a6 --- /dev/null +++ b/Games/Chess/Chess.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Chess.h" +#include + +Chess::Square::Square(const StringView& name) +{ + ASSERT(name.length() == 2); + char filec = name[0]; + char rankc = name[1]; + + if (filec >= 'a' && filec <= 'h') { + file = filec - 'a'; + } else if (filec >= 'A' && filec <= 'H') { + file = filec - 'A'; + } else { + ASSERT_NOT_REACHED(); + } + + if (rankc >= '1' && rankc <= '8') { + rank = rankc - '1'; + } else { + ASSERT_NOT_REACHED(); + } +} + +Chess::Chess() +{ + // Fill empty spaces. + for (unsigned rank = 2; rank < 6; ++rank) { + for (unsigned file = 0; file < 8; ++file) { + set_piece({ rank, file }, EmptyPiece); + } + } + + // Fill white pawns. + for (unsigned file = 0; file < 8; ++file) { + set_piece({ 1, file }, { Colour::White, Type::Pawn }); + } + + // Fill black pawns. + for (unsigned file = 0; file < 8; ++file) { + set_piece({ 6, file }, { Colour::Black, Type::Pawn }); + } + + // Fill while pieces. + set_piece(Square("a1"), { Colour::White, Type::Rook }); + set_piece(Square("b1"), { Colour::White, Type::Knight }); + set_piece(Square("c1"), { Colour::White, Type::Bishop }); + set_piece(Square("d1"), { Colour::White, Type::Queen }); + set_piece(Square("e1"), { Colour::White, Type::King }); + set_piece(Square("f1"), { Colour::White, Type::Bishop }); + set_piece(Square("g1"), { Colour::White, Type::Knight }); + set_piece(Square("h1"), { Colour::White, Type::Rook }); + + // Fill black pieces. + set_piece(Square("a8"), { Colour::Black, Type::Rook }); + set_piece(Square("b8"), { Colour::Black, Type::Knight }); + set_piece(Square("c8"), { Colour::Black, Type::Bishop }); + set_piece(Square("d8"), { Colour::Black, Type::Queen }); + set_piece(Square("e8"), { Colour::Black, Type::King }); + set_piece(Square("f8"), { Colour::Black, Type::Bishop }); + set_piece(Square("g8"), { Colour::Black, Type::Knight }); + set_piece(Square("h8"), { Colour::Black, Type::Rook }); +} + +Chess::Piece Chess::get_piece(const Square& square) const +{ + ASSERT(square.rank < 8); + ASSERT(square.file < 8); + return m_board[square.rank][square.file]; +} + +Chess::Piece Chess::set_piece(const Square& square, const Piece& piece) +{ + ASSERT(square.rank < 8); + ASSERT(square.file < 8); + return m_board[square.rank][square.file] = piece; +} + +bool Chess::is_legal(const Move& move) const +{ + // FIXME: Impelement actual chess logic. + return get_piece(move.from).colour == turn() && get_piece(move.to).colour != turn(); +} + +bool Chess::apply_move(const Move& move) +{ + if (!is_legal(move)) { + return false; + } + + set_piece(move.to, get_piece(move.from)); + set_piece(move.from, EmptyPiece); + + if (m_turn == Colour::White) { + m_turn = Colour::Black; + } else if (m_turn == Colour::Black) { + m_turn = Colour::White; + } + + return true; +} diff --git a/Games/Chess/Chess.h b/Games/Chess/Chess.h new file mode 100644 index 0000000000..9efd026f25 --- /dev/null +++ b/Games/Chess/Chess.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include +#include + +class Chess { +public: + enum class Type { + Pawn, + Knight, + Bishop, + Rook, + Queen, + King, + None, + }; + + enum class Colour { + White, + Black, + None, + }; + + struct Piece { + Colour colour; + Type type; + bool operator==(const Piece& other) const { return colour == other.colour && type == other.type; } + }; + static constexpr Piece EmptyPiece = { Colour::None, Type::None }; + + struct Square { + unsigned rank; // zero indexed; + unsigned file; + Square(const StringView& name); + Square(const unsigned& rank, const unsigned& file) + : rank(rank) + , file(file) + { + } + bool operator==(const Square& other) const { return rank == other.rank && file == other.file; } + }; + + struct Move { + Square from; + Square to; + Move(const StringView& algebraic); + Move(const Square& from, const Square& to) + : from(from) + , to(to) + { + } + }; + + Chess(); + + Piece get_piece(const Square&) const; + Piece set_piece(const Square&, const Piece&); + + bool is_legal(const Move&) const; + + bool apply_move(const Move&); + + Colour turn() const { return m_turn; }; + +private: + Piece m_board[8][8]; + Colour m_turn { Colour::White }; +}; + +template<> +struct AK::Traits : public GenericTraits { + static unsigned hash(Chess::Piece piece) + { + return pair_int_hash(static_cast(piece.colour), static_cast(piece.type)); + } +}; diff --git a/Games/Chess/ChessWidget.cpp b/Games/Chess/ChessWidget.cpp new file mode 100644 index 0000000000..aaf070170e --- /dev/null +++ b/Games/Chess/ChessWidget.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ChessWidget.h" +#include +#include + +ChessWidget::ChessWidget(const StringView& set) +{ + set_piece_set(set); +} + +ChessWidget::ChessWidget() + : ChessWidget("test") +{ +} + +ChessWidget::~ChessWidget() +{ +} + +void ChessWidget::paint_event(GUI::PaintEvent& event) +{ + GUI::Widget::paint_event(event); + + GUI::Painter painter(*this); + painter.add_clip_rect(event.rect()); + + size_t tile_width = width() / 8; + size_t tile_height = height() / 8; + + for (unsigned rank = 0; rank < 8; ++rank) { + for (unsigned file = 0; file < 8; ++file) { + Gfx::IntRect tile_rect; + if (side() == Chess::Colour::White) { + tile_rect = { file * tile_width, (7 - rank) * tile_height, tile_width, tile_height }; + } else { + tile_rect = { (7 - file) * tile_width, rank * tile_height, tile_width, tile_height }; + } + + painter.fill_rect(tile_rect, ((rank % 2) == (file % 2)) ? m_dark_square_color : m_light_square_color); + + Chess::Square square = { rank, file }; + if (!(m_dragging_piece && square == m_moving_square)) { + auto bmp = m_pieces.get(board().get_piece(square)); + if (bmp.has_value()) { + painter.draw_scaled_bitmap(tile_rect, *bmp.value(), bmp.value()->rect()); + } + } + } + } + + if (m_dragging_piece) { + auto bmp = m_pieces.get(board().get_piece(m_moving_square)); + if (bmp.has_value()) { + auto center = m_drag_point - Gfx::IntPoint(tile_width / 2, tile_height / 2); + painter.draw_scaled_bitmap({ center, { tile_width, tile_height } }, *bmp.value(), bmp.value()->rect()); + } + } +} + +void ChessWidget::resize_event(GUI::ResizeEvent& event) +{ + GUI::Widget::resize_event(event); +} + +void ChessWidget::mousedown_event(GUI::MouseEvent& event) +{ + GUI::Widget::mousedown_event(event); + auto square = mouse_to_square(event); + auto piece = board().get_piece(square); + if (piece.colour == board().turn()) { + m_dragging_piece = true; + m_drag_point = event.position(); + m_moving_square = square; + update(); + } +} + +void ChessWidget::mouseup_event(GUI::MouseEvent& event) +{ + GUI::Widget::mouseup_event(event); + if (!m_dragging_piece) + return; + + m_dragging_piece = false; + + auto target_square = mouse_to_square(event); + + board().apply_move({ m_moving_square, target_square }); + update(); +} + +void ChessWidget::mousemove_event(GUI::MouseEvent& event) +{ + GUI::Widget::mousemove_event(event); + if (!m_dragging_piece) + return; + + m_drag_point = event.position(); + update(); +} + +static String set_path = String("/res/icons/chess/sets/"); + +static RefPtr get_piece(const StringView& set, const StringView& image) +{ + StringBuilder builder; + builder.append(set_path); + builder.append(set); + builder.append('/'); + builder.append(image); + return Gfx::Bitmap::load_from_file(builder.build()); +} + +void ChessWidget::set_piece_set(const StringView& set) +{ + m_piece_set = set; + m_pieces.set({ Chess::Colour::White, Chess::Type::Pawn }, get_piece(set, "white-pawn.png")); + m_pieces.set({ Chess::Colour::Black, Chess::Type::Pawn }, get_piece(set, "black-pawn.png")); + m_pieces.set({ Chess::Colour::White, Chess::Type::Knight }, get_piece(set, "white-knight.png")); + m_pieces.set({ Chess::Colour::Black, Chess::Type::Knight }, get_piece(set, "black-knight.png")); + m_pieces.set({ Chess::Colour::White, Chess::Type::Bishop }, get_piece(set, "white-bishop.png")); + m_pieces.set({ Chess::Colour::Black, Chess::Type::Bishop }, get_piece(set, "black-bishop.png")); + m_pieces.set({ Chess::Colour::White, Chess::Type::Rook }, get_piece(set, "white-rook.png")); + m_pieces.set({ Chess::Colour::Black, Chess::Type::Rook }, get_piece(set, "black-rook.png")); + m_pieces.set({ Chess::Colour::White, Chess::Type::Queen }, get_piece(set, "white-queen.png")); + m_pieces.set({ Chess::Colour::Black, Chess::Type::Queen }, get_piece(set, "black-queen.png")); + m_pieces.set({ Chess::Colour::White, Chess::Type::King }, get_piece(set, "white-king.png")); + m_pieces.set({ Chess::Colour::Black, Chess::Type::King }, get_piece(set, "black-king.png")); +} + +Chess::Square ChessWidget::mouse_to_square(GUI::MouseEvent& event) const +{ + size_t tile_width = width() / 8; + size_t tile_height = height() / 8; + + if (side() == Chess::Colour::White) { + return { 7 - (event.y() / tile_height), event.x() / tile_width }; + } else { + return { event.y() / tile_height, 7 - (event.x() / tile_width) }; + } +} diff --git a/Games/Chess/ChessWidget.h b/Games/Chess/ChessWidget.h new file mode 100644 index 0000000000..0cd06dd82c --- /dev/null +++ b/Games/Chess/ChessWidget.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "Chess.h" +#include +#include +#include +#include +#include + +class ChessWidget final : public GUI::Widget { + C_OBJECT(ChessWidget) +public: + ChessWidget(); + ChessWidget(const StringView& set); + virtual ~ChessWidget() override; + + virtual void paint_event(GUI::PaintEvent&) override; + virtual void resize_event(GUI::ResizeEvent&) override; + virtual void mousedown_event(GUI::MouseEvent&) override; + virtual void mouseup_event(GUI::MouseEvent&) override; + virtual void mousemove_event(GUI::MouseEvent&) override; + + Chess& board() { return m_board; }; + + Chess::Colour side() const { return m_side; }; + void set_side(Chess::Colour side) { m_side = side; }; + + void set_piece_set(const StringView& set); + const String& piece_set() const { return m_piece_set; }; + + Chess::Square mouse_to_square(GUI::MouseEvent& event) const; + +private: + Chess m_board; + Color m_dark_square_color { Color::from_rgb(0xb58863) }; + Color m_light_square_color { Color::from_rgb(0xf0d9b5) }; + Chess::Colour m_side { Chess::Colour::White }; + HashMap> m_pieces; + String m_piece_set; + Chess::Square m_moving_square { 50, 50 }; + Gfx::IntPoint m_drag_point; + bool m_dragging_piece { false }; +}; diff --git a/Games/Chess/main.cpp b/Games/Chess/main.cpp new file mode 100644 index 0000000000..29ad23722a --- /dev/null +++ b/Games/Chess/main.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ChessWidget.h" +#include +#include + +int main(int argc, char** argv) +{ + auto app = GUI::Application::construct(argc, argv); + + auto window = GUI::Window::construct(); + auto& widget = window->set_main_widget(); + widget.set_side(Chess::Colour::White); + + window->set_title("Chess"); + window->resize(512, 512); + window->set_resizable(false); + window->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/app-chess.png")); + + window->show(); + + return app->exec(); +}