Merge pull request #21 from Trimutex/development

Development
This commit is contained in:
Gregory 2023-09-14 22:26:12 -05:00 committed by GitHub
commit a0c2e7778a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 71 additions and 26 deletions

View File

@ -6,6 +6,7 @@ add_executable(snakeplusplus
./snake.cpp ./snake.cpp
./playerinterface.cpp ./playerinterface.cpp
./common.cpp ./common.cpp
./botinterface.cpp
) )
target_include_directories(snakeplusplus PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(snakeplusplus PUBLIC ${CMAKE_CURRENT_LIST_DIR})

26
src/botinterface.cpp Executable file
View File

@ -0,0 +1,26 @@
#include "botinterface.hpp"
#include "common.hpp"
#include <SFML/System/Vector2.hpp>
namespace snakeplusplus
{
PlayerDirection lastKnownDirection = kNone;
PlayerDirection GetBotInput(const sf::Vector2f* snakeHeadLocation, const sf::Vector2f* foodLocation)
{
sf::Vector2f directionDelta;
directionDelta = *snakeHeadLocation - *foodLocation;
if ((directionDelta.y > 0)
&& (lastKnownDirection != kDown))
{ lastKnownDirection = kUp; }
else if ((directionDelta.y < 0)
&& (lastKnownDirection != kUp))
{ lastKnownDirection = kDown; }
else if ((directionDelta.x > 0)
&& (lastKnownDirection != kRight))
{ lastKnownDirection = kLeft; }
else if ((directionDelta.x < 0)
&& (lastKnownDirection != kLeft))
{ lastKnownDirection = kRight; }
return lastKnownDirection;
}
}

12
src/botinterface.hpp Executable file
View File

@ -0,0 +1,12 @@
#ifndef BOTINTERFACE_HPP
#define BOTINTERFACE_HPP
#include "common.hpp"
#include <SFML/System/Vector2.hpp>
namespace snakeplusplus
{
PlayerDirection GetBotInput(const sf::Vector2f* snakeHeadLocation, const sf::Vector2f* foodLocation);
}
#endif

View File

@ -1,7 +1,7 @@
// GameState.cpp // GameState.cpp
#include <stdexcept> #include <stdexcept>
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include <tuple> #include "botinterface.hpp"
#include "common.hpp" #include "common.hpp"
#include "playerinterface.hpp" #include "playerinterface.hpp"
#include "gamestate.hpp" #include "gamestate.hpp"
@ -10,7 +10,7 @@ namespace snakeplusplus
{ {
GameEngine::GameEngine() GameEngine::GameEngine()
{ {
snakeplusplus::InitializeGenerator(); InitializeGenerator();
return; return;
} }
@ -24,10 +24,10 @@ namespace snakeplusplus
void GameEngine::Reset() void GameEngine::Reset()
{ {
graphics.CheckContinue(); graphics.CheckContinue(isBotControlled);
player.Reset(); player.Reset();
PrepareGameBoard(); PrepareGameBoard();
isGameOver = 0; isGameOver = false;
return; return;
} }
@ -35,7 +35,7 @@ namespace snakeplusplus
{ {
while (graphics.IsOpen()) while (graphics.IsOpen())
{ {
if (isGameOver) {Reset();} if (isGameOver) { Reset(); }
UpdatePlayerSpeed(); UpdatePlayerSpeed();
PlaceNewSnakePart(MovePlayer()); PlaceNewSnakePart(MovePlayer());
RegenerateFood(); RegenerateFood();
@ -88,8 +88,7 @@ namespace snakeplusplus
playerFood.GenerateNewFood(GetGameBoundaries()); playerFood.GenerateNewFood(GetGameBoundaries());
newLocation = playerFood.location; newLocation = playerFood.location;
} }
if (isUpdated) if (isUpdated) { gameBoard.at(newLocation.y).at(newLocation.x) = 'X'; }
gameBoard.at(newLocation.y).at(newLocation.x) = 'X';
return; return;
} }
@ -99,40 +98,44 @@ namespace snakeplusplus
sf::Vector2f boardDimensions = GetGameBoundaries(); sf::Vector2f boardDimensions = GetGameBoundaries();
gameBoard.resize(boardDimensions.y, std::vector<char> (boardDimensions.x, ' ')); gameBoard.resize(boardDimensions.y, std::vector<char> (boardDimensions.x, ' '));
// Snake setup // Snake setup
player.headLocation.x = GenerateRandomNumber(boardDimensions.x);
player.headLocation.y = GenerateRandomNumber(boardDimensions.y);
{ {
player.headLocation.x = GenerateRandomNumber(boardDimensions.x);
player.headLocation.y = GenerateRandomNumber(boardDimensions.y);
char* locationState = &gameBoard.at(player.headLocation.y).at(player.headLocation.x); char* locationState = &gameBoard.at(player.headLocation.y).at(player.headLocation.x);
player.body.push(locationState); player.body.push(locationState);
*locationState = 'O'; *locationState = 'O';
} }
// Food setup // Food setup
{ playerFood.GenerateNewFood(boardDimensions);
playerFood.GenerateNewFood(boardDimensions); gameBoard.at(playerFood.location.y).at(playerFood.location.x) = 'X';
sf::Vector2f newLocation = playerFood.location;
gameBoard.at(newLocation.y).at(newLocation.x) = 'X';
}
return; return;
} }
void GameEngine::UpdatePlayerSpeed(void) void GameEngine::UpdatePlayerSpeed(void)
{ {
switch (GetPlayerInput()) { PlayerDirection controller;
if (isBotControlled) { controller = GetBotInput(&player.headLocation, &playerFood.location); }
else { controller = GetPlayerInput(); }
switch (controller) {
case kUp: case kUp:
if (player.speed.y == kUnitSpeed) { break; }
player.speed.x = 0; player.speed.x = 0;
player.speed.y = -1; player.speed.y = -kUnitSpeed;
break; break;
case kLeft: case kLeft:
player.speed.x = -1; if (player.speed.x == kUnitSpeed) { break; }
player.speed.x = -kUnitSpeed;
player.speed.y = 0; player.speed.y = 0;
break; break;
case kRight: case kRight:
player.speed.x = 1; if (player.speed.x == -kUnitSpeed) { break; }
player.speed.x = kUnitSpeed;
player.speed.y = 0; player.speed.y = 0;
break; break;
case kDown: case kDown:
if (player.speed.y == -kUnitSpeed) { break; }
player.speed.x = 0; player.speed.x = 0;
player.speed.y = 1; player.speed.y = kUnitSpeed;
break; break;
default: default:
break; break;

View File

@ -8,6 +8,8 @@
namespace snakeplusplus namespace snakeplusplus
{ {
const int kUnitSpeed = 1;
class GameEngine class GameEngine
{ {
public: public:
@ -21,6 +23,7 @@ namespace snakeplusplus
Snake player; Snake player;
Food playerFood; Food playerFood;
bool isGameOver = 0; bool isGameOver = 0;
bool isBotControlled = 1;
void DisplayEndScreen(void); void DisplayEndScreen(void);
void Loop(void); void Loop(void);
sf::Vector2f MovePlayer(void); sf::Vector2f MovePlayer(void);

View File

@ -38,9 +38,9 @@ namespace snakeplusplus
return; return;
} }
void PlayerOutput::CheckContinue(void) void PlayerOutput::CheckContinue(bool isBotControlled)
{ {
sf::Event event; if (isBotControlled) { return; }
DisplayEndScreen(); DisplayEndScreen();
while (true) while (true)
{ {
@ -108,7 +108,6 @@ namespace snakeplusplus
void PlayerOutput::CheckWindowEvents(void) void PlayerOutput::CheckWindowEvents(void)
{ {
sf::Event event;
while (gameWindow.pollEvent(event)) while (gameWindow.pollEvent(event))
{ {
if ((event.type == sf::Event::Closed) if ((event.type == sf::Event::Closed)

View File

@ -16,7 +16,7 @@ namespace snakeplusplus
sf::Vector2f gameBoundaries; sf::Vector2f gameBoundaries;
PlayerOutput(void); PlayerOutput(void);
bool IsOpen(void); bool IsOpen(void);
void CheckContinue(void); void CheckContinue(bool isBotControlled);
void DisplayGameState(std::vector< std::vector<char> >& gameBoard); void DisplayGameState(std::vector< std::vector<char> >& gameBoard);
void StartGameWindow(void); void StartGameWindow(void);
private: private:
@ -28,8 +28,9 @@ namespace snakeplusplus
sf::RenderWindow gameWindow; sf::RenderWindow gameWindow;
sf::VideoMode gameVideoSettings; sf::VideoMode gameVideoSettings;
sf::RectangleShape drawObject; sf::RectangleShape drawObject;
sf::Event event;
bool isWindowAlive; bool isWindowAlive;
sf::Time delay = sf::milliseconds(60); sf::Time delay = sf::milliseconds(50);
}; };
} }

View File

@ -24,8 +24,8 @@ namespace snakeplusplus
// Returns a new food object for the snakeFood // Returns a new food object for the snakeFood
void Food::GenerateNewFood(sf::Vector2f boundaries) void Food::GenerateNewFood(sf::Vector2f boundaries)
{ {
location.x = snakeplusplus::GenerateRandomNumber(boundaries.x); location.x = GenerateRandomNumber(boundaries.x);
location.y = snakeplusplus::GenerateRandomNumber(boundaries.y); location.y = GenerateRandomNumber(boundaries.y);
return; return;
} }
} }