#include #include #include #include #include #define X_MAX 80 #define Y_MAX 23 #define ROOMS 8 #define ROOM_SIZE 7 #define ENEMIES_IN_LEVEL 5 #define HP_MAX 50 #define MAX_POTIONS_PER_FLOOR 5 #define WALL 0xB2 #define EMPTY 0xFF #define PLAYER 0x02 #define ENEMY 'X' #define EXIT '>' #define DOUBLELINE 0xCD #define ITEM_SMALL_POTION 'p' #define ITEM_MEDIUM_POTION 'n' #define ITEM_BIG_POTION 'm' using namespace std; //Mappa del gioco unsigned char map[X_MAX][Y_MAX]; //Tutta sta roba non si potrebbe mettere in una classe giocatore o qualcosa del genere? //Numero del piano raggiunto dal giocatore int depth = 1; //Salute del giocatore int hp = HP_MAX; //Inventario del giocatore int pozioni_vita_piccole = 3; int pozioni_vita_medie = 2; int pozioni_vita_grandi = 1; //Classe dei nemici class Enemy { public: int x; int y; void move() { //Se intorno c'è il giocatore if(map[x-1][y] == PLAYER || map[x+1][y] == PLAYER || map[x][y-1] == PLAYER || map[x][y+1] == PLAYER) { //Forse sarebbe meglio fare una funzione per togliere vita che controlla anche se va a 0... hp--; } else { //Muoviti in una direzione casuale bool moving = true; while(moving) { int direction = rand() % 4; switch(direction) { case 0: //Sinistra if(map[x-1][y] == EMPTY) { map[x][y] = EMPTY; map[x-1][y] = ENEMY; x--; moving = false; } break; case 1: //Destra if(map[x+1][y] == EMPTY) { map[x][y] = EMPTY; map[x+1][y] = ENEMY; x++; moving = false; } break; case 2: //Su if(map[x][y-1] == EMPTY) { map[x][y] = EMPTY; map[x][y-1] = ENEMY; y--; moving = false; } break; case 3: //Giù if(map[x][y+1] == EMPTY) { map[x][y] = EMPTY; map[x][y+1] = ENEMY; y++; moving = false; } break; } } } } }; //Cura il giocatore di x void heal(int x) { if(hp + x > HP_MAX) { hp = HP_MAX; } else { hp += x; } } //Visualizza l'inventario void inventory() { system("cls"); cout << "Piano: " << depth << ' ' << "Vita: " << hp << "/" << HP_MAX << "\n"; for(int i = 0; i < X_MAX; i++) { cout << (char) DOUBLELINE; } //Anche qui, credo si possa migliorare qualcosa... if(pozioni_vita_piccole > 0) { cout << pozioni_vita_piccole << "x Pozione di Vita (p)iccola\tRipristina 10 Vita\n"; } else { cout << '\n'; } if(pozioni_vita_medie > 0) { cout << pozioni_vita_medie << "x Pozione di Vita (n)ormale\tRipristina 20 Vita\n"; } else { cout << '\n'; } if(pozioni_vita_grandi > 0) { cout << pozioni_vita_grandi << "x Pozione di Vita (m)aggiore\tRipristina 50 Vita\n"; } else { cout << '\n'; } //Selezione dell'oggetto da usare. cout << "Scrivi la lettera corrispondente all'oggetto che vuoi usare.\n"; while(true) { //Effetto degli oggetti unsigned char selezione = getch(); if(selezione == 112) //p { if(pozioni_vita_piccole > 0) { pozioni_vita_piccole--; heal(10); break; } } else if(selezione == 110) //n { if(pozioni_vita_medie > 0) { pozioni_vita_medie--; heal(20); break; } } else if(selezione == 109) //m { if(pozioni_vita_grandi > 0) { pozioni_vita_grandi--; heal(50); break; } } } } //Aggiorna la console con la situazione corrente del gioco. void draw() { //Svuota lo schermo della console. Sono sicuro che ci sia un modo molto migliore per farlo, ma non mi viene in mente... system("cls"); for(int y=0; y end_y) { for(int y=end_y; y<=start_y; y++) { map[start_x][y] = EMPTY; } } else { for(int y=start_y; y<=end_y; y++) { map[start_x][y] = EMPTY; } } if(start_x > end_x) { for(int x=end_x; x<=start_x; x++) { map[x][end_y] = EMPTY; } } else { for(int x=start_x; x<=end_x; x++) { map[x][end_y] = EMPTY; } } } else { if(start_x > end_x) { for(int x=end_x; x<=start_x; x++) { map[x][start_y] = EMPTY; } } else { for(int x=start_x; x<=end_x; x++) { map[x][start_y] = EMPTY; } } if(start_y > end_y) { for(int y=end_y; y<=start_y; y++) { map[end_x][y] = EMPTY; } } else { for(int y=start_y; y<=end_y; y++) { map[end_x][y] = EMPTY; } } } } //Genera il livello void generate(int player[2], Enemy* list[ENEMIES_IN_LEVEL]) { int corridor_x; int corridor_y; //Creazione delle stanze for(int r=0; r 0) { int link_x = rand() % size_x + 1 + start_x; int link_y = rand() % size_y + 1 + start_y; corridor(link_x, link_y, corridor_x, corridor_y, rand() % 2); } corridor_x = rand() % size_x + start_x; corridor_y = rand() % size_y + start_y; //Posiziona il giocatore se è l'ultima stanza if(r == ROOMS - 1) { player[0] = corridor_x; player[1] = corridor_y; map[corridor_x][corridor_y] = PLAYER; } } //Posizionamento nemici for(int e=0; ex = x; created->y = y; list[e] = created; break; } } } //Posizionamento uscita while(true) { int x = rand() % (X_MAX - 1) + 1; int y = rand() % (Y_MAX - 1) + 1; if(map[x][y] == EMPTY) { map[x][y] = EXIT; break; } } //Posizionamento pozioni di vita int placed_potions = 0; int potions_in_floor = rand() % MAX_POTIONS_PER_FLOOR + 1; while(placed_potions < potions_in_floor) { int x = rand() % (X_MAX - 1) + 1; int y = rand() % (Y_MAX - 1) + 1; int size = rand() % 100; if(map[x][y] == EMPTY) { if(size < 60) { map[x][y] = ITEM_SMALL_POTION; } else if(size > 90) { map[x][y] = ITEM_BIG_POTION; } else { map[x][y] = ITEM_MEDIUM_POTION; } placed_potions++; } } } //Processa il resto di un turno, dopo il movimento del giocatore. void tick(Enemy* list[ENEMIES_IN_LEVEL]) { for(int e=0; emove(); } } int main() { int player[2]; Enemy* list[ENEMIES_IN_LEVEL]; //Lista di tutti i nemici nel livello srand(0); //TODO: Rendere il seed modificabile...? //Ciclo del gioco while(true) { init(); generate(player, list); draw(); //Ciclo di un livello while(true) { int trigger = move(player); if(trigger == 1) //Uscita toccata { break; } tick(list); draw(); } depth++; } return 0; }