simplifying by hardcoding
This commit is contained in:
+8
-13
@@ -1,33 +1,28 @@
|
||||
#ifndef ENGINE_HPP
|
||||
#define ENGINE_HPP
|
||||
|
||||
#include <map>
|
||||
#include <array>
|
||||
#include <ncurses.h>
|
||||
|
||||
constexpr int ROW = 5;
|
||||
constexpr int COL = 5;
|
||||
|
||||
struct vec2 {
|
||||
int x, y;
|
||||
vec2(int x, int y) : x(x), y(y) {}
|
||||
auto operator <=> (const vec2&) const = default;
|
||||
};
|
||||
constexpr int ROW = 3;
|
||||
constexpr int COL = 3;
|
||||
|
||||
struct Window {
|
||||
Window();
|
||||
std::map<vec2, char> view;
|
||||
void draw_display();
|
||||
std::array<char, ROW * COL> view;
|
||||
void draw_display() const;
|
||||
};
|
||||
|
||||
class Engine {
|
||||
public:
|
||||
Engine();
|
||||
~Engine();
|
||||
~Engine() { endwin(); };
|
||||
void run();
|
||||
|
||||
private:
|
||||
struct Player {
|
||||
Player(char id) : id(id) {};
|
||||
char id;
|
||||
const char id;
|
||||
};
|
||||
|
||||
Window win;
|
||||
|
||||
+32
-46
@@ -1,30 +1,22 @@
|
||||
#include <algorithm>
|
||||
#include <engine.hpp>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <chrono>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <ncurses.h>
|
||||
#include <thread>
|
||||
#include <ranges>
|
||||
|
||||
Window::Window() : view {
|
||||
{ { 0, 0 }, ' ' }, { { 2, 0 }, ' ' }, { { 4, 0 }, ' ' },
|
||||
{ { 0, 2 }, ' ' }, { { 2, 2 }, ' ' }, { { 4, 2 }, ' ' },
|
||||
{ { 0, 4 }, ' ' }, { { 2, 4 }, ' ' }, { { 4, 4 }, ' ' }
|
||||
} {}
|
||||
Window::Window() {
|
||||
view.fill(' ');
|
||||
}
|
||||
|
||||
void Window::draw_display() {
|
||||
char c;
|
||||
std::cout << "\033[H" << std::flush; // Clear screen
|
||||
for(int i : std::ranges::views::iota(0, ROW)) {
|
||||
for(int j : std::ranges::views::iota(0, COL)) {
|
||||
if(i % 2 == 0 && j % 2 == 0) { c = view[{i, j}]; }
|
||||
else if(i % 2 == 0) { c = '|'; }
|
||||
else if(j % 2 == 0) { c = '-'; }
|
||||
else { c = '+'; }
|
||||
std::cout << c << " ";
|
||||
}
|
||||
std::cout << "\r\n";
|
||||
}
|
||||
void Window::draw_display() const {
|
||||
std::cout << "\033[H" << std::format(
|
||||
"{} | {} | {}\r\n- + - + -\r\n{} | {} | {}\r\n- + - + -\r\n{} | {} | {}\r\n",
|
||||
view.at(0), view.at(1), view.at(2),
|
||||
view.at(3), view.at(4), view.at(5),
|
||||
view.at(6), view.at(7), view.at(8)
|
||||
) << std::flush;
|
||||
}
|
||||
|
||||
Engine::Engine() {
|
||||
@@ -35,36 +27,33 @@ Engine::Engine() {
|
||||
nodelay(stdscr, true);
|
||||
}
|
||||
|
||||
Engine::~Engine() {}
|
||||
|
||||
void Engine::run() {
|
||||
while (exit_code() && process_input()) {
|
||||
win.draw_display();
|
||||
std::cout << "Current Player: " << temp->id << "\n";
|
||||
std::cout << "Current Player: " << temp->id << "\r\n";
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds((int) (150)));
|
||||
}
|
||||
endwin();
|
||||
}
|
||||
|
||||
bool Engine::exit_code() {
|
||||
if(check_line(player1.id)) {
|
||||
std::cout << "Game Over! Player 1 wins!" << std::endl;
|
||||
std::cout << "Game Over! Player 1 wins!\n";
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
return false;
|
||||
} else if(check_line(player2.id)) {
|
||||
std::cout << "Game Over! Player 2 wins!" << std::endl;
|
||||
std::cout << "Game Over! Player 2 wins!\n";
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
return false;
|
||||
}
|
||||
int filled = std::ranges::count_if(win.view, [](const auto &pair) {
|
||||
return pair.second != ' ';
|
||||
});
|
||||
|
||||
if(filled == 9) {
|
||||
std::cout << "Game Over! Its a tie!" << std::endl;
|
||||
int filled = std::ranges::count_if(win.view, [](const auto &sym) { return sym != ' '; });
|
||||
|
||||
if(filled == ROW * COL) {
|
||||
std::cout << "Game Over! Its a tie!\n";
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,9 +63,8 @@ bool Engine::process_input() {
|
||||
if(ch == 'q') { return false; }
|
||||
if(ch >= '1' && ch <= '9') {
|
||||
index = ch - '1';
|
||||
x = (index % 3) * 2, y = (index / 3) * 2;
|
||||
if(win.view[{y, x}] != ' ') continue;
|
||||
win.view[{y, x}] = temp->id;
|
||||
if(win.view.at(index) != ' ') continue;
|
||||
win.view.at(index) = temp->id;
|
||||
if(temp->id == 'x') { temp = &player2; }
|
||||
else if(temp->id == 'o') { temp = &player1; }
|
||||
}
|
||||
@@ -85,22 +73,20 @@ bool Engine::process_input() {
|
||||
}
|
||||
|
||||
bool Engine::check_line(char id) {
|
||||
for(int i : std::ranges::views::iota(0, COL)) {
|
||||
if(COL % 2 != 0) continue;
|
||||
if(win.view[{0, i}] == id && win.view[{2, i}] == id && win.view[{4, i}] == id) {
|
||||
for(int i = 0; i < COL; i++) {
|
||||
if(win.view.at(i) == id && win.view.at(i + 3) == id && win.view.at(i + 6) == id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for(int i : std::ranges::views::iota(0, ROW)) {
|
||||
if(ROW % 2 != 0) continue;
|
||||
if(win.view[{i, 0}] == id && win.view[{i, 2}] == id && win.view[{i, 4}] == id) {
|
||||
for(int i = 0; i < ROW * COL; i += ROW) {
|
||||
if(win.view.at(i) == id && win.view.at(i + 1) == id && win.view.at(i + 2) == id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
auto same_symbol = [&](vec2 a, vec2 b) {
|
||||
return win.view[{a.y, a.x}] == id &&
|
||||
win.view[{2, 2}] == id &&
|
||||
win.view[{b.y, b.x}] == id;
|
||||
auto same_symbol = [&](int first, int last) {
|
||||
return win.view.at(first) == id &&
|
||||
win.view.at(4) == id &&
|
||||
win.view.at(last) == id;
|
||||
};
|
||||
return same_symbol({ 0, 0 }, { 4, 4 }) || same_symbol({ 4, 0 }, { 0, 4 });
|
||||
return same_symbol(0, 8) || same_symbol(2, 6);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user