Javascript - Tetris - How to turn around the blocks - javascript

I'm working on a Tetris Game with a friend. How can we turn around the blocks?
We know how to calculate the position of the blocks but we don't know how to add it to the code :
i' = a * i + b * j
j' = c * i + d * j
newJ = -i;
newI = j;
What we were thinking of is adding Arrays but as I said we are not sure.. how to start it
This is our code so far:
function stylingSquares() {
var i;
var j;
for (i = 1; i > -2; i--) {
for (j = -1; j < 2; j++) {
var myDiv = document.createElement("div");
myDiv.style.width = "100px";
myDiv.style.height = "100px";
myDiv.style.backgroundColor = "black";
myDiv.setAttribute("class", "quad");
document.getElementById("game").appendChild(myDiv);
if ((i === 0 && j === 0) ||
(i === 1 && j === -1) ||
(i === 0 && j === -1) ||
(i === 0 && j === 1) ||
(i === 0 && j === 0)) {
myDiv.style.backgroundColor = "red";
} else {
}
}
}
setInterval(function() {
document.body.onkeyup = function(e) {
if (e.keyCode == 32) {
}
}
}, 300);
}
stylingSquares();
.quad {
float: left;
margin: 1 1 1 1;
}
#game {
position: relative;
width: 308px;
height: 308px;
background-color: black;
}
<div id="game"></div>

I would create a 2D-array of the play field (to keep track of the current piece, already placed blocks, borders), select a rotation point for the current piece and finally attempt to move the piece's blocks around that point, 1 or 2 "steps" at a time (as needed).
If the new location collides with something else in the array, try to move the piece one step in the opposite direction. If that's not possible then the piece cannot be rotated.

Related

The algorithm problem: Unique Paths III. Using backtracing pattern in javascript and not work

