diff --git a/application.cpp b/application.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0064756abb7588db3997c88f76be3ca512f8c29 --- /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 0000000000000000000000000000000000000000..b65313e2249a1338571e00c9a410ca5cdf1d4d42 --- /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 0000000000000000000000000000000000000000..c7f35a12261ace33511bf2f57dcb6b5647c6c96c --- /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 0000000000000000000000000000000000000000..58a781833ea27202991d9bea0809ec0ba6190f09 --- /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 0000000000000000000000000000000000000000..8bde9538b089ef91aefe2c71712b7a2a43ae708b --- /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 0000000000000000000000000000000000000000..684db5b7a7559b63919c29246a319d126bc9f2dd --- /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 0000000000000000000000000000000000000000..15562afa4253b60281b61cd871f5977e755d0a53 --- /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 0000000000000000000000000000000000000000..518da5ef52c9fba071b274a05c4a93854bc15ce0 --- /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 0000000000000000000000000000000000000000..690c479a653088fcbbf4644a089dd450f7018707 --- /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 0000000000000000000000000000000000000000..3a55da94e5db66b88f2b28293c490dc711eb8ab1 --- /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 0000000000000000000000000000000000000000..3675459133b853a023a65955933279273b03aace --- /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 0000000000000000000000000000000000000000..ca81c1624b2ed9c4325433af55ff3d56584a6149 --- /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