Reputation: 12890
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
Reputation: 955
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
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
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