I need to optymalise my chessboard code (JS) to avoid soo many lines of copied code for the same chess piece like pawn, and other pieces.
I need to create better data structure i think , but i dont have good idea how to iterate my data structure to locate all pieces on the board.This is codepen link for this project.
For example this is my function to place knight piece on the board.
function addKnight() {
//piece create function
var KnightFirst = oneKnight[8];
var KnightSecond = oneKnight[15];
var KnightThird = oneKnight[48];
var KnightFour = oneKnight[55];
pieceKnight1 = document.createElement("i");
pieceKnight1.classList.add("fas");
pieceKnight1.classList.add("fa-chess-knight");
pieceKnight2 = document.createElement("i");
pieceKnight2.classList.add("fas");
pieceKnight2.classList.add("fa-chess-knight");
pieceKnight3 = document.createElement("i");
pieceKnight3.classList.add("fas");
pieceKnight3.classList.add("fa-chess-knight");
pieceKnight4 = document.createElement("i");
pieceKnight4.classList.add("fas");
pieceKnight4.classList.add("fa-chess-knight");
KnightFirst.appendChild(pieceKnight1);
KnightSecond.appendChild(pieceKnight2);
pieceKnight2.classList.add("color");
KnightThird.appendChild(pieceKnight3);
KnightFour.appendChild(pieceKnight4);
pieceKnight4.classList.add("color");
}
I would do something like this. It isn't a complete code but just the structure.
var piece = {
x, y,
type,
color,
sprite: new Image(),
}
var pieces = [];
function addPieces () {
if (i < 16) {
for (let i = 0; i < 32; i++) {
for (let j = 0; j < 16; j++) {
pieces.push(piece);
pieces[i].type = "pawn";
if (j < 4) {
//set position for white pawns
} else {
//set position for black pawns
}
} }
if (i >= 16 && i < 20) {
for (let j = 0; j < 4; j++) {
pieces.push(piece);
pieces[i].type = "knight";
if (j < 2) {
//set position for white knights
} else {
//set position for black knights
}
}}
if (i >= 20 && i < 24) {
for (let j = 0; j < 4; j++) {
pieces.push(piece);
pieces[i].type = "rook";
if (j < 2) {
//set position for white rooks
} else {
//set position for black rooks
}
}}
if (i >= 24 && i < 28) {
for (let j = 0; j < 4; j++) {
pieces.push(piece);
pieces[i].type = "bishop";
if (j < 2) {
//set position for white bishops
} else {
//set position for black bishops
}
}}
if (i >= 28 && i < 30) {
for (let j = 0; j < 2; j++) {
pieces.push(piece);
pieces[i].type = "queen";
if (j < 1) {
//set position for white queen
} else {
//set position for black queen
}
}}
if (i >= 30 && i < 32) {
for (let j = 0; j < 2; j++) {
pieces.push(piece);
pieces[i].type = "king";
if (j < 1) {
//set position for white king
} else {
//set position for black king
}
} }
}
}
You could apply the same type of function for the update each frame, but that's your call. Hope this helps!
Related
I watched a coding train video about the game of life and i tried making a program but it doesn't work. It just generates random squares on the screen as a first image (the starting position) and then just generates another frame with the positive squares (white) disappearing and that's it. Only 2 frames. And it doesn't show an error. Can someone explain why?
function make2D(x, y) {
let arr = new Array(x);
for (let i = 0; i < x; i++) {
arr[i] = new Array(y);
}
return arr;
}
let grid;
let col;
let row;
let resolution = 20;
function setup() {
createCanvas(500, 500);
col = width / resolution;
row = height / resolution;
grid = make2D(col, row);
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
grid[i][j] = floor(random(2));
}
}
}
function draw() {
frameRate(1);
background(0);
//drawing
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
let x = i * resolution;
let y = j * resolution;
if (grid[i][j]) {
fill(255);
} else {
fill(0);
}
rect(x, y, resolution, resolution);
}
}
//processing
let next = make2D(col, row);
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
let nb = calculatePosition(grid, i, j);
//fill(255,0,0);
//text(grid[i][j],i*resolution+6,j*resolution+15);
if (grid[i][j] == 0 && nb == 3) {
next[i][j] == 1;
} else if (grid[i][j] == 1 && (nb > 3 || nb < 2)) {
next[i][j] == 0;
} else {
next[i][j] = grid[i][j];
}
}
}
grid = next;
}
function calculatePosition(grid, x, y) {
let sum = 0;
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
let cols = (x + i + col) % col;
let rows = (y + j + row) % row;
sum += grid[cols][rows];
}
}
sum -= grid[x][y];
console.log(sum);
return sum;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>
You accidentally are using equality (==) instead of assignment (=) here
if (grid[i][j] == 0 && nb == 3) {
next[i][j] == 1;
} else if (grid[i][j] == 1 && (nb > 3 || nb < 2)) {
next[i][j] == 0;
} else {
next[i][j] = grid[i][j];
}
You should also move your frameRate call to setup().
function LCSubStr(X, Y) {
let m = X.length;
let n = Y.length;
let result = 0;
let end;
let len = new Array(4);
for (let i = 0; i < len.length; i++) {
len[i] = new Array(n);
for (let j = 0; j < n; j++) {
len[i][j] = 0;
}
}
let currRow = 0;
for (let i = 0; i <= m; i++) {
for (let j = 0; j <= n; j++) {
if (i == 0 || j == 0) {
len[currRow][j] = 0;
}
else if (X[i - 1] == Y[j - 1]) {
len[currRow][j] = len[1 - currRow][j - 1] + 1;
if (len[currRow][j] > result) {
result = len[currRow][j];
end = i - 1;
}
}
else {
len[currRow][j] = 0;
}
}
currRow = 1 - currRow;
}
if (result == 0) {
return "-1";
}
return X.substr(end - result + 1, result);
}
// Driver Code
let X = "GeeksforGeeks";
let Y = "GeeksQuiz";
// function call
document.write(LCSubStr(X, Y));
How can I convert this code for multiple input?
I checked many lcs code but no one works with
ABCQEFDEFGHIJ BCXEFGYZBCDEWEFGHU > EFGH
This one just works good without any problem. I should convert this one for multiple input in Javascript.
Now we have X,Y but it shoulde be with multiple inputs.
I've implemented Conway's game of life in p5.js.
I have a function which counts the number of alive neighbours of a given cell, it appears from the tests I did that it works perfectly. That being said I'm having unexpected behaviour when it comes to simulating : it's not following the correct patterns. I start here with 3 aligned squares (a blinker) and it's supposed to rotate but for some reason they just all die.
Wikipedia shows how a blinker should behave : https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Examples_of_patterns
You can copy paste the source below into https://editor.p5js.org/ and see for yourself.
I'm suspecting the issue has got something to do with copying of the board (matrice of cells), because an update has to be simultaneous for all cells, hence we keep in memory the previous board and update the current board based on the previous board.
Source :
//size of cell in pixels.
const size = 20;
const canvasWidth = 400;
const canvasHeight = 400;
const n = canvasWidth / size;
const m = canvasHeight / size;
class Cell {
constructor(status, position) {
this.status = status;
this.position = position;
}
}
let board = [];
function setup() {
//initialise matrix.
for(let i=0; i < m; i++) {
board[i] = new Array(n);
}
//fill matrix of cells.
for(let i=0; i < m; i++ ) {
for(let j=0; j < n; j++ ) {
board[i][j] = new Cell(false, [i*size, j*size]);
}
}
console.log("start", floor(m /2), floor(n / 2))
//[x, y] positions.
board[floor(m /2)][floor(n / 2)].status = true;
board[floor(m /2)+1][floor(n / 2)].status = true;
board[floor(m /2)+2][floor(n / 2)].status = true;
createCanvas(canvasWidth, canvasHeight);
frameRate( 1 )
}
//I'm 99.99% sure this function works, all the tests shows it does.
function updateCell(i, j, previousBoard) {
let count = 0;
//check neighbourgh cells.
for(let k=-1; k < 2; k++) {
for(let p=-1; p < 2; p++) {
if( !(i + k < 0 || j + p < 0 || j + p >= n || i + k >= m) ) {
if(k != 0 || p != 0) {
if(previousBoard[i+k][j+p].status === true) {
count++;
}
}
}
}
}
console.log(count)
if((previousBoard[i][j].status === true) && (count < 2 || count > 3)) {
//console.log("false", i, j, count)
board[i][j].status = false;
} else if((count === 3) && (previousBoard[i][j].status === false)) { //if dead but 3 alive neighbours.
//alive
console.log("true", i, j, count)
board[i][j].status = true;
} else if((previousBoard[i][j].status === true) && (count === 2 || count === 3)) {
console.log("true", i, j, count)
board[i][j].status = true;
}
}
function copyMatrix() {
let newMatrix = []
for(let i=0; i < m; i++) {
//console.log(board[i])
newMatrix[i] = board[i].slice()
}
//console.log(newMatrix)
return newMatrix
}
function draw() {
background(220);
//draw rectangles.
for(let i=0; i < m; i++) {
for(let j=0; j < n; j++) {
if (board[i][j].status === true) {
fill('black');
} else {
fill('white');
}
rect(board[i][j].position[0], board[i][j].position[1], size, size);
}
}
//slice copies previous array into a new reference, previousBoard and board are
//now independent.
let previousBoard = copyMatrix();
//updateCell(11, 9, previousBoard) //uncommenting this line creates weird results...
//console.log(previousBoard)
//update all cells based on previousBoard. (we'll modify board based on previous)
for(let i=0; i < m; i++) {
for(let j=0; j < n; j++) {
updateCell(i, j, previousBoard);
}
}
}
<html>
<head>
<Title>Gordon's Game of Life</Title>
<script src = "p5.js"></script>
<script src = "sketch.js"></script>
</head>
<body>
<h1>Gordon's Game of Life</h1>
</body>
</html>
The issue is that copyMatrix needs to do a deep copy.
Change copy matrix to this:
function copyMatrix() {
let newMatrix = []
for(let i=0; i < m; i++) {
newMatrix[i] = [];
for (let j=0;j< n;j++){
newMatrix[i][j] = new Cell(board[i][j].status, board[i][j].position);
}
}
return newMatrix
}
Here is your code with the copyMatrix change and an added glider to help demonstrate behavior.
//size of cell in pixels.
const size = 20;
const canvasWidth = 400;
const canvasHeight = 400;
const n = canvasWidth / size;
const m = canvasHeight / size;
class Cell {
constructor(status, position) {
this.status = status;
this.position = position;
}
}
let board = [];
function setup() {
//initialise matrix.
for(let i=0; i < m; i++) {
board[i] = new Array(n);
}
//fill matrix of cells.
for(let i=0; i < m; i++ ) {
for(let j=0; j < n; j++ ) {
board[i][j] = new Cell(false, [i*size, j*size]);
}
}
board[floor(m /2)][floor(n / 2)].status = true;
board[floor(m /2)+1][floor(n / 2)].status = true;
board[floor(m /2)+2][floor(n / 2)].status = true;
// glider
board[0][0].status = true;
board[0][2].status = true;
board[1][1].status = true;
board[1][2].status = true;
board[2][1].status = true;
createCanvas(canvasWidth, canvasHeight);
frameRate( 1 )
}
function updateCell(i, j, previousBoard) {
let count = 0;
//check neighbourgh cells.
for(let k=-1; k < 2; k++) {
for(let p=-1; p < 2; p++) {
if( !(i + k < 0 || j + p < 0 || j + p >= n || i + k >= m) ) {
if(k != 0 || p != 0) {
if(previousBoard[i+k][j+p].status === true) {
count++;
}
}
}
}
}
if((previousBoard[i][j].status) && (count < 2 || count > 3)) {
board[i][j].status = false;
} else if((count === 3) && (!previousBoard[i][j].status)) { //if dead but 3 alive neighbours.
board[i][j].status = true;
} else if((previousBoard[i][j].status) && (count === 2 || count === 3)) {
board[i][j].status = true;
}
}
function copyMatrix() {
let newMatrix = []
for(let i=0; i < m; i++) {
newMatrix[i] = [];
for (let j=0;j< n;j++){
newMatrix[i][j] = new Cell(board[i][j].status, board[i][j].position);
}
}
return newMatrix
}
function draw() {
background(220);
//draw rectangles.
for(let i=0; i < m; i++) {
for(let j=0; j < n; j++) {
if (board[i][j].status === true) {
fill('black');
} else {
fill('white');
}
rect(board[i][j].position[0], board[i][j].position[1], size, size);
}
}
let previousBoard = copyMatrix();
//updateCell(11, 9, previousBoard) //uncommenting this line creates weird results...
//console.log(previousBoard)
//update all cells based on previousBoard. (we'll modify board based on previous)
for(let i=0; i < m; i++) {
for(let j=0; j < n; j++) {
updateCell(i, j, previousBoard);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>
With the glider this setup demonstrates all three possible patterns. We start with a moving spaceship glider and an oscillator and when the glider runs into the oscillator we have a few iterations that break both patterns and then it settles down into a 2x2 still life.
I am starting to write a recursion backtrack maze system printed in console but I already stumble in a trivial problem, I can't set the lines from my grid structure as you can see below:
console.log("Teste de Labirinto - Recursive Backtracking")
let grid = []
let cells = []
const width = 8
const height = 10
for (let i = 0; i < width; i++){
cells.push(".")
}
for (let j = 0; j < height; j++){
grid.push(cells)
}
function printMaze(){
let line = " "
for (let j = 0; j < height; j++) {
for (let i = 0; i < width; i++) {
line += " " + grid[j][i] + " "
}
console.log(line)
line = " "
}
}
function createMazeBorder() {
for (let j = 0; j < height; j++) {
for (let i = 0; i < width; i++) {
if(i == 0) {
grid[j][i] = "X"
}
}
}
}
createMazeBorder()
printMaze()
How can I create a wall of "X" in my grid? I tried all the "ifs" as possible and swap the "i" and "j", widht, height, still can't do it... Thank you for the time.
Well, solved it, it was not possible to create the walls because all my cells got the same reference, there is the code:
console.log("Teste de Labirinto - Recursive Backtracking")
let grid = []
const width = 8
const height = 10
for (let j = 0; j < height; j++){
let cells = [];
for (let i = 0; i < width; i++){
cells.push(".")
}
grid.push(cells)
}
function printMaze(){
let line = " "
for (let j = 0; j < height; j++) {
for (let i = 0; i < width; i++) {
line += " " + grid[j][i] + " "
}
console.log(line)
line = " "
}
}
function createMazeBorder() {
for (let j = 0; j < height; j++) {
for (let i = 0; i < width; i++) {
if(j == 0 || i == 0 || j == height-1 || i == width-1) {
grid[j][i] = "X"
}
}
}
}
createMazeBorder()
printMaze()
Ok so i tried to make conway's game of life in p5.js and i am stuck in some wierd bug .
function make2DArray(cols, rows) {
let arr = new Array(cols);
for (let i = 0; i < arr.length; i++) {
arr[i] = new Array(rows);
}
return arr;
}
function countNeighbors(grid, x, y) {
let sum = 0;
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
let col = x + i;
let row = y + i;
if (grid[col][row] === undefined){
sum += grid[col][row];
}
}
}
sum-=grid[x][y]
return sum;
}
let grid;
let next;
let cols;
let rows;
let resolution = 20;
let fr = 15;
function setup() {
createCanvas(600, 400);
frameRate(fr);
cols = width / resolution;
rows = height / resolution;
next = make2DArray(cols, rows);
grid = make2DArray(cols, rows);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
grid[i][j] = floor(random(2));
}
}
}
function draw() {
background(0);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let x = i * resolution;
let y = j * resolution;
if (grid[i][j] == 1) {
fill(0);
stroke(150);
rect(x, y, resolution - 1, resolution - 1);
} else {
fill(255);
stroke(150);
rect(x, y, resolution - 1, resolution - 1);
}
}
}
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let state = grid[i][j];
let neighbors = countNeighbors(grid, i, j);
if (state == 0 && neighbors == 3) {
next[i][j] = 1;
} else if (state == 1 && (neighbors < 2 || neighbors > 3)) {
next[i][j] = 0;
} else {
next[i][j] = state;
}
}
}
grid = next;
}
Soo basically i have function countNeighbors and i think that bug is in there , i tried checking if col and row are i boundaries of array
like this
if (col>-1 && col <grid.length && row>-1 && row < grid[0].length){
//increase sum
}
but its even worse. I am new to js so i figured out that if for example
let x=new Array(10);
//and then when i try this
console.log(c[-1])
//it should give undefined
but program still wont work :(
Thanks!
With a few changes you can make it work:
1) Replace let row = y + i; by let row = y + j; That typo was making most of the counts off.
2) Replace the condition
if (grid[col][row] === undefined){
by
if (0 <= col && col < cols && 0 <= row && row < rows){
The problem with your original condition is that if grid[col] is undefined then grid[col][row] is undefined[row], which doesn't make sense.
3) For consistency sake, add a semicolon to the end of sum-=grid[x][y]
4) Finally, so as to not create an unintended alias, you need to replace grid = next by something like:
for(let i = 0; i < grid.length; i++){
grid[i] = next[i].slice();
}
Alternatively, make next a variable which is local to draw() and place the line let next = make2DArray(cols, rows); to the beginning of draw().