How to make new arrays and recognize them?

Hi everyone,
i'm trying to make a roguelike game in my spare time, it's all based on arrays(monsters positions, obstacles) but i'm to sure how to implement loots:

When a monster die it drops some items on the floor, or, in the same way, the player can drop some items, in a certain point of the map; so i think i need some "container" linked to that specific position, in fact i needs two arrays: one for item names and one for quantity (i can do the job in one array but let suppose using two).

So, i can't code an array for every single spot on the map (suppose 250x250 tiles map), i need something that can create an array when needed; the "key" to open a specific array can be the position on map, but i don't know how to create an array on-the-fly which is linked with the "key"!

Can you please help me?


PS im not searching for a theoretical lesson on how computer works, i need a practical solution of the problem
Last edited on
This sounds like something you'd want to use an associative container for, something like an std::map or std::unordered_map.

Alternatively, if you already have a class that represents one space in your grid, you could just add 1 or 2 std::vectors to it for stuff that's dropped on the ground.

-Albatross
Use vectors instead of C style arrays. Easily resizable on demand.

Easier to work with, much the same syntax for element access as arrays, really convenient if you are wanting to pass vectoring into functions.

Creating multi-dimensional vectors is doable, too.

Now go forth and study. If/when you have written some code post it here so we can help you with any problems/questions that come up.
tie them all together.

struct items
{
string name; //thinking "arrows"
int quantity; //thinking: 25 arrows
//other stuff... as needed? type perhaps.. weapon/armor/consumed/ eh?
}


struct maptile
{
int x,y; //thinking: position
//type again? blocked, open, door, stairs,
//things that can be there... traps, etc?
vector<items> myloot; //empty is possible, a list of things is possible...
};

and a 2d vector of maptiles is your floor?

isn't the source for rogue or angband still around? could see how it was done, though it may be C or something.
Last edited on
@jonnin

I'like your way of thinking :)

Suppose i am on tile "X" and i'm entering in tile "Y", how can i make code do:

"is entering on "Y", check for the existence of a "Y_items_container"";

or in the same way:

"a monster is killed on "Y" tile, dropping items, create an array named "Y_items_container""
or even:
"a monster is killed on "Y" tile, dropping items, create an array with unique name", then i'll find a way [maybe a switch] in which 'if entering Y tile -> open this specific array'.


I'think the source code of angband is free, but i don't want to analyze it, is a complete and complex game, with its own logic and structure, i don't tink i can undestand something really useful :/
Last edited on
I assumed tiles in my code are a 2-d x,y pair, like math coordinates.
so if you are at 0,0 and moving to 0,1
ok... you have some routine out there that moves your guy around.
when you move, you land in (0,1) and immediately handle that tile … or offer the user a way to interact with that tile (user can attempt to pick up any junk there, drop junk there, move up and down the stairs if any, … etc).

and a monster is going to have its own movement routine.
it moves around, chasing the hero (or sitting still, or wandering aimlessly, as per rogue original), until a fight happens, then when it dies, you detect that in its combat routine and drop the loot there, on the tile where it currently is (was?)

does this make sense?

the 'specific' arrays are already there, and you know them.
you know you are at a tile, or a monster is at a tile. And a tile has a property, the array of stuff at that tile. Its there, you just use it. It could be empty, it could be the motherload of all loot, doesn't matter. The tile tells you which array to tap.


yea angband is gigantic, for an ascii art dos game, it was intense.

but do not just listen to me blindly. Consider what I said, but consider what YOU want to DO with your game more. This is a generic, 10 cent starting place for a design.. an object oriented design, though very crude so far. You have to think about what needs to be an object .. is an item an object? I said yes. Is a map tile an object? I said yes. Monsters? Your character? Probably. The map itself? Maybe, I said no (I made it a container of tiles instead). Think about how you want things to interact, and the relations between things. A player has items. A maptile has items. A monster even has items (the stuff it will drop). So you need to re-use items, making it stand-alone makes sense. Think along those lines. Design first, code later.... ask if you need help, as design takes practice and experience. Also learn about red flags.. if you feel you are tying yourself in knots trying to use your design, then the design has a problem, and you should stop, fix it, and resume. USE of the design should make writing the game much, much easier. Any place it makes it harder, that means something was not put together quite right. One of the biggest lessons I got from my OOP classes in college was that putting it all together should be the easy part, the design and definition of the interactions is the hardest part.
Last edited on
Thanks you!

Exactly, you described well what i want to do, the tile (x,y) position have to tell me which array to open, if any, but.. how?
Suppose i create another 2d bool array which has the same size of the world map, when some item is dropped in (x,y), in this array in the (x,y) position i set "true" so when i'm on it i can say "ok, under my feet there's some loot".. but how i make the relative container? And how i can link position to array?


At the moment i'm working on the map builder tool, i have some idea on how final game would work, i'm inspired by ShadowForge by John Carmack.

PS
Another thing that i don't get, but fortunatly i don't need, an example: i need to create 1000 arrays of 100 of lenght and fill everyone array with, i don't know, a random character, how can i do that? In fact is the same problem i have, in some way.
Each tile can have its own "myloot". The loot is empty, if there is no loot:
1
2
3
4
5
6
7
8
maptile& here = map(x,y);
// 'here' is the tile where you are now
if ( ! here.myloot.empty() ) {
  std::cout << "Loot here!\n";
  for ( const items& z : here.myloot ) {
    std::cout << z.name << ' ' << z.quantity << '\n';
  }
}



For randoms: http://www.cplusplus.com/reference/random/uniform_int_distribution/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// uniform_int_distribution
#include <iostream>
#include <chrono>
#include <random>

int main()
{
  // obtain a seed from the system clock:
  unsigned seed1 = std::chrono::system_clock::now().time_since_epoch().count();

  std::mt19937 generator (seed1);  // mt19937 is a standard mersenne_twister_engine

  std::uniform_int_distribution<char> distribution('a','z');

  const int nrolls = 40;
  for (int i=0; i<nrolls; ++i) {
    std::cout << distribution(generator);
  }
  std::cout << '\n';
}
I think i have a solution for my problem but i've not tried yet.

It needs 1 array of bool isLoot, and 3 lists: int Position , string Items, int Quantity.

The array of bools has the same size of the world map, when some loot is dropped i write in this array a 'true' (i need this passage in future, when i will step on a loot tile for starting getting the items in it).

Writing items:
Then i pushfront in the int Position list the coordinates of this tile (it needs only one value, a 2D array is actually a 1D array).
I pushfront in the Items list the name and in Quantity list the quantity.
And so on for any following dropped item.

Reading items:
When i step on a tile with some loot the isLoot array true valor make me start the research.
I start scrolling the Position list from start to end searching for the actual tile coordinate, when i found them i use its position in the list(the 'index',[n]) to open the Items list and Quantity list in the same position/index and read it.
Then i can modify the quantity valor and when it reaches zero with list type i can erase in all lists the element corresponding to the position of zero and turn to 'false' the valor in the isLoot array which index is tell by Position list.

I hope it's comprehensible!

Example:

isLoot = {0,0,1,0,1}, i enter in the 2 tile, isLoot[2]=true.

Position{5,5,2,5,2}; i found 2 in position 2 (and 4 then).

Items{gloves,sword,bow,axe,coin}; Items[2]=bow (and Items[4]=coin).

Quantity{1,1,1,1,5); Quantity[2]=1 (and Quantity[4]=5).

I take the bow so Quantity(2)==0;
Position.erase(2); Items.erase(2); Quantity.erase(2).

I think i need another list to temporarily write the Position indices just to not make researching every time i pick an item.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct Tile {
    //...
    vector<Item> vItems;
};

Tile g_map[250][250];

#define MAX_MONSTER_ITEMS 3

struct Monster {
    //...
    int position[2];
    Item items[MAX_MONSTER_ITEMS];
    int numItems;
};

void OnMonsterDeath(Monster* pMonster)
{
    //...
    for (int i = 0; i < pMonster->numItems; i++)
    {
        g_map[pMonster->position[0]][pMonster->position[1]].vItems.push_back(pMonster->items[i]);
    }
}
Last edited on
Registered users can post here. Sign in or register to post.