Created
May 27, 2016 11:42
-
-
Save soutar/02c6778d4d22634f43626245f2d69aa7 to your computer and use it in GitHub Desktop.
2048
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const range = require('array-range'); | |
// | |
// console.log('Basic value grid') | |
// const initialGrid = makeGrid(5, 5, 2) | |
// console.log(initialGrid) | |
// console.log('Constructed grid') | |
// const constructedGrid = makeGrid(5, 5, (x, y, rows, columns) => (columns*y+x)) | |
// console.log(constructedGrid) | |
// console.log('2048 grid') | |
// const 2048 = makeGrid(5, 5, (x, y, rows, columns) => { | |
// return (x === rows - 1 && y === columns - 1) ? 2 : undefined | |
// }) | |
// console.log(randomGrid) | |
const LEFT = [-1, 0] | |
const RIGHT = [1, 0] | |
const UP = [0, -1] | |
const DOWN = [0, 1] | |
const EMPTY_TILE = ' ' | |
const START_VALUE = 2 | |
function getRandomInt (min, max) { | |
return Math.floor(Math.random() * (max - min + 1)) + min | |
} | |
function makeGrid (rows, columns, constructor) { | |
return Array.from(Array(rows)).map((_, yIndex) => | |
Array.from(Array(columns)).map((_, xIndex) => { | |
return (typeof constructor === 'function') | |
? constructor(xIndex, yIndex, rows, columns) | |
: constructor | |
}) | |
) | |
} | |
function mutateGrid (grid, mutator) { | |
const rows = grid | |
return rows.map((row, yIndex) => | |
row.map((cellValue, xIndex) => mutator(xIndex, yIndex, cellValue)) | |
) | |
} | |
function create2048Grid (rows, columns) { | |
const firstTile = createRandomPair(0, columns-1, 0, rows-1) | |
const secondTile = createRandomPair(0, columns-1, 0, rows-1, [firstTile]) | |
return makeGrid(rows, columns, (x, y) => { | |
const value = ( | |
x === firstTile[0] && y === firstTile[1] | |
|| x === secondTile[0] && y === secondTile[1] | |
) ? START_VALUE : EMPTY_TILE | |
return value | |
}) | |
} | |
function createRandomPair (xMin, xMax, yMin, yMax, existingPairs = []) { | |
const randomPair = [getRandomInt(xMin, xMax), getRandomInt(yMin, yMax)] | |
const [randomX, randomY] = randomPair | |
const pairExists = existingPairs.find(([x, y]) => x === randomX && y === randomY) | |
return (pairExists) | |
? createRandomPair(xMin, xMax, yMin, yMax, existingPairs) | |
: randomPair | |
} | |
function shiftGrid (grid, direction) { | |
const rows = grid | |
const newGrid = [...grid] | |
let moveOccured = false | |
rows.forEach((row, yIndex) => { | |
const y = (direction === UP) ? row.length-1 - yIndex : yIndex | |
row.forEach((cell, xIndex) => { | |
const x = (direction === RIGHT) ? rows.length-1 - xIndex : xIndex | |
const currentCell = newGrid[y][x] | |
if (currentCell === EMPTY_TILE) return | |
const nextX = x + direction[0] | |
const nextY = y + direction[1] | |
if (nextX < 0 || nextX >= row.length) return | |
if (nextY < 0 || nextY >= rows.length) return | |
if (newGrid[nextY][nextX] === EMPTY_TILE) { | |
newGrid[nextY][nextX] = currentCell | |
newGrid[y][x] = EMPTY_TILE | |
moveOccured = true | |
} else if (newGrid[nextY][nextX] === currentCell) { | |
newGrid[nextY][nextX] = currentCell*2 | |
newGrid[y][x] = EMPTY_TILE | |
moveOccured = true | |
} | |
}) | |
}) | |
// console.log(findOccupiedCells(newGrid)) | |
if (moveOccured) { | |
const [newTileX, newTileY] = createRandomPair(0, newGrid[0].length-1, 0, newGrid.length-1) | |
newGrid[newTileY][newTileX] = 2 | |
} | |
return newGrid | |
} | |
function findOccupiedCells (grid) { | |
return grid.reduce((occupied, row, yIndex) => { | |
const occupiedOnRow = row.reduce((occupiedOnRow, cell, xIndex) => { | |
return (cell !== EMPTY_TILE) ? [...occupiedOnRow, [xIndex, yIndex]] : occupiedOnRow | |
}, []) | |
return [...occupied, ...occupiedOnRow] | |
}, []) | |
} | |
function printGrid (grid) { | |
console.log(' ' + grid[0].map((_, index) => index).join(' ')) | |
console.log(grid.map((row, y) => { | |
return `${y} ${row.map((_, x) => grid[y][x]).join(' ')}` | |
}).join('\n')) | |
} | |
// const grid = create2048Grid(4, 4) | |
// printGrid(grid) | |
// // hgh | |
// | |
// /* | |
// kgdlfkgdfgk | |
// */ | |
// | |
// const step1 = shiftGrid(grid, LEFT) | |
// printGrid(step1) | |
// | |
// const step2 = shiftGrid(step1, RIGHT) | |
// printGrid(step2) | |
const steps = [ | |
[UP, 'up'], | |
[RIGHT, 'right'], | |
[UP, 'up'], | |
[RIGHT, 'right'], | |
[UP, 'up'], | |
[RIGHT, 'right'], | |
[LEFT, 'left'], | |
[UP, 'up'], | |
[RIGHT, 'right'], | |
[UP, 'up'], | |
[RIGHT, 'right'], | |
[UP, 'up'], | |
[RIGHT, 'right'], | |
[LEFT, 'left'], | |
[UP, 'up'], | |
[RIGHT, 'right'], | |
[UP, 'up'], | |
[RIGHT, 'right'], | |
[UP, 'up'], | |
[RIGHT, 'right'], | |
// [UP, 'up'], | |
// [RIGHT, 'right'], | |
[LEFT, 'left'] | |
] | |
const grid = create2048Grid(4, 4); | |
printGrid(grid) | |
const newGrid = steps.reduce((grid, [direction, label]) => { | |
const newGrid = shiftGrid(grid, direction) | |
console.log(label) | |
printGrid(newGrid) | |
return newGrid | |
}, grid) | |
function findFarthestPosition (grid, [x, y], direction) { | |
switch (direction) { | |
case UP: | |
if (y === 0) return [x, y] | |
const obstacle = range(0, y).reverse().find(y => { | |
console.log('Looking at', [x, y]) | |
return grid[y][x] !== EMPTY_TILE | |
}) | |
return [x, obstacle-1 || 0] | |
break; | |
case DOWN: | |
// if (y === grid.length-1) return [x, y] | |
// const obstacle = range(y+1, grid.length-1).find(y => { | |
// return grid[y][x] !== EMPTY_TILE | |
// }) | |
// return [x, obstacle-1] | |
break; | |
case LEFT: | |
break; | |
case RIGHT: | |
break; | |
} | |
} | |
findFarthestPosition(newGrid, [0, 2], UP); | |
// | |
// console.log('Mutated grid') | |
// const mutatedGrid = mutateGrid(initialGrid, (x, y, value) => { | |
// // if (x % 2 === 0) return '1' | |
// // return value | |
// // return value * 2 | |
// return Math.round(Math.random()*10) || undefined | |
// }) | |
// console.log(mutatedGrid) | |
// console.log('Shifted grid') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment