Fixed hard crash
This commit is contained in:
@ -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<TicTacToeTile>();
|
||||
auto itTiles = ts.begin();
|
||||
while(itTiles != ts.end()) {
|
||||
this->tiles[(*itTiles)->tile] = *itTiles;
|
||||
++itTiles;
|
||||
}
|
||||
|
||||
useEffect([&]{
|
||||
if(!gameOver) return;
|
||||
|
||||
auto board = this->getBoard();
|
||||
std::vector<uint8_t> 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<Camera>();
|
||||
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<TicTacToeTile>();
|
||||
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<uint8_t, enum TicTacToeTileState> TicTacToeGame::getBoard() {
|
||||
std::map<uint8_t, enum TicTacToeTileState> 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<TicTacToeTile>();
|
||||
auto itTiles = ts.begin();
|
||||
while(itTiles != ts.end()) {
|
||||
this->tiles[(*itTiles)->tile] = *itTiles;
|
||||
++itTiles;
|
||||
}
|
||||
|
||||
useEffect([&]{
|
||||
if(!gameOver) return;
|
||||
|
||||
auto board = this->getBoard();
|
||||
std::vector<uint8_t> 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<Camera>();
|
||||
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<TicTacToeTile>();
|
||||
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<uint8_t, enum TicTacToeTileState> TicTacToeGame::getBoard() {
|
||||
std::map<uint8_t, enum TicTacToeTileState> 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user