Specify the right time to call a function inside a setInterval - javascript

I am trying to write a loop that switches from red, green and blue, but when it reaches the 255 of a color, it turn black.
I got stuck at the function change(), how can I specify to the function the exact time that it should call the inner functions (turnRed, turnGreen, turnBlue)?
var r = 0;
var g = 0;
var b = 0;
var dir = true;
function turnRed(){
if (dir == true){
r < 256 ? r++ : 0;
if (r == 255){
dir = false;
}else{
turnBlack;
}
}
}
function turnGreen(){
if (dir == true){
g < 256 ? g++ : 0;
if (g == 255){
dir = false;
}else{
turnBlack;
}
}
}
function turnBlue(){
if (dir == true){
b < 256 ? b++ : 0;
if (b == 255){
dir = false;
} else{
turnBlack;
}
}
}
function turnBlack(){
b > 0 ? b-- : 0;
if (b == 0){
dir = true;
}
g > 0 ? g-- : 0;
if (g == 0){
dir = true;
}
r > 0 ? r-- : 0;
if (r == 0){
dir = true;
}
}
function change() {
color = 'rgb('+r+', '+g+', '+b+')';
document.body.style.backgroundColor = color;
setTimeout(turnRed, 1000);
clearInterval();
//then
setTimeout(turnGreen, 1000);
clearInterval();
//then
setTimeout(turnBlue, 1000);
clearInterval();
}
setInterval(change, 10);
clearInterval();
My logic: if I put setTimeout(function, time) into a setInterval, it will call the function once, and setInterval will run in a loop changing the colors, but in my case the function just runs once and stops.

This is how I would go about it rather than trying to time intervals within a main loop.
intervals and timeouts are fine however for smooth transitions it's better to use requestAnimationFrame. In addition the way I set the code up is just a simple cycle function and you just iterate through the color patterns over time using the steps array.
Another note defintely check out template literals they're handy for things like this document.body.style.backgroundColor = `rgb(${red},${green},${blue})`;
function cycle(val, target, step = 1) {
if (val !== target) {
return val += step;
}
return val;
}
const steps = [
{r: 255, g: 0, b: 0},
{ r: 0, g: 0, b: 255},
{ r: 0 ,g: 255, b: 0},
{ r: 0, g: 0, b: 0 }
]
let curStep = 0;
let red = 0;
let green = 0;
let blue = 0;
function colorize() {
requestAnimationFrame(colorize);
const step = steps[curStep];
const {r, g, b} = step;
if (red === r && g === green && b === blue) {
curStep++;
if (curStep >= steps.length) {
curStep = 0;
}
} else {
red = cycle(red, r, r < red ? -1 : 1);
green = cycle(green, g, g < green ? -1 : 1);
blue = cycle(blue, b, b < blue ? -1 : 1);
}
document.body.style.backgroundColor = `rgb(${red},${green},${blue})`;
}
colorize();
If you wanted to actually time each color cycle you could do it this way outside of the main loop in the next example.
All this does is increase the current active step each time setTimeout is called, which in this example is 1, 5, and 8 seconds.
Note it wont continue after the last step since each one is scheduled in this example. The main method stays the same though, letting a function with requestAnimationFrame actually handle the updates.
function cycle(val, target, step = 1) {
if (val !== target) {
return val += step;
}
return val;
}
const steps = [
{ r: 0, g: 0, b: 0 },
{r: 255, g: 0, b: 0},
{ r: 0, g: 0, b: 255},
{ r: 0 ,g: 255, b: 0},
]
let curStep = 0;
let red = 0;
let green = 0;
let blue = 0;
function colorize() {
requestAnimationFrame(colorize);
const step = steps[curStep];
const {r, g, b} = step;
red = cycle(red, r, r < red ? -1 : 1);
green = cycle(green, g, g < green ? -1 : 1);
blue = cycle(blue, b, b < blue ? -1 : 1);
document.body.style.backgroundColor = `rgb(${red},${green},${blue})`;
}
function nextStep() {
curStep++;
if (curStep >= steps.length) {
curStep = 0;
}
}
setTimeout(() => {nextStep()}, 1000);
setTimeout(() => {nextStep()}, 5000);
setTimeout(() => {nextStep()}, 8000);
colorize();

Here is a working example. There were a few bugs in your code. You didn't have the () after turnBlack to actually call the function. I removed the g > 0 ? g-- : 0; since you change direction when it's needed and then it won't matter. I'm also not sure the setTimeouts are needed inside change. This just delays everything 1 second from happening.
var r = 0;
var g = 0;
var b = 0;
var dir = true;
function turnRed(){
if (dir == true) {
if (r < 256) {
r++;
} else {
dir = false;
}
} else {
turnBlack();
}
}
function turnGreen(){
if (dir == true) {
if (g < 256) {
g++;
} else {
dir = false;
}
} else {
turnBlack();
}
}
function turnBlue(){
if (dir == true) {
if (b < 256) {
b++;
} else {
dir = false;
}
} else {
turnBlack();
}
}
function turnBlack(){
if (b == 0){
dir = true;
} else {
b--
}
if (g == 0){
dir = true;
} else {
g--
}
if (r == 0){
dir = true;
} else {
r--
}
}
function change() {
color = 'rgb('+r+', '+g+', '+b+')';
document.body.style.backgroundColor = color;
setTimeout(turnRed, 1000);
clearInterval();
setTimeout(turnBlue, 1000);
clearInterval();
setTimeout(turnGreen, 1000);
clearInterval();
}
setInterval(change, 10);
clearInterval();
Clear interval doesn't do anything unless you pass it an interval. But that would stop what you want. For example:
var myVar = setInterval(myTimer, 1000);
clearInterval(myVar)
I think this will work fine.
var r = 0;
var g = 0;
var b = 0;
var dir = true;
function turnRed(){
if (dir == true) {
if (r < 256) {
r++;
} else {
dir = false;
}
} else {
turnBlack();
}
}
function turnGreen(){
if (dir == true) {
if (g < 256) {
g++;
} else {
dir = false;
}
} else {
turnBlack();
}
}
function turnBlue(){
if (dir == true) {
if (b < 256) {
b++;
} else {
dir = false;
}
} else {
turnBlack();
}
}
function turnBlack(){
if (b == 0){
dir = true;
} else {
b--
}
if (g == 0){
dir = true;
} else {
g--
}
if (r == 0){
dir = true;
} else {
r--
}
}
function change() {
color = 'rgb('+r+', '+g+', '+b+')';
document.body.style.backgroundColor = color;
turnRed();
turnBlue();
turnGreen();
}
setInterval(change, 10);
This changes colors individually. First to Red -> Black -> Green -> Black -> Blue -> Black
var r = 0;
var g = 0;
var b = 0;
var dir = 'red';
var nextColor = 'green'
function turnRed(){
if (dir == 'red') {
if (r < 256) {
r++;
} else {
dir = 'black';
nextColor = 'green'
}
}
}
function turnGreen(){
if (dir == 'green') {
if (g < 256) {
g++;
} else {
dir = 'black';
nextColor = 'blue'
}
}
}
function turnBlue(){
if (dir == 'blue') {
if (b < 256) {
b++;
} else {
dir = 'black';
nextColor='red';
}
}
}
function turnBlack(){
if (dir !== 'black') return;
if (b > 0) b--;
if (r > 0) r--;
if (g > 0) g--;
if (b <= 0 && r <= 0 && g <= 0) {
dir = nextColor;
}
}
function change() {
color = 'rgb('+r+', '+g+', '+b+')';
document.body.style.backgroundColor = color;
turnRed();
turnBlue();
turnGreen();
turnBlack()
}
setInterval(change, 10);
Lastly this changes to Red, then decreases Red as it Increases Blue, and keeps doing that for all the colors.
var r = 0;
var g = 0;
var b = 0;
var dir = 'red';
var nextColor = 'green'
function turnRed(){
if (dir == 'red') {
if (r < 256) {
r++;
} else {
dir = 'green'
}
}
}
function turnGreen(){
if (dir == 'green') {
if (g < 256) {
g++;
} else {
dir = 'blue'
}
}
}
function turnBlue(){
if (dir == 'blue') {
if (b < 256) {
b++;
} else {
dir = 'red';
}
}
}
function turnBlack(){
if (b > 0 && dir !== 'blue') b--;
if (r > 0 && dir !== 'red') r--;
if (g > 0 && dir !== 'green') g--;
}
function change() {
color = 'rgb('+r+', '+g+', '+b+')';
document.body.style.backgroundColor = color;
turnRed();
turnBlue();
turnGreen();
turnBlack();
}
setInterval(change, 10);

Related

Background Error fault when applying condition