On a 2-dimensional grid, there are 4 types of squares:
1 represents the starting square.  There is exactly one starting square.
2 represents the ending square.  There is exactly one ending square.
0 represents empty squares we can walk over.
-1 represents obstacles that we cannot walk over.
Return the number of 4-directional walks from the starting square to the ending square, that walk over every non-obstacle square exactly once.
source:力扣(LeetCode)
link:https://leetcode-cn.com/problems/unique-paths-iii
i'm trying to use backtrack pattern to solve this problem
here is my code
/**
* #param {number[][]} grid
* #return {number}
*/
var uniquePathsIII = function(grid) {
let m = grid.length,
n = grid[0].length;
let start, targetIndex1,targetIndex2;
let res = 0;
let zero_counts = 0;
for(let i = 0; i < m; i++){
for(let j = 0; j < n; j++){
if(grid[i][j] == 1){
start = [i,j]
}
else if(grid[i][j] == 0){
zero_counts += 1;
}
else if(grid[i][j] == 2){
targetIndex1 = i;
targetIndex2 = j;
}
}
}
const backtrace = (i, j, zero_count) => {
if( i < 0 || i >= m ||
j < 0 || j >= n ||
grid[i][j] == -1 || zero_count < 0)
{
return;
}
if(i == targetIndex1 && j == targetIndex2 ){
if(zero_count == 0)
{
console.log("yes")
res += 1;
}
return
}
grid[i][j] = -1;
backtrace(i+1, j, zero_count - 1)
backtrace(i-1, j, zero_count - 1)
backtrace(i, j+1, zero_count - 1)
backtrace(i, j-1, zero_count - 1)
grid[i][j] = 0;
}
backtrace(start[0], start[1], zero_counts);
return res;
};
test sample:
[[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
expect result:
2
acutal result:
0
Perhaps a simpler solution is to use Depth First Search to solve Unique Paths III, as shown here.
The concept is that you take a point and then traverse in all directions until you hit an obstacle.
The guts are as follows:
int totalPaths = dfs(grid, x+1, y, zero) +
dfs(grid, x, y+1, zero) +
dfs(grid, x-1, y, zero) +
dfs(grid, x, y-1, zero);

for loops with and without block statements

I looked for a function to determine if a number is prime and found this
for (var i = 2; i <= Math.sqrt(num); i++)
if (num % i === 0) {
return false;
}
return true;
and I don't understand why that works, yet this doesn't
for (var i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) {
return false;
}
return true;
}
What is it about the (lack of the) block statement that is functioning differently
Your first code looks like this:
for (var i = 2; i <= Math.sqrt(num); i++){
if (num % i === 0) {
return false;
}
}
return true;
Notice how return true is on the outside. Your second code doesn't work because it prematurely returns true when there are more numbers to check. Your entire for loop is equivalent to
return num % 2 !== 0;
which is clearly incorrect.
Let me tell you something about blocks that you might not have known (It took me a while to discover this at least).
When you use a loop or if-else statement, you can ignore the using braces { and }.
Example 1
if (a === b){
c = 0;
}
is actually the same as
if (a === b)
c = 0;
Example 2
for (i = 0; i < 10; i++){
a += 1;
}
is actually the same as
for (i = 0; i < 10; i++)
a += 1;
However 1
if (a === b){
c = 0;
d = 1;
}
is not the same with
if (a === b)
c = 0;
d = 1;
However 2
for (i = 0; i < 10; i++){
a += 1;
b += 1;
}
is not the same with
for (i = 0; i < 10; i++)
a += 1;
b += 1;
Explanation
In loops and if-else statement, the block statement (codes surrounded by { and } groups the codes within it and execute it.
However, in the absence of { and }, the loops or if-else statement will only execute the single line of code after it.
Meaning,
var a = 0,
b = 0;
for (i = 0; i < 10; i++)
a += 1;
b += 1;
In this case, a === 10 but b === 1.
Also, in the following case,
var a = 0,
b = 0;
if (false)
a = 10;
b = 10;
a === 0 but b === 10.

How does (else) if and || work and which is better?

I don't know how these 2 block of codes executes,they have different outputs, do I have to use else if on the first block, if so, which is faster?
demo
var output = 0;
for (var n = 0; n < 100; n++) {
if (n % 3 === 0) {
output += n;
}
if (n % 5 === 0) {
output += n;
}
}
console.log(output);
/* ------------------------- */
var sum = 0;
for (var x = 0; x < 100; x++) {
if (x % 3 === 0 || x % 5 === 0) {
sum += x;
}
}
console.log(sum);
If you use else if instead of the second if in the first block, you should get the same results.
For example, n=15:
in the first block of code:
you check n%3 === 0 is true, so output is increased by 15
you check n%5 === 0 is true, so output is increased by 15 again
in the second block of code:
you check n%3 === 0 is true, no other checks are done, sum is increased by 15
if you use else if:
you check n%3 === 0 is true, so output is increased by 15
no other checks are done
I believe || and else if speeds are pretty the same. Hope it helps
In the first block of code, for the numbers divisible by 15(lowest common multiple of 3 and 5), sum was getting added twice.
In the second block of code, as its a || statement. Only once sum was added if its a multiple of 15.
Check the third block of code, I added. I am just looking for the sum of the multiples of 15. See its the exact diff you were finding.
var output = 0;
for (var n = 0; n < 100; n++) {
if (n % 3 === 0) {
output += n;
}
if (n % 5 === 0) {
output += n;
}
}
console.log(output);
/* ------------------------- */
var sum = 0;
for (var x = 0; x < 100; x++) {
if (x % 3 === 0 || x % 5 === 0) {
sum += x;
}
}
console.log(sum);
/* ------------------------- */
sum = 0;
for (x = 0; x < 100; x++) {
if (x % 15 === 0) {
sum += x;
}
}
console.log(sum);

How do you make every 9th element in Math.random array to be the same element?[javascript]

I have this bit of code here
<script language='javascript' type='text/javascript'>
var imagesArray = ["1.png","2.png","3.png","4.png","5.png","6.png","7.png","8.png","9.png","10.png","11.png","12.png","13.png","14.png","15.png","16.png","17.png","18.png","19.png","20.png","21.png" ];
var newArray = new Array(100);
for (i = 0; i < 100; i++)
{
if (i % 9 === 0)
{
}
else
{
newArray[i] = imagesArray[Math.floor(Math.random() * imagesArray.length)];
}
}
</script>
the idea behind is that i need it so that every 9th number that would be randomly chosen would remain the same, but i have no idea what do i put there so it would work.
Do you got any advice?
Thanks!
Here is a sample of what you can do :
First fill your array with Math.random() or whatever you want.
imagesArray[i] = Math.floor((Math.random() * 10) + 1);
If you want the value to be the same every 9 elements , use a loop starting at 9 and going through every 9 elements with i+9
for(var i = 9; i < yourArray.length ; i = i + 9){
imagesArray[i] = imagesArray[9];
}
Actually you can start the loop at 18 as well
Demo
Try defining a variable outside of for loop to store value at first i % 9 === 0
var newArray = new Array(100), ninth = null;
for (i = 0; i < 100; i++) {
newArray[i] = imagesArray[Math.floor(Math.random() * imagesArray.length)];
if (i % 9 === 0 && ninth === null && i === 9) {
ninth = newArray[i]
};
if (i % 9 === 0 && i >= 9) {
newArray[i] = ninth;
};
}

Check the diagonal neighbors of a node

I'm trying to compare the values of a node. Using the flood-fill algorithm I was able to check vertically and horizontally every node of my grid. Now I have to update my code to check the cells that sit on the diagonal, as in the image below:
In red you have the current node, in yellow are the cells that need to be checked.
Here is a snippet of what I have so far:
var mapWidth = Math.sqrt(mapData.length);
var currentCell = $('[data-x="'+ x +'"][data-y="'+ y +'"]');
if (x < 0 || y < 0 || x > mapWidth || y > mapWidth) {
return;
}
if(mapData[x*mapWidth+y] !== 0 || currentCell.hasClass('cell-grey')) {
if(mapData[x*mapWidth+y] > 0) {
currentCell.addClass('cell-grey').css('opacity', '1');
}
if(mapData[(x-1)*mapWidth+(y-1)] > 0 && mapData[(x-1)*mapWidth+(y-1)] < mapWidth) {
currentCell.addClass('cell-grey').css('opacity', '1');
return;
}
if(mapData[(x-1)*mapWidth+(y+1)] > 0 && mapData[(x-1)*mapWidth+(y+1)] < mapWidth) {
currentCell.addClass('cell-grey').css('opacity', '1');
return;
}
if(mapData[(x+1)*mapWidth+(y-1)] > 0 && mapData[(x+1)*mapWidth+(y-1)] < mapWidth) {
currentCell.addClass('cell-grey').css('opacity', '1');
return;
}
if(mapData[(x+1)*mapWidth+(y+1)] > 0 && mapData[(x+1)*mapWidth+(y+1)] < mapWidth) {
currentCell.addClass('cell-grey').css('opacity', '1');
return;
}
return true;
}
mapWidth is the variable that contains all the cells of the grid, and currentCell is the current node cell. This snippet is not really working for me.
When you evaluate mapData[(x-1)*mapWidth+(y-1)], the values of x-1 and y-1 may cause an out-of-bounds reference, which returns undefined. You have to validate the cell coordinates before accessing the array.
You can iterate over the four diagonal neighbors like this:
for (var neighborX = x - 1; neighborX <= x + 1; neighborX += 2) {
if (neighborX < 0 || neighborX >= mapWidth) {
continue;
}
for (var neighborY = y - 1; neighborY <= y + 1; neighborY += 2) {
if (neighborY < 0 || neighborY >= mapWidth) {
continue;
}
currentCell.addClass('cell-grey').css('opacity', '1');
}
}
I'm not sure exactly what you're trying to accomplish, but it looks like there are other bugs in your code. You probably don't want to return immediately after turning a cell gray, for example. If you want each of the diagonal neighbors to turn gray, the loop above should do the trick.
This line near the beginning of your code contains a subtle error:
if (x < 0 || y < 0 || x > mapWidth || y > mapWidth) {
Valid indices range from 0 through mapWidth - 1, so you should write:
if (x < 0 || y < 0 || x >= mapWidth || y >= mapWidth) {

Categories

Resources