Array element mysteriously overwritten - javascript

I'm learning p5.js.
I have a function that is called in setup() (don't worry, just the call is in setup, it is defined elsewhere):
CreateMaze = () => {
for(let i = 1; i <= numTiles; i++) {
let newTile = CreateTile(i);
let tileAdded = false;
while(!tileAdded) {
for(let j = 0; j < tiles.length; j++) {
print('new tile ' + newTile.x + ' ' + newTile.y);
print('array tile ' + tiles[j].x + ' ' + tiles[j].y);
if(newTile.x == tiles[j].x && newTile.y == tiles[j].y) {
print('new tile ' + newTile.x + ' ' + newTile.y);
print('array tile ' + tiles[j].x + ' ' + tiles[j].y);
newTile = CreateTile(i);
} else {
tiles.push(newTile);
tileAdded = true;
}
}
}
}
}
Also in setup(), I create a tile with let centralTile = new Tile(floor(windowWidth/2), floor(windowHeight/2),'#4caf50'); and push it to an array by tiles.push(centralTile);.
CreateTile is:
CreateTile = (ndx) => {
print('creating tile; index: ' + ndx);
let dir = ChooseDir(); //choose a direction
print(dir);
let xoff, yoff;
switch(dir) { //assign an offset value
case "N": xoff = 0; yoff = -50; break;
case "E": xoff = 50; yoff = 0; break;
case "S": xoff = 0; yoff = 50; break;
case "W": xoff = -50; yoff = 0; break;
}
//create a tile based on previous tile's location
let newTile = new Tile(tiles[ndx - 1].x + xoff, tiles[ndx - 1].y + yoff);
print('new tile ' + newTile.x + ' ' + newTile.y);
print('array tile (' + ndx-1 + ') ' + tiles[ndx-1].x + ' ' + tiles[ndx-1].y);
return newTile;
}
I'm running into an issue where the first tile I created in setup is the same as the second that comes from CreateTile(). I used the print statements to see where the value for the first tile is changing. It is right before the if. After I create the second tile, the prints tell me the two are different. But just before I compare them, they are the same. I cannot figure out why/how I'm changing the values of this initial array item. There is nothing I can find that would suggest it's changing. Like I said, when I create a second tile, it is different from the first (like it should be). But when it comes time to compare, they are the same. Where is this change occurring?

Related

Bliffoscope Data Analysis solution using javascript

I want to solve Bliffoscope Data Analysis Problem using javascript. I have following question.
This is SlimeTorpedo
+
+
+++
+++++++
++ ++
++ + ++
++ +++ ++
++ + ++
++ ++
+++++++
+++
This is TestData
+ + + ++ + +++ + +
+ ++ + + ++++ + + + + + + +++ +++ +
+ + + ++ ++ ++ + ++ + + + + +
+ ++ + ++ + + + ++ ++ + +
++++++ + + + ++ + + + + ++ + + +
+ + + + + ++ + ++ + + + +
+++ + ++ + + + +++ + + ++ +
+++++ + + + + + + + +
+ + + + + + + + + + + +
++ + + + ++ + + + ++
There is one question already similar to this but in Java. This question is asked here.
How can I solve this in JavaScript.
UPDATE
I tried following solution.
const fs = require('fs');
let torpedo = [], starship = [], testData = [];
// counter = -1;
function getTorpedoData(fileName, type) {
let counter = -1;
return new Promise(function(resolve, reject) {
fs.readFile(fileName,'utf8', (err, data) => {
if (err) {
reject();
} else {
for (let i = 0; i < data.length; i++) {
if (data[i] == '\n' || counter === -1) {
torpedo.push([]);
counter++;
} else {
torpedo[counter].push(data[i]);
}
}
}
console.log(data);
resolve();
});
});
}
function getTestData(fileName, type) {
let counter = -1;
return new Promise(function(resolve, reject) {
fs.readFile(fileName,'utf8', (err, data) => {
if (err) {
reject();
} else {
for (let i = 0; i < data.length; i++) {
if (data[i] == '\n' || counter === -1) {
testData.push([]);
counter++;
} else {
testData[counter].push(data[i]);
}
}
}
console.log(data);
resolve();
});
});
}
let score = 0;
getTorpedoData('./SlimeTorpedo.blf', 'torpedo').then((data) => {
getTestData('./TestData.blf', 'testData').then(() => {
torpedo.forEach((torpedoArray, torpedoIndex) => {
torpedoArray.filter((contents) => {
if (contents === '+') {
testData.forEach((testDataArray) => {
testDataArray.filter((dataContents, dataIndex) => {
// console.log(dataContents);
if (dataContents === '+') {
if (torpedoIndex === dataIndex) {
score++;
}
// console.log(score);
}
});
});
}
});
});
});
});
I creating 3 arrays torpedo, starship and testData. I read all these files and put them in multidimensional array(above). Then I am trying to find compare the indexes if torpedo array in testData array. However, there is something I am doing wrong. How can I fix it?
[Edit by Spektre]
Test results for test data (both this and the one from #greybeard link):
Red mean mismatch and Yellow mean match. Score is incremented for match and decremented for mismatch. x counts from zero to rightwards and y counts from zero downwards but your data was enlarged by empty line so you can count from 1 instead ...
Are you looking for something like this (Fiddle)?
// Create our images: torpedo (object) and background (context)
var object = " +\n +\n +++\n +++++++\n ++ ++\n++ + ++\n++ +++ ++\n++ + ++\n ++ ++\n +++++++\n +++",
context = " + + + ++ + +++ + +\n + ++ + + ++++ + + + + + + +++ +++ +\n + + + ++ ++ ++ + ++ + + + + +\n+ ++ + ++ + + + ++ ++ + +\n ++++++ + + + ++ + + + + ++ + + +\n + + + + + ++ + ++ + + + +\n+++ + ++ + + + +++ + + ++ +\n +++++ + + + + + + + +\n + + + + + + + + + + + +\n ++ + + + ++ + + + ++ ";
var c = document.getElementById("test_canvas"),
ctx = c.getContext("2d"),
scale = 10;
// Draw a pixel on canvas
function draw_pixel(x, y, fill_style) {
ctx.fillStyle = fill_style;
ctx.fillRect(x * scale, y * scale, scale, scale);
}
// Receive an array of coordinates, draw pixels
function draw_image(serialized_image, fill_style) {
for (var i = 0, len = serialized_image.length; i < len; i++) {
draw_pixel(serialized_image[i][0], serialized_image[i][1], fill_style);
}
}
// Receive a text string, turn it into an array of coordinates of filled in pixels
function serialize_map(char_map) {
var x = 0,
y = 0,
c,
map = [];
for (var i = 0, len = char_map.length; i < len; i++) {
c = char_map[i];
if (c == '+') {
map.push([x, y])
}
x += 1;
if (c == '\n') {
x = 0;
y += 1;
}
}
return map;
}
// Find number of intersections between two images
function array_intersect() {
var a, d, b, e, h = [],
f = {},
g;
g = arguments.length - 1;
b = arguments[0].length;
for (a = d = 0; a <= g; a++) {
e = arguments[a].length, e < b && (d = a, b = e);
}
for (a = 0; a <= g; a++) {
e = a === d ? 0 : a || d;
b = arguments[e].length;
for (var l = 0; l < b; l++) {
var k = arguments[e][l];
f[k] === a - 1 ? a === g ? (h.push(k), f[k] = 0) : f[k] = a : 0 === a && (f[k] = 0);
}
}
return h;
}
// Translate the coordinates of a serialized image
function translate(coords, ix, iy) {
return [coords[0] + ix, coords[1] + iy];
}
// Find in which position the object has more intersections with the background
function get_best_position(context, object) {
// Calculate image dimensions
context_width = context.sort(function(a, b) {
return b[0] - a[0];
})[0][0];
context_height = context.sort(function(a, b) {
return b[1] - a[1];
})[0][1];
object_width = object.sort(function(a, b) {
return b[0] - a[0];
})[0][0];
object_height = object.sort(function(a, b) {
return b[1] - a[1];
})[0][1];
// Swipe context, store amount of matches for each patch position
similaritudes = [];
for (var cx = 0; cx < context_width; cx++) {
for (var cy = 0; cy < context_height; cy++) {
translated_object = object.map(function(coords) {
return translate(coords, cx, cy);
})
intersection = array_intersect(context, translated_object);
// console.log(translated_object);
similaritudes[intersection.length] = [cx, cy];
}
}
// Return position for which number of matches was greater
return similaritudes.slice(-1)[0];
}
// Parse our images from the text strings
var serialized_context = serialize_map(context);
var serialized_object = serialize_map(object);
// Find best position for our torpedo
var best_position = get_best_position(serialized_context, serialized_object);
// Translate torpedo to best position
positioned_object = serialized_object.map(function(coords) {
return translate(coords, best_position[0], best_position[1]);
});
// Draw background and torpedo
draw_image(serialized_context, "gray");
draw_image(positioned_object, "rgba(0, 255, 0, 0.5)");
<canvas id="test_canvas" width="800" height="120" style="border:1px solid #000000;">
</canvas>

Modifying an X and Y variable, based on position in For Loop

EDIT - I don't think I explained it very well the first time.
I have a lot of data - it's in an Array, with each item in the array being an object. In the system I am working in (a control system for A/V devices, which uses JavaScript as the programming language), I am generating buttons based on the length of the array. I want to be able to position a button, and essentially know the X and Y coordinates for each button in the array - with X and Y being Row/Column. (which I then translate to a X/Y pixel position on my UI.
My initial code, which is below, is within a for loop, and I manually calculated the button position. But this is tedious, as I use this same function to show off different groups/sizes of buttons.
Anywhere there is mirage.log = console.log.
The code below is part of a For Loop
button.element.style.position = 'absolute'; //Do to all Buttons.
if (i == 0) //First Item
{
button.element.style.left = btn_Info.startLeft + 'px'; button.element.style.top = btn_Info.startTop + 'px';
}
else if (i <= btn_Info.numRow-1) //First Column.
{
mirage.log('Setting Position of First Column');
button.element.style.left = btn_Info.startLeft + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * i + btn_Info.startTop + 'px';
}
else if (i > btn_Info.numRow - 1 && i <= btn_Info.numRow * 2 - 1)
{
mirage.log('Setting Second column ' + i);
button.element.style.left = btn_Info.startLeft + btn_Info.width + btn_Info.hOffset + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * (i-btn_Info.numRow) + btn_Info.startTop + 'px';
}
else
{
mirage.log('Setting Third column ' + i);
button.element.style.left = btn_Info.startLeft + ((btn_Info.width + btn_Info.hOffset)*2) + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * (i - (btn_Info.numRow*2)) + btn_Info.startTop + 'px';
}
Thanks in advance for the help - I have grabbed so many answers from this forum over the last year, you guys are awesome!
EDIT -
I was able to get some adjustment if I generate rows first then columns:
I was able to get a little close with the help of a friend, and be able to adjust for a 2 column layout by doing the following:
encoder = {
'buttonVals':{'width':125,'height':50,'numCols':2,'numRows':null;'vOffset':10,'hOffset':10}
var posLeft;
var posTop;
posLeft = (i % encoder.buttonVals.numCols) * (encoder.buttonVals.width + encoder.buttonVals.hOffset) + encoder.buttonVals.startLeft;
posTop = Math.floor(i / encoder.buttonVals.numCols) * (encoder.buttonVals.height + encoder.buttonVals.vOffset) + encoder.buttonVals.startTop;
After working on this for a bit - here is the code that I got to work. This prints out both the row position, and the column position.
testFunction = function(incRow, incCol){
var myFunc = {
'testLength':0,
'numRows':incRow,
'numCols':incCol,
'array':[],
};
myFunc.testLength = incRow * incCol;
for(var c=0, posCol = 0, posRow = 0; c < myFunc.testLength; c++)
{
var whichRow;
posRow = Math.floor(c/myFunc.numRows);
whichRow = Math.floor(c/myFunc.numRows) + c;
if (whichRow > myFunc.numRows)
{
whichRow = whichRow - (myFunc.numRows * posRow) - posRow;
if (whichRow === 0)
{
posCol = posCol + 1;
}
}
console.log(c + ' : ' + whichRow + ' : ' + posCol);
}
};
testFunction(6,4);

Reversing my encrypt method

I created minor encrypt method to convert a small string based on distance between characters, but can't for the life of me figure out how to reverse it without knowing the distance between each character from the initial conversion. See image for example how it works imgur.com/Ine4sBo.png
I've already made the encrypt method here (Javascript):
var all = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.#-?").split('');
var position;
//var oKey = "P";
function encrypt() // Encrypt Fixed
{
var sEncode = ("HI-MOM").split('');
var oKey = "P";
for (var i = 0; i < sEncode.length; i++) {
if (all.indexOf(oKey) < all.indexOf(sEncode[i])) {
position = all.indexOf(sEncode[i]) - all.indexOf(oKey);
output.value += "oKey: " + oKey + " distance to sEncode[" + i + "]: " + sEncode[i] + " Count: " + position + " Final Char: " + all[position-1] + "\n";
oKey = sEncode[i];
}
else {
position = all.length - all.indexOf(oKey) + all.indexOf(sEncode[i]);
output.value += "oKey: " + oKey + " distance to sEncode[" + i + "]: " + sEncode[i] + " Count: " + position + " Final Char: " + all[position-1] + "\n";
oKey = sEncode[i];
}
}
}
However, it's the decrypt() method that's killing me.
From what I can tell, your encrypt function can be reduced to this:
var all = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.#-?").split('');
function encrypt(str)
{
var sEncode = str.split('');
var result = '';
var oKey = "P";
for(var i = 0; i < sEncode.length; i++)
{
result += all[(all.indexOf(sEncode[i]) - all.indexOf(oKey) + all.length - 1) % all.length];
oKey = sEncode[i];
}
return result;
}
(I got rid of the if clause by adding all.length either way, and removing it again with the remainder operator if necessary.)
From there, all you need to do is flip the operands (- all.indexOf(oKey) - 1 becomes + all.indexOf(oKey) + 1 (and since we have no more subtractions, adding all.length is no longer necessary)) and reverse the order (so oKey gets assigned the transformed value instead of the original one):
var all = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.#-?").split('');
function decrypt(str)
{
var sEncode = str.split('');
var result = '';
var oKey = "P";
for(var i = 0; i < sEncode.length; i++)
{
oKey = all[(all.indexOf(sEncode[i]) + all.indexOf(oKey) + 1) % all.length];
result += oKey;
}
return result;
}

Javascript If statement not acknowledged

Here is the code
setHighScore: function() {
var highScore = 0;
if (!window.snake || !window.fpsls || !window.fmlts) {
return;
}
if (++bot.tickCounter >= 20) {
bot.tickCounter = 0;
var currentScore = parseInt(Math.floor(150 * (window.fpsls[window.snake.sct] +
window.snake.fam / window.fmlts[window.snake.sct] - 1) - 50) / 10);
if (Number(currentScore) > Number(highScore)) {
highScore = currentScore;
window.localStorage.setItem('highScoreLoc', highScore);
console.log('Current Score: ' + currentScore);
}
}
},
onFrameUpdate: function() {
// Botstatus overlay
var generalStyle = '<span style = "opacity: 0.35";>';
window.fps_overlay.innerHTML = generalStyle + 'FPS: ' +
userInterface.framesPerSecond.getFPS() + '</span>';
if (window.position_overlay && window.playing) {
// Display Personal High Score
userInterface.setHighScore();
window.scoreHuD.innerHTML = generalStyle +
'Your High Score: ' + parseInt(Number(window.localStorage.getItem('highScoreLoc')));
// Display the X and Y of the snake
window.position_overlay.innerHTML = generalStyle +
'X: ' + (Math.round(window.snake.xx) || 0) +
' Y: ' + (Math.round(window.snake.yy) || 0) +
'</span>';
}
It's meant to check if the score is bigger than the high score then save the new high score (if its bigger) and after that print it on screen. But it isn't for some reason
line 10 is the if statement
the 2 lines above it are to find the current score and i know it outputs the current score because of line 13
Its Tampermonkey
and the actual script https://github.com/Classicanon/Slither.io-bot/blob/master/bot.user.js For (Slither.io)

Jquery -Combining string & Variable

I am new to jQuery and I cant seem to get the following code working..
for ( var i = 0; i < 2; i++ ) {
$status[i] = $('select[name="status'+ i +'"] option:selected').val();
$odd_a[i] = $("input:text[name='odd_a"+ 1 +"']").val();
$odd_b[i] = $("input:text[name='odd_b"+ 1 +"']").val();
$term[i] = $("select[name='term"+ 1 +"'] option:selected").val();
$dh_place[i] = $("input:text[name='dh_place"+ 1 +"']").val();
$dh_total[i] = $("input:text[name='dh_total"+ 1 +"']").val();
}
I have several text boxes "status1, status2, status3 etc. I need to call their name by the for loop. If I replace the "i" with the "1" it works. I cant seem to call the variable "i" at that position.
Try with
$status[i] = $('select[name="status'+ i +'"]').val();
and You need to start i value from 1 like
for ( var i = 1; i < 2; i++ ) {
One problem I can see is the i starts with 0 where as your input starts with 1, so the first loop will not return any elements.
for (var i = 0; i < 2; i++) {
$status[i] = $('select[name="status' + (i + 1) + '"]').val();
$odd_a[i] = $("input:text[name='odd_a" + (i + 1) + "']").val();
$odd_b[i] = $("input:text[name='odd_b" + (i + 1) + "']").val();
$term[i] = $("select[name='term" + (i + 1) + "']").val();
$dh_place[i] = $("input:text[name='dh_place" + (i + 1) + "']").val();
$dh_total[i] = $("input:text[name='dh_total" + (i + 1) + "']").val();
}

Categories

Resources