#include "game.h" #include const std::string Game::SYM_NAMES[3] = {"NONE", "X", "O"}; std::string Game::UserInfo::getUsernameOrName() const { return username.empty() ? name : ("@" + username); } bool Game::UserInfo::operator==(const UserInfo& other) const { if(id != 0 && other.id != 0) { return id == other.id; } return username == other.username; } bool Game::UserInfo::operator!=(const UserInfo& other) const { if(id != 0 && other.id != 0) { return id != other.id; } return other.username != username; } Game::Game() { for(uint_fast8_t i = 0; i < SIZE * SIZE; ++i) { field[i] = SYM::NONE; } } void Game::setPlayerA(const UserInfo& player) { playerA = player; } void Game::setPlayerB(const UserInfo& player) { playerB = player; } bool Game::addPlayer(const UserInfo& player) { if(!playerA) { playerA = player; return true; } if(!playerB && playerA != player) { playerB = player; return true; } return false; } const Game::UserInfo& Game::getPlayerA() const { return playerA; } const Game::UserInfo& Game::getPlayerB() const { return playerB; } bool Game::ready() const { return playerA && playerB && !done(); } bool Game::done() const { return (checkWinner() != SYM::NONE) || isFull(); } bool Game::isFull() const { for(uint_fast8_t i = 0; i < SIZE * SIZE; ++i) { if(field[i] == SYM::NONE) return false; } return true; } bool Game::turn(uint_fast8_t x, uint_fast8_t y, const UserInfo& player) { if(!isInField(x, y)) { return false; } if(!ready()) { return false; } // Log::info << "turn player: " << player.id << " n: " << player.name << " u: " << player.username; // Log::info << "playerA: " << playerA.id << " n: " << playerA.name << " u: " << playerA.username << " e: " << (player == playerA); // Log::info << "playerB: " << playerB.id << " n: " << playerB.name << " u: " << playerB.username << " e: " << (player == playerB); // playerA if(player == playerA && nextturna) { SYM s = getField(x, y); if(s != SYM::NONE) { return false; } setField(x, y, SYM::A); } //playerB else if(player == playerB && !nextturna) { SYM s = getField(x, y); if(s != SYM::NONE) { return false; } setField(x, y, SYM::B); } // other user -> not allowed else return false; nextturna = !nextturna; return true; } const std::string& Game::getWinner() const { Game::SYM winner = checkWinner(); if(winner == SYM::NONE) { static const std::string EMPTY = ""; return EMPTY; } return SYM_NAMES[(int) winner]; } Game::SYM Game::getPos(uint_fast8_t x, uint_fast8_t y) const { return getField(x, y); } void Game::setPos(uint_fast8_t x, uint_fast8_t y, Game::SYM s) { setField(x, y, s); } static constexpr bool checkThree(Game::SYM s1, Game::SYM s2, Game::SYM s3) { return s1 == s2 && s2 == s3; } Game::SYM Game::checkWinner() const { // diagonal top-left -> bottom right if(checkThree(getField(0, 0), getField(1, 1), getField(2, 2))) { return getField(1, 1); } // diagonal top right -> bottom left if(checkThree(getField(2, 0), getField(1, 1), getField(0, 2))) { return getField(1, 1); } // check rows and cols for(uint_fast8_t i = 0; i < SIZE; ++i) { if(checkThree(getField(0, i), getField(1, i), getField(2, i))) { // spalte gleich return getField(0, i); } if(checkThree(getField(i, 0), getField(i, 1), getField(i, 2))) { // zeile gleich return getField(i, 0); } } return SYM::NONE; }