openct-tasks/bebras/2014/2014-FR-06-bridge/task.js

246 lines
8.1 KiB
JavaScript

function initTask(subTask) {
var state = {};
var level;
var answer = null;
var data = {
easy: {
maxWeight: 6,
weights: [ 5, 4, 1, 2],
solution: [2, 4, 1, 5]
},
medium: {
maxWeight: 10,
weights: [3, 6, 7, 4, 9, 2, 1, 8],
solution: [4, 6, 3, 7, 2, 8, 1, 9]
},
hard: {
maxWeight: 14,
weights: [2, 6, 12, 1, 9, 11, 5, 3, 13, 8, 4, 10],
solution: [6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]
}
};
var paper;
var dragAndDrop;
var weights;
var maxWeight;
var colors = ["#FFFF00", "#00FFFF", "#FF00FF", "#8080FF", "#FF8080", "#00FF00", "#FFFFFF", "#A0A0A0", "#FF8080", "#00FF00", "#FFFFFF", "#A0A0A0"];
var nbBalls;
var nbSpacesAfter;
var bridgeY;
var bridge;
var circles = [];
var radius = 20;
var space = radius * 2 + 4;
var fontSize = 20;
var timeoutId;
subTask.loadLevel = function(curLevel) {
level = curLevel;
weights = JSON.parse(JSON.stringify(data[level].weights));
nbBalls = weights.length;
maxWeight = data[level].maxWeight;
nbSpacesAfter = nbBalls / 2;
};
subTask.getStateObject = function() {
return state;
};
subTask.reloadAnswerObject = function(answerObj) {
answer = answerObj;
if(answer){
}
};
subTask.resetDisplay = function() {
drawBridge();
replaceCircles();
initButton();
displayHelper.hideValidateButton = true;
};
subTask.getAnswerObject = function() {
return answer;
};
subTask.getDefaultAnswerObject = function() {
var defaultAnswer = getInitAnswer();
return defaultAnswer;
};
subTask.unloadLevel = function(callback) {
stopAnimation();
callback();
};
function getResultAndMessage() {
var result;
var nbBallsCrossing = getNbBallsCrossing(answer);
if (nbBallsCrossing == nbBalls) {
result = { successRate: 1, message: taskStrings.success };
} else {
result = { successRate: 0, message: taskStrings.failure };
}
return result;
}
subTask.getGrade = function(callback) {
callback(getResultAndMessage());
};
function initButton() {
$("#cross_or_retry").off("click");
$("#cross_or_retry").click(crossOrRetry);
};
var getObject = function(id) {
var circle = paper.circle(0, 0, radius).attr('fill', colors[id]);
var text = paper.text(0, 0, weights[id]).attr({'font-size' : fontSize, 'font-weight' : 'bold'});
return [circle, text];
};
var getInitAnswer = function() {
return Beav.Array.init(nbBalls, function(iBall) { return iBall; });
};
var getNbBallsCrossing = function(answer) {
for (var iBall = nbBalls - 2; iBall >= 0; iBall--) {
if (weights[answer[iBall]] + weights[answer[iBall + 1]] > maxWeight) {
return nbBalls - iBall - 2;
}
}
return nbBalls;
};
var drawBridge = function() {
paper = subTask.raphaelFactory.create("anim","anim",740, space * 2 + 2 * radius);
dragAndDrop = DragAndDropSystem({
paper : paper,
actionIfDropped : function(srcCont, srcPos, dstCont, dstPos, type)
{
if (dstCont == null)
return false;
return true;
},
drop : function(srcCont, srcPos, dstCont, dstPos, type)
{
answer = dragAndDrop.getObjects('seq');
},
over : function(srcCont, srcPos, dstCont, dstPos)
{
}
});
dragAndDrop.addContainer({
ident : 'seq',
cx : space * (nbBalls / 2),
cy : space,
widthPlace: space,
heightPlace: space,
nbPlaces : nbBalls,
dropMode : 'insertBefore',
dragDisplayMode : 'marker',
placeBackgroundArray : []
});
for (var col = nbBalls; col < nbBalls + 3; col += 2) {
paper.rect(col * space, space + radius + 3, 1, 20).attr('stroke-width', 3);
}
paper.rect(0, space + radius + 3, nbBalls * space, 1).attr('stroke-width',5);
bridge = paper.rect(nbBalls * space + 5, space + radius + 3, 2 * space - 9, 1).attr({'stroke-width':5, 'stroke': 'orange'});
paper.rect((nbBalls + 2) * space + 2, space + radius + 3, nbSpacesAfter * space, 1).attr({'stroke-width':5});
paper.text((nbBalls + 1) * space, space * 2 + radius, "Max " + maxWeight + " kg").attr({'font-size': fontSize, 'font-weight':'bold'});
};
var replaceCircles = function() {
var objects = dragAndDrop.getObjects('seq');
for (var i = 0; i < objects.length; i++) {
if (objects[i] != null) {
dragAndDrop.removeObject('seq', i);
}
}
for (var i = 0; i < nbBalls; i++) {
dragAndDrop.insertObject('seq',i, {ident : answer[i], elements : getObject(answer[i])});
}
for (var iCircle = 0; iCircle < circles.length; iCircle++) {
circles[iCircle][0].remove();
circles[iCircle][1].remove();
}
circles = [];
bridgeY = space + radius + 3;
bridge.attr('y', bridgeY);
$("#cross_or_retry").text(taskStrings.attempt);
$("#cross_or_retry").removeAttr('disabled');
displayHelper.stopShowingResult();
};
crossOrRetry = function() {
if ($("#cross_or_retry").text() == taskStrings.attempt) {
checkSolution();
} else {
replaceCircles();
}
};
var stopAnimation = function() {
if (timeoutId != -1) {
clearTimeout(timeoutId);
}
if(bridge) {
bridge.stop();
}
for (var iCircle = 0; iCircle < circles.length; iCircle++) {
circles[iCircle][0].stop();
circles[iCircle][1].stop();
}
};
function checkSolution() {
if (circles.length > 0) { // TODO: est-ce censé arriver ?
return;
}
$("#cross_or_retry").attr('disabled', 'disabled');
var answer = dragAndDrop.getObjects('seq');
circles = [];
for (var i = 0; i < nbBalls; i++) {
dragAndDrop.removeObject('seq', i);
circles.push(getObject(answer[i]));
}
var nbBallsCrossing = getNbBallsCrossing(answer);
var time = ((nbBallsCrossing + 2) * 200);
for (var i = 0; i < nbBalls; i++) {
var ball = answer[i];
circles[i][0].attr({cx: space * i + radius + 7, cy: space});
circles[i][1].attr({x: space * i + radius + 7, y: space});
var x = (i + nbBallsCrossing + 2) * space + radius + 7;
var crossAnim = new Raphael.animation({"x":x,"cx":x},time);
subTask.raphaelFactory.animate("crossAnim",circles[i][0],crossAnim);
subTask.raphaelFactory.animate("crossAnim",circles[i][1],crossAnim);
}
if (nbBallsCrossing != nbBalls) {
var animBridge = Raphael.animation({y: bridgeY + radius}, 100).delay(time);
subTask.raphaelFactory.animate("animBridge",bridge,animBridge);
var firstBallFalling = nbBalls - nbBallsCrossing - 2;
var fallAnim = Raphael.animation({cy: bridgeY, y: bridgeY}, 100).delay(time);
if (firstBallFalling >= 0) {
subTask.raphaelFactory.animate("fallAnim",circles[firstBallFalling][0],fallAnim);
subTask.raphaelFactory.animate("fallAnim",circles[firstBallFalling][1],fallAnim);
}
if (firstBallFalling + 1 < nbBalls) {
subTask.raphaelFactory.animate("fallAnim",circles[firstBallFalling + 1][0],fallAnim);
subTask.raphaelFactory.animate("fallAnim",circles[firstBallFalling + 1][1],fallAnim);
}
}
timeoutId = setTimeout(function() {
$("#cross_or_retry").text(taskStrings.putLogsBack);
$("#cross_or_retry").removeAttr('disabled');
if (nbBallsCrossing == nbBalls) {
platform.validate("done");
} else {
displayHelper.validate("stay");
}
}, time);
};
}
initWrapper(initTask, ["easy", "medium", "hard"]);
displayHelper.useFullWidth();