How can I optimise this code for my Google sheet macro? - javascript

I would love to make a macro that helps me average 7 values from 7 different cells(currently placeholders) but only when those are greater than 0, it should be fairly simple but I'm not an expert in JS just yet.
function macro1(){
var total = 0;
var ess = [];
ess[0] = 0;
ess[1] = 1;
ess[2] = 0;
ess[3] = 2;
ess[4] = 0;
ess[5] = 3;
ess[6] = 0;
if (ess[0] >= 1){
(total++)
}
if (ess[1] >= 1){
(total++)
}
if (ess[2] >= 1){
(total++)
}
if (ess[3] >= 1){
(total++)
}
if (ess[4] >= 1){
(total++)
}
if (ess[5] >= 1){
(total++)
}
if (ess[6] >= 1){
(total++)
}
if (total <= 0){
( total++ )
}
var avg = ( ess[0] + ess[1] + ess[2] + ess[3] + ess[4] + ess[5] + ess[6] ) / ( total );
console.log(avg);
}

Try this:
function macro1(){
var total= 0, count = 0;
var ess = [0, 1, 0, 2, 0, 3, 0];
for( x in ess ){
if(ess[x] > 0){
total += ess[x];
count++;
}
}
var avg = total / count;
console.log(avg);
}

Related

how to calculate percisely the character movement in a tiles

So, i have started building a game 2d just a few day so its make me so confuse with some reason of the movement character in the tilemap.In my tilemap, every per tiles2 is have the width and height 16px and the whole map is 800 x 1250, every movement of my character will add/sub 1 in per step, when I calculating detection collisions, the position became wrong position specifically when character move a step then the position return to far though i try to divide 16 px in every movement of character.
This is my movement:
this.setting_walking_speed = 3 ;
if (this.player.control_direction[0] == 1) {
this.player.x -= this.setting_walking_speed;
this.player.walking = 1;
this.player.direction = 0;
} else if (this.player.control_direction[1] == 1) {
this.player.y -= this.setting_walking_speed;
this.player.walking = 1;
this.player.direction = 2;
} else if (this.player.control_direction[2] == 1) {
this.player.x += this.setting_walking_speed;
this.player.walking = 1;
this.player.direction = 1;
} else if (this.player.control_direction[3] == 1) {
this.player.y += this.setting_walking_speed;
this.player.walking = 1;
this.player.direction = 3;
}
var posf = {
x:Math.floor( this.player.y /16 ) ,
y:Math.floor( this.player.x /16 )
};
this.collide(posf);
console.log(posf.x , posf.y);
}
And the collision function is:
The this.setting_minblocksize\[k\] = 16;
this.bound = this.draw_collision();
function rectangularCollision({rect1, rect2 }) {
return (
rect1.x >= rect2.x &&
rect1.x <= rect2.x &&
rect1.y <= rect2.y &&
rect1.y >= rect2.y
)
}
this.collide = function(player){
// console.log(this.bound);
this.bound.forEach((boundaries) => {
if(
rectangularCollision({,
rect1: player,
rect2: boundaries
})
){
console.log('collide');
}
})
}
this.draw_collision = function () {
var obj = [];
this.ctxt.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < canvas.height; i++) {
for (var j = 0; j < canvas.width; j++) {
var data = 0;
if (i >= 0 && j >= 0 && i < this.map.layers[1].height && j < this.map.layers[1].width) {
var data = this.map.layers[1].data[i * this.map.layers[1].width + j];
for (var k = 0; k < 1; k++) {
this.ctxt.fillStyle = 'red';
if (data != 0) {
obj.push({
x: j ,
y: i
});
this.ctxt.fillRect(
(j * this.setting_minblocksize[k]) ,
(i * this.setting_minblocksize[k]) ,
this.setting_minblocksize[k],
this.setting_minblocksize[k]
);
}
}
}
}
}
return obj;
}
My codepen link is right here
Thank you all for helping me!

Mine Sweeper - getting all cells until they neighbor with a bomb

I'm trying to perform the function where i click on a cell , and if it isn't in proximity of a bomb, it'll reveal all up until those who neighbour with a bomb.
I'm practically stuck :
I'm adding the code i think relevant here
//Click cells to reveal + placing mines for the first time
function cellClicked(elCell, i, j) {
if (!gGame.isOn) return;
if (gClickCounter === 0) {
getRandomMine(gLevel.mines, i, j);
startTimeInterval();
gClickCounter++;
}
var cell = gBoard[i][j];
console.log('cell:', cell);
if (cell.isShown) return;
if (!cell.isShown) {
cell.isShown = true;
elCell.classList.add('shown');
gGame.shownCount++;
console.log('gGame.shownCount:', gGame.shownCount);
}
if (cell.isMine === true) {
gLivesLeft--;
var elLives = document.querySelector('.lives');
elLives.innerHTML = gLivesLeft;
elCell.innerText = BOMB;
if (gLivesLeft === 0) {
gameOver();
}
} else {
var gNegs = countNegs(i, j);
elCell.innerText = gNegs;
console.log('elCell:', elCell.dataset.i);
console.log('elCell:', elCell.dataset.j);
cell.minesAroundCount = gNegs;
if (gNegs === 0) {
//check up
if (i > 0) {
var uCell = document.getElementById(gBoard.length * (i - 1) + j);
if (!gBoard[i - 1][j].isShown && !gBoard[i - 1][j].isMarked) {
cellClicked(uCell, i - 1, j);
}
}
//check down
if (i < gBoard.length - 1) {
var uCell = document.getElementById(gBoard.length * (i + 1) + j);
if (!gBoard[i + 1][j].isShown && !gBoard[i + 1][j].isMarked) {
cellClicked(uCell, i + 1, j);
}
}
//check right
if (j < gBoard.length - 1) {
var uCell = document.getElementById(gBoard.length * i + (j + 1));
if (!gBoard[i][j + 1].isShown && !gBoard[i][j + 1].isMarked) {
cellClicked(uCell, i, j + 1);
}
}
}
}
}
//counting neighbors
function countNegs(cellI, cellJ) {
var negsCount = 0;
for (var i = cellI - 1; i <= cellI + 1; i++) {
if (i < 0 || i > gBoard.length - 1) continue;
for (var j = cellJ - 1; j <= cellJ + 1; j++) {
if (j < 0 || j > gBoard[i].length - 1) continue;
if (i === cellI && j === cellJ) continue;
if (gBoard[i][j].isMine) {
negsCount++;
}
if (negsCount === 0) {
}
}
}
return negsCount;
}
and the entire code is here :
https://codepen.io/Aegtar/pen/XWaLLzz
Would appreciate any life savers here!

JavaScript value changes but canvas doesn't redraw with updated values

I am trying to implement John Conway's Game of Life in HTML using canvas and JavaScript.
In a 2D array I store the cell's x-y position and state (alive or dead).
I avoid the outer most cells to avoid having to worry about boundary conditions.
Using requestAnimationFrame, I clear the canvas, update the cells for the next generation based on the number of neighbors, then draw them.
I console log the states of the cells, which do change but for some reason they don't get updated in the canvas.
I have already used this link for reference, but to no avail:
Canvas: X value changing in console but not in canvas
Here is the JavaScript code:
var cv = document.querySelector('#cv');
var c = cv.getContext('2d');
var h = cv.height;
var w = cv.width;
//Cell class
function Cell(alive, x, y) {
this.alive = alive;
this.x = x;
this.y = y;
this.draw = function () {
//c.beginPath();
this.x = x;
this.y = y;
if(alive == true) {
c.fillStyle = 'black';
c.fillRect(this.x, this.y, 10, 10);
}
else if(alive == false){
c.fillStyle = 'white';
c.fillRect(this.x, this.y, 10, 10);
}
//c.stroke();
}
}
//2d array to contain Cell objects
var cellArray = new Array(100);
for (var i = 0; i < cellArray.length; i++) {
cellArray[i] = new Array(70);
}
//initial drawing
for(var i = 0; i < cellArray.length; i++) {
for(var j = 0; j < 100; j++) {
var b = Math.round(Math.random() - 0.4);
if(b == 1) {
cellArray[i][j] = new Cell(true, i * 10, j * 10);
cellArray[i][j].draw();
}
else {
cellArray[i][j] = new Cell(false, i * 10, j * 10);
cellArray[i][j].draw();
}
}
}
//find number of neghbor cells
function neighborSum(cell, i, j) {
this.cell = cell;
this.i = i;
this.j = j;
var sum = 0;
if(cellArray[i - 1][j - 1].alive == true) {
sum += 1;
}
if(cellArray[i][j - 1].alive == true) {
sum += 1;
}
if(cellArray[i - 1][j].alive == true) {
sum += 1;
}
if(cellArray[i + 1][j - 1].alive == true) {
sum += 1;
}
if(cellArray[i - 1][j + 1].alive == true) {
sum += 1;
}
if(cellArray[i + 1][j].alive == true) {
sum += 1;
}
if(cellArray[i][j + 1].alive == true) {
sum += 1;
}
if(cellArray[i + 1][j + 1].alive == true) {
sum += 1;
}
return sum;
}
//animate function
function play() {
requestAnimationFrame(play);
c.clearRect(0, 0, w, h);
//check surrounding neighbor cells
for(var i = 1; i < cellArray.length - 1; i++) {
for(var j = 1; j < 70 - 1; j++) {
if( cellArray[i][j].alive == true && ( neighborSum(cellArray[i][j], i, j) > 3 || neighborSum(cellArray[i][j], i, j) < 2 ) ) {
cellArray[i][j].alive = false;
}
else if( cellArray[i][j].alive == true && ( neighborSum(cellArray[i][j], i, j) == 3 || neighborSum(cellArray[i][j], i, j) == 2 ) ) {
cellArray[i][j].alive = true;
}
else if(cellArray[i][j].alive == false && neighborSum(cellArray[i][j], i, j) == 3 ) {
cellArray[i][j].alive = true;
}
}
}
//console.log(cellArray)
//redraw cells alive or dead
for(var i = 1; i < cellArray.length - 1; i++) {
for(var j = 1; j < 70 - 1; j++) {
cellArray[i][j].draw();
}
}
}
requestAnimationFrame(play);
Here is a JSFiddle: https://jsfiddle.net/ew3046st/1/
Okay, so I was able to fix the problem by removing the draw() function and instead I just directly call the fillRect() function in the requestAnimationFrame function. Also, fixed the behavior of the cells by adding another 2d array of the same size to store the state of the cells for the next generation:
...
for(var i = 1; i < cellArray.length - 1; i++) {
for(var j = 1; j < 70 - 1; j++) {
//cellArray[i][j].draw();
c.beginPath();
//cellArray[i][j].draw();
if(cellArray[i][j].alive == true) {
c.fillStyle = 'black';
c.fillRect(cellArray[i][j].x, cellArray[i][j].y, 10, 10);
}
else if(cellArray[i][j].alive == false){
c.fillStyle = 'white';
c.fillRect(cellArray[i][j].x, cellArray[i][j].y, 10, 10);
}
c.stroke();
}
}
...
Here is a working jsfiddle: https://jsfiddle.net/e7u19xpq/1/

