diff --git a/src/dawntictactoe/components/TicTacToeGame.cpp b/src/dawntictactoe/components/TicTacToeGame.cpp index 1f4e8281..012baf79 100644 --- a/src/dawntictactoe/components/TicTacToeGame.cpp +++ b/src/dawntictactoe/components/TicTacToeGame.cpp @@ -1,119 +1,119 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#include "TicTacToeGame.hpp" -#include "game/DawnGame.hpp" -#include "scene/components/example/ExampleSpin.hpp" -#include "scene/components/physics/3d/CubeCollider.hpp" - -using namespace Dawn; - -TicTacToeGame::TicTacToeGame(SceneItem *item) : - SceneItemComponent(item), - winner(TIC_TAC_TOE_EMPTY), - nextMove(TIC_TAC_TOE_NOUGHT), - gameOver(false) -{ -} - -void TicTacToeGame::onStart() { - // Map tiles by tile number = tile - auto ts = getScene()->findComponents(); - auto itTiles = ts.begin(); - while(itTiles != ts.end()) { - this->tiles[(*itTiles)->tile] = *itTiles; - ++itTiles; - } - - useEffect([&]{ - if(!gameOver) return; - - auto board = this->getBoard(); - std::vector winningCombo; - winner = ticTacToeDetermineWinner(board, &winningCombo); - std::cout << "Winner is " << winner << std::endl; - }, gameOver); - - useEvent([&](float_t delta) { - // Only allow player input if it's their turn. - if(winner != TIC_TAC_TOE_EMPTY) return; - - Camera *camera = getScene()->findComponent(); - if(camera == nullptr) return; - - TicTacToeTile *hovered = nullptr; - bool_t isPlayerMove = nextMove == TIC_TAC_TOE_NOUGHT; - - // Get hovered tile (for player move only) - if(isPlayerMove) { - // Get mouse in screen space. - auto mouse = getGame()->inputManager.getAxis2D(INPUT_BIND_MOUSE_X, INPUT_BIND_MOUSE_Y); - mouse *= 2.0f; - mouse -= glm::vec2(1, 1); - - struct Ray3D ray; - ray.origin = camera->transform->getWorldPosition(); - ray.direction = camera->getRayDirectionFromScreenSpace(mouse); - - // Find the hovered tile (if any) - auto results = getPhysics()->raycast3DAll(ray); - auto itResult = results.begin(); - while(itResult != results.end()) { - auto result = *itResult; - auto tile = result.collider->item->getComponent(); - if(tile == nullptr) { - ++itResult; - continue; - } - - hovered = tile; - break; - } - } - - // Now update the hover state(s) - auto itTiles = tiles.begin(); - while(itTiles != tiles.end()) { - auto t = itTiles->second; - if(t == hovered) { - t->hovered = true; - } else { - t->hovered = false; - } - ++itTiles; - } - - if(isPlayerMove) { - if(getGame()->inputManager.isPressed(INPUT_BIND_MOUSE_CLICK)) { - this->makeMove(hovered->tile, nextMove); - } - } else if(nextMove != TIC_TAC_TOE_NOUGHT) { - auto board = this->getBoard(); - auto move = ticTacToeGetAiMove(board, nextMove); - this->makeMove(move, nextMove); - } - - // Did game just end? - if(ticTacToeIsGameOver(this->getBoard())) gameOver = true; - }, getScene()->eventSceneUpdate); -} - -std::map TicTacToeGame::getBoard() { - std::map tileMap; - - auto itTiles = tiles.begin(); - while(itTiles != tiles.end()) { - auto t = itTiles->second; - tileMap[t->tile] = t->tileState; - ++itTiles; - } - - return tileMap; -} - -void TicTacToeGame::makeMove(uint8_t tile, enum TicTacToeTileState player) { - this->tiles[tile]->tileState = player; - nextMove = player == TIC_TAC_TOE_NOUGHT ? TIC_TAC_TOE_CROSS : TIC_TAC_TOE_NOUGHT; -} +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "TicTacToeGame.hpp" +#include "game/DawnGame.hpp" +#include "scene/components/example/ExampleSpin.hpp" +#include "scene/components/physics/3d/CubeCollider.hpp" + +using namespace Dawn; + +TicTacToeGame::TicTacToeGame(SceneItem *item) : + SceneItemComponent(item), + winner(TIC_TAC_TOE_EMPTY), + nextMove(TIC_TAC_TOE_NOUGHT), + gameOver(false) +{ +} + +void TicTacToeGame::onStart() { + // Map tiles by tile number = tile + auto ts = getScene()->findComponents(); + auto itTiles = ts.begin(); + while(itTiles != ts.end()) { + this->tiles[(*itTiles)->tile] = *itTiles; + ++itTiles; + } + + useEffect([&]{ + if(!gameOver) return; + + auto board = this->getBoard(); + std::vector winningCombo; + winner = ticTacToeDetermineWinner(board, &winningCombo); + std::cout << "Winner is " << winner << std::endl; + }, gameOver); + + useEvent([&](float_t delta) { + // Only allow player input if it's their turn. + if(gameOver) return; + + Camera *camera = getScene()->findComponent(); + if(camera == nullptr) return; + + TicTacToeTile *hovered = nullptr; + bool_t isPlayerMove = nextMove == TIC_TAC_TOE_NOUGHT; + + // Get hovered tile (for player move only) + if(isPlayerMove) { + // Get mouse in screen space. + auto mouse = getGame()->inputManager.getAxis2D(INPUT_BIND_MOUSE_X, INPUT_BIND_MOUSE_Y); + mouse *= 2.0f; + mouse -= glm::vec2(1, 1); + + struct Ray3D ray; + ray.origin = camera->transform->getWorldPosition(); + ray.direction = camera->getRayDirectionFromScreenSpace(mouse); + + // Find the hovered tile (if any) + auto results = getPhysics()->raycast3DAll(ray); + auto itResult = results.begin(); + while(itResult != results.end()) { + auto result = *itResult; + auto tile = result.collider->item->getComponent(); + if(tile == nullptr) { + ++itResult; + continue; + } + + hovered = tile; + break; + } + } + + // Now update the hover state(s) + auto itTiles = tiles.begin(); + while(itTiles != tiles.end()) { + auto t = itTiles->second; + if(t == hovered) { + t->hovered = true; + } else { + t->hovered = false; + } + ++itTiles; + } + + if(isPlayerMove) { + if(getGame()->inputManager.isPressed(INPUT_BIND_MOUSE_CLICK)) { + this->makeMove(hovered->tile, nextMove); + } + } else if(nextMove != TIC_TAC_TOE_NOUGHT) { + auto board = this->getBoard(); + auto move = ticTacToeGetAiMove(board, nextMove); + this->makeMove(move, nextMove); + } + + // Did game just end? + gameOver = ticTacToeIsGameOver(this->getBoard()); + }, getScene()->eventSceneUpdate); +} + +std::map TicTacToeGame::getBoard() { + std::map tileMap; + + auto itTiles = tiles.begin(); + while(itTiles != tiles.end()) { + auto t = itTiles->second; + tileMap[t->tile] = t->tileState; + ++itTiles; + } + + return tileMap; +} + +void TicTacToeGame::makeMove(uint8_t tile, enum TicTacToeTileState player) { + this->tiles[tile]->tileState = player; + nextMove = player == TIC_TAC_TOE_NOUGHT ? TIC_TAC_TOE_CROSS : TIC_TAC_TOE_NOUGHT; +}