Here's the problem, simplified to the problem that I'm facing.
I have an object, consisting of a score counter and an arbitrary 1D array of elements, filled with numbers:
{ score: 0, board: [4, 2, 2] }
I am looking for a function, that will do a 2048-ish move left (as if these numbers are tiles are on one row of a 2048 game board), and will also add score to the counter (merging into an 8 adds 8 to the score).
I have searched, and found functions, that do this, but i found none that also counted score. how can I accomplish this?
Here are some test cases:
{ score: 0, board: [] } => { score: 0, board: [] }
{ score: 0, board: [2,2] } => { score: 4, board: [4] }
{ score: 4, board: [2,2,2] } => { score: 8, board: [4,2] }
{ score: 6, board: [4,2,2] } => { score: 10, board: [4,4] }
{ score: 0, board: [2,2,2,2] } => { score: 8, board: [4,4] }
{ score: 8, board: [4,4] } => { score: 16, board: [8] }
{ score: 2, board: [8,8] } => { score: 18, board: [16] }
{ score: 0, board: [16,16] } => { score: 32, board: [32] }
{ score: 0, board: [1024,1024] } => { score: 2048, board: [2048] }
A comment under my post gave me an idea on how to approach this, and I wrote a function, that has passed all of my tests:
const mergeFunc = ({score, board}) => {
let returnObject = {
score: score,
board: [...board] // just in case
};
for(let i=0; i<returnObject.board.length-1; i++)
// parsing through the array left to right,
if(returnObject.board[i] === returnObject.board[i+1]){
// if an element is the same as the element to it's right,
returnObject.score += returnObject.board[i]*2;
// add the value of the new tile to the score,
returnObject.board.splice(i,2,returnObject.board[i]*2)
// and merge the two tiles.
}
return returnObject;
}
console.log(mergeFunc({score:0,board:[2,2,2,2]}))
The function iterates over the array left to right, merging any two identical neighbouring numbers that it finds using .splice()
, and adds the value of the new cell to the score.
Here's the function, edited to work for 2D arrays (though, it still only merges left):
const mergeFunc2D = ({score, board}) => {
let returnObject = {
score: score || 0,
board: board.map(x=>x.filter(y=>y!==undefined))
};
for(let j=0; j<returnObject.board.length; j++) { // for each array:
for(let i=0; i<returnObject.board[j].length-1; i++) // parsing through the array left to right,
if(returnObject.board[j][i] === returnObject.board[j][i+1]){ // if an element is the same as the element to it's right,
returnObject.score += returnObject.board[j][i]*2; // add the value of the new tile to the score,
returnObject.board[j].splice(i,2,returnObject.board[j][i]*2) // and merge the two tiles.
}
// optionally, cut to specific width and pad with undefs
returnObject.board[j] = returnObject.board[j].concat([undefined,undefined,undefined,undefined]).splice(0,4);
}
return returnObject;
}
console.log(mergeFunc2D({
board:[
[2,2,undefined,undefined],
[2,undefined,2,2],
[2,2,2,2],
[2,2,4,4],
]
}))