2007-10-30 22:31:13 +00:00
|
|
|
<?php
|
2008-08-05 22:43:14 +00:00
|
|
|
// This file is part of BOINC.
|
|
|
|
// http://boinc.berkeley.edu
|
|
|
|
// Copyright (C) 2008 University of California
|
|
|
|
//
|
|
|
|
// BOINC is free software; you can redistribute it and/or modify it
|
|
|
|
// under the terms of the GNU Lesser General Public License
|
|
|
|
// as published by the Free Software Foundation,
|
|
|
|
// either version 3 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// BOINC is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
2007-10-30 22:31:13 +00:00
|
|
|
|
2008-01-28 22:42:05 +00:00
|
|
|
// Bolt exercise API
|
|
|
|
|
2008-10-24 20:09:16 +00:00
|
|
|
// The following is a global var accessed by exercise functions.
|
|
|
|
//
|
|
|
|
$bolt_ex = null;
|
|
|
|
$bolt_ex->mode = 0; // input: SHOW/SCORE/ANSWER
|
|
|
|
$bolt_ex->index = 0; // input: sequence of this exercise in file
|
|
|
|
$bolt_ex->score = 0; // input/output: cumulative score (if mode = SCORE)
|
|
|
|
$bolt_ex->weight = 0; // input/output: cumulative weight
|
|
|
|
$bolt_ex->query_string = ""; // user's response (if SCORE or ANSWER)
|
2007-11-29 23:26:49 +00:00
|
|
|
|
2008-10-24 20:09:16 +00:00
|
|
|
function weight($w) {
|
2008-10-30 18:27:22 +00:00
|
|
|
return array('weight', $w);
|
2008-10-24 20:09:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function exclusive_choice() {
|
|
|
|
global $bolt_ex;
|
|
|
|
$weight = 1;
|
|
|
|
|
|
|
|
$choices = array();
|
|
|
|
$args = func_get_args();
|
|
|
|
foreach ($args as $arg) {
|
|
|
|
if (is_string($arg)) {
|
|
|
|
$choices[] = $arg;
|
2008-10-30 18:27:22 +00:00
|
|
|
} else if (is_array($arg)) {
|
|
|
|
switch ($arg[0]) {
|
|
|
|
case 'weight': $weight = $arg[1]; break;
|
|
|
|
default: echo "bad arg to exclusive_choice()";
|
2008-10-24 20:09:16 +00:00
|
|
|
}
|
|
|
|
} else {
|
2008-10-30 18:27:22 +00:00
|
|
|
echo "bad arg to exclusive_choice()";
|
2008-10-24 20:09:16 +00:00
|
|
|
}
|
|
|
|
}
|
2007-12-19 16:31:41 +00:00
|
|
|
|
2008-10-24 20:09:16 +00:00
|
|
|
parse_str($bolt_ex->query_string);
|
2007-11-29 16:47:56 +00:00
|
|
|
|
2008-10-24 20:09:16 +00:00
|
|
|
switch ($bolt_ex->mode) {
|
2007-11-29 16:47:56 +00:00
|
|
|
case BOLT_MODE_SHOW:
|
2007-11-29 23:26:49 +00:00
|
|
|
shuffle($choices);
|
|
|
|
$i = 0;
|
2007-12-07 23:23:25 +00:00
|
|
|
start_table();
|
2007-11-29 16:47:56 +00:00
|
|
|
foreach ($choices as $choice) {
|
2008-10-24 20:09:16 +00:00
|
|
|
row2($choice, "<input name=q_$bolt_ex->index type=radio value=$i>");
|
2007-11-29 23:26:49 +00:00
|
|
|
$i++;
|
2007-11-29 16:47:56 +00:00
|
|
|
}
|
2007-12-07 23:23:25 +00:00
|
|
|
end_table();
|
2007-11-29 16:47:56 +00:00
|
|
|
break;
|
|
|
|
case BOLT_MODE_SCORE:
|
2007-11-29 23:26:49 +00:00
|
|
|
$right_ans = $choices[0];
|
|
|
|
shuffle($choices);
|
2008-10-24 20:09:16 +00:00
|
|
|
$key = "q_$bolt_ex->index";
|
2007-12-19 16:31:41 +00:00
|
|
|
if (isset($$key)) {
|
|
|
|
$response = $$key;
|
2007-12-18 20:28:08 +00:00
|
|
|
if ($choices[$response] == $right_ans) {
|
2008-10-24 20:09:16 +00:00
|
|
|
$bolt_ex->score += 1;
|
2007-12-18 20:28:08 +00:00
|
|
|
}
|
2007-11-29 23:26:49 +00:00
|
|
|
}
|
2008-10-24 20:09:16 +00:00
|
|
|
$bolt_ex->weight += $weight;
|
2007-11-29 16:47:56 +00:00
|
|
|
break;
|
|
|
|
case BOLT_MODE_ANSWER:
|
2007-11-29 23:26:49 +00:00
|
|
|
$right_ans = $choices[0];
|
|
|
|
shuffle($choices);
|
2008-10-24 20:09:16 +00:00
|
|
|
$key = "q_$bolt_ex->index";
|
2007-12-19 16:31:41 +00:00
|
|
|
if (isset($$key)) {
|
|
|
|
$response = $$key;
|
2007-12-18 20:28:08 +00:00
|
|
|
} else {
|
|
|
|
$response = -1;
|
|
|
|
}
|
2007-11-29 23:26:49 +00:00
|
|
|
$i = 0;
|
2007-12-07 23:23:25 +00:00
|
|
|
start_table();
|
2007-11-29 23:26:49 +00:00
|
|
|
foreach ($choices as $choice) {
|
2008-02-01 23:11:09 +00:00
|
|
|
$x = "<td><br></td>";
|
|
|
|
if ($response == $i) {
|
|
|
|
if ($choice == $right_ans) {
|
|
|
|
$x = "<td bgcolor=#88ff88>Right</a>";
|
|
|
|
} else {
|
|
|
|
$x = "<td bgcolor=#ff8888>You chose this answer</a>";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ($choice == $right_ans) {
|
|
|
|
$x = "<td>Right answer</td>";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
echo "<tr><td width=50% class=fieldname>$choice $x </tr>";
|
2007-11-29 23:26:49 +00:00
|
|
|
$i++;
|
|
|
|
}
|
2007-12-07 23:23:25 +00:00
|
|
|
end_table();
|
2007-11-29 16:47:56 +00:00
|
|
|
break;
|
2007-10-30 22:31:13 +00:00
|
|
|
}
|
2008-10-24 20:09:16 +00:00
|
|
|
$bolt_ex->index++;
|
2007-10-30 22:31:13 +00:00
|
|
|
}
|
2007-12-01 22:43:11 +00:00
|
|
|
|
2008-10-24 20:09:16 +00:00
|
|
|
function inclusive_choice() {
|
|
|
|
global $bolt_ex;
|
|
|
|
$weight = 1;
|
|
|
|
|
|
|
|
$choices = array();
|
|
|
|
$args = func_get_args();
|
|
|
|
foreach ($args as $arg) {
|
|
|
|
if (is_array($arg)) {
|
|
|
|
$choices[] = $arg;
|
|
|
|
} else if (is_object($arg)) {
|
|
|
|
if (get_class($arg) == 'BoltWeight') {
|
|
|
|
$weight = $arg->weight;
|
|
|
|
} else {
|
2008-10-30 18:27:22 +00:00
|
|
|
echo "bad arg to inclusive_choice()";
|
2008-10-24 20:09:16 +00:00
|
|
|
}
|
|
|
|
} else {
|
2008-10-30 18:27:22 +00:00
|
|
|
echo "bad arg to inclusive_choice()";
|
2008-10-24 20:09:16 +00:00
|
|
|
}
|
|
|
|
}
|
2007-12-19 16:31:41 +00:00
|
|
|
|
2008-10-24 20:09:16 +00:00
|
|
|
parse_str($bolt_ex->query_string);
|
2007-12-10 22:13:48 +00:00
|
|
|
|
2008-10-24 20:09:16 +00:00
|
|
|
switch ($bolt_ex->mode) {
|
2007-12-10 22:13:48 +00:00
|
|
|
case BOLT_MODE_SHOW:
|
|
|
|
shuffle($choices);
|
|
|
|
$i = 0;
|
|
|
|
start_table();
|
|
|
|
foreach ($choices as $choice) {
|
|
|
|
$c = $choice[0];
|
2008-10-24 20:09:16 +00:00
|
|
|
row2("<input name=q_".$bolt_ex->index."_$i type=checkbox>", $c);
|
2007-12-10 22:13:48 +00:00
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
end_table();
|
|
|
|
break;
|
|
|
|
case BOLT_MODE_SCORE:
|
|
|
|
$i = 0;
|
|
|
|
$n = count($choices);
|
|
|
|
$score = 0;
|
|
|
|
shuffle($choices);
|
|
|
|
foreach ($choices as $choice) {
|
2008-10-24 20:09:16 +00:00
|
|
|
$key = "q_".$bolt_ex->index."_$i";
|
2007-12-19 16:31:41 +00:00
|
|
|
$response = isset($$key);
|
2007-12-10 22:13:48 +00:00
|
|
|
$r = $choice[1];
|
|
|
|
$correct = ($r && $response) || (!$r && !$response);
|
|
|
|
if ($correct) $score += 1./$n;
|
2007-12-18 20:28:08 +00:00
|
|
|
$i++;
|
2007-12-10 22:13:48 +00:00
|
|
|
}
|
2008-10-24 20:09:16 +00:00
|
|
|
$bolt_ex->score += $score;
|
|
|
|
$bolt_ex->weight += $weight;
|
2007-12-10 22:13:48 +00:00
|
|
|
break;
|
|
|
|
case BOLT_MODE_ANSWER:
|
|
|
|
$i = 0;
|
|
|
|
$n = count($choices);
|
|
|
|
shuffle($choices);
|
|
|
|
start_table();
|
2007-12-18 20:28:08 +00:00
|
|
|
table_header("Choice", "Correct?", "Your answer");
|
2007-12-10 22:13:48 +00:00
|
|
|
foreach ($choices as $choice) {
|
|
|
|
$c = $choice[0];
|
2008-10-24 20:09:16 +00:00
|
|
|
$key = "q_".$bolt_ex->index."_$i";
|
2007-12-19 16:31:41 +00:00
|
|
|
$response = isset($$key);
|
2007-12-10 22:13:48 +00:00
|
|
|
$r = $choice[1];
|
|
|
|
$correct = ($r && $response) || (!$r && !$response);
|
2008-02-01 23:11:09 +00:00
|
|
|
$color = $correct?"#88ff88":"#ff8888";
|
|
|
|
table_row($c, $r?"yes":"no",
|
|
|
|
array($response?"yes":"no", "bgcolor=$color")
|
|
|
|
);
|
2007-12-10 22:13:48 +00:00
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
end_table();
|
|
|
|
break;
|
|
|
|
}
|
2008-10-24 20:09:16 +00:00
|
|
|
$bolt_ex->index++;
|
2007-12-10 22:13:48 +00:00
|
|
|
}
|
|
|
|
|
2008-02-08 17:20:09 +00:00
|
|
|
function image_rect($img, $rect) {
|
2008-10-24 20:09:16 +00:00
|
|
|
global $bolt_ex;
|
2007-12-01 22:43:11 +00:00
|
|
|
|
2008-10-24 20:09:16 +00:00
|
|
|
parse_str($bolt_ex->query_string);
|
2007-12-19 16:31:41 +00:00
|
|
|
|
2008-10-24 20:09:16 +00:00
|
|
|
switch ($bolt_ex->mode) {
|
2007-12-01 22:43:11 +00:00
|
|
|
case BOLT_MODE_SHOW:
|
2008-10-30 18:27:22 +00:00
|
|
|
echo "<input type=image name=pic_$bolt_ex->index src=$img>
|
2008-10-24 22:28:34 +00:00
|
|
|
";
|
|
|
|
break;
|
|
|
|
case BOLT_MODE_SCORE:
|
|
|
|
$x = get_int("pic_".$bolt_ex->index."_x");
|
|
|
|
$y = get_int("pic_".$bolt_ex->index."_y");
|
|
|
|
$right = true;
|
|
|
|
if ($x < $rect[0]) $right = false;
|
|
|
|
if ($x > $rect[1]) $right = false;
|
|
|
|
if ($y < $rect[2]) $right = false;
|
|
|
|
if ($y > $rect[3]) $right = false;
|
|
|
|
if ($right) {
|
|
|
|
$bolt_ex->score += 1;
|
|
|
|
}
|
|
|
|
$bolt_ex->weight += $weight;
|
|
|
|
break;
|
|
|
|
case BOLT_MODE_ANSWER:
|
|
|
|
$x = get_int("pic_".$bolt_ex->index."_x");
|
|
|
|
$y = get_int("pic_".$bolt_ex->index."_y");
|
|
|
|
$right = true;
|
|
|
|
if ($x < $rect[0]) $right = false;
|
|
|
|
if ($x > $rect[1]) $right = false;
|
|
|
|
if ($y < $rect[2]) $right = false;
|
|
|
|
if ($y > $rect[3]) $right = false;
|
|
|
|
$cx = $rect[0];
|
|
|
|
$cy = $rect[2];
|
|
|
|
$sizex = $rect[1]-$rect[0];
|
|
|
|
$sizey = $rect[3]-$rect[2];
|
|
|
|
$ax = $x-4;
|
|
|
|
$ay = $y-4;
|
|
|
|
$color = $right?"green":"red";
|
|
|
|
if ($right) {
|
|
|
|
echo "The point you selected (shown in green) is correct.";
|
|
|
|
} else {
|
|
|
|
echo "The point you selected (shown in red) is not correct.";
|
|
|
|
}
|
|
|
|
echo "
|
|
|
|
<div style=\"position:relative; \">
|
|
|
|
<span style=\"width:".$sizex."px;height:".$sizey."px;position:absolute;top:".$cy.";left:".$cx.";color:white;border-style:solid;border-width:3px\"><br></span>
|
|
|
|
<span style=\"width:8;height:8;position:absolute;top:".$ay.";left:".$ax.";color:$color;border-style:solid;border-width:4px\"><br></span>
|
|
|
|
<img src=$img align=left>
|
|
|
|
</div>
|
|
|
|
<br clear=all>
|
|
|
|
";
|
2007-12-01 22:43:11 +00:00
|
|
|
break;
|
|
|
|
}
|
2008-10-24 22:28:34 +00:00
|
|
|
$bolt_ex->index++;
|
2007-12-01 22:43:11 +00:00
|
|
|
}
|
|
|
|
|
2008-10-30 18:27:22 +00:00
|
|
|
class BoltFitbField {
|
|
|
|
public $textarea, $nrows, $ncols;
|
|
|
|
function __construct($textarea, $nrows, $ncols) {
|
|
|
|
$this->textarea = $textarea;
|
|
|
|
$this->nrows = $nrows;
|
|
|
|
$this->ncols = $ncols;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function field($n) {
|
|
|
|
return new BoltFitbField(false, 1, $n);
|
|
|
|
}
|
|
|
|
|
|
|
|
function box($nr, $nc) {
|
|
|
|
return new BoltFitbField(true, $nr, $nc);
|
|
|
|
}
|
|
|
|
|
|
|
|
class BoltFitbAnswer {
|
|
|
|
public $type; // 0=constant, 1=regexp, 2=func
|
|
|
|
public $ans;
|
|
|
|
function __construct($type, $ans) {
|
|
|
|
$this->type = $type;
|
|
|
|
$this->ans = $ans;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function answer($ans) {
|
|
|
|
return new BoltFitbAnswer(0, $ans);
|
|
|
|
}
|
|
|
|
|
|
|
|
function answer_regexp($ans) {
|
|
|
|
return new BoltFitbAnswer(1, $ans);
|
|
|
|
}
|
|
|
|
|
|
|
|
function answer_func($ans) {
|
|
|
|
return new BoltFitbAnswer(2, $ans);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fitb() {
|
|
|
|
global $bolt_ex;
|
|
|
|
$args = func_get_args();
|
|
|
|
$field = new BoltFitbField(false, 1, 20);
|
|
|
|
$answer = null;
|
|
|
|
foreach ($args as $arg) {
|
|
|
|
if (is_array($arg)) {
|
|
|
|
$choices[] = $arg;
|
|
|
|
} else if (is_object($arg)) {
|
|
|
|
if (get_class($arg) == 'BoltFitbField') {
|
|
|
|
$field = $arg;
|
|
|
|
} else if (get_class($arg) == 'BoltFitbAns') {
|
|
|
|
$answer = $arg;
|
|
|
|
} else {
|
|
|
|
echo "bad arg to fitb()";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
echo "bad arg to fitb()";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ($bolt_ex->mode) {
|
|
|
|
case BOLT_MODE_SHOW:
|
|
|
|
if ($field->textarea) {
|
|
|
|
echo "<textarea name=q_".$bolt_ex->index." nrows=$field->nrows ncols=$field->ncols>
|
|
|
|
</textarea>
|
|
|
|
";
|
|
|
|
} else {
|
|
|
|
echo "<input name=q_".$bolt_ex->index." length=$field->ncols>";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case BOLT_MODE_SCORE:
|
|
|
|
if (!$answer) break;
|
|
|
|
$bolt_ex->score = 0;
|
|
|
|
$key = "q_".$bolt_ex->index;
|
|
|
|
if (isset($$key)) {
|
|
|
|
$response = $$key;
|
|
|
|
} else {
|
|
|
|
$response = "";
|
|
|
|
}
|
|
|
|
switch ($answer->type) {
|
|
|
|
case 0:
|
|
|
|
if ($response == $answer->ans) {
|
|
|
|
$bolt_ex->score = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (ereg($answer->ans, $response)) {
|
|
|
|
$bolt_ex->score = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
$bolt_ex->score = call_user_func($answer->ans, $response);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case BOLT_MODE_ANSWER:
|
|
|
|
$key = "q_".$bolt_ex->index;
|
|
|
|
if (isset($$key)) {
|
|
|
|
$response = $$key;
|
|
|
|
} else {
|
|
|
|
$response = "";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$bolt_ex->index++;
|
|
|
|
}
|
|
|
|
|
2007-10-30 22:31:13 +00:00
|
|
|
?>
|