2022-08-15 23:51:18 -05:00
|
|
|
// GameState.cpp
|
2023-04-06 19:27:10 -05:00
|
|
|
#include <memory>
|
|
|
|
#include <stdexcept>
|
2023-03-17 20:13:50 -05:00
|
|
|
#include <string>
|
2023-03-17 17:27:02 -05:00
|
|
|
#include <SFML/Graphics.hpp>
|
2023-04-06 19:27:10 -05:00
|
|
|
#include "common.hpp"
|
|
|
|
#include "playerinterface.hpp"
|
|
|
|
#include "gamestate.hpp"
|
2022-07-28 15:18:24 -05:00
|
|
|
|
2023-04-06 19:27:10 -05:00
|
|
|
namespace snakeplusplus
|
2022-07-28 15:18:24 -05:00
|
|
|
{
|
2023-04-06 19:27:10 -05:00
|
|
|
GameEngine::GameEngine()
|
2023-03-17 20:13:50 -05:00
|
|
|
{
|
2023-04-06 19:27:10 -05:00
|
|
|
return;
|
2023-03-17 20:13:50 -05:00
|
|
|
}
|
|
|
|
|
2023-04-06 19:27:10 -05:00
|
|
|
void GameEngine::SetGameSettings(int argc, char* argv[])
|
|
|
|
{
|
|
|
|
std::string convertedString;
|
|
|
|
for (int i = 0; i < argc; i++)
|
|
|
|
{
|
|
|
|
convertedString = argv[i];
|
|
|
|
if (convertedString == "--no-sfml")
|
|
|
|
useSFML = false;
|
|
|
|
}
|
|
|
|
}
|
2023-03-13 08:24:56 -05:00
|
|
|
|
2023-04-06 19:27:10 -05:00
|
|
|
void GameEngine::StartGame()
|
|
|
|
{
|
|
|
|
ApplySettings();
|
|
|
|
ResetGameBoard();
|
|
|
|
graphics->StartGameWindow();
|
|
|
|
GameLoop();
|
|
|
|
return;
|
|
|
|
}
|
2023-03-12 08:50:50 -05:00
|
|
|
|
2023-04-06 19:27:10 -05:00
|
|
|
void GameEngine::ApplySettings(void)
|
|
|
|
{
|
|
|
|
if (useSFML)
|
|
|
|
graphics.reset(new SFML());
|
|
|
|
else
|
|
|
|
graphics.reset(new CommandLine());
|
|
|
|
return;
|
|
|
|
}
|
2023-03-12 21:57:46 -05:00
|
|
|
|
2023-04-06 19:27:10 -05:00
|
|
|
// TODO: Reimplement for DisplayInterface
|
|
|
|
void GameEngine::DisplayEndScreen(void)
|
|
|
|
{
|
|
|
|
graphics->DisplayEndScreen();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GameEngine::GameLoop(void)
|
|
|
|
{
|
|
|
|
sf::Vector2f newHeadPosition;
|
|
|
|
while (graphics->IsOpen())
|
|
|
|
{
|
|
|
|
// player.UpdateDirection(playerInput.GetPlayerInput());
|
|
|
|
// newHeadPosition = player.Move();
|
|
|
|
// if (playerFood.GetFoodLocation() != newHeadPosition)
|
|
|
|
// player.Pop();
|
|
|
|
// PlaceNewSnakePart(newHeadPosition);
|
|
|
|
graphics->DisplayGameState(&gameBoard);
|
|
|
|
// if (isGameOver)
|
|
|
|
// PlayerWantsToContinue();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2023-03-17 21:07:58 -05:00
|
|
|
|
2023-04-06 19:27:10 -05:00
|
|
|
sf::Vector2f GameEngine::GetGameBoundaries(void)
|
|
|
|
{
|
|
|
|
return graphics->gameBoundaries;
|
|
|
|
}
|
2023-03-13 08:24:56 -05:00
|
|
|
|
2023-04-06 19:27:10 -05:00
|
|
|
void GameEngine::PlaceNewSnakePart(sf::Vector2f location)
|
2023-03-17 21:40:49 -05:00
|
|
|
{
|
2023-04-06 19:27:10 -05:00
|
|
|
char locationState;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
locationState = gameBoard.at(location.y).at(location.x);
|
|
|
|
if (locationState == 'O')
|
|
|
|
isGameOver = true; // Game should end (Snake touching snake)
|
|
|
|
if (locationState == ' ')
|
|
|
|
player.Pop(); // Snake shouldn't extend
|
|
|
|
gameBoard.at(location.y).at(location.x) = 'O';
|
|
|
|
} catch (const std::out_of_range& error) {
|
|
|
|
isGameOver = true; // Snake ran into edge
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return;
|
2023-03-17 21:40:49 -05:00
|
|
|
}
|
2022-08-02 21:17:23 -05:00
|
|
|
|
2023-04-06 19:27:10 -05:00
|
|
|
void GameEngine::PlayerWantsToContinue(void)
|
|
|
|
{
|
|
|
|
graphics->CheckContinue();
|
|
|
|
return;
|
|
|
|
}
|
2023-03-17 21:40:49 -05:00
|
|
|
|
2023-04-06 19:27:10 -05:00
|
|
|
// Generates new food until not colliding with player
|
|
|
|
void GameEngine::RegenerateFood(void)
|
|
|
|
{
|
|
|
|
sf::Vector2f newLocation = playerFood.GetFoodLocation();
|
|
|
|
bool isUpdated = false;
|
|
|
|
// Keep making new food until generating a valid spot
|
|
|
|
while (gameBoard.at(newLocation.y).at(newLocation.x) == 'O')
|
|
|
|
{
|
|
|
|
isUpdated = true;
|
|
|
|
playerFood.GenerateNewFood(GetGameBoundaries());
|
|
|
|
newLocation = playerFood.GetFoodLocation();
|
|
|
|
}
|
|
|
|
if (isUpdated)
|
|
|
|
gameBoard.at(newLocation.y).at(newLocation.x) = 'X';
|
|
|
|
return;
|
|
|
|
}
|
2023-03-17 17:27:02 -05:00
|
|
|
|
2023-04-06 19:27:10 -05:00
|
|
|
void GameEngine::ResetGameBoard(void)
|
2022-08-02 21:17:23 -05:00
|
|
|
{
|
2023-04-06 19:27:10 -05:00
|
|
|
gameBoard.clear();
|
|
|
|
sf::Vector2f boardDimensions = GetGameBoundaries();
|
|
|
|
std::vector<char> tempBoard;
|
|
|
|
tempBoard.resize(boardDimensions.x, ' ');
|
|
|
|
gameBoard.resize(boardDimensions.y, tempBoard);
|
|
|
|
PlaceNewSnakePart(player.Reset());
|
|
|
|
// playerFood.GenerateNewFood(boardDimensions);
|
|
|
|
// sf::Vector2f foodStartLocation = playerFood.GetFoodLocation();
|
|
|
|
// gameBoard.at(foodStartLocation.y).at(foodStartLocation.x) = 'X';
|
|
|
|
// return;
|
2022-08-02 21:17:23 -05:00
|
|
|
}
|
|
|
|
}
|