|
|
|
@ -60,7 +60,7 @@ class Board { |
|
|
|
|
this.grid = []; |
|
|
|
|
this.tiles = []; |
|
|
|
|
|
|
|
|
|
for(let i=0; i<120;i++) { |
|
|
|
|
for (let i = 0; i <= 120; i++) { |
|
|
|
|
this.grid[i] = null; |
|
|
|
|
this.tiles[i] = null; |
|
|
|
|
} |
|
|
|
@ -204,6 +204,12 @@ class Board { |
|
|
|
|
* @param {Boolean} errorIfEmpty |
|
|
|
|
*/ |
|
|
|
|
removeOrbByIndex(index, errorIfEmpty = false) { |
|
|
|
|
// placeholder orb
|
|
|
|
|
if (typeof this.grid[index] === 'string') { |
|
|
|
|
this.grid[index] = null; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (this.grid[index]) { |
|
|
|
|
this.$orbs.removeChild(this.grid[index].node); |
|
|
|
|
this.grid[index] = null; |
|
|
|
@ -626,7 +632,7 @@ class Game { |
|
|
|
|
/** |
|
|
|
|
* Init the game |
|
|
|
|
*/ |
|
|
|
|
constructor(seed=null) { |
|
|
|
|
constructor(seed = null) { |
|
|
|
|
this.board = new Board(); |
|
|
|
|
if (seed === null) { |
|
|
|
|
seed = +new Date(); |
|
|
|
@ -664,7 +670,7 @@ class Game { |
|
|
|
|
'frisbee': [0, 11, 12, 13, 14, 15, 22, 25, 26, 27, 28, 29, 33, 34, 36, 38, 39, 40, 41, 45, 46, 47, 49, 50, 53, 57, 58, 59, 60, 62, 64, 65, 68, 69, 72, 74, 75, 80, 81, 82, 83, 84, 85, 86, 92, 95, 96, 97, 104, 106, 107, 115, 116, 117, 118], |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
this.newGame() |
|
|
|
|
setTimeout(() => this.newGame(), 100); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -842,19 +848,20 @@ class Game { |
|
|
|
|
|
|
|
|
|
// Highlight pattern shape
|
|
|
|
|
|
|
|
|
|
if (this.board.tiles[i]) { |
|
|
|
|
if (allo) { |
|
|
|
|
this.board.tiles[i].setAttribute('opacity', 1) |
|
|
|
|
} else { |
|
|
|
|
this.board.tiles[i].setAttribute('opacity', 0.6) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// if (this.board.tiles[i]) {
|
|
|
|
|
// if (allo) {
|
|
|
|
|
// this.board.tiles[i].setAttribute('opacity', 1)
|
|
|
|
|
// } else {
|
|
|
|
|
// this.board.tiles[i].setAttribute('opacity', 0.6)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const place = (n, symbol) => { |
|
|
|
|
if (!allowed[n]) throw Error(`Position ${n} not allowed by template`); |
|
|
|
|
if (this.board.grid[n]) throw Error(`Position ${n} is occupied`); |
|
|
|
|
this.board.placeOrbByIndex(n, symbol); |
|
|
|
|
// we use a hack to speed up generation here - SVG is not altered until we have a solution
|
|
|
|
|
this.board.grid[n] = symbol; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const findAvailableIndexWithNeighbours = (count) => { |
|
|
|
@ -904,55 +911,6 @@ class Game { |
|
|
|
|
console.log('Solution: ', toPlace); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
updateOrbDisabledStatus() { |
|
|
|
|
for (let n = 0; n < 120; n++) { |
|
|
|
|
if (this.board.grid[n]) { |
|
|
|
|
this.board.grid[n].node.classList.toggle('disabled', !this.isAvailable(n)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
newGame() { |
|
|
|
|
// this.board.onTileClick = (n) => {
|
|
|
|
|
// console.log(n, this.board.gridIndexToXy(n));
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
const RETRY_IN_TEMPLATE = 100; |
|
|
|
|
const RETRY_NEW_TEMPLATE = 15; |
|
|
|
|
|
|
|
|
|
// retry loop, should not be needed if everything is correct
|
|
|
|
|
let suc = false; |
|
|
|
|
let numretries = 0; |
|
|
|
|
const alertOnError = false; |
|
|
|
|
for (let i = 0; i < RETRY_NEW_TEMPLATE && !suc; i++) { |
|
|
|
|
console.log('RNG seed is: ' + this.rng.state); |
|
|
|
|
const template = this.getRandomTemplate(); |
|
|
|
|
for (let j = 0; j < RETRY_IN_TEMPLATE; j++) { |
|
|
|
|
try { |
|
|
|
|
this.placeOrbs(template); |
|
|
|
|
suc = true; |
|
|
|
|
break; |
|
|
|
|
} catch (e) { |
|
|
|
|
if (alertOnError) alert('welp'); |
|
|
|
|
numretries++; |
|
|
|
|
console.warn(e.message); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!suc) { |
|
|
|
|
console.warn("Exhausted all retries for the template, getting a new one"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!suc) { |
|
|
|
|
alert(`Sorry, could not find a valid board setup after ${numretries} retries.`); |
|
|
|
|
return; |
|
|
|
|
} else { |
|
|
|
|
console.info(`Found valid solution (with ${numretries} retries)`); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.updateOrbDisabledStatus() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
shuffleArray(a) { |
|
|
|
|
let j, x, i; |
|
|
|
|
for (i = a.length - 1; i > 0; i--) { |
|
|
|
@ -991,7 +949,7 @@ class Game { |
|
|
|
|
const nsalted = this.rng.nextInt(2); |
|
|
|
|
for (let i = 0; i < nsalted; i++) { |
|
|
|
|
while (true) { |
|
|
|
|
const n = this.rng.nextInt(toPlace.length-1); |
|
|
|
|
const n = this.rng.nextInt(toPlace.length - 1); |
|
|
|
|
if (toPlace[n][1] !== 'salt') { |
|
|
|
|
// console.log(`Pairing ${toPlace[n][1]} with salt.`);
|
|
|
|
|
newSaltedPairs.push([toPlace[n][1], 'salt']); |
|
|
|
@ -1044,6 +1002,70 @@ class Game { |
|
|
|
|
|
|
|
|
|
return toPlace; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
renderPreparedBoard() { |
|
|
|
|
for (let n = 0; n <= 120; n++) { |
|
|
|
|
if (this.board.grid[n] !== null) { |
|
|
|
|
const symbol = this.board.grid[n]; |
|
|
|
|
this.board.grid[n] = null; |
|
|
|
|
this.board.placeOrbByIndex(n, symbol); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
updateOrbDisabledStatus() { |
|
|
|
|
for (let n = 0; n <= 120; n++) { |
|
|
|
|
if (this.board.grid[n]) { |
|
|
|
|
this.board.grid[n].node.classList.toggle('disabled', !this.isAvailable(n)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
newGame() { |
|
|
|
|
// this.board.onTileClick = (n) => {
|
|
|
|
|
// console.log(n, this.board.gridIndexToXy(n));
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
const RETRY_IN_TEMPLATE = 100; |
|
|
|
|
const RETRY_NEW_TEMPLATE = 15; |
|
|
|
|
|
|
|
|
|
// retry loop, should not be needed if everything is correct
|
|
|
|
|
let suc = false; |
|
|
|
|
let numretries = 0; |
|
|
|
|
const alertOnError = false; |
|
|
|
|
for (let i = 0; i < RETRY_NEW_TEMPLATE && !suc; i++) { |
|
|
|
|
console.log('RNG seed is: ' + this.rng.state); |
|
|
|
|
const template = this.getRandomTemplate(); |
|
|
|
|
for (let j = 0; j < RETRY_IN_TEMPLATE; j++) { |
|
|
|
|
try { |
|
|
|
|
this.placeOrbs(template); |
|
|
|
|
suc = true; |
|
|
|
|
break; |
|
|
|
|
} catch (e) { |
|
|
|
|
if (alertOnError) alert('welp'); |
|
|
|
|
numretries++; |
|
|
|
|
console.warn(e.message); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!suc) { |
|
|
|
|
console.warn("Exhausted all retries for the template, getting a new one"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!suc) { |
|
|
|
|
// show the failed attempt
|
|
|
|
|
this.renderPreparedBoard(); |
|
|
|
|
this.updateOrbDisabledStatus(); |
|
|
|
|
|
|
|
|
|
alert(`Sorry, could not find a valid board setup after ${numretries} retries.`); |
|
|
|
|
return; |
|
|
|
|
} else { |
|
|
|
|
console.info(`Found valid solution (with ${numretries} retries)`); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.renderPreparedBoard(); |
|
|
|
|
this.updateOrbDisabledStatus() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Start */ |
|
|
|
|