God is no longer drunk (rightly chose invs)
+ some refactoring
This commit is contained in:
parent
af8476c4ba
commit
6b24924b95
@ -5,6 +5,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "playerDef.h"
|
#include "playerDef.h"
|
||||||
#include "invaderDef.h"
|
#include "invaderDef.h"
|
||||||
|
#include "invadersGrid.h"
|
||||||
|
|
||||||
typedef string configKey;
|
typedef string configKey;
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "projectiles.h"
|
#include "projectiles.h"
|
||||||
#include "scoresManager.h"
|
#include "scoresManager.h"
|
||||||
#include "god.h"
|
#include "god.h"
|
||||||
|
#include "invadersGrid.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -62,7 +63,6 @@ private:
|
|||||||
// god things
|
// god things
|
||||||
void awakeGod();
|
void awakeGod();
|
||||||
void manageGod();
|
void manageGod();
|
||||||
void _manageGod_retrieve(bool back);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// in case someone wants to mess with the code, here's a minimal API, costs nothing to us
|
// in case someone wants to mess with the code, here's a minimal API, costs nothing to us
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define GUARD_GOD_H
|
#define GUARD_GOD_H
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "invadersGrid.h"
|
||||||
|
|
||||||
enum class GodState{
|
enum class GodState{
|
||||||
NONE,
|
NONE,
|
||||||
|
26
headers/invadersGrid.h
Normal file
26
headers/invadersGrid.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef GUARD_INVADERSGRID_H
|
||||||
|
#define GUARD_INVADERSGRID_H
|
||||||
|
|
||||||
|
#include<vector>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
enum class InvaderType {
|
||||||
|
TYPEA,
|
||||||
|
TYPEB,
|
||||||
|
TYPEC,
|
||||||
|
NONE,
|
||||||
|
};
|
||||||
|
class InvadersColumn : public vector<InvaderType>{
|
||||||
|
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<InvadersColumn>{
|
||||||
|
public:
|
||||||
|
unsigned randomValid() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -22,19 +22,9 @@ enum class WinValue{
|
|||||||
INVADERS,
|
INVADERS,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class InvaderType {
|
|
||||||
TYPEA,
|
typedef nsGraphics::Vec2D IndexPair;
|
||||||
TYPEB,
|
typedef nsGraphics::Vec2D Position;
|
||||||
TYPEC,
|
|
||||||
NONE,
|
|
||||||
};
|
|
||||||
class InvadersColumn : public vector<InvaderType>{
|
|
||||||
public:
|
|
||||||
// idk why CLion says this is not implemented, but it is
|
|
||||||
size_t getOutterInvader() const;
|
|
||||||
};
|
|
||||||
typedef vector<InvadersColumn> InvadersGrid;
|
|
||||||
typedef nsGraphics::Vec2D Position; // TODO replace with Vec2D ?
|
|
||||||
typedef unsigned playerID; // 0 for player 1, 1 for player 2
|
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
|
// didn't want to use Position because of the semantic with x and y
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
560753531201765499
|
10912949710723305374
|
||||||
|
Thomas,2000
|
||||||
Thomas,1000
|
Thomas,1000
|
||||||
Thomas,300
|
Thomas,300
|
||||||
Thomas,0
|
Thomas,0
|
||||||
Thomas,0
|
Thomas,0
|
||||||
Thomas,0
|
|
||||||
|
@ -96,7 +96,7 @@ void Game::displayGod() const {
|
|||||||
// pos is now the position we need to draw our hand to
|
// pos is now the position we need to draw our hand to
|
||||||
pm.drawGodRightHand(pos);
|
pm.drawGodRightHand(pos);
|
||||||
// TODO remove "closed" arg
|
// 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(GOD_HAND_SIZE/2, GOD_HAND_SIZE/2);
|
||||||
pos-=Position(confData.invadersSize/2, confData.invadersSize/2);
|
pos-=Position(confData.invadersSize/2, confData.invadersSize/2);
|
||||||
|
@ -14,12 +14,12 @@ Game::Game() : WININIT, pm(window) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Game::updateColumns(){
|
void Game::updateColumns(){
|
||||||
while(grid.at(0).getOutterInvader()==grid.at(0).size()){
|
while(grid.at(0).hasNoValid()){
|
||||||
grid.erase(grid.begin());
|
grid.erase(grid.begin());
|
||||||
basePos+=confData.invadersSize+confData.invadersDistance;
|
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);
|
grid.erase(grid.end()-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,6 +134,7 @@ WinValue Game::playGame(){ // returns when game is finished
|
|||||||
|
|
||||||
this_thread::sleep_until(startTime+maxFrameTime);
|
this_thread::sleep_until(startTime+maxFrameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
return WinValue::NOBODY;
|
return WinValue::NOBODY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,26 +37,12 @@ bool Game::manageInvaders(){
|
|||||||
if(fireCooldown==0) {
|
if(fireCooldown==0) {
|
||||||
fireCooldown = confData.invadersFireCooldown + rand() % 60;
|
fireCooldown = confData.invadersFireCooldown + rand() % 60;
|
||||||
|
|
||||||
// compute the number of valid columns for firing, so rand() can't pick an empty column to fire
|
unsigned rdCol = grid.randomValid();
|
||||||
unsigned counter=0;
|
|
||||||
for(InvadersColumn& col : grid){
|
|
||||||
if(!col.empty())++counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned rd = (rand()%counter)+1;
|
|
||||||
counter = 0;
|
|
||||||
|
|
||||||
for(size_t i=0;i<grid.size();++i){
|
|
||||||
if(!grid[i].empty())++counter;
|
|
||||||
if(counter==rd){
|
|
||||||
// fire !
|
// fire !
|
||||||
missiles.push_back(basePos + Position(
|
missiles.push_back(basePos + Position(
|
||||||
confData.invadersSize*i+confData.invadersDistance*(i+0.5),
|
confData.invadersSize * rdCol + confData.invadersDistance * (rdCol + 0.5),
|
||||||
confData.invadersSize*(grid[i].size()-1)+confData.invadersDistance*(grid[i].size()-1)
|
confData.invadersSize * (grid[rdCol].size() - 1) + confData.invadersDistance * (grid[rdCol].size() - 1)
|
||||||
));
|
));
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else --fireCooldown;
|
}else --fireCooldown;
|
||||||
|
|
||||||
// moving
|
// moving
|
||||||
@ -171,7 +157,7 @@ bool Game::checkTorpedosAndInvaders() {
|
|||||||
size_t i=0;
|
size_t i=0;
|
||||||
for(;i<grid.size();++i){
|
for(;i<grid.size();++i){
|
||||||
|
|
||||||
size_t alienIndex = grid[i].getOutterInvader();
|
unsigned alienIndex = grid[i].getOutterInvader();
|
||||||
// calculate top-left Position of invader
|
// calculate top-left Position of invader
|
||||||
Position pos = basePos + Position(
|
Position pos = basePos + Position(
|
||||||
confData.invadersSize*i+confData.invadersDistance*i,
|
confData.invadersSize*i+confData.invadersDistance*i,
|
||||||
|
@ -18,30 +18,43 @@ void Game::manageGod() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GodState::WAIT: {
|
case GodState::WAIT: {
|
||||||
if (god.counter == 100) {
|
if (god.counter < 100) {
|
||||||
|
++god.counter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
// init throw
|
// init throw
|
||||||
god.counter = 0;
|
god.counter = 0;
|
||||||
god.state = GodState::RETRIEVE1;
|
god.state = GodState::RETRIEVE1;
|
||||||
god.thrownInvPosX = rand() % grid.size();
|
god.thrownInvPosX = grid.randomValid();
|
||||||
god.thrownInvPosY = rand() % grid[0].size();
|
god.thrownInvPosY = grid[god.thrownInvPosX].randomValid();
|
||||||
|
god.thrownInvType = InvaderType::NONE;
|
||||||
god.thrownInvType = grid[god.thrownInvPosX][god.thrownInvPosY];
|
|
||||||
|
|
||||||
god.thrownTransition.setX(pm.getScreenWidth() - GOD_HAND_DISTANCE - GOD_HAND_SIZE);
|
god.thrownTransition.setX(pm.getScreenWidth() - GOD_HAND_DISTANCE - GOD_HAND_SIZE);
|
||||||
god.thrownTransition.setY(basePos.getY() + INV_GET_POS(god.thrownInvPosY));
|
god.thrownTransition.setY(basePos.getY() + INV_GET_POS(god.thrownInvPosY));
|
||||||
} else ++god.counter;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GodState::RETRIEVE1: {
|
case GodState::RETRIEVE1: {
|
||||||
if (god.counter == 100) {
|
if (god.counter < 100) {
|
||||||
|
god.counter += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (grid.size() > god.thrownInvPosY && grid[god.thrownInvPosX][god.thrownInvPosY] != InvaderType::NONE) {
|
||||||
|
god.thrownInvType = grid[god.thrownInvPosX][god.thrownInvPosY];
|
||||||
grid[god.thrownInvPosX][god.thrownInvPosY] = InvaderType::NONE;
|
grid[god.thrownInvPosX][god.thrownInvPosY] = InvaderType::NONE;
|
||||||
updateColumns();
|
updateColumns();
|
||||||
|
}
|
||||||
god.state = GodState::RETRIEVE2;
|
god.state = GodState::RETRIEVE2;
|
||||||
} else god.counter += 2;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GodState::RETRIEVE2: {
|
case GodState::RETRIEVE2: {
|
||||||
if (god.counter == 0) {
|
if (god.counter > 0) {
|
||||||
|
god.counter -= 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(god.thrownInvType==InvaderType::NONE){
|
||||||
|
god.state = GodState::WAIT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
god.state = GodState::THROW;
|
god.state = GodState::THROW;
|
||||||
|
|
||||||
// compute the launch vector
|
// compute the launch vector
|
||||||
@ -60,7 +73,6 @@ void Game::manageGod() {
|
|||||||
god.thrownVector = god.thrownVector / (god.thrownVector.computeMagnitude() / 1000.0);
|
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
|
// let's normalize it, but keep it's length big so x and y and non-zero
|
||||||
// We will divide it in display
|
// We will divide it in display
|
||||||
} else god.counter -= 2;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GodState::THROW: {
|
case GodState::THROW: {
|
||||||
|
57
src/invaderGrids.cpp
Normal file
57
src/invaderGrids.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include<invadersGrid.h>
|
||||||
|
#include<iostream>
|
||||||
|
|
||||||
|
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;i<size();++i){
|
||||||
|
if(at(i)!=InvaderType::NONE){
|
||||||
|
if(validIndex==rd)return i;
|
||||||
|
++validIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw runtime_error("SHOULD NOT HAPPEN");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned InvadersGrid::randomValid() const {
|
||||||
|
|
||||||
|
|
||||||
|
unsigned validTotal = 0;
|
||||||
|
for(const InvadersColumn& i : *this){
|
||||||
|
if(!i.hasNoValid())++validTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned rd = rand() % validTotal;
|
||||||
|
|
||||||
|
unsigned validIndex = 0;
|
||||||
|
for(unsigned i=0;i<size();++i){
|
||||||
|
if(!at(i).hasNoValid()){
|
||||||
|
if(validIndex==rd)return i;
|
||||||
|
++validIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw runtime_error("SHOULD NOT HAPPEN");
|
||||||
|
}
|
@ -8,15 +8,6 @@ bool areLinesColliding(unsigned start1, unsigned end1, unsigned start2, unsigned
|
|||||||
// if it returns true, lines are colliding. I like truth tables
|
// if it returns true, lines are colliding. I like truth tables
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t InvadersColumn::getOutterInvader() const {
|
|
||||||
size_t i=size();
|
|
||||||
while(i>0){
|
|
||||||
--i;
|
|
||||||
if(at(i)!=InvaderType::NONE)return i;
|
|
||||||
}
|
|
||||||
return size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void applyTransformation(Position& pos, unsigned sizeFrom, unsigned sizeTo){
|
void applyTransformation(Position& pos, unsigned sizeFrom, unsigned sizeTo){
|
||||||
pos += Position(sizeFrom/2, sizeFrom/2);
|
pos += Position(sizeFrom/2, sizeFrom/2);
|
||||||
pos -= Position(sizeTo/2, sizeTo/2);
|
pos -= Position(sizeTo/2, sizeTo/2);
|
||||||
|
Loading…
Reference in New Issue
Block a user