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 0000000000..e53265f12e Binary files /dev/null and b/Base/res/icons/16x16/app-chess.png differ diff --git a/Base/res/icons/32x32/app-chess.png b/Base/res/icons/32x32/app-chess.png new file mode 100644 index 0000000000..835c7a72c0 Binary files /dev/null and b/Base/res/icons/32x32/app-chess.png differ diff --git a/Base/res/icons/chess/sets/test/black-bishop.png b/Base/res/icons/chess/sets/test/black-bishop.png new file mode 100644 index 0000000000..ddb986fd5d Binary files /dev/null and b/Base/res/icons/chess/sets/test/black-bishop.png differ 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 0000000000..17c1ea8b1b Binary files /dev/null and b/Base/res/icons/chess/sets/test/black-king.png differ 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 0000000000..7f16e286d6 Binary files /dev/null and b/Base/res/icons/chess/sets/test/black-knight.png differ 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 0000000000..7e9d6aef14 Binary files /dev/null and b/Base/res/icons/chess/sets/test/black-pawn.png differ 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 0000000000..8cbc65b982 Binary files /dev/null and b/Base/res/icons/chess/sets/test/black-queen.png differ 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 0000000000..ff007ec3ee Binary files /dev/null and b/Base/res/icons/chess/sets/test/black-rook.png differ 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 0000000000..321259a3ee Binary files /dev/null and b/Base/res/icons/chess/sets/test/white-bishop.png differ diff --git a/Base/res/icons/chess/sets/test/white-king.png b/Base/res/icons/chess/sets/test/white-king.png new file mode 100644 index 0000000000..5496cc6bf0 Binary files /dev/null and b/Base/res/icons/chess/sets/test/white-king.png differ diff --git a/Base/res/icons/chess/sets/test/white-knight.png b/Base/res/icons/chess/sets/test/white-knight.png new file mode 100644 index 0000000000..082a33763b Binary files /dev/null and b/Base/res/icons/chess/sets/test/white-knight.png differ diff --git a/Base/res/icons/chess/sets/test/white-pawn.png b/Base/res/icons/chess/sets/test/white-pawn.png new file mode 100644 index 0000000000..788e0dc6a7 Binary files /dev/null and b/Base/res/icons/chess/sets/test/white-pawn.png differ 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 0000000000..fd38bb386b Binary files /dev/null and b/Base/res/icons/chess/sets/test/white-queen.png differ 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 0000000000..e384732c99 Binary files /dev/null and b/Base/res/icons/chess/sets/test/white-rook.png differ 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(); +}