a bunch of mini optimizations
This commit is contained in:
+7
-19
@@ -1,39 +1,27 @@
|
|||||||
#ifndef ENGINE_HPP
|
#pragma once
|
||||||
#define ENGINE_HPP
|
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <ncurses.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
constexpr int ROW = 3;
|
|
||||||
constexpr int COL = 3;
|
|
||||||
|
|
||||||
struct Window {
|
struct Window {
|
||||||
Window();
|
Window();
|
||||||
std::array<char, ROW * COL> view;
|
std::array<char, 9> view;
|
||||||
void draw_display() const;
|
void draw_display() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Engine {
|
class Engine {
|
||||||
public:
|
public:
|
||||||
Engine();
|
Engine();
|
||||||
~Engine() { endwin(); };
|
~Engine();
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Player {
|
|
||||||
Player(char id) : id(id) {};
|
|
||||||
const char id;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string status;
|
std::string status;
|
||||||
Window win;
|
Window win;
|
||||||
Player player1 { 'x' };
|
char p1 { 'x' };
|
||||||
Player player2 { 'o' };
|
char p2 { 'o' };
|
||||||
Player *temp { &player1 };
|
char temp { p1 };
|
||||||
bool process_input();
|
bool process_input();
|
||||||
bool exit_code();
|
bool check_game_over();
|
||||||
bool check_line(char id) const;
|
bool check_line(char id) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
+33
-25
@@ -1,7 +1,8 @@
|
|||||||
#include <cctype>
|
|
||||||
#include <engine.hpp>
|
#include <engine.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <ncurses.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
Window::Window() {
|
Window::Window() {
|
||||||
@@ -9,14 +10,12 @@ Window::Window() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Window::draw_display() const {
|
void Window::draw_display() const {
|
||||||
std::cout << "\033[H"
|
clear();
|
||||||
<< view[0] << " | " << view[1] << " | " << view[2]
|
mvprintw(0, 0, " %c | %c | %c ", view[0], view[1], view[2]);
|
||||||
<< "\r\n- + - + -\r\n"
|
mvprintw(1, 0, " - + - + - ");
|
||||||
<< view[3] << " | " << view[4] << " | " << view[5]
|
mvprintw(2, 0, " %c | %c | %c ", view[3], view[4], view[5]);
|
||||||
<< "\r\n- + - + -\r\n"
|
mvprintw(3, 0, " - + - + - ");
|
||||||
<< view[6] << " | " << view[7] << " | " << view[8]
|
mvprintw(4, 0, " %c | %c | %c ", view[6], view[7], view[8]);
|
||||||
<< "\r\n"
|
|
||||||
<< std::flush;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::Engine() {
|
Engine::Engine() {
|
||||||
@@ -27,23 +26,28 @@ Engine::Engine() {
|
|||||||
nodelay(stdscr, true);
|
nodelay(stdscr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Engine::~Engine() { endwin(); }
|
||||||
|
|
||||||
void Engine::run() {
|
void Engine::run() {
|
||||||
while (process_input()) {
|
while (process_input()) {
|
||||||
bool game_over = exit_code();
|
bool game_over = check_game_over();
|
||||||
if(!game_over) { status = "Current Player: " + std::string(1, temp->id) + "\n"; }
|
if(!game_over) { status = "Current Player: " + std::string(1, temp) + "\n"; }
|
||||||
win.draw_display();
|
win.draw_display();
|
||||||
std::cout << status;
|
mvprintw(6, 0, status.c_str());
|
||||||
|
refresh();
|
||||||
if(game_over) { break; }
|
if(game_over) { break; }
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(150));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mvprintw(7, 0, "Press any key to quit.");
|
||||||
|
nodelay(stdscr, false);
|
||||||
|
getch();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Engine::exit_code() {
|
bool Engine::check_game_over() {
|
||||||
if(check_line(player1.id)) { status = "Game Over! Player 1 wins!"; return true; }
|
if(check_line(p1)) { return status = "Game Over! Player 1 wins!", true; }
|
||||||
if(check_line(player2.id)) { status = "Game Over! Player 2 wins!"; return true; }
|
if(check_line(p2)) { return status = "Game Over! Player 2 wins!", true; }
|
||||||
if(std::count(win.view.begin(), win.view.end(), ' ') == 0) {
|
if(std::ranges::count(win.view, ' ') == 0) {
|
||||||
status = "Game Over! It's a tie!";
|
return status = "Game Over! It's a tie!", true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -51,23 +55,27 @@ bool Engine::exit_code() {
|
|||||||
|
|
||||||
bool Engine::process_input() {
|
bool Engine::process_input() {
|
||||||
int ch, index;
|
int ch, index;
|
||||||
|
bool hit = false;
|
||||||
while((ch = getch()) != ERR) {
|
while((ch = getch()) != ERR) {
|
||||||
|
hit = true;
|
||||||
if(ch == 'q') { return false; }
|
if(ch == 'q') { return false; }
|
||||||
if(ch >= '1' && ch <= '9') {
|
if(ch < '1' || ch > '9') continue;
|
||||||
index = ch - '1';
|
index = ch - '1';
|
||||||
if(win.view[index] == ' ') { win.view[index] = temp->id; }
|
if(win.view[index] == ' ') {
|
||||||
temp = (temp == &player1) ? &player2 : &player1;
|
win.view[index] = temp;
|
||||||
|
temp = (temp == p1) ? p2 : p1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!hit) { std::this_thread::sleep_for(std::chrono::milliseconds(150)); }
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Engine::check_line(char id) const {
|
bool Engine::check_line(char id) const {
|
||||||
static constexpr int wins[8][3] = {
|
static constexpr std::array<std::array<int, 3>, 8> wins = {{
|
||||||
{0, 1, 2}, {3, 4, 5}, {6, 7, 8},
|
{0, 1, 2}, {3, 4, 5}, {6, 7, 8},
|
||||||
{0, 3, 6}, {1, 4, 7}, {2, 5, 8},
|
{0, 3, 6}, {1, 4, 7}, {2, 5, 8},
|
||||||
{0, 4, 8}, {2, 4, 6}
|
{0, 4, 8}, {2, 4, 6}
|
||||||
};
|
}};
|
||||||
for(const auto& i : wins) {
|
for(const auto& i : wins) {
|
||||||
if(win.view[i[0]] == id && win.view[i[1]] == id && win.view[i[2]] == id) {
|
if(win.view[i[0]] == id && win.view[i[1]] == id && win.view[i[2]] == id) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user