diff --git a/CMakeLists.txt b/CMakeLists.txt index 78b1174..bb58a89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ file(GLOB_RECURSE HEADERS headers/*) add_executable(Space ${LIB_HEADERS} ${HEADERS} ${SRC}) - target_link_directories(Space PUBLIC .) +target_link_directories(Space PUBLIC .) target_include_directories(Space PUBLIC headers) target_include_directories(Space PUBLIC lib_headers) diff --git a/headers/configData.h b/headers/configData.h index 38dae41..5b6725b 100644 --- a/headers/configData.h +++ b/headers/configData.h @@ -5,6 +5,7 @@ #include "utils.h" #include "playerDef.h" #include "invaderDef.h" +#include "invadersGrid.h" typedef string configKey; diff --git a/headers/game.h b/headers/game.h index f26279d..62ddeb2 100644 --- a/headers/game.h +++ b/headers/game.h @@ -11,6 +11,7 @@ #include "projectiles.h" #include "scoresManager.h" #include "god.h" +#include "invadersGrid.h" using namespace std; @@ -62,7 +63,6 @@ private: // god things void awakeGod(); void manageGod(); - void _manageGod_retrieve(bool back); public: // in case someone wants to mess with the code, here's a minimal API, costs nothing to us diff --git a/headers/god.h b/headers/god.h index 1a28aea..858fced 100644 --- a/headers/god.h +++ b/headers/god.h @@ -2,6 +2,7 @@ #define GUARD_GOD_H #include "utils.h" +#include "invadersGrid.h" enum class GodState{ NONE, diff --git a/headers/invadersGrid.h b/headers/invadersGrid.h new file mode 100644 index 0000000..3cf12ae --- /dev/null +++ b/headers/invadersGrid.h @@ -0,0 +1,26 @@ +#ifndef GUARD_INVADERSGRID_H +#define GUARD_INVADERSGRID_H + +#include + +using namespace std; + +enum class InvaderType { + TYPEA, + TYPEB, + TYPEC, + NONE, +}; +class InvadersColumn : public vector{ +public: + // idk why CLion says this is not implemented, but it is + bool hasNoValid() const; + unsigned getOutterInvader() const; + unsigned randomValid() const; +}; +class InvadersGrid : public vector{ +public: + unsigned randomValid() const; +}; + +#endif \ No newline at end of file diff --git a/headers/utils.h b/headers/utils.h index e74cf97..4ff55d2 100644 --- a/headers/utils.h +++ b/headers/utils.h @@ -22,19 +22,9 @@ enum class WinValue{ INVADERS, }; -enum class InvaderType { - TYPEA, - TYPEB, - TYPEC, - NONE, -}; -class InvadersColumn : public vector{ -public: - // idk why CLion says this is not implemented, but it is - size_t getOutterInvader() const; -}; -typedef vector InvadersGrid; -typedef nsGraphics::Vec2D Position; // TODO replace with Vec2D ? + +typedef nsGraphics::Vec2D IndexPair; +typedef nsGraphics::Vec2D Position; typedef unsigned playerID; // 0 for player 1, 1 for player 2 // didn't want to use Position because of the semantic with x and y diff --git a/scores.kus b/scores.kus index f030686..d89cc97 100644 --- a/scores.kus +++ b/scores.kus @@ -1,6 +1,6 @@ -560753531201765499 +10912949710723305374 +Thomas,2000 Thomas,1000 Thomas,300 Thomas,0 Thomas,0 -Thomas,0 diff --git a/src/game/display.cpp b/src/game/display.cpp index 11fbd2a..ce2aa69 100644 --- a/src/game/display.cpp +++ b/src/game/display.cpp @@ -96,7 +96,7 @@ void Game::displayGod() const { // pos is now the position we need to draw our hand to pm.drawGodRightHand(pos); // TODO remove "closed" arg - if(god.state==GodState::RETRIEVE2){ + if(god.thrownInvType!=InvaderType::NONE){ pos+=Position(GOD_HAND_SIZE/2, GOD_HAND_SIZE/2); pos-=Position(confData.invadersSize/2, confData.invadersSize/2); diff --git a/src/game/gameBasics.cpp b/src/game/gameBasics.cpp index 3fba575..29f1b74 100644 --- a/src/game/gameBasics.cpp +++ b/src/game/gameBasics.cpp @@ -14,12 +14,12 @@ Game::Game() : WININIT, pm(window) { } void Game::updateColumns(){ - while(grid.at(0).getOutterInvader()==grid.at(0).size()){ + while(grid.at(0).hasNoValid()){ grid.erase(grid.begin()); basePos+=confData.invadersSize+confData.invadersDistance; } - while(grid.at(grid.size()-1).getOutterInvader()==grid.at(grid.size()-1).size()){ + while(grid.at(grid.size() - 1).hasNoValid()){ grid.erase(grid.end()-1); } } @@ -134,6 +134,7 @@ WinValue Game::playGame(){ // returns when game is finished this_thread::sleep_until(startTime+maxFrameTime); } + return WinValue::NOBODY; } diff --git a/src/game/gameManagers.cpp b/src/game/gameManagers.cpp index b08afac..95dafe7 100644 --- a/src/game/gameManagers.cpp +++ b/src/game/gameManagers.cpp @@ -34,29 +34,15 @@ void Game::managePlayers(){ */ bool Game::manageInvaders(){ // shoot - if(fireCooldown==0){ - fireCooldown = confData.invadersFireCooldown+rand()%60; + if(fireCooldown==0) { + fireCooldown = confData.invadersFireCooldown + rand() % 60; - // compute the number of valid columns for firing, so rand() can't pick an empty column to fire - unsigned counter=0; - for(InvadersColumn& col : grid){ - if(!col.empty())++counter; - } - - unsigned rd = (rand()%counter)+1; - counter = 0; - - for(size_t i=0;i god.thrownInvPosY && grid[god.thrownInvPosX][god.thrownInvPosY] != InvaderType::NONE) { + god.thrownInvType = grid[god.thrownInvPosX][god.thrownInvPosY]; grid[god.thrownInvPosX][god.thrownInvPosY] = InvaderType::NONE; updateColumns(); - god.state = GodState::RETRIEVE2; - } else god.counter += 2; + } + god.state = GodState::RETRIEVE2; break; } case GodState::RETRIEVE2: { - if (god.counter == 0) { - god.state = GodState::THROW; + if (god.counter > 0) { + god.counter -= 2; + break; + } + if(god.thrownInvType==InvaderType::NONE){ + god.state = GodState::WAIT; + break; + } + god.state = GodState::THROW; - // compute the launch vector + // compute the launch vector - Position invaderMiddlePos(pm.getScreenWidth() - GOD_HAND_DISTANCE - GOD_HAND_SIZE / 2, - GOD_HAND_SIZE / 2); + Position invaderMiddlePos(pm.getScreenWidth() - GOD_HAND_DISTANCE - GOD_HAND_SIZE / 2, + GOD_HAND_SIZE / 2); - playerID target; - if (players.size() == 1)target = 0; // don't want to use random if not needed - else target = rand() % players.size(); - Position playerMiddlePos(players[target].x + confData.playersWidth / 2, - pm.getScreenHeight() - PLAYER_HEIGHT / 2); + playerID target; + if (players.size() == 1)target = 0; // don't want to use random if not needed + else target = rand() % players.size(); + Position playerMiddlePos(players[target].x + confData.playersWidth / 2, + pm.getScreenHeight() - PLAYER_HEIGHT / 2); - god.thrownVector = playerMiddlePos - invaderMiddlePos; - god.thrownVector = god.thrownVector / (god.thrownVector.computeMagnitude() / 1000.0); - // let's normalize it, but keep it's length big so x and y and non-zero - // We will divide it in display - } else god.counter -= 2; + god.thrownVector = playerMiddlePos - invaderMiddlePos; + god.thrownVector = god.thrownVector / (god.thrownVector.computeMagnitude() / 1000.0); + // let's normalize it, but keep it's length big so x and y and non-zero + // We will divide it in display break; } case GodState::THROW: { diff --git a/src/invaderGrids.cpp b/src/invaderGrids.cpp new file mode 100644 index 0000000..26b9082 --- /dev/null +++ b/src/invaderGrids.cpp @@ -0,0 +1,57 @@ +#include +#include + +bool InvadersColumn::hasNoValid() const { + return getOutterInvader()==size(); +} +unsigned InvadersColumn::getOutterInvader() const { + unsigned i=size(); + while(i>0){ + --i; + if(at(i)!=InvaderType::NONE)return i; + } + return size(); +} + + +// these are used to invoke rand() as less as possible + +unsigned InvadersColumn::randomValid() const { + + + unsigned validTotal = 0; + for(InvaderType ite : *this){ + if(ite!=InvaderType::NONE)++validTotal; + } + + unsigned rd = rand() % validTotal; + + unsigned validIndex = 0; + for(unsigned i=0;i0){ - --i; - if(at(i)!=InvaderType::NONE)return i; - } - return size(); -} - void applyTransformation(Position& pos, unsigned sizeFrom, unsigned sizeTo){ pos += Position(sizeFrom/2, sizeFrom/2); pos -= Position(sizeTo/2, sizeTo/2);