As you can see in this JSFiddle, when you use the arrow keys to move the red square around, the transition between tiles is very choppy and it just does not look good.
I am wondering if there is a way to have a smooth transition between tiles so it looks like one smooth motion?
var canvas, context, board, imageObj, tiles, board, display;
var NUM_OF_TILES = 2;
// viewport
var vX = 0,
vY = 0,
vWidth = 15,
vHeight = 10;
var playerX = 0,
playerY = 0;
var worldWidth = 29,
worldHeight = 19;
function loadMap(map) {
if (map == 1) {
return [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 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, 0], [0, 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, 0], [0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0], [0, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0], [0, 1, 1, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 0], [0, 1, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 0], [0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 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, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];
}
}
$(document).ready(function() {
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
canvas.tabIndex = 0;
canvas.focus();
canvas.addEventListener('keydown', function(e) {
console.log(e);
var key = null;
switch (e.which) {
case 37:
// Left
if (playerX > 0) playerX--;
break;
case 38:
// Up
if (playerY > 0) playerY--;
break;
case 39:
// Right
if (playerX < worldWidth) playerX++;
break;
case 40:
// Down
if (playerY < worldHeight) playerY++;
break;
}
// Okay! The player is done moving, now we have to determine the "best" viewport.
// Ideally the viewport centers the player,
// but if its too close to an edge we'll have to deal with that edge
vX = playerX - Math.floor(0.5 * vWidth);
if (vX < 0) vX = 0;
if (vX+vWidth > worldWidth) vX = worldWidth - vWidth;
vY = playerY - Math.floor(0.5 * vHeight);
if (vY < 0) vY = 0;
if (vY+vHeight > worldHeight) vY = worldHeight - vHeight;
draw();
}, false);
var board = [];
canvas.width = 512;
canvas.height = 352;
board = loadMap(1);
imageObj = new Image();
tiles = [];
var loadedImagesCount = 0;
for (x = 0; x <= NUM_OF_TILES; x++) {
var imageObj = new Image(); // new instance for each image
imageObj.src = "http://mystikrpg.com/canvas/img/tiles/t" + x + ".png";
imageObj.onload = function() {
// console.log("Added tile ... "+loadedImagesCount);
loadedImagesCount++;
if (loadedImagesCount == NUM_OF_TILES) {
// Onces all tiles are loaded ...
// We paint the map
draw();
}
};
tiles.push(imageObj);
}
function draw() {
context.clearRect(0,0,canvas.width, canvas.height);
for (y = 0; y <= vHeight; y++) {
for (x = 0; x <= vWidth; x++) {
theX = x * 32;
theY = y * 32;
context.drawImage(tiles[board[y+vY][x+vX]], theX, theY, 32, 32);
}
}
context.fillStyle = 'red';
context.fillRect((playerX-vX)*32, (playerY-vY)*32, 32, 32);
}
});
I played around a little bit and got something working:
case 39:
// Right
if (playerX < worldWidth) {
var start = playerX;
var end = Math.round(playerX + 1);
$({ i : start }).animate({ i: end}, {
duration: 400,
step: function(now) {
playerX = now;
draw();
}
});
}
break;
I use the jquery animate function in order to interpolate between the values. I realized the draw function is called only once, in order to get an animation i had to call it every step.
In order to avoid errors on the re-centering use Math.round() there too.
vX = Math.round(playerX) - Math.floor(0.5 * vWidth);
if (vX < 0) vX = 0;
if (vX+vWidth > worldWidth) vX = worldWidth - vWidth;
vY = Math.round(playerY) - Math.floor(0.5 * vHeight);
if (vY < 0) vY = 0;
if (vY+vHeight > worldHeight) vY = worldHeight - vHeight;
Of course you have to do additional work, e.g. the start and stop points could vary this way. As suggested you maybe should use pixel positions for your char instead of tiles. But i dont know your intent.
You can avoid the getting stuck on keydown by checking if the tile is in a "full" position by checking
if (playerY < worldHeight && playerY % 1 == 0) {...
Related
I have a game, (published BTW its here at https://juniorcpc.itch.io/dungeon-game and the download file for the code is there too), and it uses arrays to create tile maps. (0-4 numbers represent different tiles) The problem is i can only create maps and publish those, and i want to know how to have the code create those array maps for me. I cannot use other tutorials, as they only show how to with tile maps, or mazes, or something else, but mine uses arrays not other systems. If there is a way to make a procedural map with arrays that would be awesome, thanks!
BTW the arrays are 10x10 grids, 1 = wall, 0 = empty space, 3 = exit.
Example of array:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 2, 4, 1,
1, 2, 2, 0, 0, 2, 2, 2, 2, 1,
1, 1, 1, 2, 0, 2, 2, 2, 2, 1,
1, 2, 2, 0, 0, 2, 2, 2, 4, 1,
1, 0, 0, 0, 2, 2, 2, 3, 2, 1,
1, 0, 2, 2, 2, 2, 2, 2, 2, 1,
1, 0, 2, 1, 1, 2, 0, 0, 0, 1,
1, 0, 2, 2, 2, 2, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
],
Here is how it draws them: ( i have a canvas in my HTML with a width of 300px and a height of 300px)
function mapM() {
var ctx = document.getElementById("canv").getContext('2d');
ctx.fillStyle = "red";
var mapOnX = -1;
var mapOnY = 0;
var l = map[0].length + 1;
for (i = 0; i < l; i++) {
if (i % 10 == 0) {
var mapOnX = 0;
mapOnY++;
} else {
mapOnX++;
}
if (map[level][i] == 1) {
ctx.fillStyle = "red";
} else {
if (map[level][i] == 0) {
ctx.fillStyle = 'blue';
} else {
if (map[level][i] == 3) {
ctx.fillStyle = 'gold';
} else {
if (map[level][i] == 2) {
ctx.fillStyle = 'black';
} else {
ctx.fillStyle = 'lightBlue';
}
}
}
}
ctx.fillRect(mapOnX * 25, mapOnY * 25, 25, 25);
ctx.fillStyle = 'purple';
ctx.fillRect(mapX * 25, mapY * 25, 25, 25);
}
}
Dont worry about other numbers i can do that. Thanks!
:) I'm creating a maze using JS and P5, with a two dimensional array filled with numbers 0-8. 0 are empty spots, 1 are walls, 2 is the character you walk with, 3 is the exit and 4-8 are items that randomly spawn. In order to exit the maze (through 3, which is set on a fixed spot), all items need to be collected (if you walk over an item, the value of this spot changes back to 0), so every value in the array should be below 4 in order to exit. Now I need a way to check if this is the case.
I tried it with every() but I guess this only works for regular arrays. I suppose I need a for loop but I don't know this should look. So that's where I need help!
My maze consists of 18 rows and columns, like so (but then 15 more rows)
let maze = [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,2,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,3],
[1,1,1,1,1,0,1,0,0,0,1,1,0,0,0,0,1,0,1,0,1,0,1]
]
The items spawn randomly, this already works. Now I tried checking if every value is <= 3, with the every, like so
function checkBoard(mazenumbers){
return mazenumbers <= 3;
}
function alertMazenumbers() {
alert(maze.every(checkBoard));
}
And want this to display through an alert, once you walk into the exit location, like this
else if(direction === 'right') {
if(maze[playerPos.y][playerPos.x + 1] == 3) {
alertMazenumbers();
}
I want to get an alert with true if every value is <= 3, and false if not.
Currently, with this every(), I do get the alert but it only returns false, even when all items are cleared and it should return true.
You are on the right track using every!
The maze is an array of arrays (as Denys mentioned in his comment), so you have to use every twice, like so:
function canExitMaze(maze) {
return maze.every(row => row.every(cell => cell <= 3))
}
If you don't recognize the arrow function syntax (=>) this article explains it.
Hope this helps!
You can check if every point in the maze is <=3 by doing this
const isTrue = num => num <= 3; // is a single cell true
const isRowTrue = row => row.every(isTrue); // are all cells in a row true
const isMazeTrue = rows => rows.every(isTrue); // are all cells in all rows true
const maze = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 3],
[1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]
];
console.log(isMazeTrue(maze));
Method 1: Check if every array only contains numbers that are <= 3
let maze = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 3],
[1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]
];
function testMaze(maze) {
return maze.every(row => row.every(itemIsValid));
}
function itemIsValid(item) {
return item <= 3;
}
console.log(testMaze(maze));
maze[2][4] = 4;
console.log(testMaze(maze));
Method 2: Merge the arrays and search the numbers
var maze = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 3],
[1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]
];
function testMaze(maze) {
return [].concat(...maze).every(itemIsValid);
}
function itemIsValid(item) {
return item <= 3;
}
console.log(testMaze(maze));
maze[2][4] = 4;
console.log(testMaze(maze));
Method 3: Convert the maze to a string and use regex
var maze = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 3],
[1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]
];
function testMaze(maze) {
//or maze.toString().match(/\d+/g).every(x => itemIsValid(+x));
return !/[4-8]/g.test(`${maze}`);
}
function itemIsValid(item) {
return item <= 3;
}
console.log(testMaze(maze));
maze[2][4] = 4;
console.log(testMaze(maze));
I have the following array:
arr = [
[ 1, 1, 1, 1, 1, 1, 1 ],
[ 1, 1, 0, 0, 1, 1, 0 ],
[ 1, 0, 0, 0, 1, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 1, 0, 0, 2 ],
[ 1, 0, 0, 1, 0, 2, 4 ],
[ 0, 0, 0, 0, 2, 4, 4 ],
[ 0, 0, 0, 0, 4, 4, 0 ],
[ 1, 1, 1, 0, 0, 0, 0 ],
[ 1, 1, 0, 2, 0, 0, 2 ],
[ 1, 0, 0, 4, 0, 2, 0 ],
[ 0, 0, 0, 4, 2, 0, 0 ],
[ 0, 0, 2, 0, 0, 0, 1 ],
[ 0, 2, 4, 0, 0, 1, 2 ],
[ 2, 4, 4, 2, 1, 2, 4 ],
[ 4, 4, 0, 0, 2, 4, 0 ]
]
Currently, I'm getting the max array sum in arr i.e 19 like this
function getMaxSum(arr) {
return arr.map(e => e.reduce((a, b) => a + b, 0)).sort((a,b) => a - b)[arr.length - 1];
}
I need to know is there any better way to achieve this?
I'm using array length of the original array to get the last element of resulting array because in this case, length of original array and resulting array is same. If the scenario is different then how can I use the length of the resulting array here:
return arr.map(e => e.reduce((a, b) => a + b, 0)).sort((a,b) => a - b)[HERE - 1];
Not a huge improvement, but it seems a little more literal to spread the values into Math.max
const data = [
[ 1, 1, 1, 1, 1, 1, 1 ],
[ 1, 1, 0, 0, 1, 1, 0 ],
[ 1, 0, 0, 0, 1, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 1, 0, 0, 2 ],
[ 1, 0, 0, 1, 0, 2, 4 ],
[ 0, 0, 0, 0, 2, 4, 4 ],
[ 0, 0, 0, 0, 4, 4, 0 ],
[ 1, 1, 1, 0, 0, 0, 0 ],
[ 1, 1, 0, 2, 0, 0, 2 ],
[ 1, 0, 0, 4, 0, 2, 0 ],
[ 0, 0, 0, 4, 2, 0, 0 ],
[ 0, 0, 2, 0, 0, 0, 1 ],
[ 0, 2, 4, 0, 0, 1, 2 ],
[ 2, 4, 4, 2, 1, 2, 4 ],
[ 4, 4, 0, 0, 2, 4, 0 ]
]
function getMaxSum(arr) {
return Math.max(...arr.map(e => e.reduce((a, b) => a + b, 0)))
}
console.log(getMaxSum(data))
As #Rajesh points out, Math.max is faster that a sort:
const numbers = Array(10000).fill().map((x,i)=>i);
const max = numbersIn => Math.max(...numbersIn);
const getMaxViaSort = numbersIn => numbersIn
.sort((a, b) => a > b ? -1 : 1)[0]
console.time('max');
max(numbers);
console.timeEnd('max');
console.time('max via sort');
getMaxViaSort(numbers);
console.timeEnd('max via sort');
The optimal strategy should be one where we need the least interaction with the arrays.
In my method i test the array products individually and compare that with a variable inside my loop. In this way i don't need to run a new implied loop to have Math.max check all my entries again, netting a speed boost.
This also saves on memory management as i don't need to map and return a new array of results for Math.max.
At the end of the loop i simply return the variable.
var data = [
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 0, 0, 1, 1, 0],
[1, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 2],
[1, 0, 0, 1, 0, 2, 4],
[0, 0, 0, 0, 2, 4, 4],
[0, 0, 0, 0, 4, 4, 0],
[1, 1, 1, 0, 0, 0, 0],
[1, 1, 0, 2, 0, 0, 2],
[1, 0, 0, 4, 0, 2, 0],
[0, 0, 0, 4, 2, 0, 0],
[0, 0, 2, 0, 0, 0, 1],
[0, 2, 4, 0, 0, 1, 2],
[2, 4, 4, 2, 1, 2, 4],
[4, 4, 0, 0, 2, 4, 0]
];
function getMaxSum1(arr) {
//The original method
return arr.map(function (e) { return e.reduce(function (a, b) { return a + b; }, 0); }).sort(function (a, b) { return a - b; })[arr.length - 1];
}
function getMaxSum2(arr) {
//From https://stackoverflow.com/a/51704254/5242739
return Math.max.apply(Math, arr.map(function (e) { return e.reduce(function (a, b) { return a + b; }, 0); }));
}
function sumArray(arr) {
var val = 0;
for (var index = 0; index < arr.length; index++) {
val += val;
}
return val;
}
function getMaxSum3(arr) {
//My method
var max;
for (var i = 0; i < arr.length; i++) {
var val = sumArray(arr[i]);
if (max === void 0 || val > max) {
max = val;
}
}
return max;
}
//TEST
//parameters
var runs = 10;
var tests = 100000;
//output area
var out = document.body.appendChild(document.createElement("pre"));
//test functions
function simulate1() {
var t = tests;
var dt = Date.now();
while (t--) {
getMaxSum1(data);
}
out.textContent += 'getMaxSum1 took: ' + (Date.now() - dt) + "ms\n";
requestAnimationFrame(simulate2);
}
function simulate2() {
var t = tests;
var dt = Date.now();
while (t--) {
getMaxSum2(data);
}
out.textContent += 'getMaxSum2 took: ' + (Date.now() - dt) + "ms\n";
requestAnimationFrame(simulate3);
}
function simulate3() {
var t = tests;
var dt = Date.now();
while (t--) {
getMaxSum3(data);
}
out.textContent += 'getMaxSum3 took: ' + (Date.now() - dt) + "ms\n\n";
if (runs--) {
requestAnimationFrame(simulate1);
}
}
//start
simulate1();
pre {
max-height: 200px;
overflow-y: scroll;
background-color: #eee;
}
I included OliverRadini's answer to compare the relative speed boosts.
I am trying to implement a word game, where a user types a letter on a board to form a meaningful word and submitt it, if the typed word is present in a JSON file, the user gets a point. So I have implemented the basics of the game, but unfortunately I have found that my linear algorithm is inefficient to traverse about 400k words in the JSON file. So my question is what kind of algorithm I can write to make it efficient?
My interface looks like this. Letters appear randomly on the board.
A tiny part of my JSON file look like this
{"a": 1, "aa": 1, "aaa": 1, "aah": 1, "aahed": 1, "aahing": 1, "aahs": 1, "aal": 1, "aalii": 1, "aaliis": 1, "aals": 1, "aam": 1, "aani": 1, "aardvark": 1, "aardvarks": 1, "aardwolf": 1, "aardwolves": 1, "aargh": 1, "aaron": 1, "aaronic": 1, "aaronical": 1, "aaronite": 1, "aaronitic": 1, "aarrgh": 1, "aarrghh": 1, "aaru": 1, "aas": 1, "aasvogel": 1, "aasvogels": 1, "ab": 1, "aba": 1, "ababdeh": 1, "ababua": 1, "abac": 1, "abaca": 1, "abacay": 1, "abacas": 1, "abacate": 1, "abacaxi": 1, "abaci": 1, "abacinate": 1, "abacination": 1, "abacisci": 1, "abaciscus": 1, "abacist": 1, "aback": 1, "abacli": 1, "abacot": 1, "abacterial": 1, "abactinal": 1, "abactinally": 1, "abaction": 1, "abactor": 1, "abaculi": 1, "abaculus": 1, "abacus": 1, "abacuses": 1, "abada": 1, "abaddon": 1, "abadejo": 1, "abadengo": 1, "abadia": 1, "abadite": 1, "abaff": 1, "abaft": 1, "abay": 1, "abayah": 1, "abaisance": 1, "abaised": 1, "abaiser": 1, "abaisse": 1, "abaissed": 1, "abaka": 1, "abakas": 1, "abalation": 1, "abalienate": 1, "abalienated": 1, "abalienating": 1, "abalienation": 1, "abalone": 1, "abalones": 1, "abama": 1, "abamp": 1, "abampere": 1, "abamperes": 1, "abamps": 1, "aband": 1, "abandon": 1, "abandonable": 1, "abandoned": 1, "abandonedly": 1, "abandonee": 1, "abandoner": 1, "abandoners": 1, "abandoning": 1, "abandonment": 1, "abandonments": 1, "abandons": 1, "abandum": 1, "abanet": 1, "abanga": 1, "abanic": 1, "abannition": 1, "abantes": 1, "abapical": 1, "abaptiston": 1, "abaptistum": 1, "abarambo": 1, "abaris": 1, "abarthrosis": 1, "abarticular": 1, "abarticulation": 1, "abas": 1, "abase": 1, "abased": 1, "abasedly": 1, "abasedness": 1, "abasement": 1, "abasements": 1, "abaser": 1, "abasers": 1, "abases": 1, "abasgi": 1, "abash": 1, "abashed": 1, "abashedly": 1, "abashedness": 1, "abashes": 1, "abashing": 1, "abashless": 1, "abashlessly": 1, "abashment": 1, "abashments": 1, "abasia": 1, "abasias": 1, "abasic": 1, "abasing": 1, "abasio": 1, "abask": 1, "abassi": 1, "abassin": 1, "abastard": 1, "abastardize": 1, "abastral": 1, "abatable": 1, "abatage": 1, "abate": 1, "abated": 1, "abatement": 1, "abatements": 1, "abater": 1, "abaters": 1, "abates": 1, "abatic": 1, "abating": 1, "abatis": 1, "abatised": 1, "abatises": 1, "abatjour": 1, "abatjours": 1, "abaton": 1, "abator": 1, "abators": 1, "abattage": 1, "abattis": 1, "abattised": 1, "abattises": 1, "abattoir": 1, "abattoirs": 1, "abattu": 1, "abattue": 1, "abatua": 1, "abature": 1, "abaue": 1, "abave": 1, "abaxial": 1, "abaxile": 1, "abaze": 1, "abb": 1, "abba": 1, "abbacy": 1, "abbacies": 1, "abbacomes": 1, "abbadide": 1, "abbaye": 1, "abbandono": 1, "abbas": 1, "abbasi": 1, "abbasid": 1, "abbassi": 1, "abbasside": 1, "abbate": 1, "abbatial": 1, "abbatical": 1, "abbatie": 1, "abbe": 1, "abbey": 1, "abbeys": 1, "abbeystead": 1, "abbeystede": 1, "abbes": 1, "abbess": 1, "abbesses": 1, "abbest": 1, "abbevillian": 1, "abby": 1, "abbie": 1, "abboccato": 1, "abbogada": 1, "abbot": 1, "abbotcy": 1, "abbotcies": 1, "abbotnullius": 1, "abbotric": 1, "abbots": 1, "abbotship": 1, "abbotships": 1, "abbott": 1, "abbozzo": 1, "abbr": 1, "abbrev": 1, "abbreviatable": 1, "abbreviate": 1, "abbreviated": 1, "abbreviately": 1, "abbreviates": 1, "abbreviating": 1, "abbreviation": 1, "abbreviations": 1, "abbreviator": 1, "abbreviatory": 1, "abbreviators": 1, "abbreviature": 1, "abbroachment": 1, "abc": 1, "abcess": 1, "abcissa": 1, "abcoulomb": 1, "abd": 1, "abdal": 1, "abdali": 1, "abdaria": 1, "abdat": 1, "abderian": 1, "abderite": 1, "abdest": 1, "abdicable": 1, "abdicant": 1, "abdicate": 1, "abdicated": 1, "abdicates": 1, "abdicating": 1, "abdication": 1, "abdications": 1, "abdicative": 1, "abdicator": 1, "abdiel": 1, "abditive": 1, "abditory": 1, "abdom": 1, "abdomen": 1, "abdomens": 1, "abdomina": 1, "abdominal": 1, "abdominales": 1, "abdominalia": 1, "abdominalian": 1, "abdominally": 1, "abdominals": 1, "abdominoanterior": 1, "abdominocardiac": 1, "abdominocentesis": 1, "abdominocystic": 1, "abdominogenital": 1, "abdominohysterectomy": 1, "abdominohysterotomy": 1, "abdominoposterior": 1, "abdominoscope": 1, "abdominoscopy": 1, "abdominothoracic": 1, "abdominous": 1, "abdominovaginal": 1, "abdominovesical": 1, "abduce": 1, "abduced": 1, "abducens": 1, "abducent": 1, "abducentes": 1, "abduces": 1, "abducing": 1, "abduct": 1, "abducted": 1, "abducting": 1, "abduction": 1, "abductions": 1, "abductor": 1, "abductores": 1, "abductors": 1, "abducts": 1, "abe": 1, "abeam": 1, "abear": 1, "abearance": 1, "abecedaire": 1, "abecedary": 1, "abecedaria": 1, "abecedarian": 1, "abecedarians": 1, "abecedaries": 1, "abecedarium": 1, "abecedarius": 1, "abed": 1, "abede": 1, "abedge": 1, "abegge": 1, "abey": 1, "abeyance": 1, "abeyances": 1, "abeyancy": 1, "abeyancies": 1, "abeyant": 1, "abeigh": 1, "abel": 1, "abele": 1, "abeles": 1, "abelia": 1, "abelian": 1, "abelicea": 1, "abelite": 1, "abelmoschus": 1, "abelmosk": 1, "abelmosks": 1, "abelmusk": 1, "abelonian": 1, "abeltree": 1, "abencerrages": 1, "abend": 1, "abends": 1, "abenteric": 1, "abepithymia": 1, "aberdavine": 1, "aberdeen": 1, "aberdevine": 1, "aberdonian": 1, "aberduvine": 1, "aberia": 1, "abernethy": 1, "aberr": 1, "aberrance": 1, "aberrancy": 1, "aberrancies": 1, "aberrant": 1, "aberrantly": 1, "aberrants": 1, "aberrate": 1, "aberrated": 1, "aberrating": 1, "aberration": 1, "aberrational": 1, "aberrations": 1, "aberrative": 1, "aberrator": 1, "aberrometer": 1, "aberroscope": 1, "aberuncate": 1, "aberuncator": 1, "abesse": 1, "abessive": 1, "abet": 1, "abetment": 1, "abetments": 1, "abets": 1, "abettal": 1, "abettals": 1, "abetted": 1, "abetter": 1, "abetters": 1, "abetting": 1, "abettor": 1, "abettors": 1, "abevacuation": 1, "abfarad": 1, "abfarads": 1, "abhenry": 1, "abhenries": 1, "abhenrys": 1, "abhinaya": 1, "abhiseka": 1, "abhominable": 1, "abhor": 1, "abhorred": 1, "abhorrence": 1, "abhorrences": 1, "abhorrency": 1, "abhorrent": 1, "abhorrently": 1, "abhorrer": 1, "abhorrers": 1, "abhorrible": 1, "abhorring": 1, "abhors": 1, "abhorson": 1, "aby": 1, "abib": 1, "abichite": 1, "abidal": 1, "abidance": 1, "abidances": 1, "abidden": 1, "abide": 1, "abided": 1, "abider": 1, "abiders": 1, "abides": 1, "abidi": 1, "abiding": 1, "abidingly": 1, "abidingness": 1, "abie": 1, "abye": 1, "abiegh": 1, "abience": 1, "abient": 1, "abies": 1, "abyes": 1, "abietate": 1, "abietene": 1, "abietic": 1, "abietin": 1, "abietineae": 1, "abietineous": 1, "abietinic": 1, "abietite": 1, "abiezer": 1, "abigail": 1, "abigails": 1, "abigailship": 1, "abigeat": 1, "abigei": 1, "abigeus": 1, "abying": 1, "abilao": 1, "abilene": 1, "abiliment": 1, "abilitable": 1, "ability": 1, "abilities": 1, "abilla": 1, "abilo": 1, "abime": 1, "abintestate": 1, "abiogeneses": 1, "abiogenesis": 1, "abiogenesist": 1, "abiogenetic": 1, "abiogenetical": 1, "abiogenetically": 1, "abiogeny": 1, "abiogenist": 1, "abiogenous": 1, "abiology": 1, "abiological": 1, "abiologically": 1, "abioses": 1, "abiosis": 1, "abiotic": 1, "abiotical": 1, "abiotically": 1, "abiotrophy": 1, "abiotrophic": 1, "abipon": 1, "abir": 1, "abirritant": 1, "abirritate": 1, "abirritated": 1, "abirritating": 1, "abirritation": 1, "abirritative": 1, "abys": 1, "abysm": 1, "abysmal": 1, "abysmally": 1, "abysms": 1, "abyss": 1, "abyssa": 1, "abyssal": 1, "abysses": 1, "abyssinia": 1, "abyssinian": 1, "abyssinians": 1, "abyssobenthonic": 1, "abyssolith": 1, "abyssopelagic": 1, "abyssus": 1, "abiston": 1, "abit": 1, "abitibi": 1, "abiuret": 1, "abject": 1, "abjectedness": 1, "abjection": 1, "abjections": 1, "abjective": 1, "abjectly": 1, "abjectness": 1, "abjoint": 1, "abjudge": 1, "abjudged": 1, "abjudging": 1, "abjudicate": 1, "abjudicated": 1, "abjudicating": 1, "abjudication": 1, "abjudicator": 1, "abjugate": 1, "abjunct": 1, "abjunction": 1, "abjunctive": 1, "abjuration": 1, "abjurations": 1, "abjuratory": 1, "abjure": 1, "abjured": 1, "abjurement": 1, "abjurer": 1, "abjurers": 1, "abjures": 1, "abjuring": 1, "abkar": 1, "abkari": 1, "abkary": 1, "abkhas": 1, "abkhasian": 1, "abl": 1, "ablach": 1, "ablactate": 1, "ablactated": 1, "ablactating": 1, "ablactation": 1, "ablaqueate": 1, "ablare": 1, "ablastemic": 1, "ablastin": 1, "ablastous": 1, "ablate": 1, "ablated": 1, "ablates": 1, "ablating": 1, "ablation": 1, "ablations": 1, "ablatitious": 1, "ablatival": 1, "ablative": 1, "ablatively": 1, "ablatives": 1, "ablator": 1, "ablaut": 1, "ablauts": 1, "ablaze": 1, "able": 1, "ableeze": 1, "ablegate": 1, "ablegates": 1, "ablegation": 1, "ablend": 1, "ableness": 1, "ablepharia": 1, "ablepharon": 1, "ablepharous": 1, "ablepharus": 1, "ablepsy": 1, "ablepsia": 1, "ableptical": 1, "ableptically": 1, "abler": 1, "ables": 1, "ablesse": 1, "ablest": 1, "ablet": 1, "ablewhackets": 1, "ably": 1, "ablings": 1, "ablins": 1, "ablock": 1, "abloom": 1, "ablow": 1, "ablude": 1, "abluent": 1, "abluents": 1, "ablush": 1, "ablute": 1, "abluted": 1, "ablution": 1, "ablutionary": 1, "ablutions": 1, "abluvion": 1, "abmho": 1, "abmhos": 1, "abmodality": 1, "abmodalities": 1, "abn": 1, "abnaki": 1, "abnegate": 1, "abnegated": 1, "abnegates": 1, "abnegating": 1, "abnegation": 1, "abnegations": 1, "abnegative": 1, "abnegator": 1, "abnegators": 1, "abner": 1, "abnerval": 1, "abnet": 1, "abneural": 1, "abnormal": 1, "abnormalcy": 1, "abnormalcies": 1, "abnormalise": 1, "abnormalised": 1, "abnormalising": 1, "abnormalism": 1, "abnormalist": 1, "abnormality": 1, "abnormalities": 1, "abnormalize": 1, "abnormalized": 1, "abnormalizing": 1, "abnormally": 1, "abnormalness": 1, "abnormals": 1, "abnormity": 1, "abnormities": 1, "abnormous": 1, "abnumerable": 1, "abo": 1, "aboard": 1, "aboardage": 1, "abobra": 1, "abococket": 1, "abodah": 1, "abode": 1, "aboded": 1, "abodement": 1, "abodes": 1, "abody": 1, "aboding": 1, "abogado": 1, "abogados": 1, "abohm": 1, "abohms": 1, "aboideau": 1, "aboideaus": 1, "aboideaux": 1, "aboil": 1, "aboiteau": 1, "aboiteaus": 1, "aboiteaux": 1, "abolete": 1, "abolish": 1, "abolishable": 1, "abolished": 1, "abolisher": 1, "abolishers": 1, "abolishes": 1, "abolishing": 1, "abolishment": 1, "abolishments": 1, "abolition": 1, "abolitionary": 1, "abolitionise": 1, "abolitionised": 1, "abolitionising": 1, "abolitionism": 1, "abolitionist": 1, "abolitionists": 1, "abolitionize": 1, "abolitionized": 1, "abolitionizing": 1, "abolla": 1, "abollae": 1, "aboma": 1, "abomas": 1, "abomasa": 1, "abomasal": 1, "abomasi": 1, "abomasum": 1, "abomasus": 1, "abomasusi": 1, "abominability": 1, "abominable": 1, "abominableness": 1, "abominably": 1, "abominate": 1, "abominated": 1, "abominates": 1, "abominating": 1, "abomination": 1, "abominations": 1, "abominator": 1, "abominators": 1, "abomine": 1, "abondance": 1, "abongo": 1, "abonne": 1, "abonnement": 1, "aboon": 1, "aborad": 1, "aboral": 1, "aborally": 1, "abord": 1, "aboriginal": 1, "aboriginality": 1, "aboriginally": 1, "aboriginals": 1, "aboriginary": 1, "aborigine": 1, "aborigines": 1, "aborning": 1, "aborsement": 1, "aborsive": 1, "abort": 1, "aborted": 1, "aborter": 1, "aborters": 1, "aborticide": 1, "abortient": 1, "abortifacient": 1, "abortin": 1, "aborting": 1, "abortion": 1, "abortional": 1}
My JS code looks like this.
document.getElementById('button').addEventListener('click', loadData);
const letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
'p','q','r','s','t','u','v','w','x','y','z'];
var searched_word = '';
var boxes = document.querySelectorAll('.square');
//console.log(boxes);
function clickBox() {
boxes.forEach(function(box) {
box.addEventListener('click', function(e) {
e.preventDefault();
//console.log(this.innerHTML);
//return this.innerHTML;
searched_word += this.innerHTML;
document.querySelector('.input').value = searched_word;
//console.log(searched_word);
});
});
return searched_word;
}
function randomLetters(boxes) {
for (var i = 0; i < boxes.length; i++) {
let box = boxes[i];
let randomLetterNumber = Math.floor(Math.random() * letters.length);
box.innerHTML = letters[randomLetterNumber].toLocaleUpperCase();
//console.log(box);
//console.log(randomLetterNumber);
}
}
function loadData() {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'words_dictionary_full.json', true);
xhr.onload = function() {
if (this.status === 200) {
const words = JSON.parse(this.responseText);
for (word in words) {
//console.log(word);
if (word === clickBox().toLowerCase()) {
console.log('true');
} else {
console.log('false');
}
}
}
};
xhr.send();
}
clickBox();
randomLetters(boxes);
You can sort the array in your database/json file alphabetically and then use a binary search algorithm to search for words efficiently.
An implementation of a binary search algorithm is defined below (source):
/**
* Copyright 2009 Nicholas C. Zakas. All rights reserved.
* MIT-Licensed
* Uses a binary search algorithm to locate a value in the specified array.
* #param {Array} items The array containing the item.
* #param {variant} value The value to search for.
* #return {int} The zero-based index of the value in the array or -1 if not found.
*/
function binarySearch(items, value){
var startIndex = 0,
stopIndex = items.length - 1,
middle = Math.floor((stopIndex + startIndex)/2);
while(items[middle] != value && startIndex < stopIndex){
//adjust search area
if (value < items[middle]){
stopIndex = middle - 1;
} else if (value > items[middle]){
startIndex = middle + 1;
}
//recalculate middle
middle = Math.floor((stopIndex + startIndex)/2);
}
//make sure it's the right value
return (items[middle] != value) ? -1 : middle;
}
Simply pass the whole list of words and the word you're searching as parameters, it will return -1 if the entry does not exist in the list. You can use Object.keys(json) to convert the keys of the json to an array of words (used for items-parameter).
I have tried to search the forum and google but do not really know what to ask for so apologies if this have been answered before.
var currentLevel = 2;
var Level = function(layout, ColRow) {
this.layout = layout;
this.ColRow = ColRow;};
var level1 = new Level ([ 1, 2, 1, 2, 2,
1, 1, 3, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1],
[5, 4]);
var level2 = new Level ([ 1, 2, 1, 2, 2,
1, 1, 3, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1],
[2, 2]);
var drawTrack = function () {
id = 0;
for (var col = 0; col < level1.ColRow[0]; col ++) {
tile[col] = [];
for (var row = 0; row < level1.ColRow[1]; row++) {
id = col + row*level1.ColRow[0];
tile[col][row] = {x:0, y:0, type:"asphalt"};
image (tiles[level1.layout[id]], col * 256, row * 256);
}
}
};
In the example above I would like to change level1 in the code at the bottom to something like level(currentLevel).ColRow[0].
Is that possible or is there any other best practice to do this?
*edit
The array solution solved my problem, thanks!
The suggested link I did find before but could not see how it could change the variable within the code? Maybe I missed something.
How about creating an array of levels?
var levels = [
new Level ([1, 2, 1, 2, 2,
1, 1, 3, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1],
[5, 4]),
new Level ([1, 2, 1, 2, 2,
1, 1, 3, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1],
[2, 2])
];
Then to access:
levels[currentLevel].ColRow;