Skip to content
Cherie Pun edited this page Sep 25, 2015 · 7 revisions

##MOOooooooo (Cow-Driven Programming) ###Introduction In earlier levels, children have to take into account red traffic lights that block the van, they can either use conditionals or loops to avoid running a red light. However, traffic lights have deterministic behaviour and are placed at predefined places; they are therefore predictable. The aim of this new episode is to introduce into the game an advanced programming concept of handling unpredictable events. Rapid Router is extended with support for non-deterministic obstacles in the form of cows, that can randomly cross the road. Furthermore, we integrate an event handling mechanism into the Blockly language. These extensions allow us to build new levels that teach children how events can be handled in a modular fashion, which is transferable to real programming concepts such as exception, interrupt, and event handling.

###Event-driven Programming In procedural programming, the program is executed top-down from the first line of code in a completely predetermined path, despite any branch or loop. Events that are unpredictable and occur in no predetermined order cannot be handled by normal procedural programming, hence we need event-driven programming.

Events are usually user actions such as mouse click or state changes. An event-driven application is designed to deal with the events as they occur with an event-handling procedure. In the background, there will be a event-loop, provided by the event-driven environment, that waits for the event to occur and invoke the appropriate event-handling routine depending on the event type. It is usually happening behind the scenes - the programmer does not have to specify when the program should check for the event. You can imagine the event-loop as a procedure that runs continuously until an event occurs.

In Rapid Router, the event is cow crossing the road and the event procedure is event block. When a cow crosses the road, the event handler for that cow type (black & white or brown) will be triggered and the body code will be executed along side with the main program. Note that the event handler does not stop or pause the execution of the main program, otherwise it would become interrupt-driven programming. We chose to use "sound horn" and "puff up" as possible commands in the event handler, because they are actions that can be performed concurrently to the van movement - to illustrate the concurrency between the main program and event procedures execution.

###GamePlay

There are two types of cow that will appear at random location on the road, say hi to Clarice (black & white) and Jersey Clarice (brown). They are very naughty and all they do is cross the road at random times to block the van and prevent the driver from doing their job.

So what can you do when they are in your way? Scare them away! The van can now either sound the horn or puff up (enlarge itself for a short amount of time) to frighten the cows. However, each cow is scared away by only one of the tactics, so users will have to experiment which action to use for different cows.

####Blocks

New blocks are added in this episode to enable event handlers which takes care of unpredictable events such as cow crossing the road. The drop down menu on the block allow user to choose which event to react to, user can then drag an event action block into the slot to specify what the van should do if said event occurs. The event block can be placed anywhere on the workspace like a prodecure block, this is because the program written by the user do not need to actively check for those conditions to be true, this will be done implicitly, therefore it does not matter where the block is. The example block shown in the image above show that the van should sound the horn when it sees a white cow ahead.

Event action blocks are purple and they are different from the blue action blocks. These blocks are not allowed to connect to any blocks other than the event blocks, whereas normal action blocks are not allowed to be put inside an event block. First reason is to prevent users hard coding when to perform such actions and scare away the cows. Secondly, we would like to simulate concurrent execution between main program and event handler, so if we allow event handler to modify the van's movement then we will have a conflict as to which action to execute.

####Animation #####Sound horn When van sounds the horn, there's no visual animation for it. But if you turn on your speaker or put on your headphone, you will be able to hear it as the van moves.

#####Puff up

For puffing up, it takes two or more road segments to complete the animation. The van remains puff up if there's another event which triggers the same action. Beware that puffing up uses more fuel than normal driving, so the van may use up all the fuel before reaching the destination if it keeps puffing up.

####LevelEditor In order to prevent users coding static solution and pass the cow levels, cows have to appear at random locations and on each path to the destination, there should be at least one cow. To specify all these, the level editor is now equipped with "cows" options under tab Scenary.

In the editor, user will be able to specify a group of nodes which the cow could appear on, this is called a cow group. The type and number of cow appearing in each group can be specified in advanced mode.

Basic mode: All the cows added in basic mode belong to the same cow group, and the minimum and maximum number of cows that can appear in this cow group is 1, i.e. a single cow will appear on any of the potential nodes in each run of the program. Users can drag and drop cow onto the road, it will automatically snap to the closest road segment. This marks that node as a potential node that the cow will appear on.

Advanced mode: In advanced mode, users can add more cow groups and configure the properties of each group. Dragging a cow onto the map marks the node as a potential node, the background colour of each marked node will indicate which cow group it belongs to. User can specify a different set of potential nodes for each group using the drop down menu to switch between groups. Users can also specify which type of cow to appear. Min and max can be configured to restrict at least and at most how many cows should appear within the set of potential nodes.

As shown in the example, there will be at least 1 and at most 2 brown cow(s) appearing on the orange potential nodes.

###Implementation ####Blockly

In this new episode, 3 new blocks were defined in BlocklyCustomBlocks.js. There is a type check at the connections so as to make sure that only event actions will be connected to the event handler and vice versa. The type of the connections are set to "EventAction".

The image field in the On-Do block is set to editable, which means that the image url is saved to xml when the blocks are converted so we do not have to update the image to match the drop down value every time the blocks are loaded from storage.

####Checking for events

// check if any event condition is true
for (var i=0; i<this.program.events.length; i++) {
	var event = this.program.events[i];
	model.shouldObserve = false;
	if (event.condition(model)) {
		event.execute(this, model);
	}
	model.shouldObserve = true;
}

The checking for event is done before each command from the stack is executed. When the event condition is true, the event-handler routine is pushed to the stack and becomes the next command to be executed. If more than one event occur, both routines will be pushed to stack and executed within the same timestamp.

####When does the cow appear? setCowsActive() is called before van's movement. It iterates through nodes that are connected to nextNode and are 2 nodes ahead to look for cows that are in READY state. setActive() is called on these cows which sets the state of cows to ACTIVE and queue entrance animation.

####When does the cow disappear? The checking is done when incrementCowTime() is called at the beginning of each timestamp. If any active cow is found, it will then be checked by scaredAwayByHorn() and scaredAwayByPuffUp() to determine whether the exit animation should be queued.

####Animation #####Sound horn When soundHornCommand is executed, howler.js is used to play the sound. This does not affect the animation in any way and the sound is played parallely to the other animations in the same timestamp.

#####Puff up When puffUpCommand is execued, it checks for whether the van was already puffed up. If so, it will call remainPuffUp() which updates the property of the puffUp and queue a REMAINPUFFUP animation. Otherwise, it will create a puffUp object which stores the current coordinates, movementTimestamp and timeout. A puffUp animation and puffDown animation will be queued.

####How are the cow groups represented in JSON? '[{"minCows":1,"maxCows":1,"potentialCoordinates":[{"x":4,"y":5},{"x":3,"y":5}],"type":"WHITE"},{"minCows":1,"maxCows":1,"potentialCoordinates":[{"x":4,"y":3},{"x":3,"y":3}],"type":"BROWN"}]'

###Future work Equivalent levels in Python

###Credits This feature was originally implemented by Imperial College students Christian Priebe, Eric Seckler, Emanuele Vespa, Adrien Rapeaux.

Clone this wiki locally