Browse Source

Commit invaders version 4.5

Enrico Guiraud 7 months ago
commit
187efd0af2
51 changed files with 4895 additions and 0 deletions
  1. 67 0
      README.txt
  2. 1 0
      args.tmp
  3. 5 0
      big_alienboss.dat
  4. 5 0
      big_alienboss.dat.old
  5. 1 0
      body.cpp
  6. 16 0
      body.hpp
  7. 68 0
      boss.cpp
  8. 29 0
      boss.hpp
  9. 341 0
      bossrush.cpp
  10. 300 0
      box.cpp
  11. 40 0
      box.hpp
  12. 17 0
      bullet.cpp
  13. 19 0
      bullet.hpp
  14. 115 0
      checkboss.sh
  15. 1 0
      dati.dat
  16. 94 0
      definitions.hpp
  17. 77 0
      definitions.hpp.bu
  18. 38 0
      enemy.cpp
  19. 23 0
      enemy.hpp
  20. 2020 0
      functions.cpp
  21. 129 0
      functions.hpp
  22. 9 0
      game_object.cpp
  23. 14 0
      game_object.hpp
  24. 344 0
      invaders.cpp
  25. 324 0
      invaders_fork.cpp
  26. 10 0
      latest.dat
  27. 6 0
      maderna.dat
  28. 6 0
      maero.dat
  29. 91 0
      makefile
  30. 8 0
      myboss.dat.old
  31. 44 0
      notes.dat
  32. 12 0
      objectsIDs.txt
  33. 0 0
      palombo
  34. 5 0
      palombo.dat
  35. 5 0
      palombo.dat.old
  36. 58 0
      pic.cpp
  37. 25 0
      pic.hpp
  38. 213 0
      player.cpp
  39. 29 0
      player.hpp
  40. 5 0
      powerup.cpp
  41. 12 0
      powerup.hpp
  42. 45 0
      records.dat
  43. 2 0
      records_bossrush.dat
  44. 18 0
      rocket.cpp
  45. 19 0
      rocket.hpp
  46. 66 0
      setboss.sh
  47. 43 0
      setsize.sh
  48. 6 0
      spoletini.dat
  49. 6 0
      spoletini.dat.old
  50. 44 0
      wall.cpp
  51. 20 0
      wall.hpp

File diff suppressed because it is too large
+ 67 - 0
README.txt


+ 1 - 0
args.tmp

@@ -0,0 +1 @@
+palombo.dat

+ 5 - 0
big_alienboss.dat

@@ -0,0 +1,5 @@
+ \__ ______ __/  
+\___  =  =  ___/ 
+ |  | =  = |  |  
+     \_  _/      
+    /  ||  \     

+ 5 - 0
big_alienboss.dat.old

@@ -0,0 +1,5 @@
+ \__ ______ __/  
+\___  =  =  ___/ 
+ |  | =  = |  |  
+     \_  _/      
+    /  ||  \     

+ 1 - 0
body.cpp

@@ -0,0 +1 @@
+#include "body.hpp"

+ 16 - 0
body.hpp

@@ -0,0 +1,16 @@
+#ifndef _body_hpp
+#define _body_hpp
+
+#include "definitions.hpp"
+
+
+class body
+{
+	public:
+	body(){ width=0; height=0; }
+	body(int w, int h) { width=w; height=h; }
+	int width, height;
+};
+
+
+#endif

+ 68 - 0
boss.cpp

@@ -0,0 +1,68 @@
+#include "boss.hpp"
+
+boss::boss(int x, int y, int life, int w, int h, std::string newname) : enemy(x,y), pic(w,h) 
+{
+	name = newname;
+	health=life;
+	healthmax=life;
+	id=16;
+	alive=false;
+}
+
+void boss::next_pos()
+{
+	if((x==0 && direction==1) || (x==C-width-1 && direction==0))
+		direction=2;
+	
+	switch(direction){
+		case 0:
+			x++;
+			break;
+		case 1:
+			x--;
+			break;
+		case 2:
+			y++;
+			if(x==0)
+				direction=0;
+			else direction=1;
+			break;
+	}
+}
+
+void boss::set_life(int life){
+	health=life;
+	healthmax=life;
+}
+
+
+void boss::shoot(std::list<bullet> & bullets){	      //random bomb-dropping	
+	for(std::list<bullet>::reverse_iterator it=bullets.rbegin(); it!=bullets.rend(); ++it)
+		if((it->x==x+width/3 || it->x==x+2*width/3) && it->y==y+height)
+			return;
+	bullet new_bomb(x+width/3,y+height,8);
+	bullets.push_back(new_bomb);
+	bullet new_bomb2(x+2*width/3,y+height,8);
+	bullets.push_back(new_bomb2);
+}
+
+boss& boss::operator=(boss& otherboss)
+{
+	x=otherboss.x;
+	y=otherboss.y;
+	health=otherboss.health;
+	healthmax=otherboss.health;
+	width=otherboss.width;
+	height=otherboss.height;
+	name=otherboss.name;
+	
+	picture = new char* [otherboss.height];
+	for(int i=0; i<height; ++i)
+		picture[i] = new char[otherboss.width];
+	
+	for(int i=0;i<height;i++)
+		for(int j=0;j<width;j++)
+			picture[i][j] = otherboss.picture[i][j];
+				
+	return *this;		//just to get rid of the compiler warning 
+}

+ 29 - 0
boss.hpp

@@ -0,0 +1,29 @@
+#ifndef _boss_hpp
+#define _boss_hpp
+
+#include "enemy.hpp"
+#include "pic.hpp"
+#include <cstring>
+
+typedef std::list<bullet> b_list;
+
+class boss: public enemy, public pic
+{
+	public:
+	boss() { id=16; alive=false; }
+	
+	boss(int x, int y, int life, int w, int h, std::string newname); //id is automatically set to 16, alive set to FALSE
+	
+	void next_pos();
+	//inheriting direction from enemy
+	int health,healthmax;
+	std::string name;
+	void set_life(int);
+
+	void shoot(std::list<bullet> & bullets);
+	
+	boss& operator=(boss&);
+	
+};
+
+#endif

+ 341 - 0
bossrush.cpp

@@ -0,0 +1,341 @@
+#include "definitions.hpp"
+#include "rocket.hpp"
+#include "enemy.hpp"
+#include "player.hpp"
+#include "boss.hpp"
+#include "powerup.hpp"
+#include "functions.hpp"
+#include "wall.hpp"
+#include <mutex>
+#include <thread>
+
+std::mutex m_player;
+std::mutex m_enemies;
+std::mutex m_bombs;
+std::mutex m_bullets;
+std::mutex m_rockets;
+std::mutex m_pow;
+std::mutex m_boss;
+std::mutex m_walls;
+
+using std::cout;
+using std::endl; 
+using std::min;
+using std::max;
+
+int main(int argc,char** argv)
+{
+
+	if(argc>1){
+		if(strcmp(argv[1],"--uber-debug")!=0 && strcmp(argv[1],"--info")!=0){
+			cout<<"Usage: "<<argv[0]<<" [--info]"<<endl;
+			return 1;
+		}
+	
+		if(strcmp(argv[1],"--info")==0){
+			cout<<endl<<"Curses Invaders 4.4 - Bossrush"<<endl;
+			cout<<endl<<"Game developed by Giacomo Parolini (jp) and Enrico Guiraud (blue) in years 2010-2013."<<endl;
+			cout<<"Source code is available under request to jp@lcm.mi.infn.it (it's quite ugly, I warn you ;-) )"<<endl;
+			cout<<"Report any bug to the same mail address."<<endl<<endl;
+			return 1;
+		}
+	}
+
+	typedef std::list<bullet> b_list;
+  	typedef std::vector<wall> w_vec;
+  	typedef std::list<rocket> r_list;
+	
+	srand(time(NULL));
+	
+	//OBJECTS INIZIALIZATION
+
+	player player1;						//player is automatically created in [C/2][R]
+	boss bosses[5];						//vector of bosses
+	b_list bullets;                				//list of player's bullets
+	b_list bombs;						//list of enemies' bombs
+	b_list powerups;					//list of powerups
+	r_list rockets;						//list of rockets
+	boss boss1;
+	std::list<enemy> enemies;
+	int refresh_time=100;          				//how long the program waits before refreshing the screen
+	int chflag=0;						//cheat flag: 0=normal, 1=cheats allowed.
+	int num=0;
+	int commands[CMD_NUM]={'a','d','w','s','p',' ','l','m','q'};
+	
+	WINDOW *Score,*BossHP;
+	
+	//PARAMETERS/UTILITIES
+	double shootrate;				  	//probability of an enemy shooting a bomb 
+	int command;						//keyboard input
+	int score=0;					   	//score: gain +100 when an enemy is destroyed and +50 when a bomb is destroyed
+	char level='1';						//difficulty level
+	
+	create_std_bosses();
+	std::string bossname1=getenv("HOME");
+	bossname1=bossname1+RECORD_DIR+BOSS_FILE1+".dat";
+	boss newboss1(1,1,100,9,6,BOSS_FILE1);	
+	newboss1.loadpicture(bossname1.c_str());	
+	std::string bossname2=getenv("HOME");
+	bossname2=bossname2+RECORD_DIR+BOSS_FILE2+".dat";
+	boss newboss2(1,1,200,11,5,BOSS_FILE2);
+	newboss2.loadpicture(bossname2.c_str());
+	std::string bossname3=getenv("HOME");
+	bossname3=bossname3+RECORD_DIR+BOSS_FILE3+".dat";
+	boss newboss3(1,1,300,9,6,BOSS_FILE3);
+	newboss3.loadpicture(bossname3.c_str());
+	std::string bossname4=getenv("HOME");
+	bossname4=bossname4+RECORD_DIR+BOSS_FILE4+".dat";
+	boss newboss4(1,1,400,11,6,BOSS_FILE4);
+	newboss4.loadpicture(bossname4.c_str());
+	std::string bossname5=getenv("HOME");
+	bossname5=bossname5+RECORD_DIR+BOSS_FILE5+".dat";
+	boss newboss5(1,1,500,17,5,BOSS_FILE5);
+	newboss5.loadpicture(bossname5.c_str());
+	
+	bosses[0]=newboss1;
+	bosses[1]=newboss2;
+	bosses[2]=newboss3;
+	bosses[3]=newboss4;
+	bosses[4]=newboss5;
+
+	boss1=bosses[0];
+	boss1.alive=true;
+
+	player1.weaponclass=1;
+	
+	//NCURSES STUFF
+	initscr();
+	curs_set(0);
+	noecho();	
+	cbreak();
+	keypad(stdscr,TRUE);
+	start_color();
+	init_pair(0,COLOR_WHITE,COLOR_BLACK);
+	init_pair(1,COLOR_GREEN,COLOR_BLACK);	//PLAYER
+	init_pair(2,COLOR_RED,COLOR_BLACK);	//ENEMY
+	init_pair(3,COLOR_YELLOW,COLOR_BLACK);	//BULLETS-POWERUPS
+	init_pair(4,COLOR_MAGENTA,COLOR_BLACK);	//WALLS
+	init_pair(5,COLOR_CYAN,COLOR_BLACK);	//BOSS
+	init_pair(6,COLOR_BLUE,COLOR_BLACK);	//BOMBS
+	init_pair(7,COLOR_RED,COLOR_RED);
+	init_pair(8,COLOR_GREEN,COLOR_GREEN);
+	init_pair(9,COLOR_BLACK,COLOR_GREEN);
+	
+	WALLS_NUM=3;
+	
+	w_vec walls(WALLS_NUM);
+	
+	Score=newwin(3,10,R/3,C+3);
+	BossHP=newwin(3,15,R/3-3,C+3);
+	
+	int i=0;
+	for(w_vec::iterator it=walls.begin(); it!=walls.end(); ++it, ++i)				//creating walls (in a quite symmetric pattern)
+		it->create((i+1)*(C/(3*WALLS_NUM+1))+i*(2*C/(3*WALLS_NUM+1)),2*R/3,(int)min(6,2*C/(3*WALLS_NUM+1)),2,3);
+
+	choose_level_bossrush(shootrate,refresh_time,level,commands);
+	
+	player1.set_commands(commands);
+	
+	if(atoi(&level)<3)
+		player1.weaponclass=2;
+
+	erase();
+	
+	if(argc>1)
+		if(strcmp(argv[1],"--uber-debug")==0){ player1.weaponclass=5; player1.weaponclassrkt=5; player1.rocketlauncher=true; player1.length=MAX_LENGTH; }
+	
+	std::thread t_draw(draw,std::ref(player1),std::ref(bullets),std::ref(bombs),std::ref(enemies),std::ref(walls),std::ref(powerups),std::ref(rockets),std::ref(boss1));
+	
+/////////ENTERING MAIN LOOP
+	
+	while(1)
+	{
+		napms(refresh_time);					//ncurses sleep function (ms)
+
+		timeout(0);
+	    	command = getch();
+	    	              
+	    	if(command!=ERR)                        		//READING INPUT
+	    		command = tolower(command);     
+	    		           
+	    	if(command == commands[8]){ 						//q = exit game
+	    		endwin();
+	    		cout<<lightgreen<<"Game exited correctly."<<none<<endl;
+	    		return 1;
+	    	}  
+
+	    	if(command == commands[4])
+	    		pause_game(chflag);						//p = pause game
+
+	    	if(chflag==1)									//cheats
+	    		get_cheat(command,player1,enemies,shootrate);
+	    	        
+	    	if(command == commands[0] || command == KEY_LEFT || command == commands[1] || command == KEY_RIGHT || ((command == commands[2]|| command == KEY_UP || command == commands[3] || command == KEY_DOWN) && chflag==1)){   	//a or d = move player (if cheats are triggered, also w and s)
+	    		for(int i=player1.x;i<player1.x+player1.length;i++) mvaddch(player1.y,i,' ');	
+	    		player1.next_pos(command);	
+	    	}	    
+	    		
+		if(command==commands[5] || command==commands[6]) {               		//spacebar = shoot!
+			player1.shoot(bullets);
+			if(player1.rocketlauncher) player1.shootrkt(rockets);
+		}
+						
+
+		for(int i=0;i<boss1.width;i++) mvaddch(boss1.y,boss1.x+i,' ');
+		for(int j=0;j<boss1.height;j++){
+			mvaddch(boss1.y+j,boss1.x,' ');
+			mvaddch(boss1.y+j,boss1.x+boss1.width-1,' ');
+		}
+		boss1.next_pos();
+		if((double)rand()/RAND_MAX<shootrate*10.)		
+			boss1.shoot(bombs);	
+		
+		
+		if(!bullets.empty())						//evaluate new bullets' positions
+			for(b_list::iterator it=bullets.begin(); it!=bullets.end(); ++it){
+				mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+				
+		bullets.unique();      					//remove duplicates of bullets (i.e. player can't shoot enemies)
+
+		if(!rockets.empty())						//evaluate new bullets' positions
+			for(r_list::iterator it=rockets.begin(); it!=rockets.end(); ++it){
+				mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+				
+		rockets.unique(); 
+
+		if(!bombs.empty())						//evaluate new bombs' positions
+			for(b_list::iterator it=bombs.begin(); it!=bombs.end(); ++it){
+				mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+			          	
+		bombs.unique();						//remove duplicates of bombs
+
+		if(!powerups.empty())						//new powerups' positions
+			for(b_list::iterator it=powerups.begin(); it!=powerups.end(); ++it){
+				mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+				
+		powerups.unique(); 	 //FIXME: THIS ONLY WORKS ON CONSECUTIVE ELEMENTS OF THE LIST!! we should at least sort powerups before calling unique()
+
+		interactions(player1,bullets,bombs,enemies,walls,powerups,rockets,boss1,score);
+		
+		
+		if(boss1.health<=0)
+			if(num<4){
+				score+=250*atoi(&level)*(num+1);
+				for(int i=max(0,boss1.y-1);i<min(R-1,boss1.y+boss1.height+1);i++)
+					for(int j=0;j<C;j++)
+						mvaddch(i,j,' ');
+				num++;
+				mvwprintw(BossHP,0,1,"             ");
+				if((double)rand()/RAND_MAX<0.25*num){
+					if((double)rand()/RAND_MAX<1./POWERUP_RATIO){
+						if((double)rand()/RAND_MAX<1./ROCKET_RATIO){
+							powerup newpowerup(boss1.x,boss1.y+1,512);
+							powerups.push_back(newpowerup);
+						}
+						else{
+							powerup newpowerup(boss1.x,boss1.y+1,128);
+							powerups.push_back(newpowerup);
+						}
+					}
+					else{
+						powerup newpowerup(boss1.x,boss1.y+1);
+						powerups.push_back(newpowerup);
+					}
+				}
+				if(num==4 && player1.weaponclass<3) player1.weaponclass++;
+				boss1=bosses[num];
+				boss1.alive=true;
+			}
+
+		///////ENDGAME CHECKS               
+		if(boss1.health<1 && num==4)  					//YOU WON!!
+		{
+			Victory_bossrush(boss1.name,score,level,chflag);
+			
+			WINDOW *replay;
+			
+			replay=newwin(3,25,26,20);
+			box(replay,ACS_VLINE,ACS_HLINE);
+			
+			if(playagain(replay))                           //playagain() returns true if player wants to play again, false otherwise
+			{
+				delwin(replay);
+				timeout(500);
+				score=0;
+				erase();
+				refresh();
+				choose_level_bossrush(shootrate, refresh_time,level,commands);
+				reset(player1, enemies, boss1, bullets, bombs, walls, powerups,rockets, level,chflag); // reset box, player, enemy and deletes all bullets and bombs
+				resetbosses(bosses,boss1,player1);
+				num=0;
+				if(atoi(&level)<3)
+					player1.weaponclass=2;
+				erase();
+				refresh();
+				continue;  
+			}
+			else { 
+				endwin();
+				cout<<lightgreen<<"Game exited correctly."<<none<<endl;
+				return 0;
+			}	
+		}
+				
+			
+		if(gameover(player1,bombs))
+		{	
+			Defeat(score);
+			
+			WINDOW* replay;
+		
+			replay=newwin(3,25,17,20);
+			box(replay,ACS_VLINE,ACS_HLINE);
+			
+			if(playagain(replay))                                        //playagain() returns true if player wants to play again, false otherwise
+			{
+				delwin(replay);
+				timeout(500);
+				score=0;
+				erase();
+				refresh();
+				choose_level_bossrush(shootrate, refresh_time, level,commands);
+				reset(player1, enemies, boss1, bullets, bombs, walls, powerups,rockets, level,chflag);       // reset box, player, enemy and delete all bullets and bombs
+				resetbosses(bosses,boss1,player1);
+				num=0;
+				if(atoi(&level)<3)
+					player1.weaponclass=2;
+				erase();
+				refresh();
+				continue;  
+			}
+			else { 
+				endwin();
+				cout<<lightgreen<<"Game exited correctly."<<none<<endl;
+				return 0;
+			}		
+		}
+		
+		write_score(Score,score);
+	
+		if(boss1.alive){
+			write_bosshp(BossHP,boss1.health,boss1.healthmax,boss1.name);
+			wrefresh(BossHP);
+		}
+		
+		wrefresh(Score);
+		refresh();
+
+	}  
+////////END OF MAIN LOOP
+
+	endwin();
+	return 0;
+}

+ 300 - 0
box.cpp

@@ -0,0 +1,300 @@
+#include "box.hpp"
+
+void Box::refresh(b_list& bullets, b_list& bombs, e_list& enemies, player& player1, int &score, boss& boss1,w_vec &walls, b_list& powerups,r_list& rockets)
+{
+	clear();			//Empty matrix
+	upload(bullets, bombs, enemies, player1, boss1, walls, powerups, rockets);	//writes id values on matrix
+	kill(bullets, bombs, enemies, score, boss1, walls, powerups, player1, rockets);	//evaluates interactions and removes what should be removed
+	clear();			//empty again
+	upload(bullets, bombs, enemies, player1, boss1, walls, powerups, rockets);	//rewrites survived game objects' id
+}
+
+
+
+void Box::print()		//this method is used for debugging purposes, not in game
+{
+	for(int k=0; k<R; k++)
+	{
+		for(int l=0; l<C; l++)
+			cout << matrix[k][l] << " ";
+		cout << endl;
+	}
+	cout << endl;
+}
+
+
+
+void Box::clear()
+{
+	for(int i=0; i<R; i++)
+		for(int j=0; j<C; j++)
+			matrix[i][j]=0;			
+}
+
+
+
+void Box::upload(b_list & bullets, b_list& bombs, e_list& enemies, player& player1, boss& boss1, w_vec &walls, b_list & powerups,r_list& rockets)	//writes on the box the IDs of all game objects (even if superimposed). Also uploads curses's window 
+{
+
+	e_list::const_iterator e_end = enemies.end();
+	for(e_list::iterator it=enemies.begin(); it!=e_end; ++it)
+		if(it->alive){
+			attron(COLOR_PAIR(2));
+			mvaddch(it->y,it->x,ENEMY_SPRITE);			
+			matrix[it->y][it->x]+=it->id;
+		}
+	
+	if(!bullets.empty())
+		for(b_list::iterator it=bullets.begin(); it!=bullets.end(); ++it){
+			attron(COLOR_PAIR(3));
+			mvaddch(it->y,it->x,BULLET_SPRITE);
+			matrix[it->y][it->x]+=it->id;
+		}
+		
+	if(!rockets.empty())
+		for(r_list::iterator it=rockets.begin(); it!=rockets.end(); ++it){
+			attron(COLOR_PAIR(4));
+			mvaddch(it->y,it->x,ROCKET_SPRITE);
+			matrix[it->y][it->x]+=it->id;
+		}
+
+	if(!bombs.empty())
+		for(b_list::iterator it=bombs.begin(); it!=bombs.end(); ++it){
+			attron(COLOR_PAIR(6));
+			mvaddch(it->y,it->x,BOMB_SPRITE);
+			matrix[it->y][it->x]+=it->id;
+		}
+		
+	if(!powerups.empty())
+		for(b_list::iterator it=powerups.begin(); it!=powerups.end(); ++it){
+			if(it->id==64){
+				attron(COLOR_PAIR(3));
+				mvaddch(it->y,it->x,POWERUP1_SPRITE);
+			}
+			else if(it->id==128){
+				attron(COLOR_PAIR(1));
+				mvaddch(it->y,it->x,POWERUP2_SPRITE);
+			}
+			else{
+				attron(COLOR_PAIR(4));
+				mvaddch(it->y,it->x,POWERUP3_SPRITE);
+			}
+			matrix[it->y][it->x]+=it->id;
+		}
+				
+	for(int i=player1.x; i<player1.x+player1.length; ++i){
+		attron(COLOR_PAIR(1));
+		mvaddch(player1.y,i,PLAYER_SPRITE);
+		matrix[player1.y][i]+=player1.id;
+	}
+	
+	for(unsigned int i=0;i<walls.size();i++)
+		for(int k=0;k<walls[i].height;k++)
+			for(int j=0;j<walls[i].width;j++)
+				if(walls[i].health[k][j]>0){
+					attron(COLOR_PAIR(4));
+					if(walls[i].health[k][j]==1)
+						attron(COLOR_PAIR(2));
+					mvaddch(walls[i].y+k,walls[i].x+j,WALL_SPRITE);
+					matrix[walls[i].y+k][walls[i].x+j]+=walls[i].id;
+				}
+				
+	if(boss1.alive)					
+		for(int i=boss1.y; i<boss1.y+boss1.height; i++)
+			for(int j=boss1.x; j<boss1.x+boss1.width; j++){
+				if(boss1.health>.5*boss1.healthmax)
+					attron(COLOR_PAIR(5));
+				else if(boss1.health>.25*boss1.healthmax)
+					attron(COLOR_PAIR(3));
+				else
+					attron(COLOR_PAIR(2));
+				mvaddch(i,j,boss1.picture[i-boss1.y][j-boss1.x]);
+				matrix[i][j]+=boss1.id;
+			}
+	
+}
+
+
+
+void Box::kill(b_list & bullets, b_list& bombs, e_list& enemies, int &score, boss& boss1, w_vec &walls, b_list & powerups, player& player1,r_list& rockets)   //controls what changes the box's elements must undergo
+{	
+	
+	for(int i=0; i<R; i++)
+		for(int j=0; j<C; j++)
+		{
+			if(i==0 || i==R-1)
+				switch(matrix[i][j])					//destroys bullets and bombs at box's limits
+				{		              			//DESTRUCTION SHOULD HAPPEN AFTER THEY'VE BEEN PRINTED ONCE!!
+					case 2:
+					case 8:
+					case 64:
+					case 128:
+					case 256:
+					case 512:
+						destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+						break;
+					default:
+						break;
+				}
+			if(!boss1.alive && matrix[i][j]==16) destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+				
+				switch (matrix[i][j])     //id player=1 bullet=2 enemy=4 bomb=8 boss=16 wall=32 powerup+=64, powerup-=128, rocket=256, powerupX=512
+				{		                   
+					case 2:               //destruction cases: 6=enemy+bullet; 10=bomb+bullet; 14=bomb+enemy+bullet; and so on...
+						if(i!=0)
+							if(matrix[i-1][j]==8)	//to make the bullets less 'transparent'...
+							{
+								destroy(i, j, bullets,bombs, enemies,powerups,rockets);
+								destroy(i-1, j, bullets,bombs,enemies,powerups,rockets);
+								score+=50;
+							}
+						break; 
+
+					case 6:			//enemy+bullet
+						score+=100;
+						destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+						if((double)rand()/RAND_MAX<(double)AVERAGE_DROP/ENEMY_NUM)	//a powerup is dropped (AVERAGE_DROP is the mean number of powerups dropped per play in Normal mode)
+						{
+							if((double)rand()/RAND_MAX<1./POWERUP_RATIO){		//1 powerup out of POWERUP_RATIO is either a "-" (with ID 128 instead of 64) or a "X"
+								if((double)rand()/RAND_MAX<1./ROCKET_RATIO){ 	//1 powerup out of ROCKET_RATIO*POWERUP_RATIO is a "X" (ID 512)
+									powerup newpowerup(j,i+1,512);		
+									powerups.push_back(newpowerup);
+								}
+								else{
+									powerup newpowerup(j,i+1,128);		
+									powerups.push_back(newpowerup);
+								}
+							}
+							else{
+								powerup newpowerup(j,i+1);		//otherwise, it is a "+"
+								powerups.push_back(newpowerup);
+							}
+								
+						}
+						break;
+					case 10:			//bomb+bullet
+						score+=50;
+						destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+						break;
+					case 14:			//bomb+enemy+bullet
+						score+=150;
+						destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+						break;
+					case 18:			//boss+bullet
+					case 272:
+						if(j>=boss1.x+boss1.width/2-2 && j<=boss1.x+boss1.width/2+2)
+							boss1.health--;
+						break;	
+					case 34:			//wall+bullet
+					case 40:			//wall+bomb
+					case 288:			//wall+rocket
+						destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+						for(unsigned int k=0;k<walls.size();k++)
+							if(j>=walls[k].x && j<=walls[k].x+walls[k].width && i>=walls[k].y && i<=walls[k].y+walls[k].height)	//finds out what wall has been hit
+								walls[k].health[i-walls[k].y][j-walls[k].x]--;		//subtracts 1 HP to the hit wall's correct health matrix's element 
+						break;
+					case 65:			//"+" powerup+player
+						if(player1.weaponclass<MAX_WEAPONCLASS)
+							player1.weaponclass++;
+						destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+						break;
+					case 68:			//"+" powerup+enemy
+					case 72:			//"+" powerup+bomb
+					case 80:			//"+" powerup+boss
+					case 132:			//"-" powerup+enemy [etc.]
+					case 136:
+					case 144:
+					case 516:			//"X" powerup+enemy [etc.]
+					case 520:
+					case 528:
+						destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+						break;
+					case 129:			//"-" powerup+player
+						if(player1.length>2){
+							mvaddch(player1.y,player1.x+player1.length-1,' ');
+							player1.length--;
+						}
+						destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+						break;
+					case 260:			//enemy+rocket
+					case 264:			//bomb+rocket
+						destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+						break;
+					case 513:			//player+"X" powerup
+						player1.rocketlauncher=TRUE;
+						destroy(i,j,bullets,bombs,enemies,powerups,rockets);
+						break;
+				}
+		}
+}
+
+void Box::destroy(int Y, int X, b_list & bullets, b_list& bombs, e_list& enemies, b_list & powerups,r_list& rockets)	 //destroys any bomb/enemy/bullet/powerup/rocket found in matrix[Y][X]
+{
+
+	b_list::iterator it;
+	r_list::iterator itr;
+	
+	if(!bullets.empty()){
+		it=bullets.begin();                         //we could use remove_if() if i could just think of a way...
+		while(it!=bullets.end())
+		{
+			if(it->x==X && it->y==Y)
+			{
+				mvaddch(it->y,it->x,' ');
+				it = bullets.erase(it);
+				break;
+			} else ++it;
+		}
+	}
+
+	if(!rockets.empty()){
+		itr=rockets.begin();                        
+		while(itr!=rockets.end())
+		{
+			if(itr->x==X && itr->y==Y)
+			{
+				mvaddch(itr->y,itr->x,' ');
+				itr = rockets.erase(itr);
+				break;
+			} else ++itr;
+		}
+	}
+
+	if(!bombs.empty()){
+		it=bombs.begin();                         
+		while(it!=bombs.end())
+		{
+			if(it->x==X && it->y==Y)
+			{
+				mvaddch(it->y,it->x,' ');
+				it = bombs.erase(it);
+				break;
+			} else ++it;
+		}
+	}
+		
+	if(!powerups.empty()){
+		it=powerups.begin();            	     
+		while(it!=powerups.end())
+		{
+			if(it->x==X && it->y==Y)
+			{
+				mvaddch(it->y,it->x,' ');
+				it = powerups.erase(it);
+				break;
+			}else ++it;
+		}
+	}
+
+	e_list::const_iterator e_end = enemies.end();
+	
+	for(e_list::iterator it=enemies.begin(); it!=e_end; ++it)	       //this cycle destroys an enemy in X,Y (quite unefficiently?)
+		if(it->x==X && it->y==Y)
+		{
+			it->alive=false;
+			break;
+		}
+}
+
+
+

+ 40 - 0
box.hpp

@@ -0,0 +1,40 @@
+#ifndef _box_
+#define _box_
+
+#include "player.hpp"
+#include "rocket.hpp"
+#include "enemy.hpp" 	
+#include "boss.hpp"
+#include "wall.hpp"
+#include "powerup.hpp"
+#include "definitions.hpp"
+
+using std::cout; using std::endl;
+
+typedef std::list<bullet> b_list;
+typedef std::list<enemy> e_list;
+typedef std::vector<wall> w_vec;
+typedef std::list<rocket> r_list;
+
+class Box
+{
+	
+	public:
+	Box() { clear(); }
+	~Box() {}
+	
+	int matrix[R][C];                                                 		 //the position matrix
+	void refresh(b_list&, b_list&, e_list&, player&, int &score, boss& boss1,w_vec &walls, b_list & powerups,r_list&);  	 //empties, uploads, kills, empties again, uploads again matrix
+	void print();                                                   		  //prints the position matrix
+	void clear();                                                    		 //fills matrix with 0's
+	void destroy(int X, int Y, b_list & bullets, b_list& bombs, e_list& enemies, b_list & powerups,r_list&);     //destroys bullets, bombs and enemies in (X,Y)
+	
+	private:	                                                   
+	void upload(b_list & bullets, b_list& bombs, e_list& enemies, player& player1, boss& boss1,w_vec &walls, b_list & powerups,r_list&);    //fills matrix with objects id's
+	void kill(b_list & bullets, b_list& bombs, e_list& enemies, int &score, boss& spole,w_vec &walls, b_list & powerups, player & player1,r_list&);           //checks where there's something to destroy
+	
+
+};
+
+#endif
+

+ 17 - 0
bullet.cpp

@@ -0,0 +1,17 @@
+#include "bullet.hpp"
+
+void bullet::next_pos()
+{
+	switch(id){
+		case 2:
+			y--;
+			break;
+		case 8:
+		case 64:
+		case 128:
+		case 512:
+			y++;
+			break;
+	}
+			
+}

+ 19 - 0
bullet.hpp

@@ -0,0 +1,19 @@
+#ifndef _bullet_
+#define _bullet_
+
+#include "game_object.hpp"
+
+class bullet : public game_object
+{
+	
+	public:
+	bullet(int X,int Y,int ID) : game_object(X,Y,ID) {}  //constructor
+	~bullet() {}
+	
+	void next_pos();            //evaluates next position checking bullet's id (laser or bomb) 
+	
+	bool operator==(bullet& other) { if(other.x==x && other.y==y && other.id==id) return true; else return false; }
+		
+};
+
+#endif

+ 115 - 0
checkboss.sh

@@ -0,0 +1,115 @@
+#!/bin/bash
+
+# This script checks all arguments (or if no arguments are given, all files named *.dat in the directory),
+# with the exception of records.dat,
+# and prompts for cutting lines and characters in excess
+# i.e. cuts lines after the $MAX_LINES-th line and characters after the $MAX_CHARS-th character in each line
+# The script also adds as many blank spaces as needed to even the character count on each line
+# i.e. in the and each line will have $LONGEST_LINE characters in total
+# Old boss.dat file is copied to boss.dat.old to prevent data loss. I'm aware this is a coward's walkaround
+# to the fact this script has issues.
+
+# KNOWN BUGS:
+# - there is no return value checking from the functions called
+# - first bug implies that boss.dat file could be substituted with an empty file, or worse
+
+# Please report any bugs or suggestions to me .D
+
+#wc -L is the length of the longest line
+#wc -m is the character count for the file
+#wc -l is the line count for the file
+
+MAX_CHARS=10
+MAX_LINES=10
+FILES=""
+
+if [ $# -eq 1 -a $1 == "-h" ]; then echo Usage: $0 \<bossname.dat\>.; exit 1; fi
+
+if [ $# -gt 0 ]; then
+	#check that file exists
+	for k in $@; do
+		if [ ! -e $k -a ! $k.dat ]; then
+			echo $k does not exist!
+			echo ignoring argument
+			continue
+		else
+			#check that file has .dat extension
+			if [[ "$k" =~ dat$  ]]; then
+				FILES="$FILES $k"
+			else
+				if [[ "Sk.dat" =~ dat$ ]]; then
+					echo File $k is not a .dat, but a file named $k.dat exists. Did you mean that file? \(Y/N\)
+					read ans
+					if [ $ans != "y" -a $ans != "Y" ]; then exit 1 
+					else
+						FILES="$FILES $k.dat"
+						continue
+					fi
+				else
+					echo $k does not look like a .dat file
+					echo ignoring argument
+					continue
+				fi
+			fi
+		fi
+	done
+else
+	FILES=`ls *.dat 2> /dev/null`
+fi
+
+echo $FILES > args.tmp
+
+#FOR EACH boss.dat FILE
+for i in `cat args.tmp`; do
+	if [ $i == "records.dat" -o $i == "notes.dat" ]; then continue; fi
+	
+	#MAKE A BACKUP COPY	
+	cp $i $i.old
+
+	#CUT LINES IN EXCESS
+	N_LINES=`wc -l $i | cut -f1 -d' '`
+	if [ $N_LINES -gt $MAX_LINES ]; then
+		echo file $i has too many lines \($N_LINES\): cut lines in excess? Y\\N
+		read ans
+		while [ $ans != 'y' -a $ans != 'Y' -a $ans != 'n' -a $ans != 'N' ]; do
+			echo cut lines in excess? Y\\N
+			read ans
+		done
+		if [ $ans == 'y' -o $ans == 'Y' ]; then
+			head -$MAX_LINES $i > output.tmp
+			mv output.tmp $i
+			N_LINES=`wc -l $i | cut -f1 -d' '`
+			echo file has now $N_LINES lines
+		fi
+		echo
+	fi
+	
+	#CUT CHARACTERS IN EXCESS
+	LONGEST_LINE=`wc -L $i | cut -f1 -d' '`
+	if [ $LONGEST_LINE -gt $MAX_CHARS ]; then
+		echo file $i has at least one line that is longer than permitted. max length is $MAX_CHARS
+		echo cut characters in excess? Y\\N
+		read ans
+		while [ $ans != 'y' -a $ans != 'Y' -a $ans != 'n' -a $ans != 'N' ]; do  
+                        echo cut lines in excess? Y\\N
+                        read ans
+                done
+		if [ $ans == 'y' -o $ans == 'Y' ]; then
+			cat $i | cut -c1-$MAX_CHARS > output.tmp2
+			mv output.tmp2 $i
+			LONGEST_LINE=`wc -L $i | cut -f1 -d' '`
+			echo longest line has now $LONGEST_LINE characters 
+		fi
+		echo
+	fi
+
+	#ADD BLANK SPACES AT THE END OF LINES
+	for j in `seq 1 $MAX_CHARS`; do
+		sed 's/.*/& /' $i > output.tmp3
+		mv output.tmp3 $i
+	done
+	cat $i | cut -c1-$LONGEST_LINE > output.tmp4
+	mv output.tmp4 $i
+done
+
+rm args.tmp

+ 1 - 0
dati.dat

@@ -0,0 +1 @@
+lkaid landed on the strange ground of the Void Planet. It was quite an exotic panorama: blue grass and pink-leaved trees aside, the whole planet seemed to be constantly experiencing a

+ 94 - 0
definitions.hpp

@@ -0,0 +1,94 @@
+#ifndef _definitions_
+#define _definitions_
+
+//MAIN LIBRARIES INCLUDES
+#include <cstdlib>
+#include <ctime>
+#include <fstream>
+#include <sstream>
+#include <algorithm>
+#include <iostream>
+#include <iomanip>
+#include <list>
+#include <vector>
+#include <cmath>
+#include <unistd.h>
+//#include <pthread.h>	//for sounds
+#include <sys/stat.h>	//for making directories
+#include <ncurses.h>	//for graphics
+#include <mutex>
+
+
+//GAME BOX DIMENSIONS
+#define R 30	//rows (Y)
+#define C 60	//columns (X)
+
+//GAME DEFINES
+#define AVERAGE_DROP 2
+#define POWERUP_RATIO 2
+#define ROCKET_RATIO 3
+#define MAX_WEAPONCLASS 5
+#define MAX_WEAPONCLASSRKT 5
+#define MAX_LENGTH 20
+#define CMD_NUM 9
+#ifdef R
+#define MAX_WIDTH R
+#endif
+#ifdef C
+#define MAX_HEIGHT C
+#endif
+#define GLOBAL_DIR "/home/150/invaders/"
+#define RECORD_DIR "/.invaders/"
+#define RECORD_FILE "records.dat"
+#define RECORD_FILE_BOSSRUSH "records_bossrush.dat"
+#define CHEAT_CODE "pinkie"
+#define BOSS_FILE1 "spoletini"
+#define BOSS_FILE2 "palombo"
+#define BOSS_FILE3 "maderna"
+#define BOSS_FILE4 "maero"
+#define BOSS_FILE5 "big_alienboss"
+#define PLAYER_SPRITE '='
+#define ENEMY_SPRITE '#'
+#define BULLET_SPRITE '|'
+#define BOMB_SPRITE 'o'
+#define POWERUP1_SPRITE '+'
+#define POWERUP2_SPRITE '-'
+#define POWERUP3_SPRITE 'X'
+#define WALL_SPRITE '@'
+#define ROCKET_SPRITE '^'
+
+//THREAD DEFINES
+//#define THREADS_NUM 5
+
+//COLORS
+#define red "\033[31m" 
+#define crimson "\033[1;31m"
+#define magenta "\033[35m" 
+#define violet "\033[1;35m"  
+#define green "\033[32m" 
+#define lightgreen "\033[1;32m" 
+#define blue "\033[34m" 
+#define lightblue "\033[1;34m" 
+#define none "\033[0m" 
+#define yellow "\033[33m" 
+#define orange "\033[1;33m"
+#define cyan "\033[36m"
+#define azure "\033[1;36m"
+#define grey "\e[1;30m"
+#define backred "\033[41m" 
+#define backcyan "\033[46m"
+#define backgreen "\033[1;42m" 
+
+static int ENEMY_NUM=1;
+static int WALLS_NUM;
+
+extern std::mutex m_player;
+extern std::mutex m_enemies;
+extern std::mutex m_bombs;
+extern std::mutex m_bullets;
+extern std::mutex m_rockets;
+extern std::mutex m_pow;
+extern std::mutex m_boss;
+extern std::mutex m_walls;
+
+#endif

+ 77 - 0
definitions.hpp.bu

@@ -0,0 +1,77 @@
+#ifndef _definitions_
+#define _definitions_
+
+//MAIN LIBRARIES INCLUDES
+#include <cstdlib>
+#include <ctime>
+#include <fstream>
+#include <sstream>
+#include <algorithm>
+#include <iostream>
+#include <iomanip>
+#include <list>
+#include <vector>
+#include <cmath>
+//#include <unistd.h>
+#include <pthread.h>
+#include <ncurses.h>
+
+//GAME BOX DIMENSIONS
+#define R 30	//rows (Y)
+#define C 60	//columns (X)
+
+//GAME DEFINES
+#define AVERAGE_DROP 2
+#define POWERUP_RATIO 2
+#define ROCKET_RATIO 3
+#define MAX_WEAPONCLASS 5
+#define MAX_WEAPONCLASSRKT 5
+#define MAX_LENGTH 20
+#ifdef R
+#define MAX_WIDTH R
+#endif
+#ifdef C
+#define MAX_HEIGHT C
+#endif
+#define CHEAT_CODE "pinkie"
+#define BOSS_FILE1 "myboss"
+#define BOSS_FILE2 "palombo"
+#define BOSS_FILE3 "maderna"
+#define BOSS_FILE4 "maero"
+#define BOSS_FILE5 "big_alienboss"
+#define PLAYER_SPRITE '='
+#define ENEMY_SPRITE '#'
+#define BULLET_SPRITE '|'
+#define BOMB_SPRITE 'o'
+#define POWERUP1_SPRITE '+'
+#define POWERUP2_SPRITE '-'
+#define POWERUP3_SPRITE 'X'
+#define WALL_SPRITE '@'
+#define ROCKET_SPRITE '^'
+
+//THREAD DEFINES
+#define THREADS_NUM 5
+
+//COLORS
+#define red "\033[31m" 
+#define crimson "\033[1;31m"
+#define magenta "\033[35m" 
+#define violet "\033[1;35m"  
+#define green "\033[32m" 
+#define lightgreen "\033[1;32m" 
+#define blue "\033[34m" 
+#define lightblue "\033[1;34m" 
+#define none "\033[0m" 
+#define yellow "\033[33m" 
+#define orange "\033[1;33m"
+#define cyan "\033[36m"
+#define azure "\033[1;36m"
+#define grey "\e[1;30m"
+#define backred "\033[41m" 
+#define backcyan "\033[46m"
+#define backgreen "\033[1;42m" 
+
+static int ENEMY_NUM=40;
+static int WALLS_NUM;
+	
+#endif

+ 38 - 0
enemy.cpp

@@ -0,0 +1,38 @@
+#include "enemy.hpp"
+
+
+enemy::enemy() : game_object() { id=4; alive=true; direction=0; }
+
+enemy::enemy(int X,int Y) : game_object(X,Y,4) { alive=true; direction=0; }  
+
+
+void enemy::next_pos(){
+
+	if( (direction==0 && x==C-1) || (direction==1 && x==0) )
+		direction=2;
+
+	switch (direction){			//assegno a direction un valore 0,1,2
+		case 0:				//0 significa che si sta muovendo verso destra
+			x++;
+			break;
+		case 1:				//1 verso sinistra
+			x--;
+			break;
+		case 2:				//2 verso il basso (quando incontra la parete).
+			y++;
+			break;
+	}
+
+	if(direction==2)
+	{
+		if(x==0) direction=0;
+		else direction=1;
+	}
+	
+}
+
+void enemy::shoot(std::list<bullet> & bombs){	      //random bomb-dropping	
+		bullet new_bomb(x,y+1,8);
+		bombs.push_back(new_bomb);
+}
+

+ 23 - 0
enemy.hpp

@@ -0,0 +1,23 @@
+#ifndef _enemy_
+#define _enemy_
+
+#include "game_object.hpp"
+#include "bullet.hpp"
+#include "definitions.hpp"
+
+class enemy : public game_object
+{	
+	public:
+	enemy();                    //costruttori:
+	enemy(int X,int Y);		    //id viene automaticamente settato a 4, direction a 0, alive a true
+	~enemy(){}
+	
+	void next_pos();
+	void shoot(std::list<bullet> &);  //genera un nuovo proiettile 
+	
+	bool alive;			         //0: morto, 1: vivo
+	int direction; 	       	//0: si sta muovendo a dx, 1: a sx, 2: verso il basso
+	
+};
+
+#endif

File diff suppressed because it is too large
+ 2020 - 0
functions.cpp


+ 129 - 0
functions.hpp

@@ -0,0 +1,129 @@
+#ifndef _functions_
+#define _functions_
+
+//#includes here
+#include "definitions.hpp"
+#include "box.hpp"
+#include "player.hpp"
+#include "bullet.hpp"
+#include "enemy.hpp"
+#include "wall.hpp"
+#include "boss.hpp"
+
+class record
+{
+	public:
+	int score;
+	std::string nick;
+
+
+	bool operator==(record& record2)
+	{
+		if(score==record2.score && nick==record2.nick)
+			return true;
+		else return false;		
+	}
+	
+	
+	void print();
+	
+	void printwin(WINDOW*);
+
+	void print(std::ofstream& record);
+	
+};
+
+
+typedef std::list<bullet> b_list;
+typedef std::list<enemy> e_list;
+typedef std::vector<record> r_vec;
+typedef std::vector<wall> w_vec;
+
+void print_title();
+
+void print_catchphrase(std::string phrase);
+
+std::string choose_phrase();
+
+void print_info();
+
+void print_scores();
+
+int choose_level(double& shootr, int& refresh_t, boss &boss1, char& level,int* commands);
+
+void change_commands(int* commands);
+
+void load_enemies(e_list& enemies,int enemy_num);
+
+bool playagain(WINDOW*);
+
+bool gameover(player&,b_list&);
+
+void reset(player&, e_list &, boss&, b_list& bullets, b_list& bombs, w_vec& walls, b_list &powerups,r_list&,char level,int& chflag);
+
+bool enemyalive(e_list &);
+
+void refreshrecords(int,WINDOW*);
+
+void write_score(WINDOW*,int);
+
+void write_bosshp(WINDOW*,int,int,std::string);
+
+void pause_game(int&);
+
+void Victory(std::string,int,char,int);
+
+void Defeat(int);
+
+void choose_level_bossrush(double& shootr,int& refresh_t,char& level,int* commands);
+
+void resetbosses(boss* Bosses,boss& boss1,player& player1);
+
+void Victory_bossrush(std::string,int,char,int);
+
+void refreshrecords_bossrush(int,WINDOW*);
+
+void print_scores_bossrush();
+
+void get_SpecialMode(int,int&,boss&,e_list&,b_list&,b_list&,b_list&,r_list&);
+
+bool get_KonamiCode(int);
+
+void get_cheat(char,player&,e_list&,double&);
+
+void activate_combo(boss&,e_list&,b_list&,b_list&,b_list&,r_list&);
+
+void drop_powerup(int x,int y,b_list& powerups);
+
+void interactions(player& player1,b_list& bullets,b_list& bombs,e_list& enemies,w_vec& walls,b_list& powerups,r_list& rockets,boss& boss1,int& score);
+
+void draw(player& player1,b_list& bullets,b_list& bombs,e_list& enemies,w_vec& walls,b_list& powerups,r_list& rockets,boss& boss1, int& refresh_time, bool& keep_drawing,bool& kill_yourself);
+
+void create_readme();
+
+void create_std_bosses();
+
+//void create_setsize();
+
+void create_folder(int);
+
+// FORK FUNCTIONS (unused)
+/*void music();
+
+void kill_music(int);*/
+
+/*//PTHREAD FUNCTIONS
+void *pmusic(void *arg);
+
+void *pshoot_sound(void* arg);
+
+void *penshoot_sound(void* arg);
+
+void *pwin_theme(void *arg);
+
+void *plose_theme(void* arg);
+
+void pkill_music(pthread_t);*/
+
+
+#endif

+ 9 - 0
game_object.cpp

@@ -0,0 +1,9 @@
+#include "game_object.hpp"
+
+game_object::game_object(int X,int Y,int ID){
+	
+	x=X,
+	y=Y;
+	id=ID;
+
+}

+ 14 - 0
game_object.hpp

@@ -0,0 +1,14 @@
+#ifndef _gameobject_
+#define _gameobject_
+
+class game_object{
+	
+	public:
+	game_object() {}
+	game_object(int X, int Y, int ID);
+	
+	int x,y,id;
+
+};
+
+#endif

+ 344 - 0
invaders.cpp

@@ -0,0 +1,344 @@
+#include "bullet.hpp"
+#include "enemy.hpp"
+#include "player.hpp"
+#include "boss.hpp"
+#include "powerup.hpp"
+#include "definitions.hpp"
+#include "functions.hpp"
+#include "wall.hpp"
+#include <thread>
+
+std::mutex m_player;
+std::mutex m_enemies;
+std::mutex m_bombs;
+std::mutex m_bullets;
+std::mutex m_rockets;
+std::mutex m_pow;
+std::mutex m_boss;
+std::mutex m_walls;
+
+using std::cout;
+using std::endl; 
+using std::min;
+
+int main(int argc,char** argv)
+{
+	if(argc>1){
+		if(strcmp(argv[1],"--uber-debug")!=0 && strcmp(argv[1],"--info")!=0 && strcmp(argv[1],"--autowin")!=0){
+			cout<<"Usage: "<<argv[0]<<" [--info]"<<endl;
+			return 1;
+		}
+	
+		if(strcmp(argv[1],"--info")==0){
+			cout<<endl<<"Curses Invaders 4.4"<<endl;
+			cout<<endl<<"Game developed by Giacomo Parolini (jp) and Enrico Guiraud (blue) in years 2010-2013."<<endl;
+			cout<<"Source code is available under request to jp@lcm.mi.infn.it (it's quite ugly, I warn you ;-) )"<<endl;
+			cout<<"Report any bug to the same mail address."<<endl<<endl;
+			return 1;
+		}
+	}
+	
+  	typedef std::list<bullet> b_list;
+  	typedef std::list<enemy> e_list;
+  	typedef std::vector<wall> w_vec;
+  	typedef std::list<rocket> r_list;
+	srand(time(NULL));
+	
+	//OBJECTS INIZIALIZATION
+
+	player player1;						//player is automatically created in [C/2][R]
+	e_list enemies;						//vector of enemies
+	b_list bullets;                				//list of player's bullets
+	b_list bombs;						//list of enemies' bombs
+	b_list powerups;					//list of powerups
+	r_list rockets;						//list of rockets
+	int refresh_time;         				//how long the program waits before refreshing the screen
+	int chflag=0;						//cheat flag: 0=normal, 1=cheats allowed, 2=special mode activated, 3=both special mode and cheats.
+	boss boss1;
+	WINDOW *Score,*BossHP;
+	int commands[CMD_NUM]={'a','d','w','s','p',' ','l','m','q'};	//0:left,1:right,2:up,3:down,4:pause,5:shoot1,6:shoot2,7:mute,8:quit
+	
+	//PARAMETERS/UTILITIES
+	double shootrate;				  	//probability of an enemy shooting a bomb 
+	int command;						//keyboard input
+	int score=0;					   	//score: gain +100 when an enemy is destroyed and +50 when a bomb is destroyed
+	char level='1';						//difficulty level
+	//bool sound=false;					
+	
+	/*//PTHREAD STUFF
+	pthread_t thread[THREADS_NUM];
+	int bkgd_music;			//#0
+	int enshoot_sound;		//#1
+	int win_theme;			//#2
+	int lose_theme;			//#3
+	int shoot_sound;		//#4
+	
+	if(argc>1){		//./invaders -m/m/mute -> the game starts with no sounds.
+		if(strcmp(argv[1],"-s")==0 || strcmp(argv[1],"s")==0 || strcmp(argv[1],"sound")==0)
+			sound=true;
+		else{
+			cout<<"usage: "<<argv[0]<<" [-s]/[s]/[sound]"<<endl;
+			return -1;
+		}
+	}*/
+	
+	//NCURSES STUFF
+	initscr();
+	curs_set(0);
+	noecho();	
+	cbreak();
+	keypad(stdscr,TRUE);
+	start_color();
+	init_pair(0,COLOR_WHITE,COLOR_BLACK);
+	init_pair(1,COLOR_GREEN,COLOR_BLACK);	//PLAYER
+	init_pair(2,COLOR_RED,COLOR_BLACK);	//ENEMY
+	init_pair(3,COLOR_YELLOW,COLOR_BLACK);	//BULLETS-POWERUPS
+	init_pair(4,COLOR_MAGENTA,COLOR_BLACK);	//WALLS
+	init_pair(5,COLOR_CYAN,COLOR_BLACK);	//BOSS
+	init_pair(6,COLOR_BLUE,COLOR_BLACK);	//BOMBS
+	init_pair(7,COLOR_RED,COLOR_RED);	
+	init_pair(8,COLOR_GREEN,COLOR_GREEN);
+	init_pair(9,COLOR_BLACK,COLOR_GREEN);
+	
+	//////////PROGRAM START: creation of game objects and set of parameters
+	
+	WALLS_NUM=2;
+	
+	ENEMY_NUM=choose_level(shootrate, refresh_time, boss1, level, commands);     	//choose difficulty level and set game parameters and boss
+	player1.set_commands(commands);
+	erase();
+	
+	if(atoi(&level)==1) WALLS_NUM=3;
+	
+	
+	w_vec walls(WALLS_NUM);
+	
+	Score=newwin(3,10,R/3,C+3);
+	BossHP=newwin(3,15,R/3-3,C+3);
+	load_enemies(enemies,ENEMY_NUM);
+	
+	int i=0;
+	for(w_vec::iterator it=walls.begin(); it!=walls.end(); ++it, ++i)				//creating walls (in a quite symmetric pattern)
+		it->create((i+1)*(C/(3*walls.size()+1))+i*(2*C/(3*walls.size()+1)),2*R/3,(int)min(6,2*C/(3*(int)(walls.size())+1)),2,3);
+
+	bool kill_yourself = false;
+	bool keep_drawing = true;
+	std::thread t_draw(draw,std::ref(player1),std::ref(bullets),std::ref(bombs),std::ref(enemies),std::ref(walls),std::ref(powerups),std::ref(rockets),std::ref(boss1),std::ref(refresh_time),std::ref(keep_drawing),std::ref(kill_yourself));
+	
+	/////////ENTERING MAIN LOOP
+	
+	/*if(sound)
+		bkgd_music = pthread_create(&thread[0],NULL,pmusic,NULL); 	//executing background music in parallel thread*/
+	
+	if(argc>1){
+		if(strcmp(argv[1],"--uber-debug")==0){ player1.weaponclass=5; player1.weaponclassrkt=5; player1.rocketlauncher=true; player1.length=MAX_LENGTH; }
+		else if(strcmp(argv[1],"--autowin")==0){ Victory(boss1.name,score,level,0); endwin(); return 1; } 
+	}
+	
+	while(1)
+	{
+		napms(refresh_time);					//ncurses sleep function (ms)
+		timeout(0);
+	    	command = getch();
+	    	              
+	    	if(command!=ERR)                        		//READING INPUT
+	    		command = tolower(command);     
+		    		           
+	    	if(command == commands[8]){ 						//q = exit game
+	    		kill_yourself = true;
+	    		t_draw.join();
+	    		endwin();
+	    		//pkill_music(thread[0]);
+	    		cout<<lightgreen<<"Game exited correctly."<<none<<endl;
+	    		return 1;
+	    	}  
+
+	    	if(command == commands[4])
+	    		pause_game(chflag);							//p = pause game
+
+		//=====CHEATS================================================
+		
+	    	if(chflag==1 || chflag==3)
+			get_cheat(command,player1,enemies,shootrate);
+	    	if(chflag!=2 && chflag!=3)
+			get_SpecialMode(command,chflag,boss1,enemies,bullets,bombs,powerups,rockets);
+			
+		//======END CHEATS===============================================
+			    
+	    	if(command == commands[0] || command == KEY_LEFT || command == commands[1] || command == KEY_RIGHT ||
+		((chflag==1 || chflag==3) && (command == commands[2]|| command == KEY_UP || command == commands[3] || command == KEY_DOWN))){   		//a or d = move player (if cheats are triggered, also w and s)
+	    		//for(int i=player1.x;i<player1.x+player1.length;i++) //mvaddch(player1.y,i,' ');	
+	    		player1.next_pos(command);	
+	    	}	    
+		    		
+		if(command==commands[5] || command==commands[6]){                		//spacebar = shoot!
+			//if(sound) shoot_sound = pthread_create(&thread[4],NULL,pshoot_sound,NULL);
+			player1.shoot(bullets);
+			if(player1.rocketlauncher) player1.shootrkt(rockets);
+		}
+		
+		/*if(command==commands[7]){				//mute/unmute
+			if(sound) pkill_music(thread[0]);
+			else	bkgd_music = pthread_create(&thread[0],NULL,pmusic,NULL); 
+			sound=!sound;
+		}*/
+		
+		if(enemyalive(enemies))					//if there's at least one enemy alive:
+		{
+			int n_enemies=0;
+			e_list::const_iterator e_end = enemies.end();
+			
+			for(e_list::iterator it=enemies.begin(); it!=e_end; ++it)
+				if(it->alive) n_enemies++;				//counts alive enemies
+		
+			for(e_list::iterator it=enemies.begin(); it!=e_end; ++it)         
+			{
+				//mvaddch(it->y,it->x,' ');
+				it->next_pos();                                        //evaluate new positions
+				if(it->alive && (double)rand()/RAND_MAX<(shootrate*ENEMY_NUM/n_enemies)){     //try a bomb-dropping
+						//if(sound) shoot_sound = pthread_create(&thread[1],NULL,penshoot_sound,NULL);
+						it->shoot(bombs);
+				}
+			}
+		}
+		else boss1.alive = true;					//if no enemy is alive, boss spawns
+				
+		if(boss1.alive)							//if boss is alive, moves and shoots
+		{
+			for(int i=0;i<boss1.width;i++) //mvaddch(boss1.y,boss1.x+i,' ');
+			for(int j=0;j<boss1.height;j++){
+				//mvaddch(boss1.y+j,boss1.x,' ');
+				//mvaddch(boss1.y+j,boss1.x+boss1.width-1,' ');
+			}
+			boss1.next_pos();
+			if((double)rand()/RAND_MAX<shootrate*25.){		//boss's shootrate is 25 times the one of normal enemies
+				//if(sound) shoot_sound = pthread_create(&thread[1],NULL,penshoot_sound,NULL);
+				boss1.shoot(bombs);	
+			}
+		}
+		
+		if(!bullets.empty())						//evaluate new bullets' positions
+			for(b_list::iterator it=bullets.begin(); it!=bullets.end(); ++it){
+				//mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+				
+		bullets.unique();      					//remove duplicates of bullets (i.e. player can't shoot enemies)
+
+
+		if(!rockets.empty())						//evaluate new rockets' positions
+			for(r_list::iterator it=rockets.begin(); it!=rockets.end(); ++it){
+				//mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+
+		rockets.unique();
+
+		if(!bombs.empty())						//evaluate new bombs' positions
+			for(b_list::iterator it=bombs.begin(); it!=bombs.end(); ++it){
+				//mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+				  	
+		bombs.unique();						//remove duplicates of bombs
+
+		if(!powerups.empty())						//new powerups' positions
+			for(b_list::iterator it=powerups.begin(); it!=powerups.end(); ++it){
+				//mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+				
+		powerups.unique(); 	 //FIXME: THIS ONLY WORKS ON CONSECUTIVE ELEMENTS OF THE LIST!! we should at least sort powerups before calling unique()
+		
+		interactions(player1,bullets,bombs,enemies,walls,powerups,rockets,boss1,score);
+
+		///////ENDGAME CHECKS               
+		if(boss1.health<1)  					//YOU WON!!
+		{
+			/*if(sound){
+				pkill_music(thread[0]);	
+				win_theme = pthread_create(&thread[2],NULL,pwin_theme,NULL);
+			}*/
+				
+			Victory(boss1.name,score,level,chflag);
+			
+			WINDOW *replay;
+			
+			replay=newwin(3,25,26,20);
+			box(replay,ACS_VLINE,ACS_HLINE);
+		
+			if(playagain(replay))                           //playagain() returns true if player wants to play again, false otherwise
+			{
+				delwin(replay);
+				timeout(500);
+				score=0;
+				erase();
+				refresh();
+				choose_level(shootrate, refresh_time, boss1, level, commands);
+				reset(player1, enemies, boss1, bullets, bombs, walls, powerups,rockets, level,chflag); // reset box, player, enemy and deletes all bullets and bombs
+				erase();
+				refresh();
+				continue;  
+			}
+			else { 
+				kill_yourself = true;
+				t_draw.join();
+				endwin();
+				cout<<lightgreen<<"Game exited correctly."<<none<<endl;
+				return 0;
+			}	
+		}
+				
+			
+		if(gameover(player1,bombs))
+		{
+			keep_drawing = false;
+				
+			Defeat(score);
+			
+			WINDOW* replay;
+		
+			replay=newwin(3,25,17,20);
+			box(replay,ACS_VLINE,ACS_HLINE);
+			
+			if(playagain(replay))                                        //playagain() returns true if player wants to play again, false otherwise
+			{
+				delwin(replay);
+				timeout(500);
+				score=0;
+				erase();
+				refresh();
+				choose_level(shootrate, refresh_time, boss1, level, commands);
+				reset(player1, enemies, boss1, bullets, bombs, walls, powerups,rockets,level,chflag);       // reset box, player, enemy and delete all bullets and bombs
+				keep_drawing = true;
+				erase();
+				refresh();
+				continue;  
+			}
+			else {
+				kill_yourself = true;
+				t_draw.join();
+				endwin();
+				cout<<lightgreen<<"Game exited correctly."<<none<<endl;
+				return 0;
+			}
+		}
+		
+		write_score(Score,score);
+	
+		if(boss1.alive){
+			write_bosshp(BossHP,boss1.health,boss1.healthmax,boss1.name);
+			wrefresh(BossHP);
+		}
+		
+		wrefresh(Score);
+		refresh();
+	}  
+////////END OF MAIN LOOP
+
+	endwin();
+	
+	return -1;  //program never really reaches here, but compiler is happy
+}
+
+

+ 324 - 0
invaders_fork.cpp

@@ -0,0 +1,324 @@
+#include "bullet.hpp"
+#include "enemy.hpp"
+#include "player.hpp"
+#include "box.hpp"
+#include "boss.hpp"
+#include "powerup.hpp"
+#include "definitions.hpp"
+#include "functions.hpp"
+#include "wall.hpp"
+
+using std::cout;
+using std::endl; 
+using std::min;
+
+int main()
+{
+	
+  	typedef std::list<bullet> b_list;
+  	typedef std::list<enemy> e_list;
+  	typedef std::vector<wall> w_vec;
+	srand(time(NULL));
+	
+	//OBJECTS INIZIALIZATION
+	Box box1;
+	player player1;						//player is automatically created in [C/2][R]
+	e_list enemies;						//vector of enemies
+	b_list bullets;                				//list of player's bullets
+	b_list bombs;						//list of enemies' bombs
+	b_list powerups;					//list of powerups
+	int refresh_time;          				//how long the program waits before refreshing the screen
+	int chflag=0;						//cheat flag: 0=normal, 1=cheats allowed, 2=special mode activated, 3=both special mode and cheats.
+	boss boss1;
+	WINDOW *Score,*BossHP;
+	
+	//PARAMETERS/UTILITIES
+	double shootrate;				  	//probability of an enemy shooting a bomb 
+	int command;						//keyboard input
+	int score=0;					   	//score: gain +100 when an enemy is destroyed and +50 when a bomb is destroyed
+	char level='1';	
+	bool sound=true;					//difficulty level
+
+
+	//NCURSES STUFF
+	initscr();
+	curs_set(0);
+	noecho();	
+	cbreak();
+	keypad(stdscr,TRUE);
+	start_color();
+	init_pair(0,COLOR_WHITE,COLOR_BLACK);
+	init_pair(1,COLOR_GREEN,COLOR_BLACK);	//PLAYER
+	init_pair(2,COLOR_RED,COLOR_BLACK);	//ENEMY
+	init_pair(3,COLOR_YELLOW,COLOR_BLACK);	//BULLETS-POWERUPS
+	init_pair(4,COLOR_MAGENTA,COLOR_BLACK);	//WALLS
+	init_pair(5,COLOR_CYAN,COLOR_BLACK);	//BOSS
+	init_pair(6,COLOR_BLUE,COLOR_BLACK);	//BOMBS
+	init_pair(7,COLOR_RED,COLOR_RED);
+	init_pair(8,COLOR_GREEN,COLOR_GREEN);
+	
+	//////////PROGRAM START: creation of game objects and set of parameters
+		
+	WALLS_NUM=2;
+	
+	ENEMY_NUM=choose_level(shootrate, refresh_time, boss1, level);     	//choose difficulty level and set game parameters and boss
+	
+	erase();
+	
+	if(atoi(&level)==1) WALLS_NUM=3;
+	
+	w_vec walls(WALLS_NUM);
+	
+	Score=newwin(3,10,R/3,C+3);
+	BossHP=newwin(3,15,R/3-3,C+3);
+	load_enemies(enemies,ENEMY_NUM);
+	
+	int i=0;
+	for(w_vec::iterator it=walls.begin(); it!=walls.end(); ++it, ++i)				//creating walls (in a quite symmetric pattern)
+		it->create((i+1)*(C/(3*WALLS_NUM+1))+i*(2*C/(3*WALLS_NUM+1)),2*R/3,(int)min(6,2*C/(3*WALLS_NUM+1)),2,3);
+
+	box1.refresh(bullets, bombs, enemies, player1, score, boss1, walls, powerups);   //matrix is loaded for the first time
+
+	
+	/////////ENTERING MAIN LOOP
+	
+	int childPID0=fork();
+	if(childPID0==0 && sound){
+		music();
+		return 0;
+	}
+	while(1)
+	{
+		napms(refresh_time);					//ncurses sleep function (ms)
+		timeout(0);
+	    	command = getch();
+	    	              
+	    	if(command!=ERR)                        		//READING INPUT
+	    		command = tolower(command);     
+		    		           
+	    	if(command == 'q'){ 						//q = exit game
+	    		endwin();
+	    		kill_music(childPID0);
+	    		cout<<lightgreen<<"Game exited correctly."<<none<<endl;
+	    		return 1;
+	    	}  
+
+	    	if(command == 'p')
+	    		pause_game(chflag);						//p = pause game
+
+	    	if(chflag==1 || chflag==3){								//cheats
+	    		if(command == '+' && player1.weaponclass<5) player1.weaponclass++;	//increase weaponclass
+	    		if(command == '\\' && player1.weaponclass>1) player1.weaponclass--;	//decrease weaponclass
+	    		if(command == '-' && player1.length>2){					//decrease size
+				mvaddch(player1.y,player1.x+player1.length-1,' ');
+	    			player1.length--;
+	    		}
+	    		if(command == '\'' && player1.length<20) player1.length++;		//increase size
+			if(command == 'n')							//nuke enemies
+				for(e_list::iterator it=enemies.begin();it!=enemies.end();it++){
+					it->alive=false;
+					mvaddch(it->y,it->x,' ');
+				}
+	    	}
+
+	    	if(chflag!=2 && chflag!=3)
+			get_KonamiCode(command,chflag,boss1,enemies,bullets,bombs,powerups,box1);
+			    
+	    	if(command == 'a' || command == KEY_LEFT || command == 'd' || command == KEY_RIGHT ||
+		((command == 'w'|| command == KEY_UP || command == 's' || command == KEY_DOWN) &&
+		(chflag==1 || chflag==3))){   	//a or d = move player (if cheats are triggered, also w and s)
+	    		for(int i=player1.x;i<player1.x+player1.length;i++) mvaddch(player1.y,i,' ');	
+	    		player1.next_pos(command);	
+	    	}	    
+		    		
+		if(command==' '){                		//spacebar = shoot!
+			if(sound){
+				int childPID=fork();
+				if(childPID==0){
+					system("beep -f 1000 -l 30 -n -f 850 -l 30");
+					return 0;
+				}
+			}
+			player1.shoot(bullets);
+		}
+		
+		if(command=='m'){				//mute/unmute
+			if(sound) kill_music(childPID0);
+			else{
+				childPID0=fork();
+				if(childPID0==0){
+					music();
+					return 0;
+				}
+			}
+			sound=!sound;
+		}
+		
+		if(enemyalive(enemies))					//if there's at least one enemy alive:
+		{
+			int n_enemies=0;
+			e_list::const_iterator e_end = enemies.end();
+			
+			for(e_list::iterator it=enemies.begin(); it!=e_end; ++it)
+				if(it->alive) n_enemies++;				//counts alive enemies
+		
+			for(e_list::iterator it=enemies.begin(); it!=e_end; ++it)         
+			{
+				mvaddch(it->y,it->x,' ');
+				it->next_pos();                                        //evaluate new positions
+				if(it->alive && (double)rand()/RAND_MAX<(shootrate*ENEMY_NUM/n_enemies)){     //try a bomb-dropping
+						if(sound){
+							int childPID=fork();
+							if(childPID==0){
+								system("beep -f 1500 -l 30 -n -f 1000 -l 30");
+								return 0;
+							}
+						}
+						it->shoot(bombs);
+				}
+			}
+		}
+		else boss1.alive = true;					//if no enemy is alive, boss spawns
+				
+		if(boss1.alive)							//if boss is alive, moves and shoots
+		{
+			for(int i=0;i<boss1.width;i++) mvaddch(boss1.y,boss1.x+i,' ');
+			for(int j=0;j<boss1.height;j++){
+				mvaddch(boss1.y+j,boss1.x,' ');
+				mvaddch(boss1.y+j,boss1.x+boss1.width-1,' ');
+			}
+			boss1.next_pos();
+			if((double)rand()/RAND_MAX<shootrate*25.){		//boss's shootrate is 25 times the one of normal enemies
+				if(sound){
+					int childPID=fork();
+					if(childPID==0){
+						system("beep -f 1500 -l 30 -n -f 1000 -l 30");
+						return 0;
+					}
+				}
+				boss1.shoot(bombs);	
+			}
+		}
+		
+		if(!bullets.empty())						//evaluate new bullets' positions
+			for(b_list::iterator it=bullets.begin(); it!=bullets.end(); ++it){
+				mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+				
+		bullets.unique();      					//remove duplicates of bullets (i.e. player can't shoot enemies)
+
+		if(!bombs.empty())						//evaluate new bombs' positions
+			for(b_list::iterator it=bombs.begin(); it!=bombs.end(); ++it){
+				mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+				  	
+		bombs.unique();						//remove duplicates of bombs
+
+		if(!powerups.empty())						//new powerups' positions
+			for(b_list::iterator it=powerups.begin(); it!=powerups.end(); ++it){
+				mvaddch(it->y,it->x,' ');
+				it->next_pos();
+			}
+				
+		powerups.unique(); 	 //FIXME: THIS ONLY WORKS ON CONSECUTIVE ELEMENTS OF THE LIST!! we should at least sort powerups before calling unique()
+		
+		box1.refresh(bullets, bombs, enemies, player1, score, boss1, walls, powerups);		
+
+		///////ENDGAME CHECKS               
+		if(boss1.health<1)  					//YOU WON!!
+		{
+			if(sound){
+				kill_music(childPID0);
+				int childPID=fork();
+				if(childPID==0){
+					system("beep -f 1000 -l 150 -n -f 800 -l 150 -n -f 1000 -l 150 -n -f 1500 -l 600");
+					return 0;
+				}
+			}
+				
+			Victory(boss1.name,score,level,chflag);
+			
+			WINDOW *replay;
+			
+			replay=newwin(3,25,26,20);
+			box(replay,ACS_VLINE,ACS_HLINE);
+		
+			if(playagain(replay))                           //playagain() returns true if player wants to play again, false otherwise
+			{
+				delwin(replay);
+				timeout(500);
+				score=0;
+				erase();
+				refresh();
+				choose_level(shootrate, refresh_time, boss1, level);
+				reset(box1, player1, enemies, boss1, bullets, bombs, walls, powerups, level,chflag); // reset box, player, enemy and deletes all bullets and bombs
+				erase();
+				refresh();
+				continue;  
+			}
+			else { 
+				endwin();
+				cout<<lightgreen<<"Game exited correctly."<<none<<endl;
+				return 0;
+			}	
+		}
+				
+			
+		if(gameover(box1,player1))
+		{	
+			if(sound){	
+				kill_music(childPID0);
+				int childPID=fork();
+				if(childPID==0){
+					system("beep -f 700 -l 150 -n -f 585 -l 150 -n -f 550 -l 150 -n -f 520 -l 600");
+					return 0;
+				}
+			}
+				
+			Defeat(score);
+			
+			WINDOW* replay;
+		
+			replay=newwin(3,25,17,20);
+			box(replay,ACS_VLINE,ACS_HLINE);
+			
+			if(playagain(replay))                                        //playagain() returns true if player wants to play again, false otherwise
+			{
+				delwin(replay);
+				timeout(500);
+				score=0;
+				erase();
+				refresh();
+				choose_level(shootrate, refresh_time, boss1, level);
+				reset(box1, player1, enemies, boss1, bullets, bombs, walls, powerups, level,chflag);       // reset box, player, enemy and delete all bullets and bombs
+				erase();
+				refresh();
+				continue;  
+			}
+			else { 
+				endwin();
+				cout<<lightgreen<<"Game exited correctly."<<none<<endl;
+				return 0;
+			}		
+		}
+		
+		write_score(Score,score);
+	
+		if(boss1.alive){
+			write_bosshp(BossHP,boss1.health,boss1.healthmax,boss1.name);
+			wrefresh(BossHP);
+		}
+		
+		wrefresh(Score);
+		refresh();
+	}  
+////////END OF MAIN LOOP
+
+	endwin();
+	
+	return -1;  //program never really reaches here, but compiler is happy
+}
+
+

+ 10 - 0
latest.dat

@@ -0,0 +1,10 @@
+- fixato un errore in interactions che freezava il gioco (colpa mia!)
+- finito il makeover di draw...il risultato è da brivido. gelido. lungo la schiena.
+- aggiunto napms alla fine del ciclo di draw..la situazione è decisamente migliore
+- il giocatore continua a muoversi in modo incomprensibile anche resettando command a ogni ciclo
+- incluso ncurses in player.cpp nella speranza di debuggarne i movimenti inconsulti
+- riga 170 di invaders.cpp -.-" (fixatI i movimenti inconsulti)
+
+BUG:
+- dopo aver sconfitto il boss, non viene pulito lo schermo prima di sovrascrivere il main menu
+- c'è qualche problema con i rocket, fanno freezare il gioco quando colpiscono un boss (dovrebbe essere fixato)

+ 6 - 0
maderna.dat

@@ -0,0 +1,6 @@
+  99999  
+ C \ / D 
+C  0 0  D
+C_  ^  _D
+  | J |  
+   \_/   

+ 6 - 0
maero.dat

@@ -0,0 +1,6 @@
+  MMMMMMM  
+ M       M 
+|  == ==  |
+c    L    D
+ MMM   MMM 
+  MMMMMMM  

+ 91 - 0
makefile

@@ -0,0 +1,91 @@
+#MACROS
+
+OPT := -O3
+
+DEBUG := -ggdb
+
+CC := g++ -std=c++0x
+
+WARNINGS := -Wall
+
+EDITOR := gedit
+
+CURSES := -lncurses
+
+THREADS := -pthread
+
+OPTIONS := $(CURSES) $(THREADS)
+
+
+.PHONY: open, opencpp, openhpp, clean, cleanall, remake
+
+#TARGETS
+
+all: invaders bossrush
+
+invaders: game_object.o bullet.o enemy.o player.o functions.o pic.o body.o boss.o wall.o powerup.o rocket.o invaders.o
+	$(CC) $(DEBUG) $^ -o $@ $(OPTIONS)
+bossrush: game_object.o bullet.o enemy.o player.o functions.o pic.o body.o boss.o wall.o powerup.o rocket.o bossrush.o
+	$(CC) $(DEBUG) $^ -o $@ $(OPTIONS) 
+
+invaders.o: invaders.cpp bullet.hpp enemy.hpp player.hpp box.hpp rocket.hpp definitions.hpp functions.hpp
+	$(CC) $(DEBUG) -c $<
+	
+bossrush.o: bossrush.cpp bullet.hpp enemy.hpp player.hpp box.hpp rocket.hpp definitions.hpp functions.hpp
+	$(CC) $(DEBUG) -c $<
+
+#box.o: box.cpp box.hpp definitions.hpp player.hpp rocket.hpp bullet.hpp enemy.hpp boss.hpp
+#	$(CC) $(DEBUG) -c $<
+
+game_object.o: game_object.cpp game_object.hpp
+	$(CC) $(DEBUG) -c $<
+
+bullet.o: bullet.cpp bullet.hpp game_object.hpp
+	$(CC) $(DEBUG) -c $<
+	
+enemy.o: enemy.cpp enemy.hpp game_object.hpp bullet.hpp definitions.hpp
+	$(CC) $(DEBUG) -c $<
+	
+player.o: player.cpp player.hpp game_object.hpp bullet.hpp rocket.hpp definitions.hpp
+	$(CC) $(DEBUG) -c $<
+
+functions.o: functions.cpp functions.hpp definitions.hpp box.hpp player.hpp bullet.hpp enemy.hpp wall.hpp boss.hpp
+	$(CC) $(DEBUG) -c $<
+
+body.o: body.cpp body.hpp
+	$(CC) $(DEBUG) -c $<
+	
+pic.o: pic.cpp body.hpp pic.hpp definitions.hpp
+	$(CC) $(DEBUG) -c $<
+
+boss.o: boss.cpp boss.hpp pic.hpp
+	$(CC) $(DEBUG) -c $<
+
+wall.o: wall.cpp wall.hpp game_object.hpp
+	$(CC) $(DEBUG) -c $<
+	
+powerup.o: powerup.cpp powerup.hpp bullet.hpp
+	$(CC) $(DEBUG) -c $<
+
+rocket.o: rocket.cpp rocket.hpp bullet.hpp definitions.hpp
+	$(CC) $(DEBUG) -c $<
+
+#UTILITIES
+
+open:  
+	$(EDITOR) *.cpp *.hpp makefile &
+
+openhpp:
+	$(EDITOR) *.hpp&
+
+opencpp:
+	$(EDITOR) *.cpp&
+
+clean:
+	rm -f *~ *.o
+
+cleanall: clean
+	rm -f invaders
+	rm -f bossrush
+
+remake: clean invaders bossrush

+ 8 - 0
myboss.dat.old

@@ -0,0 +1,8 @@
+ertyuertyu
+ertyuertyu
+ertyuertyu
+ertyuertyu
+ertyuertyu
+ertyuertyu
+ertyuertyu
+ertyuertyu

File diff suppressed because it is too large
+ 44 - 0
notes.dat


+ 12 - 0
objectsIDs.txt

@@ -0,0 +1,12 @@
+Lest we forget:
+
+1   = PLAYER
+2   = BULLET
+4   = ENEMY
+8   = BOMB
+16  = BOSS
+32  = WALL
+64  = POWERUP+
+128 = POWERUP-
+256 = ROCKET
+512 = POWERUPX

+ 0 - 0
palombo


+ 5 - 0
palombo.dat

@@ -0,0 +1,5 @@
+  _______  
+ W _ _ _ W 
+|_|o| |o|_|
+c    c    P
+ \__NNN__/ 

+ 5 - 0
palombo.dat.old

@@ -0,0 +1,5 @@
+  _______  
+ W _ _ _ W 
+|_|o| |o|_|
+c    c    P
+ \__NNN__/ 

+ 58 - 0
pic.cpp

@@ -0,0 +1,58 @@
+#include "pic.hpp"
+
+//char** picture;
+
+pic::pic(int w, int h) : body(w,h){ 
+	picture = new char* [height];
+	for(int i=0; i<height; ++i)
+		picture[i] = new char[w];
+	clear();
+} 
+
+
+pic::~pic()
+{
+	delete [] picture;
+}
+
+
+
+void pic::loadpicture(const char* nome)
+{
+	ifstream input(nome);
+	char c;
+	if(!nome){
+		input.close();
+	}
+	else{
+		for(int i=0; i<height; i++)			//rows
+			for(int j=0; j<width; j++){    		//columns
+	 				c = input.get();       // get character from file
+	 				if(c!='\n') picture[i][j]=c;
+	 				if(c=='\n') j--;
+	 		}
+				
+		input.close();
+	}
+	
+}
+
+
+void pic::clear(){
+	for(int i=0; i<height; i++)
+		for(int j=0; j<width; j++)
+			picture[i][j]=' ';
+}
+
+void pic::set_values(int W, int H){
+	width=W;
+	height=H;
+}
+
+void pic::print(){
+	for(int i=0; i<height; i++){
+		for(int j=0; j<width; j++)
+			cout << picture[i][j];
+		cout << endl;
+	}
+}

+ 25 - 0
pic.hpp

@@ -0,0 +1,25 @@
+#ifndef _pic_hpp
+#define _pic_hpp
+
+#include "body.hpp"
+#include <fstream>
+#include <iostream>
+
+using std::ifstream; using std::ios;
+using std::cout; using std::endl;
+
+class pic : public body
+{
+	public:
+	pic() : body() { clear(); }  //carica picture piena di spazi (??????? crea un body di dimensioni indefinite!!)
+	pic(int w,int h);
+	~pic();
+	
+	char** picture;		
+	void loadpicture(const char*);	//loads picture from a file
+	void clear();		               //deletes picture
+	void set_values(int W, int H);	//sets coordinates of body
+	void print();
+};
+
+#endif

+ 213 - 0
player.cpp

@@ -0,0 +1,213 @@
+#include "player.hpp"
+
+
+player::player() : game_object(C/2, R-1, 1)
+{ 
+	length=8;
+	weaponclass=0; 
+	weaponclassrkt=0;
+	rocketlauncher=FALSE;
+	commands[0]='a';	//left
+	commands[1]='d';	//right
+	commands[2]='w';	//up
+	commands[3]='s';	//down
+	godmode=false;
+}
+
+player::player(int Length) : game_object(C/2, R, 1)
+{
+	length=(Length<2?2:(Length>20?20:Length));
+	weaponclass=0;
+	weaponclassrkt=0;
+	rocketlauncher=FALSE;
+	commands[0]='a';	//left
+	commands[1]='d';	//right
+	commands[2]='w';	//up
+	commands[3]='s';	//down
+	godmode=false;
+}
+
+void player::set_commands(int* _commands){
+	for(int i=0;i<4;i++)
+		commands[i]=_commands[i];
+}
+
+void player::next_pos(int command)  
+{
+	if((command==commands[0] || command==KEY_LEFT) && x>0) x-=2;
+	if((command==commands[1] || command==KEY_RIGHT) && x<C-length) x+=2;
+	if((command==commands[2] || command==KEY_UP) && y>0) y--;		
+	if((command==commands[3] || command==KEY_DOWN) && y<R-1) y++;
+}
+
+void player::shoot(std::list<bullet> & bullets)  
+{
+	static int thiscannon=0;
+	
+		if(weaponclass==0){
+			if(thiscannon)
+			{
+				bullet new_bullet(x+(int)(length/2.),y,2);
+				bullets.push_back(new_bullet);
+			}
+			else
+			{
+				bullet new_bullet(x+(int)(length/2.)-1,y,2);
+				bullets.push_back(new_bullet);
+			}
+			thiscannon= ~thiscannon;
+		}
+		
+		else if(weaponclass==1){
+			bullet new_bullet1(x+(int)(length/2.),y,2);
+			bullets.push_back(new_bullet1);
+			bullet new_bullet2(x+(int)(length/2.)-1,y,2);
+			bullets.push_back(new_bullet2);
+		}
+		
+		else if(weaponclass==2){
+			if(thiscannon)
+			{
+				bullet new_bullet(x+(int)(length/2.),y,2);
+				bullets.push_back(new_bullet);
+			}
+			else
+			{
+				bullet new_bullet(x+(int)(length/2.)-1,y,2);
+				bullets.push_back(new_bullet);
+			}
+			thiscannon= ~thiscannon;
+			if(length>2){
+				bullet new_bullet1(x+1,y,2);
+				bullets.push_back(new_bullet1);
+				bullet new_bullet3(x+(length-2>(int)(length/2.)?length-2:((int)(length/2.)+1>length?length-1:(int)(length/2.)+1)),y,2);
+				bullets.push_back(new_bullet3);
+			}
+		}
+		
+		else if(weaponclass==3){
+			bullet new_bullet(x+(int)(length/2.),y,2);
+			bullets.push_back(new_bullet);
+			bullet new_bullet2(x+(int)(length/2.)-1,y,2);
+			bullets.push_back(new_bullet2);
+			if(length>2){
+				bullet new_bullet1(x+1,y,2);
+				bullets.push_back(new_bullet1);
+				bullet new_bullet3(x+(length-2>(int)(length/2.)?length-2:((int)(length/2.)+1>length?length-1:(int)(length/2.)+1)),y,2);
+				bullets.push_back(new_bullet3);
+			}
+		}
+		
+		else if(weaponclass==4){
+			bullet new_bullet4(x+(int)(length/2.)-1,y,2);
+			bullets.push_back(new_bullet4);
+			bullet new_bullet5(x+(int)(length/2.),y,2);
+			bullets.push_back(new_bullet5);
+			if(length>2){
+				bullet new_bullet6(x+(int)(length/2.)+1,y,2);
+				bullets.push_back(new_bullet6);
+				bullet new_bullet2(x+(length-2>(int)(length/2.)+1?length-2:length-1),y,2);
+				bullets.push_back(new_bullet2);
+				bullet new_bullet3(x+(1<(int)(length/2.)-2?1:0),y,2);
+				bullets.push_back(new_bullet3);
+			}
+			if(length>4){
+				bullet new_bullet7(x+(int)(length/2.)-2,y,2);
+				bullets.push_back(new_bullet7);
+			}
+		}
+		
+		else if(weaponclass==5){
+			for(int i=0;i<length;i++){
+				bullet new_bullet(x+i,y,2);
+				bullets.push_back(new_bullet);
+			}
+		}
+
+
+}
+
+void player::shootrkt(std::list<rocket>& rockets)
+{
+	static int thiscannon=0;
+	
+		if(weaponclassrkt==0){
+			if(thiscannon)
+			{
+				rocket new_rocket(x+(int)(length/2.),y,1);
+				rockets.push_back(new_rocket);
+			}
+			else
+			{
+				rocket new_rocket(x+(int)(length/2.)-1,y,-1);
+				rockets.push_back(new_rocket);
+			}
+			thiscannon= ~thiscannon;
+		}
+		
+		else if(weaponclassrkt==1){
+			rocket new_rocket1(x+(int)(length/2.),y,1);
+			rockets.push_back(new_rocket1);
+			rocket new_rocket2(x+(int)(length/2.)-1,y,-1);
+			rockets.push_back(new_rocket2);
+		}
+		
+		else if(weaponclassrkt==2){
+			if(thiscannon)
+			{
+				rocket new_rocket(x+(int)(length/2.),y,1);
+				rockets.push_back(new_rocket);
+			}
+			else
+			{
+				rocket new_rocket(x+(int)(length/2.)-1,y,-1);
+				rockets.push_back(new_rocket);
+			}
+			thiscannon= ~thiscannon;
+			if(length>2){
+				rocket new_rocket1(x+1,y,1);
+				rockets.push_back(new_rocket1);
+				rocket new_rocket3(x+(length-2>(int)(length/2.)?length-2:((int)(length/2.)+1>length?length-1:(int)(length/2.)+1)),y,-1);
+				rockets.push_back(new_rocket3);
+			}
+		}
+		
+		else if(weaponclassrkt==3){
+			rocket new_rocket(x+(int)(length/2.),y,1);
+			rockets.push_back(new_rocket);
+			rocket new_rocket2(x+(int)(length/2.)-1,y,-1);
+			rockets.push_back(new_rocket2);
+			if(length>2){
+				rocket new_rocket1(x+1,y,1);
+				rockets.push_back(new_rocket1);
+				rocket new_rocket3(x+(length-2>(int)(length/2.)?length-2:((int)(length/2.)+1>length?length-1:(int)(length/2.)+1)),y,-1);
+				rockets.push_back(new_rocket3);
+			}
+		}
+		
+		else if(weaponclassrkt==4){
+			rocket new_rocket4(x+(int)(length/2.)-1,y,1);
+			rockets.push_back(new_rocket4);
+			rocket new_rocket5(x+(int)(length/2.),y,-1);
+			rockets.push_back(new_rocket5);
+			if(length>2){
+				rocket new_rocket6(x+(int)(length/2.)+1,y,1);
+				rockets.push_back(new_rocket6);
+				rocket new_rocket2(x+(length-2>(int)(length/2.)+1?length-2:length-1),y,-1);
+				rockets.push_back(new_rocket2);
+				rocket new_rocket3(x+(1<(int)(length/2.)-2?1:0),y,1);
+				rockets.push_back(new_rocket3);
+			}
+			if(length>4){
+				rocket new_rocket7(x+(int)(length/2.)-2,y,-1);
+				rockets.push_back(new_rocket7);
+			}
+		}
+		
+		else if(weaponclassrkt==5){
+			for(int i=0;i<length;i++){
+				rocket new_rocket(x+i,y,pow(-1.,(double)i));
+				rockets.push_back(new_rocket);
+			}
+		}
+}

+ 29 - 0
player.hpp

@@ -0,0 +1,29 @@
+#ifndef _player_
+#define _player_
+
+#include "game_object.hpp"
+#include "rocket.hpp"
+#include "definitions.hpp"
+#include <list>
+
+class player : public game_object
+{	
+	public:
+	player();					 //default constructor: creates a 8-long player in C/2,R
+	player(int);		        		//user-defined length constructor
+	~player() {}
+	
+	void next_pos(int command);   		//moves player according to command (WASD or arrow keys)
+	void shoot(std::list<bullet> &);           	//adds a new bullet to the list
+	void shootrkt(std::list<rocket> &);
+	void set_commands(int* _commands);
+	int weaponclass;
+	int weaponclassrkt;
+	int length;
+	bool rocketlauncher;		//when rocketlauncher is TRUE, player can shoot rockets.
+	int commands[4];
+	bool godmode;
+
+};
+
+#endif

+ 5 - 0
powerup.cpp

@@ -0,0 +1,5 @@
+#include "powerup.hpp"
+
+powerup::powerup(int x,int y):bullet(x,y,64){}
+
+powerup::powerup(int x,int y,int ID):bullet(x,y,ID){}

+ 12 - 0
powerup.hpp

@@ -0,0 +1,12 @@
+#ifndef _powerup_
+#define _powerup_
+
+#include "bullet.hpp"
+
+class powerup:public bullet{
+	public:
+	powerup(int x,int y);
+	powerup(int x,int y,int ID);
+};
+
+#endif

+ 45 - 0
records.dat

@@ -0,0 +1,45 @@
+erc.. 	26400
+jack. 	25150
+jack. 	24650
+blue. 	19900
+blue. 	19500
+jack. 	18400
+jack. 	18300
+lupy. 	18250
+jack. 	17800
+i.... 	17000
+jack. 	16200
+jack. 	15250
+ano.. 	14300
+blue. 	13800
+jack. 	13800
+jack. 	13600
+lupy. 	13500
+jack. 	13350
+lupy. 	13000
+jack. 	12700
+lupy. 	12650
+jack. 	12600
+jack. 	12100
+jack. 	12050
+jack. 	11950
+blue. 	11300
+jack. 	11300
+jack. 	11150
+erc.. 	11100
+jack. 	10950
+jack. 	10950
+jack. 	9800
+blue. 	9700
+blue. 	9700
+blue. 	9400
+jack. 	8750
+jackù 	8250
+jack. 	6000
+jack. 	5800
+jack. 	5400
+jack. 	5350
+lol.. 	5100
+jack. 	4850
+jack. 	4750
+a.... 	1700

+ 2 - 0
records_bossrush.dat

@@ -0,0 +1,2 @@
+jack. 	6650
+jack. 	6600

+ 18 - 0
rocket.cpp

@@ -0,0 +1,18 @@
+#include "rocket.hpp"
+
+rocket::rocket(int X,int Y,int V) : bullet(X,Y,256){
+	v=(V>=0?1:-1);
+}
+
+void rocket::next_pos(){
+	y--;
+	if(x==C-1 || x==0) v*=-1;
+	switch(v){
+		case 1:
+			x++;
+			break;
+		case -1:
+			x--;
+			break;
+	}
+}

+ 19 - 0
rocket.hpp

@@ -0,0 +1,19 @@
+#ifndef _rocket_
+#define _rocket_
+
+#include "bullet.hpp"
+#include "definitions.hpp"
+
+class rocket : public bullet
+{
+	public:
+	rocket(int X,int Y,int V);
+	~rocket() {}
+
+	void next_pos();
+
+	int v;
+
+};
+	
+#endif

+ 66 - 0
setboss.sh

@@ -0,0 +1,66 @@
+#!/bin/bash
+
+# Usage: ./setboss.sh <boss_name> <n>
+# This script modifies invaders' source code so that
+# the boss depicted in boss_name.dat be the boss for the n-th level
+# WHAT'S ACTUALLY DONE: (using command line setboss myboss.dat 2)
+# in file "definitions.hpp", line
+# #define BOSS_FILE2 "palombo"
+# becomes
+# #define BOSS_FILE2 "myboss"
+
+
+# Just to be on the safe side, the script also creates a backup copy
+# of definitions.hpp called definitions.hpp.bu
+
+MAX_LVL=3
+MIN_LVL=1
+
+if [ $# -ne 2 ]; then
+	echo Usage: $0 \<bossname\> \(must be a .dat, but DON\'T specify the extension when passing it\) \<level\>
+	echo Now leaving
+	exit 1
+fi
+
+NEW_BOSS_NAME=$1
+NEW_BOSS_FILE="$NEW_BOSS_NAME.dat"
+if [ ! -e $NEW_BOSS_FILE -o ! -f $NEW_BOSS_FILE ]; then
+	echo Could not find specified file $1
+	echo Now leaving
+	exit 2
+elif [[ ! "$NEW_BOSS_FILE" =~ dat$  ]]; then
+	echo This does not look like a text file
+	echo Now leaving
+	exit 3
+fi
+
+LEVEL=$2
+# This works too for some reason
+# if ! [ $2 -eq $2 ] &> /dev/null; then
+# 	echo Second argument $2 should be numeric!
+# 	echo Now leaving
+# 	exit 4
+# fi
+if [ $LEVEL -eq $LEVEL ] &> /dev/null; then
+	if [ $LEVEL -lt $MIN_LVL ]; then
+		LEVEL=$MIN_LVL
+	elif [ $LEVEL -gt $MAX_LVL ]; then
+		LEVEL=$MAX_LVL
+	fi
+else
+	echo Second argument should be numeric!
+	echo Now leaving
+	exit 4
+fi
+
+
+./checkboss.sh $NEW_BOSS_FILE
+
+# Everything has been checked, file exists and has .dat extension, second argument is an integer
+# with value between $MIN_LVL and $MAX_LVL
+# Now for the easy part:
+
+cp definitions.hpp definitions.hpp.bu
+sed s/"BOSS_FILE$LEVEL \".*\""/"BOSS_FILE$LEVEL \"$NEW_BOSS_NAME\""/ definitions.hpp > outputsed.tmp
+mv outputsed.tmp definitions.hpp
+echo "boss lv $LEVEL  successfully set."

+ 43 - 0
setsize.sh

@@ -0,0 +1,43 @@
+#!/bin/bash
+
+DEFAULT_R=30
+DEFAULT_C=60
+R=0
+C=0
+INPUT_FILE=definitions.hpp
+
+trap "rm $INPUT_FILE.tmp 2> /dev/null; exit -1" SIGINT SIGTERM
+
+if [[ $1 == "default" ]]; then
+	sed s/"#define R [0-9]*"/"#define R $DEFAULT_R"/ <$INPUT_FILE >$INPUT_FILE.tmp
+	sed s/"#define C [0-9]*"/"#define C $DEFAULT_C"/ <$INPUT_FILE.tmp >$INPUT_FILE
+	rm $INPUT_FILE.tmp
+	make clean
+	make -j4
+	exit 0
+elif [[ $# -gt 0 ]]; then echo Usage: $0 "[default]"; exit 1
+else
+
+echo Insert new Row number \(5-120\)
+until [[ $R -ge 5 && $R -le 120 ]]; do
+	read R
+	if [[ $R -lt 5 || $R -gt 120 ]]; then echo Invalid size.; fi
+	echo New R will be $R
+done
+
+echo Insert new Column number \(5-120\)
+until [[ $C -ge 5 && $C -le 120 ]]; do
+	read C
+	if [[ $C -lt 5 || $C -gt 120 ]]; then echo Invalid size.; fi
+	echo New C will be $C
+done
+
+sed s/"#define R [0-9]*"/"#define R $R"/ <$INPUT_FILE >$INPUT_FILE.tmp
+sed s/"#define C [0-9]*"/"#define C $C"/ <$INPUT_FILE.tmp >$INPUT_FILE
+
+rm $INPUT_FILE.tmp
+
+make clean
+make -j4
+
+fi

+ 6 - 0
spoletini.dat

@@ -0,0 +1,6 @@
+  _____  
+//     \\
+|  0 0  |
+c   L   P
+\  MMM  /
+ \_____/ 

+ 6 - 0
spoletini.dat.old

@@ -0,0 +1,6 @@
+  _____  
+//     \\
+|  0 0  |
+c   L   P
+\  MMM  /
+ \_____/ 

+ 44 - 0
wall.cpp

@@ -0,0 +1,44 @@
+#include "wall.hpp"
+
+wall::wall():game_object(0,0,32) , body(0,0){}		//default constructor
+
+wall::wall(int x,int y,int w,int h,int life) : game_object(x,y,32) , body(w,h){ 
+	/*health = new int* [height];
+	for(int i=0; i<height; ++i)
+		health[i] = new int[w];*/
+	set_life(life);	
+} 
+
+
+wall::~wall()
+{
+	//delete [] health;		if this line is commented, the program won't receive SIGSEGV after calling the destructor while creating walls' vector.
+}
+
+
+void wall::set_life(int Life){
+	for(int i=0;i<width;i++)
+		for(int j=0;j<height;j++)
+			health[j][i]=Life;
+	
+}
+
+void wall::create(int X,int Y,int W, int H,int life){ 
+	x=X;
+	y=Y;
+	width=W;
+	height=H;
+	/*health = new int* [height];
+	for(int i=0; i<height; ++i)
+		health[i] = new int[width];*/
+	set_life(life);	
+} 
+
+void wall::printlife(){
+	for(int i=0;i<height;i++){
+		for(int j=0;j<width;j++)
+			std::cout<<health[i][j];
+		std::cout<<std::endl;
+	}
+	std::cout<<std::endl;
+}

+ 20 - 0
wall.hpp

@@ -0,0 +1,20 @@
+#ifndef _wall_
+#define _wall_
+
+#include "game_object.hpp"
+#include "body.hpp"
+#include <iostream>
+
+class wall:public game_object, public body{
+	public:
+	wall();
+	wall(int x,int y,int w,int h,int life);
+	~ wall();
+	//int** health;
+	int health[MAX_WIDTH][MAX_HEIGHT];
+	void set_life(int life);
+	void create(int x,int y,int w,int h,int life);	//re-initializes parameters of a pre-existent wall
+	void printlife();					//prints health matrix
+};
+
+#endif