Reputation: 105
I've been working on a project for my class and I've completed it theoretically but it has some problems where it does not execute as fast as I'd like. The task is as follows: You have a 10x10 board to make moves on. You go up, down, left or right randomly. If a move takes you off the board skip it. Do this until 1,000,000 steps are taken or you reach the top right of the board. We are also supposed to count the max number of steps that a single tile received and the same with the minimum. I have done this using a 2D array and it counts sometimes and will output however it takes multiple button clicks to get an output. I'm not sure if this is a memory allocation error related to how I am accessing the 2D array to keep track of number of steps or not. I am relatively new to javascript so I don't know if my way was all that efficient.
Code
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>Path Game</h1>
<!-- Starts Game -->
<button onclick="doGame()">Click Here to start Game</button>
<p id="MaxSteps"></p>
<p id="MinSteps"></p>
<p id="totalSteps"></p>
<p id="reachedSteps"></p>
<p id="reachedSquare"></p>
<p id="reachedBoth"></p>
<!-- JS -->
<script>
function doGame()
{
var gameBoard = [0,0];
var stepCount = 0;
//10x10 array to hold step counts (may be a better way. check back later)
//Cell counter
var cells = [
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0]
];
while(true)
{
var oneMove = Math.floor(1+(Math.random()*4));
//Conditional checks
//Check if both square and step counts are satisfied
if(gameBoard[0] == 9 && gameBoard[1] == 9 && stepCount == 1000000)
{
document.getElementById("reachedBoth").innerHTML = "Reached 1,000,000 steps and top square";
break;
}
//Reached Top right before 1,000,000 steps
else if(gameBoard[0] == 9 && gameBoard[1] == 9)
{
document.getElementById("reachedSquare").innerHTML = "Reached Top right square";
break;
}
//Reached 1,000,000 steps before top right
else if(stepCount == 1000000)
{
document.getElementById("reachedSteps").innerHTML = "Reached 1,000,000 steps";
break;
}
//Movement on the board
var x = gameBoard[0];
var y = gameBoard[1];
cells[x][y] += 1;
//Move left
if(oneMove == 1)
{
//Initialized at 1 so less than is suitable
if(gameBoard[0] < 0)
{
gameBoard[0] = 0; //Reset
}
else{
gameBoard[0]--;//Goes left
}
}
//Move right
else if(oneMove == 2)
{
//If its at the edge, keep it there or keeps from going over
if(gameBoard[0] >= 9)
{
gameBoard[0] = 9; //Reset
}
else{
gameBoard[0]++;//Goes right
}
}
//Move up
else if(oneMove == 3)
{
//If its at the edge, keep it there or keeps from going over
if(gameBoard[1] >= 9)
{
gameBoard[1] = 9; //Reset
}
else{
gameBoard[1]++;//Goes up
}
}
//Move down
else if(oneMove == 4)
{
//Initialized at 1 so less than is suitable
if(gameBoard[1] < 0)
{
gameBoard[1] = 0; //Reset
}
else{
gameBoard[1]--;//Goes down
}
}
stepCount++; //Count the steps
}
var max = 0;
var min = Infinity;
//Find max
for(var i = 0; i < cells.length;i++)
{
for(var j = 0; j < cells[i].length; j++)
{
if(max < cells[i][j])
{
max = cells[i][j];
}
}
}
//Find min
for(var i = 0; i < cells.length;i++)
{
for(var j = 0; j < cells[i].length; j++)
{
if(min > cells[i][j])
{
min = cells[i][j];
}
}
}
//Total Steps print
document.getElementById("MaxSteps").innerHTML = "Max steps were: " + max;
document.getElementById("MinSteps").innerHTML = "Min steps were: " + min;
document.getElementById("totalSteps").innerHTML = "Total steps were: " + stepCount;
}
</script>
</body>
</html>
Upvotes: 0
Views: 128
Reputation: 3839
This block is the one that strikes me as particularly inefficient:
if(oneMove == 1)
{
//Initialized at 1 so less than is suitable
if(gameBoard[0] < 1)
{
gameBoard[0] = 1; //Reset
}
else{
gameBoard[0]--;//Goes left
}
}
//Move right
else if(oneMove == 2)
{
//If its at the edge, keep it there or keeps from going over
if(gameBoard[0] >= 10)
{
gameBoard[0] = 10; //Reset
}
else{
gameBoard[0]++;//Goes right
}
}
//Move up
else if(oneMove == 3)
{
//If its at the edge, keep it there or keeps from going over
if(gameBoard[1] >= 10)
{
gameBoard[1] = 10; //Reset
}
else{
gameBoard[1]++;//Goes up
}
}
//Move down
else if(oneMove == 4)
{
//Initialized at 1 so less than is suitable
if(gameBoard[1] < 1)
{
gameBoard[1] = 1; //Reset
}
else{
gameBoard[1]--;//Goes down
}
}
This is for a class, so I won't offer you an answer directly, but can you think of a solution that instead of incrementing or decrementing your gameboard counters directly using the random value that was generated?
For example, if I had a simple 1-dimension gameboard like so:
var gameboard = [0,0,0];
var position = 0,
direction = 0;
function move() {
direction = Math.round(Math.random()) * 2 - 1;
position += direction;
}
The only thing that is missing is to account for the possibility that I have moved off the gameboard. If the requirement were to start your marker on the other side of the board (think PacMan), this could also be accomplished using the modulo operator, which in JS is %:
function move() {
direction = Math.round(Math.random()) * 2 - 1;
position += direction;
position = (position + 3) % 3;
}
Unfortunately, given your requirements, I don't see a way around if conditions to stay on the board:
position = position < 0 ? 0 : position;
position = position > 2 ? 2 : position;
Hopefully this should get you going in the right direction. The above three lines of code could actually be combined into one line, though I prefer to make them a bit more readable.
A few more notes:
Good luck with your class!
Upvotes: 1