There is a dynamic two-dimensional array. There is a base of items. An item can occupy an arbitrary number of cells in an array.

The item has the [coordinates] parameter, where the coordinates of the cell are shown, where the left-top corner of the item is located and its length and height are additionally indicated. About such a scheme is meant.

In this case: [crossbow: 2-2: 2: 4].

To transfer an item, drag-n-drop is used. BUT, since in the inventory database, in fact, the item is located in the coordinates of one cell, then the items are elementary superimposed on one another.

And if the item comes from the outside, the inventory is not generated at all: the system checks the coordinate entries, makes corrections x + width, y + height and inserts the item into the empty space, if it exists. But such checks are very monstrous and costly, since all corrections should fall into the temporary storage of occupied cells and not be taken into account when checking for their freedom.

You can back up with a crutch on the other hand: with each inventory operation, send a new version of the mask of occupied sectors in the array to the database, but tests have shown that 4 people strenuously rearranging the items in the inventory put the fuckin base on them and eats an unforgivably much memory.

Did someone develop similar systems? Solved similar problems? How can this be optimized? Or maybe I do not notice which thread is a simpler approach to the topic?

  • And what is the monstrosity and costly checks? Add two matrices, with the first 2-ke to perform some kind of action. * with a new item to search for free space * when moving an item just do not allow to shove where there is no place - return to the previous position IMHO, Tetris with squares) - Yura Ivanov
  • That is, the first matrix is ​​the current inventory, and the second matrix is ​​the item being dragged? But they, after all, have different dimensions. And what to do with the situation when we need to move a 2x4 item 1 row to the right? The first check will show that there is already an item in the adjacent row (the one that is being transferred) and the check will be recorded. - lopar pm
  • @lopar, when you picked up the item - it is not in the inventory;) Next, you need to overlay the текущий_инвентарь_без_предмета matrix + пустой_инвентарь_с_предметом , i.e. one dimension. In the most banal case, you make a matrix of zeros and ones, and if you add at least one deuce, you forbid it. - Sh4dow

1 answer 1

Example from kamenta:

There is (on the left) inventory (occupied - 1, empty - 0), 10x5

And there is (right) an item, for example, at the moment in the position [7; 2], 2x3 in size

 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 

When they are added, you get the following:

 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 2 1 0 0 0 0 1 1 0 1 1 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1 

Here we see a deuce - this means, the objects are superimposed and can not be put here.

Threw you a simple function of substituting an object into a matrix. You just have to add the arrays and check the total presence of twos :)

Accordingly, when "adding to inventory" you have to go over the inventory and look in it for such places, when adding an item to which these twos do not occur.

 function getItemMatrix( $item /* x, y, w, h */ ) { $invWidth = 10; $invHeight = 5; $result = array(); if ($item->x + $item->w > $invWidth or $item->y + $item->h > $invHeight) return false; // сюда ставить нельзя for ($i = 1; $i <= $invWidth; $i++) { $result[$i] = array(); for ($j = 1; $j <= $invHeight ; $j++) $result[$i][$j] = ($i >= $item->x and $i <= $item->x + $item->w and $j >= $item->y and $j <= $item->y + $item->w ) ? 1 : 0; } return $result; } /* - Аааа, я видел двойку! - Успокойсся, Бендер, это был сон, двоек не бывает... © futurama */ 
  • Well, it is not necessary to reduce to one dimension of the matrix, it is enough to go through the matrix of the item. the base matrix is ​​shifted to the tested position, plus the same checks for going beyond the boundaries. and you can read everything in the browser, on the server just additional checks when updating, if necessary ... in general, it is more convenient, in any case, the check is quite fast, it should not hang anything. - Yura Ivanov