Created
January 26, 2013 15:19
-
-
Save johnlettman-old/4642871 to your computer and use it in GitHub Desktop.
Langston's Ant (old program)
This file contains hidden or 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
HTMLCanvasElement::relativeMouseCoordinates = (event) -> | |
x = new Number() | |
y = new Number() | |
if event.x isnt undefined and event.y isnt undefined | |
x = event.x | |
y = event.y | |
else | |
x = event.clientX + document.body.scrollLeft + | |
document.documentElement.scrollLeft | |
y = event.clientY + document.body.scrollTop + | |
document.documentElement.scrollTop | |
x -= this.offsetLeft | |
y -= this.offsetTop | |
return {x:x, y:y} | |
Number::mod = (n) -> ((this % n) + n) % n # Stupid Javascript modulus fix. | |
class window.LangstonsAnt | |
TURN_LEFT: 0x1 | |
TURN_RIGHT: 0x2 | |
DIRECTION_N: 0x0 | |
DIRECTION_E: 0x1 | |
DIRECTION_S: 0x2 | |
DIRECTION_W: 0x3 | |
antColour: 'red' | |
gridColour: 'grey' | |
moves: 0 | |
movementRules: [] | |
__movementRulesLocation: 0 | |
__xLimit: 0 | |
__yLimit: 0 | |
__grid: [] | |
__antLocation: [0,0] | |
__antDirection: @DIRECTION_N | |
__callback_dirchange: null | |
__callback_locchange: null | |
__callback_moveschange: null | |
constructor: (canvasID, @squareSize = 5) -> | |
@canvasElement = document.getElementById canvasID | |
@canvasContext = @canvasElement.getContext '2d' | |
@canvasElement.onclick = (e) => | |
realCoords = @canvasElement.relativeMouseCoordinates(e) | |
gridX = Math.round((realCoords.x - (@squareSize / 2)) / @squareSize) | |
gridY = Math.round((realCoords.y - (@squareSize / 2)) / @squareSize) | |
if not (gridX is @__antLocation[0] and gridY is @__antLocation[1]) | |
this.__flip gridX, gridY | |
# Initialize defaults | |
@__antDirection = @DIRECTION_N | |
@movementRules.push { white:@TURN_RIGHT, black:@TURN_LEFT } | |
generateGrid: () -> | |
@canvasContext.clearRect(0, 0, @canvasElement.width, @canvasElement.height); | |
@canvasContext.beginPath() | |
@canvasContext.lineWidth = 1 | |
for xCoord in [0..@canvasElement.width] by @squareSize | |
@canvasContext.moveTo xCoord, 0 | |
@canvasContext.lineTo xCoord, @canvasElement.height | |
@__xLimit++ | |
for yCoord in [0..@canvasElement.height] by @squareSize | |
@canvasContext.moveTo 0, yCoord | |
@canvasContext.lineTo @canvasElement.width, yCoord | |
@__yLimit++ | |
@__yLimit -= 2 | |
@__xLimit -= 1 | |
@canvasContext.strokeStyle = @gridColour | |
@canvasContext.stroke() | |
for row in [0..@__xLimit] | |
@__grid.push [] | |
for column in [0..@__yLimit] | |
@__grid[row].push 0 | |
this.placeAnt() | |
reset: () -> this.generateGrid() | |
setLocationCallback: (func) -> @__callback_locchange = func | |
setDirectionCallback: (func) -> @__callback_dirchange = func | |
setMovesCallback: (func) -> @__callback_moveschange = func | |
addMovementRule: (rule) -> | |
if (rule.white is @TURN_LEFT or rule.white is @TURN_RIGHT) and | |
(rule.black is @TURN_LEFT or rule.black is @TURN_RIGHT) then @movementRules.push rule | |
addMovementRules: (ruleList) -> | |
for rule in ruleList | |
this.addMovementRule rule | |
return | |
move: (iterations = 0) -> | |
@moves++ | |
@__antPrev = @__antLocation | |
# Turn according to the square rules. | |
switch @__antDirection | |
when @DIRECTION_N | |
if (@__antPrev[1] - 1) < 0 | |
this.__turn @__grid[ @__antPrev[0] ][ @__yLimit ] | |
else | |
this.__turn @__grid[ @__antPrev[0] ][ @__antPrev[1] - 1 ] | |
when @DIRECTION_E | |
if (@__antPrev[0] + 1) > @__xLimit | |
this.__turn @__grid[ 0 ][ @__antPrev[1] ] | |
else | |
this.__turn @__grid[ @__antPrev[0] + 1 ][ @__antPrev[1] ] | |
when @DIRECTION_S | |
if (@__antPrev[1] + 1) > @__yLimit | |
this.__turn @__grid[ @__antPrev[0] ][ 0 ] | |
else | |
this.__turn @__grid[ @__antPrev[0] ][ @__antPrev[1] + 1 ] | |
when @DIRECTION_W | |
if (@__antPrev[0] - 1) < 0 | |
this.__turn @__grid[ @__xLimit ][ @__antPrev[1] ] | |
else | |
this.__turn @__grid[ @__antPrev[0] - 1 ][ @__antPrev[1] ] | |
switch @__antDirection | |
when @DIRECTION_N | |
if (@__antPrev[1] - 1) < 0 | |
@__antLocation = [@__antPrev[0], @__yLimit] | |
else | |
@__antLocation = [@__antPrev[0], @__antPrev[1] - 1] | |
when @DIRECTION_E | |
if (@__antPrev[0] + 1) > @__xLimit | |
@__antLocation = [0, @__antPrev[1]] | |
else | |
@__antLocation = [@__antPrev[0] + 1, @__antPrev[1]] | |
when @DIRECTION_S | |
if (@__antPrev[1] + 1) > @__yLimit | |
@__antLocation = [@__antPrev[0], 0] | |
else | |
@__antLocation = [@__antPrev[0], @__antPrev[1] + 1] | |
when @DIRECTION_W | |
if (@__antPrev[0] - 1) < 0 | |
@__antLocation = [@__xLimit, @__antPrev[1]] | |
else | |
@__antLocation = [@__antPrev[0] - 1, @__antPrev[1]] | |
this.placeAnt @__antLocation[0], @__antLocation[1] | |
this.__flip @__antPrev[0], @__antPrev[1] | |
@__callback_locchange @__antLocation | |
@__callback_dirchange @__antDirection | |
@__callback_moveschange @moves | |
iterations-- | |
if iterations > 0 | |
while iterations > 0 | |
this.move() | |
iterations-- | |
return | |
placeAnt: (x = -1, y = -1) -> | |
if (x < 0 or y < 0) or (x > @__xLimit or y > @__yLimit) | |
x = Math.round @__xLimit / 2 | |
y = Math.round @__yLimit / 2 | |
@__antLocation = [x,y] | |
this.__drawAnt x, y | |
__turn: (encounteredSquare) -> | |
turnDirection = @movementRules[@__movementRulesLocation].white if encounteredSquare is 0 | |
turnDirection = @movementRules[@__movementRulesLocation].black if encounteredSquare is 1 | |
@__antDirection = (@__antDirection + 1).mod(4) if turnDirection is @TURN_RIGHT | |
@__antDirection = (@__antDirection - 1).mod(4) if turnDirection is @TURN_LEFT | |
@__movementRulesLocation = (@__movementRulesLocation + 1) % @movementRules.length | |
return | |
__flip: (x, y) -> | |
if @__grid[x][y] is 1 then @__grid[x][y] = 0 | |
else @__grid[x][y] = 1 | |
if @__grid[x][y] is 1 then this.__drawSquare x, y, 'black' | |
else this.__drawSquare x, y, 'white' | |
__drawAnt: (x = -1, y = -1) -> | |
x = @__antLocation[0] if x < 0 | |
y = @__antLocation[1] if y < 0 | |
this.__drawSquare x, y, @antColour | |
squareMiddle = Math.round(@squareSize / 2) | |
@canvasContext.fillStyle = 'black' | |
switch @__antDirection | |
when @DIRECTION_N | |
@canvasContext.fillRect( | |
(x * @squareSize) + Math.round(squareMiddle / 2), | |
(y * @squareSize) + 1, squareMiddle, squareMiddle) | |
when @DIRECTION_E | |
@canvasContext.fillRect( | |
(x * @squareSize) + (@squareSize - squareMiddle), | |
(y * @squareSize) + Math.round(squareMiddle / 2), | |
squareMiddle, squareMiddle) | |
when @DIRECTION_S | |
@canvasContext.fillRect( | |
(x * @squareSize) + Math.round(squareMiddle / 2), | |
(y * @squareSize) + squareMiddle, | |
squareMiddle, squareMiddle) | |
when @DIRECTION_W | |
@canvasContext.fillRect( | |
(x * @squareSize) + 1, | |
(y * @squareSize) + Math.round(squareMiddle / 2), | |
squareMiddle, squareMiddle) | |
__drawSquare: (x, y, colour = null) -> | |
if colour is null | |
colour = 'white' if @__grid[x][y] is 0 | |
colour = 'black' if @__grid[x][y] is 1 | |
@canvasContext.fillStyle = colour | |
@canvasContext.fillRect (x * @squareSize) + 1, (y * @squareSize) + 1, | |
@squareSize - 1, @squareSize - 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment