Skip to content

Instantly share code, notes, and snippets.

@coderd00d
Created May 31, 2013 02:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coderd00d/5682602 to your computer and use it in GitHub Desktop.
Save coderd00d/5682602 to your computer and use it in GitHub Desktop.
var col = 0;
var row = 0;
var pitWidth = 0;
var pitHeight = 0;
var clearID;
var map = [];
var H;
var fillCount = 0;
var direction = -1; // north = 0, east = 1, south = 2, west = 3;
var rotation; // 1 = clockwise, 2 = anti-clockwise
var obstacleCount;
function calcH () {
var rowData = [];
H = [];
for (var r = 0; r < pitHeight; r++) {
for (var c = 0; c < pitWidth; c++) {
rowData[c] = movesInRoom(r, c);
}
H[r] = rowData;
rowData = [];
}
}
function isObstacle(r, c) {
if (r < 0 || r >= pitHeight-1)
return false;
if (c < 0 || c >= pitWidth-1)
return false;
if (map[r][c] == -1)
return true;
return false;
}
function countAdjObs(r,c) {
var count = 0;
//if (isObstacle(r-1,c-1)) count++;
if (isObstacle(r-1,c)) count++;
//if (isObstacle(r-1,c+1)) count++;
if (isObstacle(r,c+1)) count++;
//if (isObstacle(r+1,c+1)) count++;
if (isObstacle(r+1,c)) count++;
//if (isObstacle(r+1,c-1)) count++;
if (isObstacle(r,c-1)) count++;
return count;
}
function tweakH() {
if (rotation = 1 && map[1][1] == -1 && map[1][0] == 0)
H[1][0] = 1;
if (rotation = 2 && map[1][1] == -1 && map[0][1] == 0)
H[0][1] = 1;
/*
for (var r = 0; r < pitWidth-1; r++)
for (var c = 0; c < pitHeight-1; c++)
if (countAdjObs(r,c) > 1) H[r][c] = 1;
*/
}
function countMovesAt(move, r, c) {
var count = 0;
if (r > 0)
if (H[r-1][c] == move) count++;
if (r < pitHeight-1)
if (H[r+1][c] == move) count++;
if (c > 0)
if (H[r][c-1] == move) count++;
if (c < pitWidth-1)
if (H[r][c+1] == move) count++;
return count;
}
function isEdge(r, c) {
if (r == 0 || r == pitHeight -1 || c == 0 || c == pitWidth -1)
return true;
return false;
}
function movesInRoom(r, c) {
var count = 0;
if (map[r][c] < 0)
return 0;
if (r > 0)
if (map[r-1][c] === 0)
count++;
if (r < pitHeight - 1)
if (map[r+1][c] === 0)
count++;
if (c > 0)
if (map[r][c-1] === 0)
count++;
if (c < pitWidth - 1)
if (map[r][c+1] === 0)
count++;
//showMap();
//console.log("movesInRoom count -- map[" + r + "][" + c + "] = " + count);
return count;
}
function canMoveTo(r, c) {
//console.log("canMoveTo @ map[" + r + "][" + c + "]");
//showMap();
if (r >= pitHeight || c >= pitWidth || r < 0 || c < 0)
return false;
if (map[r][c] === 0)
return true;
return false;
}
function canMoveToDirection(d) {
switch (d) {
case 0:
return (canMoveTo(row-1, col));
case 1:
return (canMoveTo(row, col+1));
case 2:
return (canMoveTo(row+1, col));
case 3:
return (canMoveTo(row, col-1));
}
}
function updateDirection(d)
{
console.log("dir = " + direction + " new d = " + d);
direction = d;
switch (d) {
case 0:
console.log("Moving North");
break;
case 1:
console.log("Moving East");
break;
case 2:
console.log("Moving South");
break;
case 3:
console.log("Moving West");
break;
}
}
function isDeadEnd(r,c,dir) {
switch (dir) {
case 0:
if (r === 0)
return false;
else if (H[r-1][c] < 2)
return true;
return false;
break;
case 1:
if (c >= pitWidth-1)
return false;
else if (H[r][c+1] < 2)
return true;
return false;
break;
case 2:
if (r >= pitHeight -1)
return false;
else if (H[r+1][c] < 2)
return true;
return false;
break;
case 3:
if (c === 0)
return false;
else if (H[r][c-1]< 2)
return true;
return false;
break;
}
}
function isDeadEndAtDir(dir) {
return isDeadEnd(row, col, dir);
}
function deadEndCount(r, c) {
var count = 0;
if (isDeadEnd(r,c,0)) count++;
if (isDeadEnd(r,c,1)) count++;
if (isDeadEnd(r,c,2)) count++;
if (isDeadEnd(r,c,3)) count++;
return count;
}
function moveSnake(dir) {
switch (dir) {
case 0:
if (canMoveTo(row-1, col) && !isDeadEndAtDir(0)) {
row--;
updateDirection(0);
return true;
}
return false;
case 1:
if (canMoveTo(row, col+1) && !isDeadEndAtDir(1)) {
col++;
updateDirection(1);
return true;
}
return false;
case 2:
if (canMoveTo(row+1, col) && !isDeadEndAtDir(2)) {
row++;
updateDirection(2);
return true;
}
return false;
case 3:
if (canMoveTo(row, col-1) && !isDeadEndAtDir(3)) {
col--;
updateDirection(3);
return true;
}
return false;
}
}
function moveOneDirection() {
console.log("moveOneDirection");
if (canMoveTo(row-1, col)) {
row--;
updateDirection(0);
return true;
}
if (canMoveTo(row, col+1)) {
col++;
updateDirection(1);
return true;
}
if (canMoveTo(row+1, col)) {
row++;
updateDirection(2);
return true;
}
if (canMoveTo(row, col-1)) {
col--;
updateDirection(3);
return true;
}
}
function carryOnMyWaywardSnake() {
console.log("carryOnMyWaywardSnake");
if (rotation == 1) {
switch (direction) {
case 0:
if (moveSnake(3)) break;
if (moveSnake(0)) break;
if (moveSnake(1)) break;
if (moveSnake(2)) break;
console.log("====PANIC!!!");
lastMove();
break;
case 1:
if (moveSnake(0)) break;
if (moveSnake(1)) break;
if (moveSnake(2)) break;
if (moveSnake(3)) break;
console.log("====PANIC!!!");
lastMove();
break;
case 2:
if (moveSnake(1)) break;
if (moveSnake(2)) break;
if (moveSnake(3)) break;
if (moveSnake(0)) break;
console.log("====PANIC!!!");
lastMove();
break;
case 3:
if (moveSnake(2)) break;
if (moveSnake(3)) break;
if (moveSnake(0)) break;
if (moveSnake(1)) break;
console.log("====PANIC!!!");
lastMove();
break;
}
} else {
switch (direction) {
case 0:
if (moveSnake(1)) break;
if (moveSnake(0)) break;
if (moveSnake(3)) break;
if (moveSnake(2)) break;
console.log("====PANIC!!!");
lastMove();
break;
case 1:
if (moveSnake(2)) break;
if (moveSnake(1)) break;
if (moveSnake(0)) break;
if (moveSnake(3)) break;
console.log("====PANIC!!!");
lastMove();
break;
case 2:
if (moveSnake(3)) break;
if (moveSnake(2)) break;
if (moveSnake(1)) break;
if (moveSnake(0)) break;
console.log("====PANIC!!!");
lastMove();
break;
case 3:
if (moveSnake(0)) break;
if (moveSnake(3)) break;
if (moveSnake(2)) break;
if (moveSnake(1)) break;
console.log("====PANIC!!!");
lastMove();
break;
}
}
}
function startEast() {
var sumSouth = 0;
var sumEast = 0;
var highSouth = 0;
var highEast = 0;
for (var row = 0; row < pitHeight; row++) {
for (var col = 0; col < pitWidth; col++)
sumEast = sumEast + H[row][col];
if (sumEast > highEast)
highEast = sumEast;
sumEast = 0;
}
for (var col = 0; col < pitWidth; col++) {
for (var row = 0; row < pitHeight; row++)
sumSouth = sumSouth + H[row][col];
if (sumSouth > highSouth)
highSouth = sumSouth;
sumSouth = 0;
}
if (highSouth > highEast)
return false;
else
return true;
}
function lastMove() {
clearInterval(clearID);
alert("Filled " + fillCount + " of " + (pitWidth * pitHeight) + " tiles with " + obstacleCount + " obstacles");
}
function calcNextMove() {
var moves = movesInRoom(row, col);
console.log("=====================");
console.log("calcNextMove Moves = " + moves);
console.log("Snake at [" + row + "][" + col + " dir = " + direction);
//showMap();
switch (moves) {
case 0: // no moves left - done
lastMove();
break;
case 1: // only 1 move - find it and take it.
moveOneDirection();
break;
default: // 2-3 moves left
// if 1st time moving -- figure out a flow and go
if (direction == -1) {
if (startEast()) {
console.log("Starting out -- Go East!");
rotation = 1;
if (canMoveTo(row, col+1)) {
updateDirection(1);
col++;
} else {
updateDirection(2);
row++;
}
} else {
rotation = 2;
console.log("Starting out -- Go South!");
if (canMoveTo(row+1, col)) {
direction = 2;
updateDirection(2);
row++;
} else {
updateDirection(1);
col++;
}
}
} else { // try to continue on current direction or divert beware of deadends.
carryOnMyWaywardSnake();
}
}
}
function draw() {
var canvas = document.getElementById('snakePit')
var ctx = canvas.getContext('2d');
ctx.fillStyle = "green";
ctx.fillRect(col*10,row*10, 10,10);
ctx.fillStyle = "white";
ctx.strokeRect(col*10,row*10, 10,10);
map[row][col] = 1;
fillCount++;
// calcH();
calcNextMove();
}
// for debugging
function showMap() {
var output = "";
console.log("Map");
console.log("-----");
for (var y = 0; y < pitHeight; y++) {
for (var x = 0; x < pitWidth; x++)
output = output + map[y][x] + " ";
console.log(output);
output = "";
}
}
function showH() {
var output = "";
console.log("H");
console.log("-----");
for (var y = 0; y < pitHeight; y++) {
for (var x = 0; x < pitWidth; x++)
output = output + H[y][x] + " ";
console.log(output);
output = "";
}
}
$(document).ready( function() {
var canvas = document.getElementById('snakePit');
var ctx = canvas.getContext("2d");
var size = [];
var coordinates;
var rowData = [];
var inputError;
// get size of map and initialize map array
size = prompt("Enter size of Snake Pit (width and height) example: 10 10").split(" ");
canvas.width = size[0] * 10;
canvas.height = size[1] * 10;
pitWidth = size[0];
pitHeight = size[1];
for (var y = 0; y < pitHeight; y++) {
for (var x = 0; x < pitWidth; x++)
rowData[x] = 0;
map[y] = rowData;
rowData = [];
}
obstacleCount = prompt("How many obstacles?");
obstacleCount = parseInt(obstacleCount,10);
console.log(obstacleCount);
for (var i = 1; i <= obstacleCount; i++) {
coordinates = prompt("Enter coordinates Row Column of obstacle " + i + " of " + obstacleCount).split(" ");
coordinates[0] = parseInt(coordinates[0],10);
coordinates[1] = parseInt(coordinates[1],10);
map[coordinates[1]][coordinates[0]] = -1; // obstacles are -1
ctx.fillStyle = "red";
ctx.fillRect(coordinates[0]*10, coordinates[1]*10, 10,10);
ctx.fillStyle = "white";
ctx.strokeRect(coordinates[0]*10, coordinates[1]*10, 10,10);
inputError = false;
}
showMap();
if (map[0][0] == -1) {
alert("Filled " + fillCount + " of " + (pitWidth * pitHeight) + " tiles with " + obstacleCount + " obstacles");
} else {
calcH();
//showH();
tweakH();
//showH();
console.log("Start Up the drawing");
clearID = setInterval(draw,100);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment