Note: Most shortest path graph problems will use BFS Directed Graph Traversal.

var snakesAndLadders = function (board) {
	const size = board.length,
		maxSquare = size * size

	return minMoves(1)
	// -----------------------------------------------
	function numToRowCol(n) {
		const row = Math.floor((maxSquare - n) / size),
			c = (n - 1) % (2 * size) //c is in the range of 0 to 2*size -1
		// Because board is "boustrophedonically", make cols 2 * size

		let col

		if (c < size) col = c
		else col = 2 * size - 1 - c

		return [row, col]
	}

	// -----------------------------------------------
	// bfs for shortest path
	function minMoves(n) {
		const queue = [],
			visited = {}

		queue.push(n)
		visited[n] = 0 //records the shortest path distance from source to this vertex

		while (queue.length) {
			const curr = queue.shift()

			for (let i = 1; i < 7; i++) {
				let next = curr + i

				if (next > maxSquare) continue

				const [row, col] = numToRowCol(next)
				// if cell is snake or ladder, go down snake or go up ladder
				if (board[row][col] !== -1) next = board[row][col]

				if (visited[next] === undefined) {
					queue.push(next)
					visited[next] = visited[curr] + 1
					// The first path to get to end will be the min
					if (next === maxSquare) return visited[next]
				}
			}
		}

		// It's possible to have an impossible game, in which case return -1
		return -1
	}
}

// tests
const board = [
	[-1, -1, -1, -1, -1, -1],
	[-1, -1, -1, -1, -1, -1],
	[-1, -1, -1, -1, -1, -1],
	[-1, 35, -1, -1, 13, -1],
	[-1, -1, -1, -1, -1, -1],
	[-1, 15, -1, -1, -1, -1],
]

console.log(snakesAndLadders(board))

Old Attempt from 2019-11-22:

/**
 * @param {number[][]} board
 * @return {number}
 */
const getLocation = (sq, n) => {
	const remainder = (sq - 1) % n,
		quotient = Math.floor((sq - 1) / n),
		row = n - 1 - quotient,
		col = row % 2 !== n % 2 ? remainder : n - 1 - remainder
	return [row, col]
}

var snakesAndLadders = function (board) {
	const queue = [1],
		n = board.length,
		end = n ** 2,
		visited = { 1: 0 }

	while (queue.length) {
		let curr = queue.shift()
		if (curr === end) return visited[curr]

		for (let i = curr + 1; i <= Math.min(curr + 6, end); i++) {
			const [row, col] = getLocation(i, n),
				next = board[row][col] === -1 ? i : board[row][col]
			if (visited[next] === undefined) {
				queue.push(next)
				visited[next] = visited[curr] + 1
			}
		}
	}
	return -1
}

const board = [
	[-1, -1, -1, -1, -1, -1],
	[-1, -1, -1, -1, -1, -1],
	[-1, -1, -1, -1, -1, -1],
	[-1, 35, -1, -1, 13, -1],
	[-1, 12, -1, -1, -1, -1],
	[-1, 15, -1, -1, -1, -1],
]
const board1 = [
	[-1, -1, -1, -1],
	[-1, -1, -1, -1],
	[-1, -1, -1, -1],
	[-1, -1, -1, -1],
]

const board2 = [
	[-1, -1, 78, -1, -1, -1, -1, -1, -1, -1],
	[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
	[-1, -1, -1, -1, -1, -1, -1, -1, 99, -1],
	[-1, -1, -1, 50, -1, -1, -1, -1, -1, -1],
	[-1, 88, -1, -1, -1, -1, -1, -1, -1, -1],
	[-1, -1, -1, -1, 69, -1, -1, -1, -1, -1],
	[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
	[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
	[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
	[-1, -1, -1, 18, -1, -1, -1, -1, -1, -1],
]

//Test cases
console.log(snakesAndLadders(board))
// console.log(snakesAndLadders(board1))
// console.log(snakesAndLadders(board2))