You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

304 lines
11 KiB

8 years ago
{% extends "layout.html" %}
{% block body %}
<h1 style="margin-left:10%;margin-top:0px;">Level {{level['id']}}: {{level['name']}}</h1>
<section>
<div class="half">
<h2>Map</h2>
<div id="map"></div>
8 years ago
<p><span id="cell_info">&lt;No cell selected&gt;</span></p>
8 years ago
</div>
<div class="half">
<div class="half">
<h2>Altimeter</h2>
<div id="altimeter"></div>
</div>
<div class="half">
<h2>Status</h2>
<div id="status"></div> <p id="status_label"></p>
<div class="clear"></div>
<hr />
<p class="info position">(<span id="current_position"></span>)</p>
<p class="info altitude"><span id="current_altitude"></span></p>
<p class="info fuel"><span id="current_fuel"></span></p>
<p class="info bearing"><span id="current_bearing"></span></p>
<p class="info inventory"></p>
8 years ago
<ul id="current_inventory"></ul>
</div>
</div>
<div class="clear"></div>
<div>
<div class="half">
<h2>Enter your drone code below</h2>
<textarea class="drone_source">
from cardiff_drone import Drone
drone = Drone(maps[{{level['id']-1}}])
8 years ago
# Enter your code here
</textarea>
<button id="run" class="run">Run code</button>
8 years ago
</div>
<div class="half">
8 years ago
<h2>Mission information</h2>
<p id="map_desc"></p>
8 years ago
<div id="starting_info">
<h3>Starting position</h3>
<p>The drone starts at position (<span id="drone_start"></span>) facing <span id="drone_start_angle"></span>.</p>
</div>
8 years ago
<h3>Finish position</h3>
<p>Get the drone to position (<span id="drone_finish"></span>) to finish.
<h3>Wind</h3>
8 years ago
<p>Wind will blow to <span id="wind_direction"></span> <span id="wind_frequency"></span>.
<div id="available_items_info">
<h3>Items available</h3>
8 years ago
<p>The following items can be collected:</p>
<ul id="available_items"></ul>
</div>
<div id="finish_items_info">
<h3>Items needed to finish</h3>
8 years ago
<p>You need to bring the following items to the finish:</p>
<ul id="finish_items"></ul>
</div>
8 years ago
</div>
<div class="clear"></div>
</section>
{% endblock %}
{% block scripts %}
<script>
8 years ago
var obstacles, items, finish_items, finish_tile, start_tile, map_size, drone, tile_width, tile_height, selected_cell, map_desc, wind, map;
8 years ago
function Drone(x,y,z,a,fuel){
8 years ago
this.x = x;
this.y = y;
this.z = z;
this.a = a;
this.fuel = fuel;
8 years ago
this.inventory = [];
this.status = "green";
this.status_label = "Landed";
}
$(document).ready(function(){
get_map({{level['id']}});
$("#run").click(function(){
submit_code({{level['id']}});
});
});
function analyse_cell(cell){
8 years ago
if(cell == null){return;}
selected_cell = cell;
var contents = false;
$("#map .tile").removeClass("selected");
cell.addClass("selected");
8 years ago
var x = parseInt(cell.attr('data-x'));
var y = parseInt(cell.attr('data-y'));
var o = cell.attr('data-obstacles');
$("#cell_info").html("("+x+","+y+") cell contents:<br /> ");
if(o != "" && o != null){
$("#cell_info").append(' - obstacle(s) at height(s): '+o+'<br />');
contents = true;
}
if(cell.hasClass('spawn')){
8 years ago
$("#cell_info").append(' - spawn point<br />');contents = true;
}
if(cell.hasClass('finish')){
8 years ago
$("#cell_info").append(' - finish point<br />');contents = true;
}
8 years ago
if(parseInt(cell.attr('data-x'))==drone.x&&parseInt(cell.attr('data-y'))==drone.y){
$("#cell_info").append(' - Drone at height '+drone.z+'<br />');contents = true;
}
for(var i = 0; i < items.length; i++){
if(items[i]['location'][0]==x && items[i]['location'][1] == y){
$("#cell_info").append(' - '+items[i]['name']+' at height '+items[i]['location'][2]+'<br />');
contents = true;
}
}
if(contents == false){$("#cell_info").append('Empty');}
}
8 years ago
function draw_ui(){
8 years ago
if(map.drone_visible == true){
$("#drone_start").html(start_tile[0]+","+start_tile[1]+","+start_tile[2]);
$("#drone_start_angle").html(start_tile[3]+"&deg; from North");
}
if(finish_items.length == 0){
$("#finish_items_info").css({'display':'none'});
}
if(items.length == 0){
$("#available_items_info").css({'display':'none'});
}
8 years ago
$("#drone_finish").html(finish_tile[0]+","+finish_tile[1]+","+finish_tile[2]);
for(var i = 0; i < items.length; i++){
var item = items[i];
$("#available_items").append('<li>'+item.name+' at position ('+item.location[0]+','+item.location[1]+","+item.location[2]+')</li>');
}
for(var i = 0; i < finish_items.length; i++){
8 years ago
var item = finish_items[i];
$("#finish_items").append('<li>'+item+'</li>');
8 years ago
}
tile_width = 100/map_size[0];
tile_height = 100/map_size[1];
for(var i = 0; i < map_size[0]; i++){
for(var j = 0; j < map_size[1];j++){
var obstacles_here = [];
for(var k = 0; k < obstacles.length; k++){
if(obstacles[k][0]==(i+1) && obstacles[k][1]==(j+1)){
obstacles_here.push(obstacles[k][2]);
}
}
var t = '<div data-obstacles="'+obstacles_here.join()+'"data-x="'+(i+1)+'" data-y="'+(j+1)+'" style="width:'+tile_width+'%;height:'+tile_height+'%;left:'+(tile_width*i)+'%;top:'+(tile_height*j)+'%;" class="tile';
if(obstacles_here.length > 0){t = t+' obstacle ';}
if(finish_tile[0]==(i+1) && finish_tile[1]==(j+1)){t = t+' finish ';}
8 years ago
if(start_tile[0]==(i+1) && start_tile[1]==(j+1) && map.drone_visible == true){t = t+' spawn ';}
t = t+'"></div';
$("#map").append(t);
8 years ago
}
}
for(var i = 1; i <= map_size[0]; i++){
$("#map").append('<div style="left:'+(tile_width*(i-1))+'%;" class="coord x">'+i+'</div>');
}
for(var i = 1; i <= map_size[1]; i++){
$("#map").append('<div style="top:'+(tile_height*(i-1))+'%;" class="coord y">'+i+'</div>');
}
for(var i = 9; i >= 0; i--){
$("#altimeter").append('<div data-level="'+i+'" class="level" style="top:'+(9*(9-i))+'%;"><div class="measure">'+i+'</div></div>');
}
$("#altimeter").append('<div class="current_level"></div>');
8 years ago
$("#map").append("<div id='drone'></div>");
draw_drone();
$("#map .tile").click(function(){
analyse_cell($(this));
});
$("#map_desc").html(map_desc);
$("#wind_direction").html(wind.towards);
8 years ago
if(wind.frequency == "random"){
$("#wind_frequency").html("randomly");
}else{
$("#wind_frequency").html("every "+wind.frequency+" Drone move(s)");
8 years ago
}
8 years ago
}
function draw_drone(){
8 years ago
$("#current_fuel").html(drone.fuel);
$("#current_inventory").html('');
for(var i = 0; i < drone.inventory.length; i++){
$("#current_inventory").append('<li>'+drone.inventory[i]+'</li>');
}
if(drone.inventory.length == 0){$("#current_inventory").html('Empty');}
$("#status").removeClass("green").removeClass("red").addClass(drone.status);
$("#status_label").html(drone.status_label);
// If invisible drone, show no more:
if(map.drone_visible == false){
$("p.position").css({'display':'none'});
$("p.altitude").css({'display':'none'});
$("p.bearing").css({'display':'none'});
$("#altimeter .current_level").css({'display':'none'});
$("#starting_info").css({'display':'none'});
$("#cell_info").css({'display':'none'});
return;
}
$("#drone").removeClass("crashed");
$("#drone").animate({width:tile_width+'%',height:tile_height+'%',left:(tile_width*(drone.x-1))+'%',top:(tile_height*(drone.y-1))+'%'},400, function(){
if(drone.status_label == "Crashed"){
$("#drone").addClass("crashed");
8 years ago
}
});
$("#altimeter .current_level").animate({'top':(9*(9-drone.z))+'%'},500, "easeOutBounce");
8 years ago
$("#current_position").html(drone.x+','+drone.y);
$("#current_altitude").html(drone.z);
$("#current_bearing").html(drone.a+'&deg; from North');
8 years ago
8 years ago
analyse_cell(selected_cell);
8 years ago
}
function get_map(map_id){
$.get("/level/"+map_id+"/json", function(data){
data = JSON.parse(data);
8 years ago
map = data;
8 years ago
console.log(data);
obstacles = data.obstacles
items = data.items;
finish_items = data.finish_items;
finish_tile = data.finish;
start_tile = data.start;
map_size = data.size;
map_desc = data.description;
wind = data.wind;
drone = new Drone(start_tile[0],start_tile[1],start_tile[2],start_tile[3],data.fuel);
draw_ui();
8 years ago
});
}
function submit_code(map_id){
8 years ago
$("#run").fadeOut();
drone.status = "green";
drone.status_label = "Ready";
8 years ago
var postdata = {};
postdata.code = $(".drone_source").val();
$.post("/run_drone/"+map_id, postdata, function(data){
data = JSON.parse(data);
if(data.error == true){
8 years ago
$("#run").fadeIn();
8 years ago
alert("Oops - there is an error in your Python code. Have a check through.");
return;
}
8 years ago
window.scrollTo(0,0);
8 years ago
iterate_moves(data.result, 0);
8 years ago
}).fail(function(){$("#run").fadeIn();});
8 years ago
}
function iterate_moves(moves, move_count){
if(drone.status_label == "Finished"){
alert("Congratulations! You have completed the level.");
}
8 years ago
var move = moves[move_count];
8 years ago
if(move==null){$("#run").fadeIn();return;}
8 years ago
setTimeout(function(){
drone.x = move[0];
drone.y = move[1];
drone.z = move[2];
drone.a = move[3];
drone.fuel = move[6];
8 years ago
drone.status_label = move[4];
8 years ago
if(move[4] == "Crashed"){
8 years ago
drone.status = "red";
}
else{
drone.status = "green";
}
8 years ago
drone.inventory = move[5];
8 years ago
draw_drone();
iterate_moves(moves, move_count+1);
},500);
}
8 years ago
$(document).delegate('textarea', 'keydown', function(e) {
var keyCode = e.keyCode || e.which;
8 years ago
8 years ago
if (keyCode == 9) {
e.preventDefault();
var start = $(this).get(0).selectionStart;
var end = $(this).get(0).selectionEnd;
// set textarea value to: text before caret + tab + text after caret
$(this).val($(this).val().substring(0, start)
+ "\t"
+ $(this).val().substring(end));
// put caret at right position again
$(this).get(0).selectionStart =
$(this).get(0).selectionEnd = start + 1;
}
});
8 years ago
</script>
{% endblock %}