[SOLVED] Here's the entirety of my code all finished a working:
#include <ncurses.h>
#include <random>
#include <ctime>
using namespace std;
//VARIABLES
///////////
int tick_count = 0;
char key;
int width = 10, height = 10;
class Entity {
public:
class Common {
public:
char icon;
int x, y;
char collide;
int power = 0, speed = 0, defense = 0, health = 0;
int hp;
virtual void move(int dir) {
switch (dir) {
case 1:
y--;
break;
case 2:
y++;
break;
case 3:
x--;
break;
case 4:
x++;
break;
}
}
virtual ~Common() {}
};
class Player: public Common {
public:
int target, room;
Player() {
icon = '@';
x = 1, y = 1;
collide = 'n';
power = 1, speed = 1, defense = 1, health = 10;
hp = health;
}
};
class Kobold: public Common {
public:
Kobold() {
icon = 'K';
collide = 'n';
power = 1, speed = 0, defense = 1, health = 2;
hp = health;
}
};
class Spider: public Common {
public:
Spider() {
icon = 'S';
collide = 'n';
power = 4, speed = 2, defense = 0, health = 3;
hp = health;
}
};
};
class Room {
public:
int width, height, difficulty, enemies;
};
Room room[1];
Entity::Player player;
Entity::Common * enemy[2];
int enemy_ID, enemy_count = 2;
///////////
void INIT() {
room[0].width = 10, room[0].height = 10, room[0].enemies = 0;
player.x = player.y = 1, player.collide = 'n', player.room = 0;
enemy[0] = new Entity::Kobold();
enemy[1] = new Entity::Spider();
enemy[0]->x = enemy[0]->y = 5;
enemy[1]->x = enemy[1]->y = 8;
}
void DRAW() {
clear();
printw("ATK: %d, DEF: %d, HP: %d \n", player.power, player.defense, player.hp);
printw("#");
for (int i = 0; i < room[player.room].width - 1; i++) {
printw("--");
}
printw("-#\n");
for (int j = 0; j < room[player.room].height; j++) {
printw("|");
for (int i = 0; i < room[player.room].width; i++) {
if (i == room[player.room].width - 1) {
if (i == player.x and j == player.y) {
printw("%c", player.icon);
}
else if (i == enemy[enemy_ID]->x and j == enemy[enemy_ID]->y) {
printw("%c", enemy[enemy_ID]->icon);
}
else {
printw(" ");
}
}
else {
if (i == player.x and j == player.y) {
printw("%c ", player.icon);
}
else if (i == enemy[enemy_ID]->x and j == enemy[enemy_ID]->y) {
printw("%c ", enemy[enemy_ID]->icon);
}
else {
printw(" ");
}
}
}
printw("|\n");
}
printw("#");
for (int i = 0; i < width - 1; i++) {
printw("--");
}
printw("-#\n");
//Debug
mvprintw(1, 30, "%d %s %c %c", tick_count, typeid(enemy[0]).name(), player.collide, enemy[0]->collide);
}
void LOGIC() {
//GAME LOGIC
////////////
tick_count += 1;
srand(time(NULL));
////////////
//BATTLE LOGIC
//////////////
if (player.collide == 'e' or enemy[enemy_ID]->collide == 'p') {
for (int i; i < enemy_count; i++) {
if (enemy[enemy_ID]->collide == 'p')
player.target = i;
}
if (player.speed > enemy[player.target]->speed) {
}
else if (player.speed < enemy[player.target]->speed) {
}
else if (player.speed == enemy[player.target]->speed) {
if (player.collide = 'e') {
if (rand() % 2) {
enemy[player.target]->hp -= player.power - enemy[player.target]->defense;
mvprintw(14, 0, "You hit %s with %d damage", enemy[player.target], player.power - enemy[player.target]->defense);
clrtoeol();
}
else {
}
}
else if (player.collide = 'n') {
player.hp -= enemy[player.target]->power - player.defense;
mvprintw(14, 0, "%s hit you with %d damage", enemy[player.target], enemy[player.target]->power - player.defense);
getch();
clrtoeol();
}
}
}
//////////////
//PLAYER LOGIC
//////////////
if (player.x - 1 == enemy[enemy_ID]->x and player.y == enemy[enemy_ID]->y and key == 'a'
or player.x + 1 == enemy[enemy_ID]->x and player.y == enemy[enemy_ID]->y and key == 'd'
or player.y - 1 == enemy[enemy_ID]->y and player.x == enemy[enemy_ID]->x and key == 'w'
or player.y + 1 == enemy[enemy_ID]->y and player.x == enemy[enemy_ID]->x and key == 's'
)
player.collide = 'e';
else
player.collide = 'n';
if (player.x < 0)
player.x = 0;
else if (player.x == width)
player.x = width - 1;
else if (player.y < 0)
player.y = 0;
else if (player.y == height)
player.y = height - 1;
//////////////
//ENEMY LOGIC
/////////////
for (enemy_ID = 0; enemy_ID < enemy_count - 1; enemy_ID++)
enemy_ID++;
if (enemy[enemy_ID]->x == player.x and enemy[enemy_ID]->y > player.y and enemy[enemy_ID]->y - 1 != player.y)
enemy[enemy_ID]->move(1);
else if (enemy[enemy_ID]->x == player.x and enemy[enemy_ID]->y < player.y and enemy[enemy_ID]->y + 1 != player.y)
enemy[enemy_ID]->move(2);
else if (enemy[enemy_ID]->y == player.y and enemy[enemy_ID]->x > player.x and enemy[enemy_ID]->x - 1 != player.x)
enemy[enemy_ID]->move(3);
else if (enemy[enemy_ID]->y == player.y and enemy[enemy_ID]->x < player.x and enemy[enemy_ID]->x + 1 != player.x)
enemy[enemy_ID]->move(4);
if (enemy[enemy_ID]->x - 1 == player.x and player.y == enemy[enemy_ID]->y
or enemy[enemy_ID]->x + 1 == player.x and player.y == enemy[enemy_ID]->y
or enemy[enemy_ID]->y - 1 == player.y and player.x == enemy[enemy_ID]->x
or enemy[enemy_ID]->y + 1 == player.y and player.x == enemy[enemy_ID]->x
)
enemy[enemy_ID]->collide = 'p';
else
enemy[enemy_ID]->collide = 'n';
/////////////
}
void INPUT() {
key = getch();
switch (key) {
case 'w':
player.move(1);
break;
case 's':
player.move(2);
break;
case 'a':
player.move(3);
break;
case 'd':
player.move(4);
break;
}
}
int main() {
initscr();
cbreak();
noecho();
INIT();
DRAW();
while (key != '\n') {
//Main Loop
///////////////////////
INPUT();
LOGIC();
DRAW();
///////////////////////
refresh();
}
endwin();
return 0;
}
[QUESTION] (Sorry for potentially confusing title) I'm making an old styled ascii based rogue-like. Here's some code:
class Entity {
public:
class Player {
public:
int x, y, target;
char collide;
int power = 1, speed = 1, defense = 1, health = 10;
int hp = health;
void move(int dir);
};
class Kobold {
public:
int x, y;
char collide;
const int power = 2, speed = 1, defense = 1, health = 3;
int hp = health;
void move(int dir);
};
My goal is to have an array named enemy
and have each array value (or whatever it's called) have a different class as its type. For Example: enemy[0]
can be an object of Kobold
which is a member of Entity
, and have enemy[5]
be an object of Spider
which is a member of Entity
and etc. This way it's easier to have enemies that that are easier to declare and reference in for
loops. What I'm asking for is how to declare the array enemy
in such a way. It would be nice to have and answer to what I'm asking, but I'm not sure it's possible in a simple way, so if anyone has a simpler or easier way to accomplish my goal I would also like to see it. Thanks in advance.
Edit: Example code (ignore that it's not real):
//Declaring an array with 8 values with no type
void enemy[8];
//Assigning the Kobold class to the first enemy as it's type
enemy[0] = Entity::Kobold;
//Assigning the Spider class to the 3rd enemy as it's type
enemy[2] = Entity::Spider;
//Player attacks 3rd enemy (spider) and inflicts damage
enemy[2].hp -= player.power;
//Checks if any enemy is dead, and if so then delete it
for (int i = 0; i < 8; i++) {
if (enemy[i].hp <= 0) {
//Removing enemy from it's class, therefore deleting it
void enemy[i];
}
}
//First enemy (Kobold) attacks player, inflicting damage
player.hp -= enemy[0].power;
//Player isn't dead, and attacks first enemy (Kobold) and kills it
enemy[0].hp -= player.power;
//Checks if any enemy is dead, and if so then delete it (again)
for (int i = 0; i < 8; i++) {
if (enemy[i].hp <= 0) {
//Removing enemy from it's class, therefore deleting it
void enemy[i];
}
}
printw("You Win!");
I know it's not effective and probably has some errors, but it's just there to help visualize what I'm trying to do.
Edit:
This is similar to what I'm asking: Is it possible to have an array of different objects that come from the same base class?
I am trying to make an array as an object of Entity
but I want to have any array value be an object of any sub-class from Entity
. So something like this:
Entity enemy[5];
enemy[0] = new Kobold;
enemy[4] = new Spider;
And then I can reference to the easier like this:
for (int i = 0; i < 5; i++) {
if (array[i].x == player.x and array[i].y == player.y) {
printw("player and an enemy are in the same spot");
}
}
So the point is to easily access variables from every enemy (virtually) at once.
Another example (checking if any enemy has 0 hp):
for (int i = 0; i < amount_of_enemies; i++) {
if (enemy[i].hp <= 0) {
//some code to delete the enemy and give player XP etc.
}
}