push
This commit is contained in:
parent
15dc67c348
commit
a81ec496a6
@ -1,10 +1,5 @@
|
||||
Questions que je (Thomas Rubini) voudrais poser
|
||||
|
||||
- Est-ce que vous préférez l'implémentation orienté objet ou orienté macro pour lire la config ? Pourquoi ?
|
||||
- Est-ce que traduire les chars A B et C (identifiants des types d'aliens) tirés de la config en valeurs d'enum est une bonne chose, pas important, ou contre-productif ?
|
||||
- Est-ce que mon implémentation du réseau est bonne ?
|
||||
- Est-ce mon implémentation du multithreading est bonne ?
|
||||
|
||||
- Est-on obligé d'utiliser size_t quand on sait que la taille du vecteur ne dépassera jamais concrètement la taille d'un int (cas précis : taille de 100 maximum, est-on obligé d'utiliser size_t de 8 bytes ?)
|
||||
* Non
|
||||
- Que pensez-vous de la sémantique de déplacement, plutot que la référence constante ?
|
||||
|
1
README
1
README
@ -4,6 +4,7 @@ PascalCase pour les noms de classes/structures
|
||||
Nommage en anglais
|
||||
Pas de fonctions de +100 lignes
|
||||
Les guards sont de cette forme : GUARD_<filename>_H
|
||||
Lors d'un include, on utilise <> pour la STD, "" pour nos fichiers/MinGL
|
||||
|
||||
Concernant les const :
|
||||
Afin de limiter l'utilisation du mot const (pour garder une certaine lisibilité du code), les cas suivants n'ont pas besoin d'etre déclarés comme const :
|
||||
|
50
headers/configManagement.h
Normal file
50
headers/configManagement.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*!
|
||||
*
|
||||
* @file configManagement.h
|
||||
* @author RUBINI Thomas
|
||||
* @author SIMAILA Djalim
|
||||
* @date January 2022
|
||||
* @version 1.0
|
||||
* @brief config parser
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SPACE_CONFIGMANAGEMENT_H
|
||||
#define SPACE_CONFIGMANAGEMENT_H
|
||||
|
||||
/*
|
||||
* This header will only be imported once, but Djalim told me he would hurt me
|
||||
* if I didn't move it into his own header file instead of the cpp file
|
||||
*/
|
||||
|
||||
class ConfigBuilder{
|
||||
public:
|
||||
ConfigData collectedData;
|
||||
void parseFile(const string& fname);
|
||||
void readConfig();
|
||||
void dumpInternalValues() const;
|
||||
private:
|
||||
map<string, string> internalValues;
|
||||
|
||||
const string& getString(const configKey& key, const string& def) const;
|
||||
const string& getString(const configKey& key) const;
|
||||
char getChar(const configKey& key, char def) const;
|
||||
char getChar(const configKey& key) const;
|
||||
int getInt(const configKey& key) const;
|
||||
int getInt(const configKey& key, int def) const;
|
||||
void getColor(const configKey& key, nsGraphics::RGBAcolor& color, nsGraphics::RGBAcolor& def) const;
|
||||
void getColor(const configKey& key, nsGraphics::RGBAcolor& color) const;
|
||||
void getList(const configKey& key, vector<string>& vec) const;
|
||||
|
||||
void readGrid(const configKey& baseKey);
|
||||
void readPlayer(const configKey& baseKey, PlayerDef&);
|
||||
void readInvaderType(const configKey& baseKey, InvaderTypeDef&);
|
||||
};
|
||||
|
||||
void ConfigBuilder::dumpInternalValues() const {
|
||||
for(const auto& ite : internalValues){
|
||||
cerr << ite.first << " -> " << ite.second << endl;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
25
headers/errors.h
Normal file
25
headers/errors.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*!
|
||||
*
|
||||
* @file configData.h
|
||||
* @author RUBINI Thomas
|
||||
* @date January 2022
|
||||
* @version 1.0
|
||||
* @brief Configuration file data storage
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GUARD_ERRORS_H
|
||||
#define GUARD_ERRORS_H
|
||||
|
||||
#include<string>
|
||||
#include<stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// We keep the same case
|
||||
class config_error : public runtime_error {
|
||||
public:
|
||||
explicit config_error(const string& msg);
|
||||
};
|
||||
|
||||
#endif
|
@ -202,37 +202,37 @@ private:
|
||||
void moveTorpedos();
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @return
|
||||
* @fn
|
||||
* @brief checks if a missile collides with a player
|
||||
* @fn checkMissilesAndPlayers();
|
||||
*/
|
||||
bool checkMissilesAndPlayers();
|
||||
void checkMissilesAndPlayers();
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @return
|
||||
* @fn
|
||||
* @brief check if a torpedo collides with an invader
|
||||
* @return true if there is a collision, false elsewise
|
||||
* @fn bool checkTorpedosAndInvaders();
|
||||
*/
|
||||
bool checkTorpedosAndInvaders();
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @return
|
||||
* @fn
|
||||
* @brief check if the invaders have reach the players
|
||||
* @return true if they have reach the player, false elsewise
|
||||
* @fn bool invadersTouchPlayer() const;
|
||||
*/
|
||||
bool invadersTouchPlayer() const;
|
||||
|
||||
// god things
|
||||
|
||||
/*!
|
||||
*
|
||||
* @brief change god's state to awake
|
||||
* @fn void awakeGod();
|
||||
*/
|
||||
void awakeGod();
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @return
|
||||
* @fn
|
||||
* @brief make god behave
|
||||
* @return true if theres no invader left, false elsewise
|
||||
* @fn bool manageGod();
|
||||
*/
|
||||
bool manageGod();
|
||||
|
||||
@ -240,28 +240,37 @@ public:
|
||||
// in case someone wants to mess with the code, here's a minimal API, costs nothing to us
|
||||
|
||||
/*!
|
||||
*
|
||||
* @brief constructor for the game class
|
||||
* @fn Game();
|
||||
*/
|
||||
Game();
|
||||
|
||||
/*!
|
||||
*
|
||||
* @brief manages and changes the states of the game
|
||||
* @fn void managedGames();
|
||||
*/
|
||||
void managedGames();
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @return
|
||||
* @fn
|
||||
* @brief enter the main gameplay game loop
|
||||
* @return the value of the winners can be the players, the invaders or god
|
||||
* @fn WinValue enterGameLoop();
|
||||
*/
|
||||
WinValue enterGameLoop();
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @return
|
||||
* @fn
|
||||
* @brief reload the configuration file for a new game
|
||||
* @return false if an error occured, true elsewise
|
||||
* @fn bool reloadConfig();
|
||||
*/
|
||||
bool reloadConfig();
|
||||
|
||||
/*!
|
||||
* @brief tells if all players are dead
|
||||
* @return true if all player are dead, false otherwise
|
||||
* @fn bool arePlayersDead();
|
||||
*/
|
||||
bool arePlayersDead();
|
||||
};
|
||||
|
||||
#endif
|
@ -6,6 +6,9 @@
|
||||
* @version 1.0
|
||||
* @brief Special entity known as "God"
|
||||
*
|
||||
* Well, i (Djalim) discovered that Thomas put God in the game
|
||||
* I didnt think it was a good idea but no man can stop Thomas
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GUARD_GOD_H
|
||||
@ -15,7 +18,7 @@
|
||||
#include "invadersGrid.h"
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @brief list of all known god states
|
||||
*/
|
||||
enum class GodState{
|
||||
NONE,
|
||||
@ -40,18 +43,18 @@ enum class GodState{
|
||||
|
||||
/*!
|
||||
* @class God
|
||||
* @brief
|
||||
* @brief stores all God's data
|
||||
*/
|
||||
class God{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @brief god's current state
|
||||
*/
|
||||
GodState state;
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @brief manage all sorts of things, gods secrets remains unknown
|
||||
*/
|
||||
unsigned counter;
|
||||
|
||||
@ -59,34 +62,34 @@ public:
|
||||
// we do not use a Position because it is used for pixel X and Y
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @brief x pixel coordinate of the invader thrown by the hand of god
|
||||
*/
|
||||
unsigned thrownInvPosX;
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @brief y pixel coordinate of the invader thrown by the hand of god
|
||||
*/
|
||||
unsigned thrownInvPosY;
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @brief type of the invader thrown by the hand of god
|
||||
*/
|
||||
InvaderType thrownInvType;
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @brief direction of the thrown invader movement
|
||||
*/
|
||||
Position thrownVector;
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @brief position of a point for bezier's curve
|
||||
*/
|
||||
Position thrownTransition;
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* @param[in] screenWidth :
|
||||
* @return
|
||||
* @brief give initial the pixel coordinates of god's right hand
|
||||
* @param[in] screenWidth : width of the screen in pixel
|
||||
* @return pixel coordinates of the hand
|
||||
* @fn Position getRightHandPos(unsigned screenWidth) const;
|
||||
*/
|
||||
Position getRightHandPos(unsigned screenWidth) const;
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
* @return
|
||||
* @fn
|
||||
*/
|
||||
unsigned randomValid() const;
|
||||
unsigned randomValidInv() const;
|
||||
}; // class InvadersColumn
|
||||
|
||||
|
||||
|
@ -18,17 +18,62 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*!
|
||||
* @struct ScoreLink
|
||||
* @brief Makes a link between a player username and their score
|
||||
*/
|
||||
struct ScoreLink{
|
||||
|
||||
/*!
|
||||
* @brief player username
|
||||
*/
|
||||
string name;
|
||||
|
||||
/*!
|
||||
* @brief player score
|
||||
*/
|
||||
unsigned score;
|
||||
|
||||
/*!
|
||||
* @brief constructor of the struct
|
||||
* @param[in] name : player username
|
||||
* @param[in] score : player score
|
||||
* @fn ScoreLink(string name, unsigned score);
|
||||
*/
|
||||
ScoreLink(string name, unsigned score);
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* @class ScoresManager
|
||||
* @brief manage the score in the game and inside the score file
|
||||
*/
|
||||
class ScoresManager {
|
||||
public:
|
||||
|
||||
/*!
|
||||
* @brief list of pairs of player names and their score
|
||||
*/
|
||||
vector<ScoreLink> scores;
|
||||
|
||||
/*!
|
||||
* @brief add player name and their score in the list of scores
|
||||
* @param[in] name : player name
|
||||
* @param[in] score : player score
|
||||
* @fn void inputScore(string name, unsigned score);
|
||||
*/
|
||||
void inputScore(string name, unsigned score);
|
||||
|
||||
/*!
|
||||
* @brief read the score file and put all of its data inside the list of score
|
||||
* @fn void readFile();
|
||||
*/
|
||||
void readFile();
|
||||
|
||||
/*!
|
||||
* @brief write the score list into the score file
|
||||
* @fn void writeFile() const;
|
||||
*/
|
||||
void writeFile() const;
|
||||
};
|
||||
|
||||
|
@ -1,3 +1,13 @@
|
||||
/*!
|
||||
*
|
||||
* @file utils.h
|
||||
* @author RUBINI Thomas
|
||||
* @date January 2022
|
||||
* @version 1.0
|
||||
* @brief utilies for the game
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GUARD_UTILS_H
|
||||
#define GUARD_UTILS_H
|
||||
|
||||
@ -28,11 +38,14 @@
|
||||
using namespace std;
|
||||
using nsGraphics::RGBAcolor;
|
||||
|
||||
|
||||
/*!
|
||||
* @brief list of win values
|
||||
*/
|
||||
enum class WinValue{
|
||||
NOBODY, // should never be used
|
||||
PLAYERS,
|
||||
INVADERS,
|
||||
GOD,
|
||||
};
|
||||
|
||||
|
||||
@ -42,9 +55,25 @@ typedef unsigned playerID;
|
||||
#define PLAYER2 1
|
||||
|
||||
// didn't want to use Position because of the semantic with x and y
|
||||
|
||||
/*!
|
||||
* @brief tells if 2 lines are colliding in a 1 dimentionnal space
|
||||
* @param[in] start1 : position of the first point of the first line
|
||||
* @param[in] end1: posision of the last point of the first line
|
||||
* @param[in] start2 : position of the first point of the seconde line
|
||||
* @param[in] end2: posision of the last point of the second line
|
||||
* @return true if they are
|
||||
olliding, false elsewise */
|
||||
bool areLinesColliding(unsigned start1, unsigned end1, unsigned start2, unsigned end2);
|
||||
|
||||
// change draw position for a specified size (keeps the same center)
|
||||
|
||||
/*!
|
||||
* @brief change the size of a Position object
|
||||
* @param[in,out] pos : Position object
|
||||
* @param[in] sizeFrom: current size of the objet
|
||||
* @param[in] sizeTo : new size of the object
|
||||
*/
|
||||
void applyTransformation(Position& pos, unsigned sizeFrom, unsigned sizeTo);
|
||||
|
||||
#endif
|
@ -11,33 +11,9 @@
|
||||
|
||||
#include <fstream>
|
||||
#include "game.h"
|
||||
#include "configManagement.h"
|
||||
#include "errors.h"
|
||||
|
||||
// you will MOVE THIS OUT OF THIS FILE
|
||||
|
||||
class ConfigBuilder{
|
||||
public:
|
||||
ConfigData collectedData;
|
||||
void parseFile(const string& fname);
|
||||
void readConfig();
|
||||
void dumpInternalValues() const;
|
||||
private:
|
||||
map<string, string> internalValues;
|
||||
const string& getString(const configKey& key) const;
|
||||
char getChar(const configKey& key) const;
|
||||
int getInt(const configKey& key) const;
|
||||
void getColor(const configKey& key, nsGraphics::RGBAcolor&) const;
|
||||
void getList(const configKey& key, vector<string>&) const;
|
||||
|
||||
void readGrid(const configKey& baseKey);
|
||||
void readPlayer(const configKey& baseKey, PlayerDef&);
|
||||
void readInvaderType(const configKey& baseKey, InvaderTypeDef&);
|
||||
};
|
||||
|
||||
void ConfigBuilder::dumpInternalValues() const {
|
||||
for(const auto& ite : internalValues){
|
||||
cerr << ite.first << " -> " << ite.second << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void trimSpaces(string& str){
|
||||
str.erase(0, str.find_first_not_of(' '));
|
||||
@ -56,12 +32,12 @@ void sanitizeValue(string& val) {
|
||||
|
||||
/*
|
||||
* WARNING : This implementation of YAML is not meant to be complete, but to work with our specific needs
|
||||
* It also can't detect and report errors in a non YAML-compliant file
|
||||
* It also can't detect and report errors in a non-YAML-compliant file
|
||||
*/
|
||||
|
||||
void ConfigBuilder::parseFile(const string& fname) {
|
||||
ifstream file(fname);
|
||||
if(!file.is_open())throw runtime_error("Error while opening config.yml. Check file location ?");
|
||||
if(!file.is_open())throw config_error("Error while opening config.yml. Check file location ?");
|
||||
|
||||
vector<string> keyParts;
|
||||
unsigned listIndex;
|
||||
@ -91,7 +67,7 @@ void ConfigBuilder::parseFile(const string& fname) {
|
||||
|
||||
}else{
|
||||
match = line.find(':');
|
||||
if (match == string::npos)throw runtime_error("Invalid line : " + line);
|
||||
if (match == string::npos)throw config_error("Invalid line : " + line);
|
||||
string key = line.substr(0, match);
|
||||
string value = line.substr(match + 1);
|
||||
trimSpaces(key);
|
||||
@ -148,7 +124,7 @@ void ConfigBuilder::readGrid(const configKey& baseKey) {
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
throw runtime_error("Invalid invader ID in grid definition : "+ to_string(s[i]));
|
||||
throw config_error("Invalid invader ID in grid definition : "+ to_string(s[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,26 +188,60 @@ void ConfigBuilder::readConfig() {
|
||||
getColor("projectiles.torpedos.color", collectedData.torpedosColor);
|
||||
}
|
||||
|
||||
int ConfigBuilder::getInt(const configKey& key) const {
|
||||
return stoi(getString(key));
|
||||
}
|
||||
|
||||
char ConfigBuilder::getChar(const configKey& key) const {
|
||||
return getString(key)[0];
|
||||
const string& ConfigBuilder::getString(const configKey& key, const string& def) const {
|
||||
try{
|
||||
return getString(key);
|
||||
}catch(config_error& e){
|
||||
cerr << e.what() << endl;
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
const string& ConfigBuilder::getString(const configKey& key) const {
|
||||
if(internalValues.contains(key)){
|
||||
return internalValues.at(key);
|
||||
}else{
|
||||
throw runtime_error("Non-existent key requested : "+key);
|
||||
throw config_error("Non-existent key requested : "+key);
|
||||
}
|
||||
}
|
||||
|
||||
int ConfigBuilder::getInt(const configKey& key) const {
|
||||
try{
|
||||
return stoi(getString(key));
|
||||
}catch(invalid_argument& e){
|
||||
cerr << e.what() << endl;
|
||||
throw config_error("Invalid int data for key "+key+" : |"+getString(key)+"|");
|
||||
}
|
||||
}
|
||||
|
||||
int ConfigBuilder::getInt(const configKey& key, int def) const {
|
||||
try{
|
||||
return getInt(key);
|
||||
}catch(config_error& e){
|
||||
cerr << e.what() << endl;
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
char ConfigBuilder::getChar(const configKey& key) const {
|
||||
string s = getString(key);
|
||||
if(s.size()!=1)throw config_error("Invalid char data for key "+key+" : |"+s+"|");
|
||||
return s[0];
|
||||
}
|
||||
|
||||
char ConfigBuilder::getChar(const configKey& key, char def) const {
|
||||
try{
|
||||
return getChar(key);
|
||||
}catch(config_error& e){
|
||||
cerr << e.what() << endl;
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigBuilder::getList(const configKey& key, vector<string>& toPopulate) const {
|
||||
size_t i=0;
|
||||
string fullKey = key+".0";
|
||||
if(!internalValues.contains(fullKey))throw runtime_error("Non-existent list key requested : "+key);
|
||||
if(!internalValues.contains(fullKey))throw config_error("Non-existent list key requested : "+key);
|
||||
|
||||
do{
|
||||
toPopulate.push_back(internalValues.at(fullKey));
|
||||
@ -259,14 +269,10 @@ void ConfigBuilder::getColor(const configKey& key, nsGraphics::RGBAcolor& color)
|
||||
else if (colorStr == "purple")color = nsGraphics::KPurple;
|
||||
else if (colorStr == "teal")color = nsGraphics::KTeal;
|
||||
else if (colorStr == "navy")color = nsGraphics::KNavy;
|
||||
else throw runtime_error("Invalid color string : "+colorStr);
|
||||
else throw config_error("Invalid color string : "+colorStr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return false if there was an error
|
||||
*/
|
||||
bool Game::reloadConfig() {
|
||||
map<string, string> strValues;
|
||||
ConfigBuilder builder;
|
||||
@ -275,7 +281,7 @@ bool Game::reloadConfig() {
|
||||
builder.parseFile("config.yml");
|
||||
parsed = true;
|
||||
builder.readConfig();
|
||||
}catch(runtime_error& e){
|
||||
}catch(config_error& e){
|
||||
if(parsed)cerr << "An error occured while reading the configuration :" << endl;
|
||||
else cerr << "An error occured while parsing the configuration :" << endl;
|
||||
cerr << e.what() << endl;
|
||||
|
5
src/errors.cpp
Normal file
5
src/errors.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "errors.h"
|
||||
|
||||
config_error::config_error(const string& msg) : runtime_error(msg) {
|
||||
|
||||
}
|
@ -60,7 +60,6 @@ void Game::managedGames() {
|
||||
// we assume the game has been played before, and so we need to clean used members
|
||||
void Game::initGame(){
|
||||
grid = confData.grid; // will copy the grid
|
||||
updateColumns(); // Would have liked to to that in the "config grid", but.. I'm lazy
|
||||
|
||||
// we re-construct players objects, we don't have to clear all members and can rely on the construction value (set in .h file)
|
||||
players.clear();
|
||||
@ -114,16 +113,19 @@ WinValue Game::enterGameLoop(){ // returns when game is finished
|
||||
}
|
||||
}
|
||||
|
||||
manageGod();
|
||||
if(manageGod())return WinValue::PLAYERS;
|
||||
if(arePlayersDead())return WinValue::GOD;
|
||||
|
||||
moveMissiles();
|
||||
remCollidingProjectiles();
|
||||
moveTorpedos();
|
||||
remCollidingProjectiles();
|
||||
|
||||
if(checkMissilesAndPlayers())return WinValue::INVADERS;
|
||||
checkMissilesAndPlayers();
|
||||
if(checkTorpedosAndInvaders())return WinValue::PLAYERS;
|
||||
|
||||
if(arePlayersDead())return WinValue::INVADERS;
|
||||
|
||||
displayAll(fps);
|
||||
|
||||
pm.endFrame();
|
||||
@ -146,3 +148,10 @@ WinValue Game::enterGameLoop(){ // returns when game is finished
|
||||
Position Game::invIndexToPos(unsigned x, unsigned y) const {
|
||||
return basePos+Position(INV_GET_POS(x), INV_GET_POS(y));
|
||||
}
|
||||
|
||||
bool Game::arePlayersDead() {
|
||||
for(Player& p : players){
|
||||
if(!p.isEliminated())return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -48,10 +48,6 @@ void Game::managePlayers(){
|
||||
for(unsigned i=0;i<players.size();++i)manageOnePlayer(i);
|
||||
}
|
||||
|
||||
/** Makes the invaders play once, and check lower bounds
|
||||
*
|
||||
* @return true if the invaders went down from one line (and we should check lower boundary), else false
|
||||
*/
|
||||
bool Game::manageInvaders(){
|
||||
if(grid.empty())return false; // If there are no more invaders we don't need to manage them
|
||||
// shoot
|
||||
@ -94,10 +90,6 @@ bool Game::manageInvaders(){
|
||||
|
||||
}
|
||||
|
||||
/** makes projectiles move, and manage collisions between them and everything
|
||||
*
|
||||
* @return 1 if the invaders are all dead, 2 if the player is dead, else 0
|
||||
*/
|
||||
void Game::remCollidingProjectiles(){
|
||||
|
||||
auto miss = missiles.begin();
|
||||
@ -150,7 +142,7 @@ void Game::moveTorpedos() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Game::checkMissilesAndPlayers() {
|
||||
void Game::checkMissilesAndPlayers() {
|
||||
auto miss_ite = missiles.begin();
|
||||
while(miss_ite!=missiles.end()){
|
||||
bool wasColliding = false;
|
||||
@ -171,7 +163,6 @@ bool Game::checkMissilesAndPlayers() {
|
||||
if(wasColliding)missiles.erase(miss_ite);
|
||||
else ++miss_ite;
|
||||
}
|
||||
return false; // TODO manage death animation
|
||||
}
|
||||
|
||||
bool Game::checkTorpedosAndInvaders() {
|
||||
@ -202,7 +193,7 @@ bool Game::checkTorpedosAndInvaders() {
|
||||
|
||||
grid[i][alienIndex] = InvaderType::NONE;
|
||||
|
||||
if(updateColumns()) return true;
|
||||
if(!areThereInvadersLeft()) return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,11 @@ void Game::awakeGod() {
|
||||
/**
|
||||
* @returns true if we can finish the game
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a really long function, but I feel like it's still readable because of the switch, and..
|
||||
* Honestly I think splitting it into multiple small functions would be ugly
|
||||
*/
|
||||
bool Game::manageGod() {
|
||||
switch (god.state) {
|
||||
case GodState::NONE: {
|
||||
@ -35,19 +40,18 @@ bool Game::manageGod() {
|
||||
++god.counter;
|
||||
return false;
|
||||
}
|
||||
if (areThereInvadersLeft()) {
|
||||
|
||||
// init throw
|
||||
god.counter = 0;
|
||||
god.state = GodState::RETRIEVE1;
|
||||
god.thrownInvPosX = grid.randomValidCol();
|
||||
god.thrownInvPosY = grid[god.thrownInvPosX].randomValid();
|
||||
god.thrownInvPosY = grid[god.thrownInvPosX].randomValidInv();
|
||||
god.thrownInvType = InvaderType::NONE;
|
||||
|
||||
god.thrownTransition.setX(pm.getScreenWidth() - GOD_HAND_DISTANCE - GOD_HAND_SIZE);
|
||||
god.thrownTransition.setY(basePos.getY() + INV_GET_POS(god.thrownInvPosY));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case GodState::RETRIEVE1: {
|
||||
if (god.counter < 100) {
|
||||
god.counter += 2;
|
||||
@ -132,14 +136,19 @@ bool Game::manageGod() {
|
||||
* we do not need to reset other members, they'll be treated as non-initialized
|
||||
* When we cycle back between states
|
||||
*/
|
||||
return false;
|
||||
|
||||
|
||||
// We could have optimized that, but it's more readable like this and hopefully the compiler will optimize it itself
|
||||
if(areThereInvadersLeft())return false;
|
||||
else return true;
|
||||
}
|
||||
case GodState::YOLO: {
|
||||
|
||||
}
|
||||
}
|
||||
throw runtime_error("SHOULD NOT HAPPEN : invalid action for god : ID="+ to_string(static_cast<int>(god.state)));
|
||||
}
|
||||
|
||||
Position God::getRightHandPos(unsigned screenWidth) const {
|
||||
return Position(screenWidth - GOD_HAND_DISTANCE - GOD_HAND_SIZE, 0);
|
||||
return {screenWidth - GOD_HAND_DISTANCE - GOD_HAND_SIZE, 0};
|
||||
}
|
@ -27,7 +27,7 @@ unsigned InvadersColumn::getOutterInvader() const {
|
||||
|
||||
// these are used to invoke rand() as less as possible
|
||||
|
||||
unsigned InvadersColumn::randomValid() const {
|
||||
unsigned InvadersColumn::randomValidInv() const {
|
||||
|
||||
|
||||
unsigned validTotal = 0;
|
||||
|
@ -1,6 +1,3 @@
|
||||
|
||||
#include <utils.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
bool areLinesColliding(unsigned start1, unsigned end1, unsigned start2, unsigned end2){
|
||||
|
Loading…
Reference in New Issue
Block a user