Created
April 21, 2015 00:57
-
-
Save RafaelCosman/f43ab249ba0b1fa07da2 to your computer and use it in GitHub Desktop.
StreetCode Karel Library
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
{ | |
/************************************* | |
* Welcome to Karel in ProcessingJS! | |
* | |
* Karel is a great way to learn control structures while solving puzzles. Karel is | |
* a robot living in a grid world. It only knows a few things about the world around it, | |
* and can only follow a few basic commands: move(), turnLeft(), putBeeper(), and pickBeeper(). | |
* With these simple commands, you'll be able to do so many cool things! | |
* | |
* Tell Karel what to do by editting its run function. Scroll down to the bottom to get started! | |
* | |
* Check out the Karel documentation at: http://tinyurl.com/karel-reference | |
* | |
* ~~~~~ < Challenge Name > [Difficulty: < Beginner/Intermediate/Advanced >] ~~~~~~ | |
* | |
* < Challenge Description > | |
* | |
* Facts | |
* - Example: Karel always starts at (1, 3) facing East | |
* - Example: The world is always 10x10 | |
* | |
* < Challenge Notes/Tips > | |
* | |
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
* | |
* Karel is best for when you're trying to solve a specific challenge. Once you complete this one, | |
* go to http://tinyurl.com/karel-challenges to find more! | |
*************************************/ | |
/* | |
* Helper Objects and declarations. | |
* No need to edit anything here | |
*/ | |
var customDrawBackground = null; | |
var customDrawBeeper = null; | |
var customDrawWall = null; | |
var customDrawBoardDot = null; | |
var customDrawKarel = null; | |
var board; | |
var world; | |
var commandQueue; | |
var Point = function(x, y) { | |
this.x = x; | |
this.y = y; | |
}; | |
var Size = function(w, h) { | |
this.width = w; | |
this.height = h; | |
}; | |
var Direction = Object.freeze({ | |
NORTH: 0, | |
EAST: 1, | |
SOUTH: 2, | |
WEST: 3 | |
}); | |
var Util = { | |
pointToString: function(point) { | |
return point.x + ',' + point.y; | |
}, | |
stringToPoint: function(pointString) { | |
var pointArray = pointString.split(','); | |
return new Point(parseInt(pointArray[0], 10), parseInt(pointArray[1], 10)); | |
}, | |
pointsToString: function(point1, point2) { | |
return this.pointToString(point1) + 'to' + this.pointToString(point2); | |
}, | |
stringToPoints: function(pointsString) { | |
var pointStrings = pointsString.split('to'); | |
var firstPoint = this.stringToPoint(pointStrings[0]); | |
var secondPoint = this.stringToPoint(pointStrings[1]); | |
return [firstPoint, secondPoint]; | |
}, | |
stringToSize: function(sizeString) { | |
var sizeArray = sizeString.split(','); | |
return new Size(parseInt(sizeArray[0], 10), parseInt(sizeArray[1], 10)); | |
}, | |
copyObject: function(object) { | |
var copy = {}; | |
for (var key in object) { | |
copy[key] = object[key]; | |
} | |
return copy; | |
}, | |
rotationForDirection: function(direction) { | |
switch (direction) { | |
case Direction.NORTH: | |
return 0; | |
case Direction.EAST: | |
return 90; | |
case Direction.SOUTH: | |
return 180; | |
case Direction.WEST: | |
return 270; | |
default: | |
return 0; | |
} | |
} | |
}; | |
/* | |
* CommandQueue keeps track of what Karel is going to do. All of the commands are added | |
* to the queue when Karel's run function is called. Make Karel do the next command by calling | |
* runNextCommand(); | |
* No need to edit anything here | |
*/ | |
var CommandQueue = function() { | |
this.maxQueueSize = 10000; | |
this._queue = [function() { | |
debug("Starting Karel"); | |
}]; | |
this._bugHasOccured = false; | |
}; | |
CommandQueue.prototype.addBug = function(text) { | |
this.add(function() { | |
debug(text); | |
println(text); | |
}); | |
this._bugHasOccured = true; | |
}; | |
CommandQueue.prototype.add = function(command) { | |
if (!this._bugHasOccured) { | |
this._queue.push(command); | |
} | |
}; | |
CommandQueue.prototype.isAvailable = function() { | |
return (this._queue.length < this.maxQueueSize && !this._bugHasOccured); | |
}; | |
CommandQueue.prototype._performCommand = function(command) { | |
debug('running command - ' + this._queue.length + ' actions left in queue'); | |
command(); | |
}; | |
CommandQueue.prototype.runNextCommand = function(commandQueue) { | |
if (this._queue.length > 0) { | |
this._performCommand(this._queue.splice(0, 1)[0]); | |
} | |
}; | |
/* | |
* World keeps track of the world as Karel goes through its run() function to build the | |
* command queue. It tells Karel whether or not it can do certain things. | |
* No need to edit anything here | |
*/ | |
var World = function(initPos, initDir, initSize, initBeeperCount) { | |
this.walls = {}; | |
this.beepers = {}; | |
this.paintedPoints = {}; | |
this.startingPosition = initPos; | |
this.startingDirection = initDir; | |
this.startingBeeperCount = initBeeperCount; | |
this.size = initSize; | |
}; | |
World.prototype.addHorizontalWall = function(x, y) { | |
var pointsKey = Util.pointsToString(new Point(x, y), new Point(x, y + 1)); | |
this.walls[pointsKey] = true; | |
}; | |
World.prototype.addVerticalWall = function(x, y) { | |
var pointsKey = Util.pointsToString(new Point(x, y), new Point(x + 1, y)); | |
this.walls[pointsKey] = true; | |
}; | |
World.prototype.addBeeper = function (x, y, numBeepers) { | |
numBeepers = numBeepers || 1; | |
this.beepers[Util.pointToString(new Point(x, y))] = numBeepers; | |
}; | |
World.prototype.putBeeperAt = function(point) { | |
var pointKey = Util.pointToString(point); | |
var beeperCount = this.beepers[pointKey] || 0; | |
this.beepers[pointKey] = beeperCount + 1; | |
}; | |
World.prototype.canPickBeeperAt = function(point) { | |
var pointKey = Util.pointToString(point); | |
var beeperCount = this.beepers[pointKey] || 0; | |
return beeperCount > 0; | |
}; | |
World.prototype.pickBeeperAt = function(point) { | |
var pointKey = Util.pointToString(point); | |
var beeperCount = this.beepers[pointKey] || 0; | |
this.beepers[pointKey] = beeperCount - 1; | |
}; | |
World.prototype.canMove = function(from, to) { | |
if (this.walls[Util.pointsToString(from, to)] || this.walls[Util.pointsToString(to, from)] || this._pointIsOutOfBounds(from) || this._pointIsOutOfBounds(to)) { | |
return false; | |
} | |
return true; | |
}; | |
World.prototype.paintPointAt = function(point, color) { | |
var pointKey = Util.pointToString(point); | |
this.paintedPoints[pointKey] = color; | |
}; | |
World.prototype.getPaintColorAt = function(point) { | |
var pointKey = Util.pointToString(point); | |
return this.paintedPoints[pointKey]; | |
}; | |
World.prototype._pointIsOutOfBounds = function(point) { | |
if (point.x < 0 || point.x > this.size.width - 1 || | |
point.y < 0 || point.y > this.size.height - 1) { | |
return true; | |
} | |
return false; | |
}; | |
/* | |
* Board is the visual part of the Karel board. It draws the dots, walls, | |
* and beepers. It also converts board position to pixel position for the Karel | |
* sprite. Gets the initial state of the world from an initialized World object. | |
* No need to edit anything here | |
*/ | |
var Board = function(world) { | |
this._world = world; | |
this._beepers = Util.copyObject(world.beepers); | |
this._paintedPoints = {}; | |
this.squareSize = min(height / world.size.height, width / world.size.width); | |
this.pixelSize = new Size(world.size.width * this.squareSize, world.size.height * this.squareSize); | |
this.updateDisplay(); | |
}; | |
Board.prototype.updateDisplay = function() { | |
this._drawBackground(); | |
this._drawDots(); | |
this._drawWalls(); | |
this._drawPaintedPoints(); | |
this._drawBeepers(); | |
}; | |
Board.prototype._drawDots = function() { | |
var worldSize = this._world.size; | |
for (var x = 0; x < worldSize.width; x++) { | |
for (var y = 0; y < worldSize.height; y++) { | |
var pos = this.pixelPositionForBoardPosition(new Point(x, y)); | |
if (customDrawBoardDot) { | |
customDrawBoardDot(pos.x, pos.y); | |
} else { | |
stroke(0, 0, 0); | |
strokeWeight(1); | |
fill(255, 255, 255); | |
ellipse(pos.x, pos.y, 4, 4); | |
} | |
} | |
} | |
}; | |
Board.prototype._drawBackground = function() { | |
if (customDrawBackground) { | |
customDrawBackground(this.pixelSize.width, this.pixelSize.height); | |
} else { | |
rectMode(CORNER); | |
strokeWeight(2); | |
stroke(0, 0, 0); | |
fill(255, 255, 255); | |
rect(0, 0, this.pixelSize.width, this.pixelSize.height); | |
} | |
}; | |
Board.prototype._drawWalls = function() { | |
var walls = this._world.walls; | |
for (var key in walls) { | |
if (!walls[key]) { | |
continue; | |
} | |
var points = Util.stringToPoints(key); | |
this._drawWall(points[0], points[1]); | |
} | |
}; | |
Board.prototype._drawWall = function(fromPos, toPos) { | |
var fromPixelPos; | |
var toPixelPos; | |
if (toPos.y > fromPos.y) { // horizontal wall | |
var yPos = (fromPos.y + 1) * this.squareSize; | |
fromPixelPos = new Point(fromPos.x * this.squareSize, yPos); | |
toPixelPos = new Point((fromPos.x + 1) * this.squareSize, yPos); | |
} else { // vertical wall | |
var xPos = (fromPos.x + 1) * this.squareSize; | |
fromPixelPos = new Point(xPos, fromPos.y * this.squareSize); | |
toPixelPos = new Point(xPos, (fromPos.y + 1) * this.squareSize); | |
} | |
if (customDrawWall) { | |
customDrawWall(fromPixelPos.x, fromPixelPos.y, toPixelPos.x, toPixelPos.y); | |
} else { | |
strokeWeight(1); | |
stroke(0, 0, 0); | |
line(fromPixelPos.x, fromPixelPos.y, toPixelPos.x, toPixelPos.y); | |
} | |
}; | |
Board.prototype._drawBeepers = function() { | |
for (var key in this._beepers) { | |
var numBeepers = this._beepers[key]; | |
if (numBeepers > 0) { | |
var beeperPos = Util.stringToPoint(key); | |
this._drawBeeper(beeperPos, numBeepers); | |
} | |
} | |
}; | |
Board.prototype._drawBeeper = function(point, numBeepers) { | |
var pos = this.pixelPositionForBoardPosition(point); | |
if (customDrawBeeper) { | |
customDrawBeeper(pos.x, pos.y, numBeepers); | |
} else { | |
fill(196, 196, 196); | |
quad(pos.x-15, pos.y, pos.x, pos.y-15, pos.x+15, pos.y, pos.x, pos.y+15); | |
if (numBeepers > 1) { | |
fill(0, 115, 255); | |
textAlign(CENTER, CENTER); | |
text(numBeepers, pos.x, pos.y); | |
} | |
} | |
}; | |
Board.prototype._drawPaintedPoints = function() { | |
for (var key in this._paintedPoints) { | |
var color = this._paintedPoints[key]; | |
if (color) { | |
var pos = Util.stringToPoint(key); | |
this._drawPaintedPoint(pos, color); | |
} | |
} | |
}; | |
Board.prototype._drawPaintedPoint = function(point, color) { | |
var pos = this.pixelPositionForBoardPosition(point); | |
fill(color); | |
rectMode(CENTER); | |
noStroke(); | |
rect(pos.x, pos.y, this.squareSize-1, this.squareSize-1); | |
fill(255, 255, 255); | |
stroke(0, 0, 0); | |
}; | |
Board.prototype.pixelPositionForBoardPosition = function(boardPosition) { | |
var posX = boardPosition.x * this.squareSize + (this.squareSize / 2); | |
var posY = boardPosition.y * this.squareSize + (this.squareSize / 2); | |
return new Point(posX, posY); | |
}; | |
Board.prototype.paintPointAt = function(point, color) { | |
var pointKey = Util.pointToString(point); | |
this._paintedPoints[pointKey] = color; | |
}; | |
Board.prototype.putBeeperAt = function(point) { | |
var pointKey = Util.pointToString(point); | |
var beeperCount = this._beepers[pointKey] || 0; | |
this._beepers[pointKey] = beeperCount + 1; | |
}; | |
Board.prototype.pickBeeperAt = function(point) { | |
var pointKey = Util.pointToString(point); | |
var beeperCount = this._beepers[pointKey] || 0; | |
this._beepers[pointKey] = beeperCount - 1; | |
}; | |
/* Private Karel functions | |
* No need to edit anything here | |
*/ | |
var preKarel = { | |
position: null, | |
direction: null, | |
numBeepersInBag: null | |
}; // karel properties for building commandQueue | |
var karel = { | |
pixelPosition: null, | |
rotation: null, | |
speed: 4 | |
}; // karel properties for drawing | |
var setupKarel = function() { | |
preKarel.position = world.startingPosition; | |
preKarel.direction = world.startingDirection; | |
preKarel.numBeepersInBag = world.startingBeeperCount; // initial beeper count | |
karel.pixelPosition = board.pixelPositionForBoardPosition(preKarel.position); | |
karel.rotation = Util.rotationForDirection(preKarel.direction); | |
}; | |
var drawKarel = function(x, y, rotation) { | |
if (customDrawKarel) { | |
customDrawKarel(x, y, rotation); | |
} else { | |
rectMode(CENTER); | |
fill(255, 255, 255); | |
strokeWeight(1); | |
stroke(0, 0, 0); | |
translate(x, y); | |
rotate(rotation); | |
rect(0, 0, 25, 25); | |
triangle(-15, 15, 15, 15, 0, -15); | |
resetMatrix(); // Need this to reset the translate and rotate | |
} | |
}; | |
var updateBoard = function() { | |
board.updateDisplay(); | |
drawKarel(karel.pixelPosition.x, karel.pixelPosition.y, karel.rotation); | |
}; | |
var currentPositionWithOffset = function(xDiff, yDiff) { | |
return new Point(preKarel.position.x + xDiff, preKarel.position.y + yDiff); | |
}; | |
var positionInDirection = function(direction) { | |
switch (direction) { | |
case Direction.NORTH: | |
return currentPositionWithOffset(0, -1); | |
case Direction.EAST: | |
return currentPositionWithOffset(1, 0); | |
case Direction.SOUTH: | |
return currentPositionWithOffset(0, 1); | |
case Direction.WEST: | |
return currentPositionWithOffset(-1, 0); | |
default: | |
return currentPositionWithOffset(0, 1); | |
} | |
}; | |
var canMoveFromCurrentPositionTo = function(newPosition) { | |
return world.canMove(preKarel.position, newPosition) && commandQueue.isAvailable(); | |
}; | |
var rotateSpriteTo = function(newDirection) { | |
preKarel.direction = newDirection; | |
var rotation = Util.rotationForDirection(newDirection); | |
commandQueue.add(function() { | |
debug('rotate to ' + rotation); | |
karel.rotation = rotation; | |
}); | |
debug('rotate to ' + rotation); | |
}; | |
var moveSpriteTo = function(newBoardPosition) { | |
preKarel.position = newBoardPosition; | |
var pixelPosition = board.pixelPositionForBoardPosition(newBoardPosition); | |
commandQueue.add(function() { | |
debug('move to ' + pixelPosition.x + ' ' + pixelPosition.y); | |
karel.pixelPosition = pixelPosition; | |
}); | |
debug('move to ' + pixelPosition.x + ' ' + pixelPosition.y); | |
}; | |
/* | |
* Karel's Commands and Conditionals | |
* Use these to solve Karel puzzles! No need to edit them | |
*/ | |
var superKarel = { | |
turnRight: function() { | |
preKarel.direction = (preKarel.direction + 1) % 4; | |
rotateSpriteTo(preKarel.direction); | |
}, | |
turnAround: function() { | |
preKarel.direction = (preKarel.direction + 2) % 4; | |
rotateSpriteTo(preKarel.direction); | |
}, | |
paintPoint: function(color) { | |
var pos = preKarel.position; | |
world.paintPointAt(pos, color); | |
commandQueue.add(function() { | |
board.paintPointAt(pos, color); | |
}); | |
}, | |
pointPaintColorIs: function(color) { | |
return world.getPaintColorAt(preKarel.position) === color; | |
}, | |
pointIsPainted: function() { | |
return world.getPaintColorAt(preKarel.position); | |
} | |
}; | |
var move = function() { | |
var newPosition = positionInDirection(preKarel.direction); | |
if (world.canMove(preKarel.position, newPosition)) { | |
moveSpriteTo(newPosition); | |
} else { | |
commandQueue.addBug('BUG: can\'t move!'); | |
} | |
}; | |
var turnLeft = function() { | |
preKarel.direction--; | |
if (preKarel.direction < 0) { | |
preKarel.direction = 3; | |
} | |
rotateSpriteTo(preKarel.direction); | |
}; | |
var putBeeper = function() { | |
if (preKarel.numBeepersInBag > 0) { | |
var pos = preKarel.position; | |
preKarel.numBeepersInBag--; | |
debug("put beeper: " + pos.x + " " + pos.y); | |
world.putBeeperAt(pos); | |
commandQueue.add(function() { | |
debug("put beeper: " + pos.x + " " + pos.y); | |
board.putBeeperAt(pos); | |
}); | |
} else { | |
commandQueue.addBug('BUG: Karel has no beepers in its bag!'); | |
} | |
}; | |
var pickBeeper = function() { | |
if (world.canPickBeeperAt(preKarel.position)) { | |
var pos = preKarel.position; | |
preKarel.numBeepersInBag++; | |
debug("pick beeper: " + pos.x + " " + pos.y); | |
world.pickBeeperAt(pos); | |
commandQueue.add(function() { | |
debug("pick beeper: " + pos.x + " " + pos.y); | |
board.pickBeeperAt(pos); | |
}); | |
} else { | |
commandQueue.addBug('BUG: can\'t pick up a beeper that doesn\'t exist!'); | |
} | |
}; | |
var frontIsClear = function() { | |
return canMoveFromCurrentPositionTo(positionInDirection(preKarel.direction)) && commandQueue.isAvailable(); | |
}; | |
var frontIsNotClear = function() { | |
return !canMoveFromCurrentPositionTo(positionInDirection(preKarel.direction)) && commandQueue.isAvailable(); | |
}; | |
var leftIsClear = function() { | |
var directionToLeft = preKarel.direction - 1; | |
if (directionToLeft < 0) { | |
directionToLeft = 3; | |
} | |
return canMoveFromCurrentPositionTo(positionInDirection(directionToLeft)) && commandQueue.isAvailable(); | |
}; | |
var leftIsNotClear = function() { | |
var directionToLeft = preKarel.direction - 1; | |
if (directionToLeft < 0) { | |
directionToLeft = 3; | |
} | |
return !canMoveFromCurrentPositionTo(positionInDirection(directionToLeft)) && commandQueue.isAvailable(); | |
}; | |
var rightIsClear = function() { | |
var directionToRight = preKarel.direction + 1; | |
if (directionToRight > 3) { | |
directionToRight = 0; | |
} | |
return canMoveFromCurrentPositionTo(positionInDirection(directionToRight)) && commandQueue.isAvailable(); | |
}; | |
var rightIsNotClear = function() { | |
var directionToRight = preKarel.direction + 1; | |
if (directionToRight > 3) { | |
directionToRight = 0; | |
} | |
return !canMoveFromCurrentPositionTo(positionInDirection(directionToRight)) && commandQueue.isAvailable(); | |
}; | |
var beepersPresent = function() { | |
return world.canPickBeeperAt(preKarel.position) && commandQueue.isAvailable(); | |
}; | |
var noBeepersPresent = function() { | |
return !world.canPickBeeperAt(preKarel.position) && commandQueue.isAvailable(); | |
}; | |
var facingNorth = function() { | |
return preKarel.direction === Direction.NORTH && commandQueue.isAvailable(); | |
}; | |
var notFacingNorth = function() { | |
return preKarel.direction !== Direction.NORTH && commandQueue.isAvailable(); | |
}; | |
var facingEast = function() { | |
return preKarel.direction === Direction.EAST && commandQueue.isAvailable(); | |
}; | |
var notFacingEast = function() { | |
return preKarel.direction !== Direction.EAST && commandQueue.isAvailable(); | |
}; | |
var facingSouth = function() { | |
return preKarel.direction === Direction.SOUTH && commandQueue.isAvailable(); | |
}; | |
var notFacingSouth = function() { | |
return preKarel.direction !== Direction.SOUTH && commandQueue.isAvailable(); | |
}; | |
var facingWest = function() { | |
return preKarel.direction === Direction.WEST && commandQueue.isAvailable(); | |
}; | |
var notFacingWest = function() { | |
return preKarel.direction !== Direction.WEST && commandQueue.isAvailable(); | |
}; | |
var beepersInBag = function() { | |
return preKarel.numBeepersInBag > 0; | |
}; | |
var noBeepersInBag = function() { | |
return preKarel.numBeepersInBag === 0; | |
}; | |
var isTrue = function() { | |
return commandQueue.isAvailable(); | |
}; // replacement for while(true) -> while(isTrue()) | |
/* Custom Drawing! | |
* Edit these functions to make Karel your own. Use the parameters given to make | |
* drawings for Beepers, Walls, Board Dots, and Karel itself. | |
*/ | |
var loadPlainTheme = function () { | |
customDrawBackground = function (boardWidth, boardHeight) { | |
rectMode(CORNER); | |
strokeWeight(2); | |
stroke(0, 0, 0); | |
fill(255, 255, 255); | |
rect(0, 0, boardWidth, boardHeight); | |
}; | |
customDrawBeeper = function(x, y, numBeepers) { | |
fill(196, 196, 196); | |
quad(x-15, y, x, y-15, x+15, y, x, y+15); | |
if (numBeepers > 1) { | |
fill(0, 115, 255); | |
textAlign(CENTER, CENTER); | |
text(numBeepers, x, y); | |
} | |
}; | |
customDrawWall = function(x1, y1, x2, y2) { | |
strokeWeight(1); | |
stroke(0, 0, 0); | |
line(x1, y1, x2, y2); | |
}; | |
customDrawBoardDot = function(x, y) { | |
stroke(0, 0, 0); | |
strokeWeight(1); | |
fill(255, 255, 255); | |
ellipse(x, y, 4, 4); | |
}; | |
customDrawKarel = function(x, y, rotation) { | |
// This function uses translate in order to position Karel so that | |
// rotations are done about the middle of Karel, rather than at (0,0) | |
rectMode(CENTER); | |
fill(255, 255, 255); | |
strokeWeight(1); | |
stroke(0, 0, 0); | |
translate(x, y); | |
rotate(rotation); | |
rect(0, 0, 25, 25); | |
triangle(-15, 15, 15, 15, 0, -15); | |
resetMatrix(); // Need this to reset the translate and rotate | |
}; | |
}; | |
loadPlainTheme(); | |
var loadSpaceTheme = function () { | |
customDrawBackground = function (boardWidth, boardHeight) { | |
imageMode(CORNER); | |
image(getImage("space/background"), 0, 0, boardWidth, boardHeight); | |
}; | |
customDrawBeeper = function (x, y, numBeepers) { | |
imageMode(CENTER); | |
image(getImage("space/star"), x, y, 50, 50); | |
if (numBeepers > 1) { | |
fill(0, 115, 255); | |
textAlign(CENTER, CENTER); | |
text(numBeepers, x, y); | |
} | |
}; | |
customDrawKarel = function(x, y, rotation) { | |
pushMatrix(); | |
translate(x, y); | |
rotate(rotation - 90); | |
imageMode(CENTER); | |
image(getImage("space/rocketship"), 0, 0, 50, 50); | |
popMatrix(); | |
}; | |
customDrawBoardDot = function(x, y) { | |
imageMode(CENTER); | |
image(getImage("space/plus"), x, y, 15, 15); | |
}; | |
}; | |
var loadAdventureTheme = function () { | |
customDrawBackground = function (boardWidth, boardHeight) { | |
imageMode(CORNER); | |
var worldSize = world.size; | |
var boxWidth = width / worldSize.width; | |
var boxHeight = width / worldSize.height; | |
randomSeed(0); | |
for (var x = 0; x < worldSize.width; x++) { | |
for (var y = 0; y < worldSize.height; y++) { | |
var tile; | |
if (random() < 0.5) { | |
tile = getImage("cute/DirtBlock"); | |
} | |
else if (random() < 0.3) { | |
tile = getImage("cute/StoneBlock"); | |
} | |
else { | |
tile = getImage("cute/GrassBlock"); | |
} | |
image(tile, x * boxWidth, (y-1.0/2.0) * boxHeight, boxWidth, boxHeight * 2); | |
} | |
} | |
}; | |
customDrawBeeper = function (x, y, numBeepers) { | |
imageMode(CENTER); | |
image(getImage("cute/GemOrange"), x, y-5, 35, 40); | |
if (numBeepers > 1) { | |
fill(1, 2, 3); | |
textAlign(CENTER, CENTER); | |
text(numBeepers, x, y); | |
} | |
}; | |
customDrawKarel = function(x, y, rotation) { | |
pushMatrix(); | |
translate(x, y); | |
rotate(rotation - 180); | |
imageMode(CENTER); | |
image(getImage("cute/CharacterHornGirl"), 0, -3, 40, 50); | |
popMatrix(); | |
}; | |
customDrawWall = function(x1, y1, x2, y2) { | |
strokeWeight(7); | |
stroke(117, 83, 11); | |
line(x1, y1, x2, y2); | |
}; | |
customDrawBoardDot = function(x, y) { | |
}; | |
}; | |
var keys = []; | |
var useKeyControls = false; | |
var keyPressed = function() { | |
keys[keyCode] = true; | |
}; | |
var keyReleased = function() { | |
keys[keyCode] = false; | |
}; | |
var loadKeyControls = function() { | |
useKeyControls = true; | |
}; | |
/* | |
* Key Controls: change to assign different keys to different Karel * actions | |
*/ | |
var updateKarelKeyControls = function() { | |
if(!useKeyControls) { | |
return; | |
} | |
if (keys[LEFT]) { | |
turnLeft(); | |
} | |
if (keys[RIGHT]) { | |
// Currently unused: add functions here! | |
} | |
if (keys[UP]) { | |
move(); | |
} | |
if (keys[DOWN]) { | |
putBeeper(); | |
} | |
if (keys[32]) { // Space Key | |
pickBeeper(); | |
} | |
}; | |
} | |
{ | |
/* Create World | |
* Edit the world to create new challenges for yourself. Or check out other Karel | |
* projects at streetcodekarel.tk for more | |
* challenges. | |
* Do not edit this when working to solve this particular challenge! | |
*/ | |
var createWorld = function() { | |
world = new World(); | |
world.size = new Size(10, 10); | |
world.startingPosition = new Point(1,3); | |
world.startingDirection = Direction.EAST; | |
world.startingBeeperCount = 421; | |
// Top wall | |
world.addHorizontalWall(1,2); | |
world.addHorizontalWall(2,2); | |
world.addHorizontalWall(3,2); | |
world.addHorizontalWall(4,2); | |
// Bottom wall | |
world.addHorizontalWall(1,6); | |
world.addHorizontalWall(2,6); | |
world.addHorizontalWall(3,6); | |
world.addHorizontalWall(4,6); | |
// Left wall | |
world.addVerticalWall(0,3); | |
world.addVerticalWall(0,4); | |
world.addVerticalWall(0,5); | |
world.addVerticalWall(0,6); | |
// Right wall | |
world.addVerticalWall(4,3); | |
world.addVerticalWall(4,5); | |
world.addVerticalWall(4,6); | |
world.addBeeper(5, 4); | |
commandQueue = new CommandQueue(); | |
board = new Board(world); | |
};} | |
/******* | |
* Check out the Karel documentation at streetcodekarelreference.tk | |
* | |
* ~~~~~ < Challenge Name > [Difficulty: < Beginner/Intermediate/Advanced/Master >] ~~~~~~ | |
* | |
* < Challenge Description > | |
* | |
* Facts | |
* - Example: Karel always starts at (1, 3) facing East | |
* - Example: The world is always 10x10 | |
* | |
* < Challenge Notes/Tips > | |
* | |
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
* | |
*******/ | |
karel.speed = 10; // Edit this to change Karel's speed. Higher = Faster | |
loadSpaceTheme(); // try loadPlainTheme() or loadAdventureTheme() instead | |
var run = function() { | |
/**>>>>>>>>>>>> YOUR SOLUTION HERE <<<<<<<<<<<**/ | |
// move(); | |
// turnLeft(); | |
// putBeeper(); | |
// pickBeeper(); | |
// while(frontIsClear()) { | |
// move(); | |
// } | |
// etc... | |
}; | |
{ | |
/* Draw | |
* No need to edit anything here! | |
*/ | |
createWorld(); | |
setupKarel(); | |
frameRate(karel.speed); | |
run(); | |
draw = function() { | |
commandQueue.runNextCommand(); | |
updateBoard(); | |
updateKarelKeyControls(); | |
}; | |
//This call allows one to use key controls with Karel; make sure to click in the | |
// Karel world first so that the world starts listening for key | |
//presses | |
loadKeyControls(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment