we now have custom grid in config
This commit is contained in:
		
							parent
							
								
									b6574df3e3
								
							
						
					
					
						commit
						51866120f2
					
				
							
								
								
									
										7
									
								
								QUESTIONS.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								QUESTIONS.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| Questions que je (Thomas Rubini) voudrait poser au prof | ||||
| c'est un fichier perso, après si vous voulez ajouter des trucs allez-y | ||||
| 
 | ||||
| - Est-ce que vous préférez l'implémentation orienté objet ou orienté macro pour lire la config ? | ||||
| - Est-ce que vouloir faire des structures optimisées (pas de redondance de mémoire) est une bonne chose, ou osef ? | ||||
| - 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, osef, ou contre-productif ? | ||||
| - Est-ce que mon implémentation du réseau est bone ? | ||||
| @ -38,4 +38,9 @@ projectiles: | ||||
| points: | ||||
|  invader3: 100 | ||||
|  invader2: 250 | ||||
|  invader1: 600 | ||||
|  invader1: 600 | ||||
| 
 | ||||
| grid: | ||||
|  - AAAAAAAAAA | ||||
|  - BBBB BBBBB | ||||
|  - CCCCCCCCCC | ||||
| @ -17,9 +17,10 @@ enum class WinValue{ | ||||
| using namespace std; | ||||
| 
 | ||||
| enum class Invader { | ||||
| 	TypeA, | ||||
| 	TypeB, | ||||
| 	TypeC, | ||||
| 	TYPEA, | ||||
| 	TYPEB, | ||||
| 	TYPEC, | ||||
| 	NONE, | ||||
| }; | ||||
| typedef vector<Invader> InvadersColumn; | ||||
| typedef vector<InvadersColumn> InvadersGrid; | ||||
|  | ||||
| @ -13,7 +13,7 @@ private: | ||||
| 	char getChar(const configKey& key); | ||||
| 	int getInt(const configKey& key); | ||||
| 	nsGraphics::RGBAcolor getColor(const configKey& key); | ||||
| 
 | ||||
| 	void getList(const configKey& key, vector<string>&); | ||||
| }; | ||||
| 
 | ||||
| void ConfigBuilder::dumpInternalValues(){ | ||||
| @ -26,11 +26,16 @@ void trimSpaces(string& str){ | ||||
| 	str.erase(0, str.find_first_not_of(' ')); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * WARNING : This implementation of YAML is not meant to 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 ?"); | ||||
| 
 | ||||
| 	vector<string> keyParts; | ||||
| 	unsigned listIndex; | ||||
| 	while (!file.eof()) { | ||||
| 		string line; | ||||
| 		getline(file, line); | ||||
| @ -41,23 +46,40 @@ void ConfigBuilder::parseFile(const string& fname) { | ||||
| 		unsigned currentIndent = 0; | ||||
| 		while (line[currentIndent] == ' ')++currentIndent; | ||||
| 
 | ||||
| 		match = line.find(':'); | ||||
| 		if (match == string::npos)throw runtime_error("Invalid line : " + line); | ||||
| 		string key = line.substr(0, match); | ||||
| 		string value = line.substr(match + 1); | ||||
| 		trimSpaces(key); | ||||
| 		trimSpaces(value); | ||||
| 		if (value.empty()) { | ||||
| 			keyParts.resize(currentIndent); | ||||
| 			keyParts.push_back(key); | ||||
| 		} else { | ||||
| 		if(line[currentIndent]=='-'){ | ||||
| 			string value = line.substr(currentIndent+1); | ||||
| 			trimSpaces(value); | ||||
| 
 | ||||
| 			string fullKey; | ||||
| 			for (unsigned i = 0; i < currentIndent; ++i) { | ||||
| 				fullKey.append(keyParts[i]); | ||||
| 				fullKey.append("."); | ||||
| 			} | ||||
| 			fullKey.append(key); | ||||
| 			// lists are just treated as sections with key 0,1,2...
 | ||||
| 			fullKey.append(to_string((listIndex))); | ||||
| 			++listIndex; | ||||
| 			internalValues[fullKey] = value; | ||||
| 
 | ||||
| 		}else{ | ||||
| 			match = line.find(':'); | ||||
| 			if (match == string::npos)throw runtime_error("Invalid line : " + line); | ||||
| 			string key = line.substr(0, match); | ||||
| 			string value = line.substr(match + 1); | ||||
| 			trimSpaces(key); | ||||
| 			trimSpaces(value); | ||||
| 			if (value.empty()) { | ||||
| 				keyParts.resize(currentIndent); | ||||
| 				keyParts.push_back(key); | ||||
| 				listIndex = 0; | ||||
| 			} else { | ||||
| 				string fullKey; | ||||
| 				for (unsigned i = 0; i < currentIndent; ++i) { | ||||
| 					fullKey.append(keyParts[i]); | ||||
| 					fullKey.append("."); | ||||
| 				} | ||||
| 				fullKey.append(key); | ||||
| 				internalValues[fullKey] = value; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| @ -65,12 +87,47 @@ void ConfigBuilder::parseFile(const string& fname) { | ||||
| } | ||||
| 
 | ||||
| void ConfigBuilder::readConfig() { | ||||
| 	// TODO PUT THAT IN CONFIG ??
 | ||||
| #define S 48 | ||||
| 	collectedData.grid.resize(S); | ||||
| 	for(unsigned i=0;i<S;++i){ | ||||
| 		collectedData.grid[i].resize(3); | ||||
| 		for(unsigned j=0;j<3;++j)collectedData.grid[i][j] = static_cast<Invader>(j); | ||||
| 
 | ||||
| 	vector<string> tmp; | ||||
| 	getList("grid", tmp); | ||||
| 
 | ||||
| 	// we are essentially going to translate a line-oriented config to a column-oriented grid
 | ||||
| 
 | ||||
| 	unsigned maxSize = 0; | ||||
| 	for(string& s : tmp){ | ||||
| 		if(s.size()>maxSize)maxSize = s.size(); | ||||
| 	} | ||||
| 	collectedData.grid.resize(maxSize); | ||||
| 
 | ||||
| 	for(string& s : tmp){ | ||||
| 		unsigned i=0; | ||||
| 		for(;i<s.size();++i){ | ||||
| 			switch(toupper(s[i])){ | ||||
| 				case 'A':{ | ||||
| 					collectedData.grid[i].push_back(Invader::TYPEA); | ||||
| 					break; | ||||
| 				} | ||||
| 				case 'B':{ | ||||
| 					collectedData.grid[i].push_back(Invader::TYPEB); | ||||
| 					break; | ||||
| 				} | ||||
| 				case 'C':{ | ||||
| 					collectedData.grid[i].push_back(Invader::TYPEC); | ||||
| 					break; | ||||
| 				} | ||||
| 				case ' ':{ | ||||
| 					collectedData.grid[i].push_back(Invader::NONE); | ||||
| 					break; | ||||
| 				} | ||||
| 				default:{ | ||||
| 					throw runtime_error("Invalid invader ID in grid definition : "+ to_string(s[i])); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		while(i<maxSize){ | ||||
| 			collectedData.grid[i].push_back(Invader::NONE); | ||||
| 			++i; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// players
 | ||||
| @ -126,6 +183,18 @@ string& ConfigBuilder::getString(const configKey& key) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void ConfigBuilder::getList(const configKey& key, vector<string>& toPopulate) { | ||||
| 	size_t i=0; | ||||
| 	string fullKey = key+".0"; | ||||
| 	if(!internalValues.contains(fullKey))throw runtime_error("Non-existent list key requested : "+key); | ||||
| 
 | ||||
| 	do{ | ||||
| 		toPopulate.push_back(internalValues.at(fullKey)); | ||||
| 		++i; | ||||
| 		fullKey = key+"."+to_string(i); | ||||
| 	}while(internalValues.contains(key+"."+to_string(i))); | ||||
| } | ||||
| 
 | ||||
| nsGraphics::RGBAcolor ConfigBuilder::getColor(const configKey& key) { | ||||
| 	// switch do not work with strings, and I don't want to implement a constexpr hash function
 | ||||
| 	string colorStr = getString(key); | ||||
|  | ||||
| @ -119,15 +119,15 @@ void Game::display() { | ||||
| 					basePos.getY() + j * confData.invadersSize + j * confData.invadersDistance | ||||
| 			); | ||||
| 			switch(grid[i][j]){ | ||||
| 				case Invader::TypeA:{ | ||||
| 				case Invader::TYPEA:{ | ||||
| 					pm.drawInvader1(vec, confData.invadersSize); | ||||
| 					break; | ||||
| 				} | ||||
| 				case Invader::TypeB:{ | ||||
| 				case Invader::TYPEB:{ | ||||
| 					pm.drawInvader2(vec, confData.invadersSize); | ||||
| 					break; | ||||
| 				} | ||||
| 				case Invader::TypeC:{ | ||||
| 				case Invader::TYPEC:{ | ||||
| 					pm.drawInvader3(vec, confData.invadersSize); | ||||
| 					break; | ||||
| 				} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user