Chess: Add basic ChessWidget and ugly piece set
Author: https://github.com/petelliott Commit: https://github.com/SerenityOS/serenity/commit/73339162522 Pull-request: https://github.com/SerenityOS/serenity/pull/3099 Reviewed-by: https://github.com/stelar7
8
Base/res/apps/Chess.af
Normal file
|
@ -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
|
BIN
Base/res/icons/16x16/app-chess.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
Base/res/icons/32x32/app-chess.png
Normal file
After Width: | Height: | Size: 8 KiB |
BIN
Base/res/icons/chess/sets/test/black-bishop.png
Normal file
After Width: | Height: | Size: 931 B |
BIN
Base/res/icons/chess/sets/test/black-king.png
Normal file
After Width: | Height: | Size: 961 B |
BIN
Base/res/icons/chess/sets/test/black-knight.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
Base/res/icons/chess/sets/test/black-pawn.png
Normal file
After Width: | Height: | Size: 775 B |
BIN
Base/res/icons/chess/sets/test/black-queen.png
Normal file
After Width: | Height: | Size: 816 B |
BIN
Base/res/icons/chess/sets/test/black-rook.png
Normal file
After Width: | Height: | Size: 777 B |
BIN
Base/res/icons/chess/sets/test/white-bishop.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
Base/res/icons/chess/sets/test/white-king.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
Base/res/icons/chess/sets/test/white-knight.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
Base/res/icons/chess/sets/test/white-pawn.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
Base/res/icons/chess/sets/test/white-queen.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
Base/res/icons/chess/sets/test/white-rook.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
|
@ -1,4 +1,5 @@
|
|||
add_subdirectory(2048)
|
||||
add_subdirectory(Chess)
|
||||
add_subdirectory(Minesweeper)
|
||||
add_subdirectory(Snake)
|
||||
add_subdirectory(Solitaire)
|
||||
|
|
8
Games/Chess/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
set(SOURCES
|
||||
main.cpp
|
||||
Chess.cpp
|
||||
ChessWidget.cpp
|
||||
)
|
||||
|
||||
serenity_bin(Chess)
|
||||
target_link_libraries(Chess LibGUI)
|
127
Games/Chess/Chess.cpp
Normal file
|
@ -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 <AK/Assertions.h>
|
||||
|
||||
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;
|
||||
}
|
102
Games/Chess/Chess.h
Normal file
|
@ -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 <AK/StringView.h>
|
||||
#include <AK/Traits.h>
|
||||
|
||||
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<Chess::Piece> : public GenericTraits<Chess::Piece> {
|
||||
static unsigned hash(Chess::Piece piece)
|
||||
{
|
||||
return pair_int_hash(static_cast<u32>(piece.colour), static_cast<u32>(piece.type));
|
||||
}
|
||||
};
|
166
Games/Chess/ChessWidget.cpp
Normal file
|
@ -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 <AK/String.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
|
||||
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<Gfx::Bitmap> 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) };
|
||||
}
|
||||
}
|
69
Games/Chess/ChessWidget.h
Normal file
|
@ -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 <AK/HashMap.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <LibGUI/Widget.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
|
||||
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<Chess::Piece, RefPtr<Gfx::Bitmap>> m_pieces;
|
||||
String m_piece_set;
|
||||
Chess::Square m_moving_square { 50, 50 };
|
||||
Gfx::IntPoint m_drag_point;
|
||||
bool m_dragging_piece { false };
|
||||
};
|
47
Games/Chess/main.cpp
Normal file
|
@ -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 <LibGUI/Application.h>
|
||||
#include <LibGUI/Window.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
auto app = GUI::Application::construct(argc, argv);
|
||||
|
||||
auto window = GUI::Window::construct();
|
||||
auto& widget = window->set_main_widget<ChessWidget>();
|
||||
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();
|
||||
}
|