So if x = Number value background changes fine, my question is when x has no value. How can I have a background-color of #ffffff. Currently, code is defaulting to #db0000.
JS:
var grid_value = document.getElementById("Vone").innerHTML;
var x = grid_value;
if (x >= 0 && x < 15) {
document.getElementById("GridA").style.backgroundColor = "#db0000";
} else if (x >= 15 && x < 25) {
document.getElementById("GridA").style.backgroundColor = "#f0ad4e";
} else if (x >= 25) {
document.getElementById("GridA").style.backgroundColor = "#5cb85c";
} else if (x = "Pick" ) {
document.getElementById("GridA").style.backgroundColor = "#0085eb";
} else if (x = "" ) {
document.getElementById("GridA").style.backgroundColor = "#ffffff";
}
Here you haven't given any conditions if x doesn't have a value, so the default condition is x=0.
You should try else if (!x).
else if (!x) {
document.getElementById("GridA").style.backgroundColor = "#ffffff";
}
Hope this helps you out.
const gA = document.getElementById("GridA");
document.getElementById("Vone").addEventListener("blur", function(event){
gA.classList = "";
var x = this.value;
if (x === "") {
gA.classList.add("white");
} else if (x === "Pick") {
gA.classList.add("color1");
} else if (x >= 0 && x < 15) {
gA.classList.add("color2");
} else if (x >= 15 && x < 25) {
gA.classList.add("color3");
} else if (x >= 25) {
gA.classList.add("color4");
}
});
#GridA { height:100px; border:1px solid grey; margin-top:5px; }
.color1 { background-color:#dbf000; }
.color2 { background-color:#f0ad4e; }
.color3 { background-color:#5cb85c; }
.color4 { background-color:#0085eb; }
.white { background-color:#ffffff; }
<input id="Vone">
<div id="GridA"></div>

Multiple object intersection and removal problem [ processing/p5.js ]

I am new to stack and not quite sure how to use it. But here I am. I am working on a ecosystem project, and I have an animal class with 2 different genders(0 for female, 1 for male). When 2 different genders intersect each other than I want to remove those 2 objects and add a couple(different object, static) object on that position. I kinda did it but it only works for a couple of seconds. Then the code just breaks. In the console it says,
“Uncaught TypeError: Cannot read property ‘intersects’ of undefined”
Here's the question on the processing forum in case I get a solution which might help others: https://discourse.processing.org/t/multiple-object-intersection-and-removal/22900/2
Here's the sketch.js file:
var animats = [];
var couples = [];
function setup() {
frameRate(30);
createCanvas(displayWidth, 470);
for(var i = 0; i < 50; i++)
{
animats[i] = new Animat(random(0, width), random(0, height));
}
}
function draw() {
background(255,100,100);
for(var i = animats.length-1; i >= 0; i--) {
animats[i].birth();
animats[i].grow();
for(var j = i; j >= 0; j--) {
if(j != i && animats[i].intersects(animats[j])) {
animats.splice(i, 1);
animats.splice(j, 1);
}
}
}
}
Here's the animat class file:
function Animat(x, y) {
this.x = x;
this.y = y;
this.gender;
var g = random(0,1);
var c;
if(g > 0.5) {
c = 0;
this.gender = 0;
} else {
c = 255;
this.gender = 1;
}
this.speed = 1;
this.age = 0;
this.length = 0.5;
this.birth = function() {
//gender
//create
noStroke();
fill(c);
text("n", this.x, this.y, this.length, this.length);
ellipse(this.x, this.y, this.length * 2, this.length * 2);
//move
switch(floor(random(0,4))) {
case 0:
this.x += this.speed;
break;
case 1:
this.y += this.speed;
break;
case 2:
this.x -= this.speed;
break;
case 3:
this.y -= this.speed;
break;
default:
this.x++;
this.y--;
}
//bounce
if(this.x > width || this.x < 4){
this.speed *= -1;
}
if(this.y > height || this.y < 4){
this.speed *= -1;
}
}
this.grow = function() {
this.age += 0.01;
this.length += 0.05;
//age checks
if(this.age > 10) {
this.speed + 5;
} else if(this.age > 21) {
this.length = 25;
this.speed = this.speed
//console.log("max age:" + this.age)
} else if(this.age > 70) {
//die
} else {
}
//length checks
if(this.length > 25) {
this.length = 25;
//console.log("max length");
}
}
//relationship
this.intersects = function(other) {
var d = dist(this.x, this.y, other.x, other.y);
var r = this.length + other.length;
if(d < r) {
if(((this.gender == 0) && (other.gender == 1)) || ((this.gender == 1) && (other.gender == 0))) {
return true;
} else {
this.speed *= -1;
}
} else {
return false;
}
}
//mate
this.couple = function() {
if(((this.gender == 0) && (other.gender == 1)) || ((this.gender == 1) && (other.gender == 0))) {
return true;
} else {
this.speed *= -1;
}
}
//die
/*this.die = function() {
if(this.age > 50) {
return true;
} else {
return false;
}
}*/
}
Here's the codepen link for results I am getting:
https://codepen.io/AbrarShahriar/pen/XWXwLPM
Try changing your nested for loop to:
for (var i = animats.length - 1; i >= 0; i--) {
animats[i].birth();
animats[i].grow();
for (var j = i; j >= 0; j--) {
if (j != i && animats[i].intersects(animats[j])) {
animats.splice(i, 1);
animats.splice(j, 1);
break; //exit the inner loop after a match
}
}
}
In other words, add a break; after two animats have coupled and have been removed from the array. The error was probably caused by you trying to call the intersects method of an animat that had already been removed.
you need to keep animats[i] as long as the for-loop for j has not finished.
Here the code you need to fix:
for(var i = animats.length-1; i >= 0; i--) {
animats[i].birth();
animats[i].grow();
let remove = false; // mark 'i' as NOT REMOVE by default
for(var j = i; j >= 0; j--) {
if(j != i && animats[i].intersects(animats[j])) {
remove = true; // mark 'i' as to remove when collision detected
animats.splice(j, 1);
}
}
if (remove) { // remove 'i' after compared to all 'j'
animats.splice(i, 1);
}
}

Stop recursive setTimeout function

Im running a recursive setTimeout function and I can run it many times, it has a clearTimeout, with this property I can handle how to stop the function running.
But I can't figure out how to stop it in another function.
var a = 0;
var b = 0;
function Listener(x, y) {
var lValue = y == true ? a : b;
if (lValue < 100) {
console.log(lValue);
if(y == true){
a+=x;
}else{
b+=x;
}
setTimeout(Listener.bind(this, x, y), 1000);
} else {
clearTimeout(Listener);
if(y == true){
a=0;
}else{
b=0;
}
}
}
When i tried to run it twice, it works:
My doubt is: How can I stop a particular running instance.
A couple notes:
Given the constant timeout of 1000, you should be using setInterval() instead. It will greatly simplify your function, and allow you to cancel the interval whenever you want.
Using global variables is code smell, create an object instead to hold a reference to the value being incremented. Doing so will also allow your function parameters to be more intuitive.
Here's a solution incorporating these two suggestions:
function range (step, start = 0, stop = 100) {
const state = {
value: start,
interval: setInterval(callback, 1000)
};
function callback () {
if (state.value < stop) {
console.log(state.value);
state.value += step;
} else {
console.log('timer done');
clearInterval(state.interval);
}
}
callback();
return state;
}
const timer1 = range(10);
const timer2 = range(20);
setTimeout(() => {
console.log('stopping timer 1');
clearInterval(timer1.interval);
}, 2500);
setTimeout(() => {
console.log('timer 2 value:', timer2.value);
}, 3500);
You could elevate the timer to a higher scope that is accessible by other functions.
var a = 0;
var b = 0;
var timer = null;
function Listener(x, y) {
var lValue = y == true ? a : b;
if (lValue < 100) {
console.log(lValue);
if (y == true) {
a += x;
} else {
b += x;
}
timer = setTimeout(Listener.bind(this, x, y), 1000);
} else {
clearTimeout(timer);
if (y == true) {
a = 0;
} else {
b = 0;
}
}
}
function clearTimer() {
if (timer !== null) clearTimeout(timer);
}
Listener(3, 3);
// clear the timer after 3 secnods
setTimeout(clearTimer, 3000);
create a variable and store the reference of setTimout on that variable, after that you just clearTimout with that variable reference
e.x
GLOBAL VARIABLE:
var k = setTimeout(() => { alert(1)}, 10000)
clearTimeout(k)
var a = 0;
var b = 0;
var recursiveFunctionTimeout = null;
function Listener(x, y) {
var lValue = y == true ? a : b;
if (lValue < 100) {
console.log(lValue);
if(y == true){
a+=x;
}else{
b+=x;
}
recursiveFunctionTimeout = setTimeout(Listener.bind(this, x, y), 10);
} else {
clearTimeout(recursiveFunctionTimeout);
if(y == true){
a=0;
}else{
b=0;
}
}
}
LOCAL VARIABLE:
var a = 0;
var b = 0;
function Listener(x, y) {
var lValue = y == true ? a : b;
var recursiveFunctionTimeout = null;
if (lValue < 100) {
console.log(lValue);
if(y == true){
a+=x;
}else{
b+=x;
}
recursiveFunctionTimeout = setTimeout(Listener.bind(this, x, y), 10);
} else {
clearTimeout(recursiveFunctionTimeout);
if(y == true){
a=0;
}else{
b=0;
}
}
}

Infinite recursion - Javascript minimax

I am trying to create a chess AI using the chess.js library. I am using the minimax solution with Alpha-Beta pruning, but for some reason, when the program runs it continues even after the depth reaches 0. Can anyone tell me why?
var Buddha = function() {
this.movehistory = 0;
this.color = "b";
this.opp = "w";
this.minimax = function(board, depth, alpha, beta) {
console.log(depth);
if(depth === 0 || board.game_over() === true) {
console.log("Depth == 0");
return [this.eval_board(board), null]
} else {
if(board.turn() === this.color) {
var bestmove = null
var possible_moves = board.moves()
for (index = 0; index < possible_moves.length; ++index) {
var new_board = new Chess(board.fen());
new_board.move(possible_moves[index])
var mini = this.minimax(new_board, --depth, alpha, beta)
var score = mini[0];
var move = mini[1];
if(score > alpha) {
alpha = score;
bestmove = possible_moves[index];
if(alpha >= beta) {
break;
}
}
}
return [alpha, bestmove]
} else if(board.turn() === this.opp) {
var bestmove = null
var possible_moves = board.moves()
for (index = 0; index < possible_moves.length; ++index) {
var new_board = new Chess(board.fen());
new_board.move(possible_moves[index])
var mini = this.minimax(new_board, --depth, alpha, beta)
var score = mini[0];
var move = mini[1];
if(score < beta) {
beta = score;
bestmove = possible_moves[index];
if(alpha >= beta) {
break;
}
}
}
return [beta, bestmove]
}
}
}
this.eval_board = function(board) {
if(board.in_check()) {
if(board.turn() == this.opp) {
return Number.POSITIVE_INFINITY;
} else {
return Number.NEGATIVE_INFINITY;
}
} else if(board.in_checkmate()) {
if(board.turn() == this.opp) {
return Number.POSITIVE_INFINITY;
} else {
return Number.NEGATIVE_INFINITY;
}
} else if(board.in_stalemate()) {
if(board.turn() == this.opp) {
return Number.POSITIVE_INFINITY;
} else {
return Number.NEGATIVE_INFINITY;
}
}
}
this.move = function(board) {
var bestmove = this.minimax(board, 1, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY)
}
}
function minimax(board, depth, alpha, beta) {
if(depth === 0 …) { …
return …
} else {
…
for (index = 0; index < possible_moves.length; ++index) {
… minimax(new_board, --depth, alpha, beta)
// ^^
…
}
}
}
Here you're decrementing the depth in a loop. Use depth <= 0 for the base case, and/or pass depth - 1 as an argument or put the decrement statement before the loop.

Recursive program crashes computer

I am writing a labyrinth generator, and I am using a Dijkstra Algorithm to see how many parts my labyrinth is divided into.
What I do is I find a cell that does not have a "mark", and run the function "wave".
Function wave(row,column,marknumber):
1) I give this cell a mark.
2) Then, for every nearby cell that is not separated by a wall, I run the function "wave".
This algorithm should tell me how many parts my labyrinth is divided into, but instead my computer screen turns white, starts flashing, and then the computer turns off.
Here is my HTML:
<!DOCTYPE html>
<html>
<head>
<script src="/mazeGenerator.js"></script>
</head>
<body>
<canvas id="field" width="300" height="300"></canvas>
<script>
var mark = 1;
init();
generateBase();
var arsenalNum = window.prompt("How many arsenals?");
for (var i=0;i<arsenalNum;i++) {
arsenal();
}
var prizeNum = window.prompt("How many prizes?");
for (var i=0;i<prizeNum;i++) {
prize(i+1);
}
draw();
for (var r=0; r<DIM; r++) {
for (var c=0; c<DIM; c++) {
if (maze[r][c].mark === 0) {
draw();
//alert(" ");
wave(r,c,mark);
mark++;
}
}
}
draw();
alert("There are " + numberOfMarks() + " marks in this labyrinth.");
</script>
</body>
</html>
And here is my Javascript:
var DIM = window.prompt("Please choose a dimension.");
var maze = new Array (DIM);
// init();
// generate();
// draw();
function init() {
for (var i=0;i<DIM;i++) {
maze[i] = new Array (DIM);
for (var j=0;j<DIM;j++) {
maze[i][j] = {
"walls":[0,0,0,0],
"mark":0,
"hole":-1,
"arsenal":0,
"prize":0,
"blocks_arsenal_entrance":0
};
}
}
}
function generateBase() {
for (var r=0;r<DIM;r++) {
for (var c=0;c<DIM;c++) {
var ind = Math.floor(Math.random()*4);
addWall(r,c,ind);
if (r === 0) {
maze[r][c].walls[0] = 1;
}
if (c === (DIM-1)) {
maze[r][c].walls[1] = 1;
}
if (r === (DIM-1)) {
maze[r][c].walls[2] = 1;
}
if (c === 0) {
maze[r][c].walls[3] = 1;
}
}
}
}
function draw() {
var canvas=document.getElementById("field");
var ctx=canvas.getContext("2d");
for (var r=0;r<DIM;r++) {
for (var c=0;c<DIM;c++) {
drawCell(r,c,ctx);
}
}
}
function drawCell(r,c,ctx) {
var left = c*10;
var top = r*10;
var w = maze[r][c].walls;
if (w[0] === 1) {
ctx.moveTo(left,top);
ctx.lineTo((left+10),top);
ctx.stroke();
}
if (w[1] === 1) {
ctx.moveTo((left+10),top);
ctx.lineTo((left+10),(top+10));
ctx.stroke();
}
if (w[2] === 1) {
ctx.moveTo(left,(top+10));
ctx.lineTo((left+10),(top+10));
ctx.stroke();
}
if (w[3] === 1) {
ctx.moveTo(left,top);
ctx.lineTo((left),(top+10));
ctx.stroke();
}
if (maze[r][c].arsenal == 1) {
ctx.fillStyle = "#FF0000";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].prize !== 0) {
ctx.fillStyle = "#00FF00";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].mark === 1) {
ctx.fillStyle = "#FF00FF";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].mark === 2) {
ctx.fillStyle = "#FFFF00";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].mark === 3) {
ctx.fillStyle = "#00FFFF";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].mark === 4) {
ctx.fillStyle = "#0080FF";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].mark === 5) {
ctx.fillStyle = "#FF0080";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].mark === 6) {
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].mark === 7) {
ctx.fillStyle = "#000000";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].mark === 8) {
ctx.fillStyle = "#80FF80";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].mark === 9) {
ctx.fillStyle = "#8080FF";
ctx.fillRect(left,top,10,10);
}
if (maze[r][c].mark === 10) {
ctx.fillStyle = "#FF8080";
ctx.fillRect(left,top,10,10);
}
}
function up(r,c) {
if (r === 0) {
return null;
} else {
return maze[r-1][c];
}
}
function down(r,c) {
if (r == (DIM - 1)) {
return null;
} else {
return maze[r+1][c];
}
}
function left(r,c) {
if (c === 0) {
return null;
} else {
return maze[r][c-1];
}
}
function right(r,c) {
if (c == (DIM - 1)) {
return null;
} else {
return maze[r][c+1];
}
}
function neighbor(r,c,dir) {
if (dir === 0) {
return up(r,c);
}
if (dir === 1) {
return right(r,c);
}
if (dir === 2) {
return down(r,c);
}
if (dir === 3) {
return left(r,c);
}
}
function opposite(dir) {
if (dir === 0) {
return 2;
}
if (dir === 1) {
return 3;
}
if (dir === 2) {
return 0;
}
if (dir === 3) {
return 1;
}
}
function arsenal() {
var done = false;
while (!done) {
var r = Math.floor(Math.random()*DIM);
var c = Math.floor(Math.random()*DIM);
if (maze[r][c].prize !== 0) {
continue;
}
if (maze[r][c].arsenal !== 0) {
continue;
}
if (maze[r][c].blocks_arsenal_entrance !== 0) {
continue;
}
var entrance = Math.floor(Math.random()*4);
if ((r === 0) && (entrance === 0)) {
entrance = opposite(entrance);
}
if ((c === (DIM - 1)) && (entrance === 1)) {
entrance = opposite(entrance);
}
if ((r === (DIM - 1)) && (entrance === 2)) {
entrance = opposite(entrance);
}
if ((c === 0) && (entrance === 3)) {
entrance = opposite(entrance);
}
for (var d=0;d<4;d++) {
removeWall(r,c,d);
}
for (d=0;d<4;d++) {
if (d !== entrance) {
addWall(r,c,d);
}
}
neighbor(r,c,entrance).blocks_arsenal_entrance = 1;
maze[r][c].arsenal = 1;
done = true;
}
}
function prize(n) {
var done = false;
while (!done) {
var r = Math.floor(Math.random()*DIM);
var c = Math.floor(Math.random()*DIM);
if (maze[r][c].prize !== 0) {
continue;
}
if (maze[r][c].arsenal !== 0) {
continue;
}
if (maze[r][c].blocks_arsenal_entrance !== 0) {
continue;
}
for (var d=0;d<4;d++) {
addWall(r,c,d);
}
maze[r][c].prize = n;
done = true;
}
}
function addWall(r,c,ind) {
maze[r][c].walls[ind] = 1;
if (neighbor(r,c,ind) !== null) {
neighbor(r,c,ind).walls[opposite(ind)] = 1;
}
}
function removeWall(r,c,dir) {
maze[r][c].walls[dir] = 0;
var neighborCell = neighbor(r,c,dir);
if (neighborCell !== null) {
neighborCell.walls[opposite(dir)] = 0;
}
}
function wave(r,c,mark) {
//alert("Wave Started with " + r + ", " + c + ".");
if (maze[r][c].mark === 0) {//Make sure the cell doesn't have a mark
// alert(r + ", " + c + " does not have a mark.");
maze[r][c].mark = mark;
// alert("maze["+r+"]["+c+"].mark is now equal to " + maze[r][c].mark);
if ((maze[r][c].walls[0] === 0) && (up(r,c).mark === 0)) {
wave((r-1),c);
}
if ((maze[r][c].walls[1] === 0) && (right(r,c).mark === 0)) {
wave(r,(c+1));
}
if ((maze[r][c].walls[2] === 0) && (down(r,c).mark === 0)) {
wave((r+1),c);
}
if ((maze[r][c].walls[3] === 0) && (left(r,c).mark === 0)) {
wave(r,(c-1));
}
} else {
}
}
function numberOfMarks() {
var maxMark = 0;
for (var r=0;r<DIM;r++) {
for (var c=0;c<DIM;c++) {
if ((maze[r][c].mark) > maxMark) {
maxMark = maze[r][c].mark;
}
}
}
return maxMark;
}
function numberOfPrizes() {
var maxPrize = 0;
for (var r=0;r<DIM;r++) {
for (var c=0;c<DIM;c++) {
if ((maze[r][c].prize) > maxPrize) {
maxPrize = maze[r][c].prize;
}
}
}
return maxPrize;
}
function findMarkBorder() {
for (var r=0;r<DIM;r++) {
for (var c=0;c<DIM;c++) {
if (((maze[r][c].mark) !== up(r,c).mark) && (up(r,c).mark !== null)) {
document.write("<br> The cell above cell "+r+", "+c+" has a different mark.");
}
if (((maze[r][c].mark) !== right(r,c).mark) && (right(r,c).mark !== null)) {
document.write("<br> The cell to the right of cell "+r+", "+c+" has a different mark.");
}
if (((maze[r][c].mark) !== down(r,c).mark) && (down(r,c).mark !== null)) {
document.write("<br> The cell below cell "+r+", "+c+" has a different mark.");
}
if (((maze[r][c].mark) !== left(r,c).mark) && (left(r,c).mark !== null)) {
document.write("<br> The cell to the left of cell "+r+", "+c+" has a different mark.");
}
}
}
}
Please tell me what I am doing wrong! Thanks in advance!
This program is not working, because in the function wave, you are not passing enough arguments -- you are not passing the "mark".
For example,
if ((maze[r][c].walls[3] === 0) && (left(r,c).mark === 0)) {
wave(r,(c-1));
}
should be
if ((maze[r][c].walls[3] === 0) && (left(r,c).mark === 0)) {
wave(r,(c-1),mark);
}

Categories

Resources