Created
May 31, 2013 02:19
-
-
Save coderd00d/5682602 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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