Control ball speed in pong

I have this code below, and I'm having a hard time solving this one.
On dotime function, i have the ball speed:
/* HERE */
function dotime() {
move1();
if (myform != null) {
myform.text3.value = display1();
myform.score.value = "" + score;
}
/* ---Ball Speed--- */
if (!oops_flag) timerID = setTimeout("dotime()", 190);
/* ---trying to make ball speed faster--- */
if (score == 1) {
timerID = setTimeout("dotime()", 100 - 30);
}
timerRunning = true;
}
I tried to make the ball move faster but when i do the second "if", the ball just flying too fast.
Thanks in advance,
fufle.
full code:
var crlf = "\r\n";
var x = 0;
var y = 0;
var dx = 1;
var dy = 1;
var s = "";
var u = 0;
var oops_flag = false;
var score = 0;
function move1() {
x += dx;
if (x > 61) {
x -= 2 * Math.abs(dx);
if (dx > 0) dx = -dx;
}
if (x < 0) {
x += 2 * Math.abs(dx);
if (dx < 0) dx = -dx;
}
y += dy;
if (y > 24) {
y -= 2 * Math.abs(dy);
if (dy > 0) dy = -dy;
if (Math.abs(x - 2 * u - 1) > 2) {
oops_flag = true;
} else {
score += 1;
}
}
if (y < 0) {
y += 2 * Math.abs(dy);
if (dy < 0) dy = -dy;
}
}
function display1() {
var s1 = ""
var i, j;
if (oops_flag) return " Unlucky, Play again?"
for (j = 0; j < 25; j++) {
for (i = 0; i < 62; i++) {
/* BALL */
if (j == y && i == x) s1 += "🔴";
else s1 += " ";
}
s1 += crlf;
}
/* DEFENDER */
var s2 = "";
for (i = 0; i < 31; i++) {
if (u == i) s2 += "â–„â–„â–„â–„â–„";
else s2 += " ";
}
return (s1 + s2);
}
var timerID = null;
var timerRunning = false;
var myform;
function stopclock() {
if (timerRunning) clearTimeout(timerID);
timerRunning = false;
}
function startclock(form) {
myform = form;
oops_flag = false;
score = 0;
if (navigator.userAgent.indexOf("Mac") > 2) crlf = "\n";
stopclock();
dotime();
// var id= setInterval(frameElement,10000);
}
/* HERE */
function dotime() {
move1();
if (myform != null) {
myform.text3.value = display1();
myform.score.value = "" + score;
}
if (!oops_flag) timerID = setTimeout("dotime()", 100);
if (score == 1) {
timerID = setTimeout("dotime()", 100 - 30);
}
timerRunning = true;
}
Looks like you have two timers running so you need to make it so only one will run.
if (!oops_flag) {
var speed = 100;
if (score===1) speed = 70;
timerID = setTimeout(dotime, speed);
}
or with a ternary operator
if (!oops_flag) {
var speed = (score===1) ? 70 : 100;
timerID = setTimeout(dotime, speed);
}

How to use AJAX or JSON in this code?

I am creating a website application that allows users to select a seat, if it is not already reserved, and reserve it.
I have created a very round about way of getting the seats that are previously reserved using iFrames, however that was temporarily, now I need to make it secure and "proper javascript code" using proper practices. I have no clue what AJAX (or JSON) is, nor how to add it to this code, but it needs to get the file "seatsReserved"+this.id(that is the date)+"Que.html" and compare the string of previously reserved seats to see which class to make the element. If this is horrible, or if any of the other things could work better, I am open to criticism to everything. Thank you all!
Here is the javascript code:
A little side note, all of the if statements are due to different amount of seats in each row
<script>
var i = " 0 ";
var counter = 0;
var leng=0;
document.getElementById("Show1").addEventListener("click", changeDay);
document.getElementById("Show2").addEventListener("click", changeDay);
document.getElementById("Show3").addEventListener("click", changeDay);
function changeDay() {
var iFrame = document.getElementById("seatList");
iFrame.src = "seatsReserved" + this.id + "Que.html";
document.getElementById('date').innerHTML = this.id;
var seatsTaken = iFrame.contentWindow.document.body.innerHTML;
var k = 0;
let = 'a';
var lc = 0;
for (lc = 1; lc <= 14; lc++) {
if (lc == 1) {
leng = 28;
}
else if (lc == 2) {
leng = 29;
}
else if (lc == 3) {
leng = 32;
}
else if (lc == 4 || lc == 6 || lc == 12 || lc == 14) {
leng = 33;
}
else if (lc == 5 || lc == 13) {
leng = 34;
}
else if (lc == 8 || lc == 10) {
leng = 35;
}
else {
leng = 36;
}
for (k = 1; k <= leng; k++) {
if (seatsTaken.indexOf((" " +
let +k + " ")) <= -1) {
seat = document.getElementById(let +k);
seat.removeEventListener("click", selectedSeat);
}
else {
document.getElementById(let +k).className = "openseat";
document.getElementById(let +k).removeEventListener("click", doNothing);
}
}
let = String.fromCharCode(let.charCodeAt(0) + 1);
}
}
function loadChanges() {
var iFrame = document.getElementById("seatList");
var seatsTaken = iFrame.contentWindow.document.body.innerHTML;
var k = 0;
let = 'a';
var lc = 0;
var leng = 0;
for (lc = 1; lc <= 14; lc++) {
if (lc == 1) {
leng = 28;
}
else if (lc == 2) {
leng = 29;
}
else if (lc == 3) {
leng = 32;
}
else if (lc == 4 || lc == 6 || lc == 12 || lc == 14) {
leng = 33;
}
else if (lc == 5 || lc == 13) {
leng = 34;
}
else if (lc == 8 || lc == 10) {
leng = 35;
}
else {
leng = 36;
}
for (k = 1; k <= leng; k++) {
if (seatsTaken.indexOf((" " +
let +k + " ")) <= -1) {
seat = document.getElementById(let +k);
seat.addEventListener("click", selectedSeat);
seat.className = "openseat";
}
else {
document.getElementById(let +k).className = "notAvailible";
document.getElementById(let +k).addEventListener("click", doNothing);
}
}
let = String.fromCharCode(let.charCodeAt(0) + 1);
}
i = " 0 ";
counter = 0;
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
document.getElementById("seatnums").innerHTML = counter;
}
i = document.getElementById("seatString").innerHTML;
counter = document.getElementById("seatnums").innerHTML;
function selectedSeat() {
var w = this.id;
var l = (" " + w);
var b = (" " + w + " ");
if (counter < 5) {
if (i.indexOf(b) <= 0) {
this.className = "closedseat";
i = i + b;
i = i.replace(" 0 ", " ");
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
counter = counter + 1;
document.getElementById("seatnums").innerHTML = counter;
}
else if (i.indexOf(b) > 0) {
this.className = "openseat";
i = i.replace(b, "");
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
counter = counter - 1;
document.getElementById("seatnums").innerHTML = counter;
}
}
else if (i.indexOf(b) > 0) {
this.className = "openseat";
i = i.replace(b, "");
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
counter = counter - 1;
document.getElementById("seatnums").innerHTML = counter;
}
}
function doNothing() {
}
var rannum = Math.random() * 1000;
document.getElementById('getConfirmation').value = rannum;
</script>

Categories

Resources