guiapplication.cpp 4.18 KB
#include "guiapplication.h"

// othello game library
#include <orangemonkey_ai.h>


// qt
#include <QQmlContext>
#include <QQuickItem>
#include <QQuickWindow>
#include <QTimer>
#include <QDebug>
#include <QThread>

// stl
#include <chrono>
using namespace std::chrono_literals;


GuiApplication::GuiApplication(int& argc, char** argv)
  : QGuiApplication(argc, argv),
    m_game_engine{}, m_model{m_game_engine}, m_app{}
{

  m_app.rootContext()->setContextProperty("gamemodel", &m_model);

  m_app.load(QUrl("qrc:/qml/gui.qml"));

  auto* root_window = qobject_cast<QQuickWindow*>(m_app.rootObjects().first());
  if (root_window) {

    connect(root_window, SIGNAL(endGameAndQuit()), this,
            SLOT(endGameAndQuit()));

    connect(root_window, SIGNAL(boardClicked(int)), this,
            SLOT(boardClicked(int)));

    connect(root_window, SIGNAL(initNewHumanGame()), this,
            SLOT(initNewHumanGame()));

    connect(root_window, SIGNAL(initNewGameVsOrangeMonkeyAI()), this,
            SLOT(initNewGameVsOrangeMonkeyAI()));

    connect(root_window, SIGNAL(orangeMonkeyAIVsOrangeMonkeyAI()), this,
            SLOT(orangeMonkeyAIVsOrangeMonkeyAI()));

    connect(this, &GuiApplication::gameEnded, this,
            &GuiApplication::endOfGameActions);

    connect(this, &GuiApplication::enqueueNextTurn, this,
            &GuiApplication::startNextTurn);

    connect(this, SIGNAL(displayFinalScores()),
            root_window, SIGNAL(displayFinalScores()));
  }
}

//void GuiApplication::endOfTurn()
//{
//    m_model.update();
//    if (m_game_engine.noLegalMoves(m_game_engine.currentPlayerId()) and
//        m_game_engine.noLegalMoves(othello::utility::opponent(m_game_engine.currentPlayerId()))  )
//        emit gameEnded();
//    else if (m_game_engine.noLegalMoves(m_game_engine.currentPlayerId()) and not
//             m_game_engine.noLegalMoves(othello::utility::opponent(m_game_engine.currentPlayerId()))){
//        m_game_engine.switchCurrentPlayerId();
//        emit enqueueNextTurn();
//    }
//}

void GuiApplication::endOfTurn()
{
    m_model.update();
    emit enqueueNextTurn();
}

void GuiApplication::startNextTurn()
{
    if (!m_game_engine.noLegalMoves(m_game_engine.currentPlayerId())){
       if (m_game_engine.currentPlayerType() == othello::PlayerType::AI){
            m_game_engine.think(20s);
            endOfTurn();
        }
     }
    else{
        if (m_game_engine.forfeitedLastTurn() == true)
        {
            emit gameEnded();
            qDebug() << "no more moves" ;
            return;
        }
            else
            {
                m_game_engine.forfeitTurn(true);
                emit enqueueNextTurn();
            }

    }

}

void GuiApplication::boardClicked(int pos)
{
    if (!m_game_engine.ifGameStarted())
        return;
    if (m_game_engine.currentPlayerType() == othello::PlayerType::AI){
        return;
    }
    auto success = m_game_engine.performMoveForCurrentHuman(othello::BitPos{pos});
    if (!success)
        return;

    endOfTurn();
}

void GuiApplication::initNewHumanGame()
{
    m_game_engine.initPlayerType<othello::HumanPlayer, othello::PlayerId::One>();
    m_game_engine.initPlayerType<othello::HumanPlayer, othello::PlayerId::Two>();
    m_game_engine.initNewGame();
    m_model.update();
    emit enqueueNextTurn();
}

void GuiApplication::initNewGameVsOrangeMonkeyAI()
{
    m_game_engine.initPlayerType<othello::HumanPlayer, othello::PlayerId::One>();
    m_game_engine.initPlayerType<othello::monkey_ais::OrangeMonkeyAI, othello::PlayerId::Two>();
    m_game_engine.initNewGame();
    m_model.update();
    emit enqueueNextTurn();
}

void GuiApplication::orangeMonkeyAIVsOrangeMonkeyAI()
{
    m_game_engine.initPlayerType<othello::monkey_ais::OrangeMonkeyAI, othello::PlayerId::One>();
    m_game_engine.initPlayerType<othello::monkey_ais::OrangeMonkeyAI, othello::PlayerId::Two>();
    m_game_engine.initNewGame();
    m_model.update();
    emit enqueueNextTurn();
}


void GuiApplication::endGameAndQuit() {
    QGuiApplication::quit();
}


void GuiApplication::endOfGameActions()
{
    if (othello::utility::occupiedPositions(m_game_engine.board()).all())
        emit displayFinalScores();
    qDebug() << "Game Over!" ;
    emit displayFinalScores();
}