From 7084933a3e3430622eaeb3fff84fcefcba75aa3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93dor=20Bogl=C3=A1rka?= <odobo@cortex.itk.ppke.hu> Date: Sun, 19 May 2024 15:28:24 +0200 Subject: [PATCH] =?UTF-8?q?els=C5=91=20m=C5=B1k=C3=B6d=C5=91=20verzi=C3=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application.cpp | 27 +++++++++++++++++ application.hpp | 22 ++++++++++++++ board_widget.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++ board_widget.hpp | 21 ++++++++++++++ jatek_mester.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++++++ jatek_mester.hpp | 22 ++++++++++++++ main.cpp | 22 ++++++++++++++ sudoku_easy.txt | 9 ++++++ sudoku_hard.txt | 9 ++++++ sudoku_medium.txt | 9 ++++++ widgets.cpp | 21 ++++++++++++++ widgets.hpp | 28 ++++++++++++++++++ 12 files changed, 331 insertions(+) create mode 100644 application.cpp create mode 100644 application.hpp create mode 100644 board_widget.cpp create mode 100644 board_widget.hpp create mode 100644 jatek_mester.cpp create mode 100644 jatek_mester.hpp create mode 100644 main.cpp create mode 100644 sudoku_easy.txt create mode 100644 sudoku_hard.txt create mode 100644 sudoku_medium.txt create mode 100644 widgets.cpp create mode 100644 widgets.hpp diff --git a/application.cpp b/application.cpp new file mode 100644 index 0000000..a006475 --- /dev/null +++ b/application.cpp @@ -0,0 +1,27 @@ +#include "application.hpp" +#include "widgets.hpp" + +Application::Application(int width, int height) : _width(width), _height(height) { + genv::gout.open(_width, _height); +} + +void Application::register_widget(Widget* widget) { + widgets.push_back(widget); +} + +void Application::event_loop() { + genv::event ev; + while (genv::gin >> ev) { + for (Widget* widget : widgets) { + widget->handle(ev); + } + for (Widget* widget : widgets) { + widget->draw(); + } + genv::gout << genv::refresh; + } +} + +void Application::run() { + event_loop(); +} diff --git a/application.hpp b/application.hpp new file mode 100644 index 0000000..b65313e --- /dev/null +++ b/application.hpp @@ -0,0 +1,22 @@ +#ifndef APPLICATION_HPP +#define APPLICATION_HPP + +#include "graphics.hpp" +#include "widgets.hpp" +#include <vector> + +class Widget; + +class Application { +protected: + std::vector<Widget*> widgets; + int _width, _height; + +public: + Application(int width, int height); + void register_widget(Widget* widget); + void event_loop(); + void run(); +}; + +#endif // APPLICATION_HPP diff --git a/board_widget.cpp b/board_widget.cpp new file mode 100644 index 0000000..c7f35a1 --- /dev/null +++ b/board_widget.cpp @@ -0,0 +1,67 @@ +#include "board_widget.hpp" +#include "graphics.hpp" +#include <iostream> + +using namespace genv; + +BoardWidget::BoardWidget(Application* parent, JatekMester* mester, int& selected_row, int& selected_col, int x, int y, int sx, int sy) + : Widget(parent, x, y, sx, sy), mester(mester), selected_row(selected_row), selected_col(selected_col), BOARD_SIZE(9), CELL_SIZE(sx / BOARD_SIZE) {} + +void BoardWidget::draw() const { + // Draw cells and numbers + for (int i = 0; i < BOARD_SIZE; ++i) { + for (int j = 0; j < BOARD_SIZE; ++j) { + int x = _x + j * CELL_SIZE; + int y = _y + i * CELL_SIZE; + gout << move_to(x, y) << color(255, 255, 255) << box(CELL_SIZE, CELL_SIZE); + + int value = mester->get_value(i, j); + if (value != 0) { + if (!mester->is_cell_valid(i, j)) { + gout << color(255, 0, 0); // Piros ha helytelen + } else { + gout << color(0, 0, 0); // Fekete ha helyes + } + gout << move_to(x + CELL_SIZE / 3, y + CELL_SIZE / 1.5) << text(std::to_string(value)); + } + } + } + + // Draw grid lines + for (int i = 0; i <= BOARD_SIZE; ++i) { + int line_thickness = (i % 3 == 0) ? 3 : 1; // Thicker lines for block boundaries + gout << move_to(_x + i * CELL_SIZE, _y) << color(0, 0, 0); + for (int t = 0; t < line_thickness; ++t) { + gout << move_to(_x + i * CELL_SIZE + t, _y) << line(0, _size_y); + } + gout << move_to(_x, _y + i * CELL_SIZE) << color(0, 0, 0); + for (int t = 0; t < line_thickness; ++t) { + gout << move_to(_x, _y + i * CELL_SIZE + t) << line(_size_x, 0); + } + } +} + +void BoardWidget::handle(event ev) { + if (ev.type == ev_mouse && ev.button == btn_left) { + selected_row = (ev.pos_y - _y) / CELL_SIZE; + selected_col = (ev.pos_x - _x) / CELL_SIZE; + if (selected_row < 0 || selected_row >= BOARD_SIZE || selected_col < 0 || selected_col >= BOARD_SIZE) { + selected_row = -1; + selected_col = -1; + } else { + std::cout << "Selected cell: (" << selected_row << ", " << selected_col << ")\n"; + } + } + else if (ev.type == ev_key && selected_row != -1 && selected_col != -1) { + if (!mester->is_original(selected_row, selected_col)) { + if (ev.keycode >= '1' && ev.keycode <= '9') { + int number = ev.keycode - '0'; + mester->update_value(selected_row, selected_col, number); + } + else if (ev.keycode == '0' || ev.keycode == key_backspace) { + mester->update_value(selected_row, selected_col, 0); + } + gout << refresh; + } + } +} diff --git a/board_widget.hpp b/board_widget.hpp new file mode 100644 index 0000000..58a7818 --- /dev/null +++ b/board_widget.hpp @@ -0,0 +1,21 @@ +#ifndef BOARD_WIDGET_HPP +#define BOARD_WIDGET_HPP + +#include "widgets.hpp" +#include "jatek_mester.hpp" + +class BoardWidget : public Widget { +private: + JatekMester* mester; + int& selected_row; + int& selected_col; + const int BOARD_SIZE; + const int CELL_SIZE; + +public: + BoardWidget(Application* parent, JatekMester* mester, int& selected_row, int& selected_col, int x, int y, int sx, int sy); + void draw() const override; + void handle(genv::event ev) override; +}; + +#endif // BOARD_WIDGET_HPP diff --git a/jatek_mester.cpp b/jatek_mester.cpp new file mode 100644 index 0000000..8bde953 --- /dev/null +++ b/jatek_mester.cpp @@ -0,0 +1,74 @@ +#include "jatek_mester.hpp" +#include <fstream> +#include <sstream> +#include <cmath> + +JatekMester::JatekMester() + : board(9, std::vector<int>(9, 0)), original_board(9, std::vector<int>(9, 0)) {} + +bool JatekMester::is_valid_move(int number, int row, int col) const { + // Ellenőrizze a sorban + for (int j = 0; j < 9; ++j) { + if (j != col && board[row][j] == number) { + return false; + } + } + + // Ellenőrizze az oszlopban + for (int i = 0; i < 9; ++i) { + if (i != row && board[i][col] == number) { + return false; + } + } + + // Ellenőrizze a 3x3-as blokkban + int block_start_row = row - row % 3; + int block_start_col = col - col % 3; + for (int i = block_start_row; i < block_start_row + 3; ++i) { + for (int j = block_start_col; j < block_start_col + 3; ++j) { + if (i != row && j != col && board[i][j] == number) { + return false; + } + } + } + + return true; +} + +bool JatekMester::is_original(int row, int col) const { + return original_board[row][col] != 0; +} + +void JatekMester::update_value(int row, int col, int value) { + if (!is_original(row, col)) { + board[row][col] = value; + } +} + +int JatekMester::get_value(int row, int col) const { + return board[row][col]; +} + +bool JatekMester::load_from_file(const std::string& filename) { + std::ifstream file(filename); + if (!file.is_open()) { + return false; + } + + for (int i = 0; i < 9; ++i) { + for (int j = 0; j < 9; ++j) { + if (!(file >> original_board[i][j])) { + return false; + } + board[i][j] = original_board[i][j]; + } + } + + return true; +} + +bool JatekMester::is_cell_valid(int row, int col) const { + int value = board[row][col]; + if (value == 0) return true; + return is_valid_move(value, row, col); +} diff --git a/jatek_mester.hpp b/jatek_mester.hpp new file mode 100644 index 0000000..684db5b --- /dev/null +++ b/jatek_mester.hpp @@ -0,0 +1,22 @@ +#ifndef JATEK_MESTER_HPP +#define JATEK_MESTER_HPP + +#include <vector> +#include <string> + +class JatekMester { +private: + std::vector<std::vector<int>> board; + std::vector<std::vector<int>> original_board; + +public: + JatekMester(); + bool is_valid_move(int number, int row, int col) const; + bool is_original(int row, int col) const; + void update_value(int row, int col, int value); + int get_value(int row, int col) const; + bool load_from_file(const std::string& filename); + bool is_cell_valid(int row, int col) const; // �j f�ggv�ny +}; + +#endif // JATEK_MESTER_HPP diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..15562af --- /dev/null +++ b/main.cpp @@ -0,0 +1,22 @@ +#include <iostream> + +#include "application.hpp" +#include "board_widget.hpp" +#include "jatek_mester.hpp" + + + +int main() { + Application app(600, 600); + JatekMester mester; + if (!mester.load_from_file("sudoku_easy.txt")) { + std::cerr << "Failed to load Sudoku board from file.\n"; + return 1; + } + + int selected_row = -1, selected_col = -1; + BoardWidget board(&app, &mester, selected_row, selected_col, 50, 50, 500, 500); + app.run(); + + return 0; +} diff --git a/sudoku_easy.txt b/sudoku_easy.txt new file mode 100644 index 0000000..518da5e --- /dev/null +++ b/sudoku_easy.txt @@ -0,0 +1,9 @@ +0 0 6 0 0 0 5 0 8 +1 0 2 3 8 0 0 0 4 +0 0 0 2 0 0 1 9 0 +0 0 0 0 6 3 0 4 5 +0 6 3 4 0 5 8 7 0 +5 4 0 9 2 0 0 0 0 +0 8 7 0 0 4 0 0 0 +2 0 0 0 9 8 4 0 7 +4 0 9 0 0 0 3 0 0 \ No newline at end of file diff --git a/sudoku_hard.txt b/sudoku_hard.txt new file mode 100644 index 0000000..690c479 --- /dev/null +++ b/sudoku_hard.txt @@ -0,0 +1,9 @@ +0 0 6 3 0 7 0 0 0 +0 0 4 0 0 0 0 0 5 +1 0 0 0 0 6 0 8 2 +2 0 5 0 3 0 1 0 6 +0 0 0 2 0 0 3 0 0 +9 0 0 0 7 0 0 0 4 +0 5 0 0 0 0 0 0 0 +0 1 0 0 0 0 0 0 0 +0 0 8 1 0 9 0 4 0 \ No newline at end of file diff --git a/sudoku_medium.txt b/sudoku_medium.txt new file mode 100644 index 0000000..3a55da9 --- /dev/null +++ b/sudoku_medium.txt @@ -0,0 +1,9 @@ +5 3 0 0 7 0 0 0 0 +6 0 0 1 9 5 0 0 0 +0 9 8 0 0 0 0 6 0 +8 0 0 0 6 0 0 0 3 +4 0 0 8 0 3 0 0 1 +7 0 0 0 2 0 0 0 6 +0 6 0 0 0 0 2 8 0 +0 0 0 4 1 9 0 0 5 +0 0 0 0 8 0 0 7 9 diff --git a/widgets.cpp b/widgets.cpp new file mode 100644 index 0000000..3675459 --- /dev/null +++ b/widgets.cpp @@ -0,0 +1,21 @@ +#include "widgets.hpp" + +Widget::Widget(Application* parent, int x, int y, int sx, int sy) + : _parent(parent), _x(x), _y(y), _size_x(sx), _size_y(sy), is_selected(false) { + if (_parent) + _parent->register_widget(this); +} + +Widget::~Widget() {} + +bool Widget::contains(int x, int y) const { + return x >= _x && x <= _x + _size_x && y >= _y && y <= _y + _size_y; +} + +void Widget::select() { + is_selected = true; +} + +void Widget::deselect() { + is_selected = false; +} diff --git a/widgets.hpp b/widgets.hpp new file mode 100644 index 0000000..ca81c16 --- /dev/null +++ b/widgets.hpp @@ -0,0 +1,28 @@ +#ifndef WIDGETS_HPP +#define WIDGETS_HPP + +#include "graphics.hpp" +#include "application.hpp" +#include <functional> + +class Application; // Forward declaration + +class Widget { +protected: + Application* _parent; + int _x, _y, _size_x, _size_y; + bool is_selected; + +public: + Widget(Application* parent, int x, int y, int sx, int sy); + virtual ~Widget(); + + virtual void draw() const = 0; + virtual void handle(genv::event ev) = 0; + + bool contains(int x, int y) const; + void select(); + void deselect(); +}; + +#endif // WIDGETS_HPP -- GitLab