kharandziuk
kharandziuk

Reputation: 12890

Immutable.js: Data structure to represent 2D game field

I'm wondering What data structure should I use to represent a square game board(consider each cell can have some color). The most natural idea is a two dimensional List, but it's hard to query and change it.

So, now use a Map where keys are ${x}.${y}(there is no tuples in JS:() and values are stings which represent colors Something like this:

Map([['0.0', 'red'], ['0.1', 'red'], ['1.0', 'blue'], ['1.1', 'red']])

Is it ok to use such data structure? Is there any better solution in terms of Immutable.js?

Upvotes: 1

Views: 1314

Answers (3)

I'm curious why you think a List of Lists is hard to query and change. You can use arrays of length 2 as an [x, y] pair, and pass this to the getIn, setIn, and updateIn methods.

let grid = Immutable.toJS([
    ['red', 'green'],
    ['blue', 'yellow']
]);

grid.getIn([0, 1]); // => 'green';
grid = grid.setIn([0, 1], 'purple');
grid.getIn([0, 1]); // => 'purple';
grid = grid.updateIn([0, 0], cell => cell.toUpperCase());
grid.getIn([0, 0]); // => 'RED';

It's easy to apply some function to every cell in the grid with map(...):

grid.map((row, x) => row.map(cell, y) => x + cell + y);
grid.get([1, 1]); // => '1yellow1'

One thing that might be trickier than with a Map is trying to find the coordinates of a value.

const x = grid.findIndex(row => row.contains('blue')); // => 1
const y = grid.get(x).indexOf('blue'); // => 0
grid.get([x, y]); // => blue

Upvotes: 0

Kai Hao
Kai Hao

Reputation: 689

I am building some 2D game board of my own too, and I have came across the same problem. The solution I've made is Record.

It simply looks like an object, also behave like one too. But with vanilla object, you cannot do the following mapping dictionary thing.

const dict = {};

const key1 = { row: 0, col: 1 };
const value1 = { some: 'value' };

dict[key1] = value; // will not work

This is what I want though, I tried to make the mapping as simple to deal with as possible. With Record and Map from Immutable.js, you can do the following.

import { Map, Record } from 'immutable';

const dict = Map();
const Pos = Record({ row: 0, col: 0 }); // some initial value.
const Val = Record({ some: 'value' }); // same here.

const key1 = new Pos({ row: 0, col: 1 });
const value1 = new Val({ some: 'value' });

dict = dict.set(key1, value1); // works like you wish

You can read the official doc for more information. Maybe you have a better solution, please let me know :).

Upvotes: 7

Naftali
Naftali

Reputation: 146302

Is there a reason why you cannot use a 2 dimensional array like so:

let square = [
    ['red', 'green', 'blue'],
    ['orange', 'red', 'blue'],
    ['red', 'blue', 'blue']
];

Then you can add the above data structure to your map.

So to access the middle tile you can just use [1][1] index of the array.

Upvotes: 0

Related Questions