I do not need to store the number of target locations when using a grid. For example, if I am at location 10, I know that the location to the east will be 11 and the location to the west will be 9.
I do need to save whether there is an exit or not. If I use the four cardinal points, I have to store whether or not there is an exit for each of those points. I store this in one bit, 0 no exit, 1 yes exit.
For example, if location 10 has its output bit like this: 0110. This binary number means that to the north and west there is no output but to the south and east there is.
Thus, I store the outputs of two locations in a single byte.
You have to be careful to close the outputs of the locations that are on the edges of the grid.
I store the exits using one bit per exit. I need four bits per location, one to define if teir is an exit to the north, another bit to an exit the south, east and west.
But 4 bits are half of a byte, so I can stores the exits of two locations in one byte. It saves memory, but, on the other hand, you need more memory for the code to read the exits.
This is how I store exists in code.
; N S E O 0 1 2 3 4 5 6 7 8 9 10 11 12 13
exits BYTE %10101011, %00011110, %11110001, %01000110, %00010010, %10110001, %0000100
You may think that this system does not allow going up or down. You are right. You have not enough free memory to implement that kind of maps. However, if you want to introduce an especial exist you may add a new verb that makes specific checks.