dirroot.'/mod/game/db/importsudoku.php'); $recsudoku = getrandomsudoku(); if( $recsudoku == false) error( 'Empty sudoku database'); } $newrec->id = $attempt->id; $newrec->guess = ''; $newrec->data = $recsudoku->data; $newrec->opened = $recsudoku->opened; $need = 81 - $recsudoku->opened; $closed = game_sudoku_getclosed( $newrec->data); $n = min( count($closed), $need); //if the teacher set the maximum number of questions if( $game->param2 > 0){ if( $game->param2 < $n){ $n = $game->param2; } } $recs = game_questions_selectrandom( $game, CONST_GAME_TRIES_REPETITION*$n); if( $recs === false){ error( get_string( 'no_questions', 'game')); } $closed = array_rand($closed, $n); $selected_recs = game_select_from_repetitions( $game, $recs, $n); if(!game_insert_record('game_sudoku', $newrec)){ error('error inserting in game_sudoku'); } $i = 0; $field = ($game->sourcemodule == 'glossary' ? 'glossaryentryid' : 'questionid'); foreach($recs as $rec) { if( !array_key_exists( $rec->$field, $selected_recs)) continue; unset($query); $query->attemptid = $newrec->id; $query->gameid = $game->id; $query->userid = $USER->id; $query->col = $closed[ $i++]; $query->sourcemodule = $game->sourcemodule; $query->questionid = $rec->questionid; $query->glossaryentryid = $rec->glossaryentryid; $query->score = 0; if(($query->id = insert_record('game_queries', $query)) == 0){ error('error inserting in game_queries'); } game_update_repetitions($game->id, $USER->id, $query->questionid, $query->glossaryentryid); } game_updateattempts($game, $attempt, 0, 0); game_sudoku_play($id, $game, $attempt, $newrec); } function game_sudoku_play( $id, $game, $attempt, $sudoku, $onlyshow=false, $showsolution=false){ $offsetquestions = game_sudoku_compute_offsetquestions( $game->sourcemodule, $attempt, $numbers, $correctquestions); if( $game->toptext != ''){ echo $game->toptext.'
'; } game_sudoku_showsudoku( $sudoku->data, $sudoku->guess, true, $showsolution, $offsetquestions, $correctquestions, $id, $attempt, $game); switch( $game->sourcemodule){ case 'quiz': case 'question': game_sudoku_showquestions_quiz( $id, $game, $attempt, $sudoku, $offsetquestions, $numbers, $correctquestions, $onlyshow, $showsolution); break; case 'glossary': game_sudoku_showquestions_glossary( $id, $game, $attempt, $sudoku, $offsetquestions, $numbers, $correctquestions, $onlyshow, $showsolution); break; } if( $game->bottomtext != ''){ echo '
'.$game->bottomtext; } } //returns a map with an offset and id of each question function game_sudoku_compute_offsetquestions( $sourcemodule, $attempt, &$numbers, &$correctquestions){ $select = "attemptid = $attempt->id"; $fields = 'id, col, score'; //,glossaryentryid, questionid switch( $sourcemodule){ case 'quiz': case 'question': $fields .= ',questionid as id2'; break; case 'glossary': $fields .= ',glossaryentryid as id2'; break; } if( ($recs = get_records_select( 'game_queries', $select, '', $fields)) == false){ error( 'There are no questions'); } $offsetquestions = array(); $numbers = array(); $correctquestions = array(); foreach($recs as $rec){ $offsetquestions[$rec->col] = $rec->id2; $numbers[$rec->id2] = $rec->col; if($rec->score == 1) $correctquestions[$rec->col] = 1; } ksort( $offsetquestions); return $offsetquestions; } function getrandomsudoku($level1=0, $level2=0){ global $CFG; $where = ""; if($level1){ $where = " AND level >= $level1"; } if($level2){ $where .= " AND level <= $level2"; } if($where != ""){ $where = " WHERE $where"; } $sql = "SELECT COUNT(*) as c FROM {$CFG->prefix}game_sudoku_database $where"; $rec = get_record_sql($sql); $count = $rec->c; $i = mt_rand(0, $count - 1); $sql = "SELECT * FROM {$CFG->prefix}game_sudoku_database $where"; if( ($recs = get_records_sql( $sql, $i, 1)) != false) { foreach( $recs as $rec){ return $rec; } } return false; } function game_sudoku_getclosed( $data){ $textlib = textlib_get_instance(); $a = array(); $n = $textlib->strlen( $data); for( $i=1; $i <= $n; $i++) { $c = $textlib->substr( $data, $i-1, 1); if( $c >= "1" and $c <= "9") $a[ $i] = $i; } return $a; } function game_sudoku_showsudoku( $data, $guess, $bShowLegend, $bShowSolution, $offsetquestions, $correctquestions, $id, $attempt, $game){ global $CFG; $correct = $count = 0; echo "
\r\n"; echo ''; $pos=0; for($i=0; $i <= 2; $i++){ echo ""; for($j=0; $j <= 2; $j++){ echo '\r\n"; } echo ""; } echo "
'; for($k1=0; $k1 <= 2; $k1++){ echo ""; for( $k2=0; $k2 <= 2; $k2++){ $s = substr($data, $pos, 1); $g = substr($guess, $pos, 1); $pos++; if($g != 0){ $s = $g; } if($s >= "1" and $s <= "9"){ //closed number if($bShowLegend) { //show legend if($bShowSolution == false){ if(!array_key_exists($pos, $correctquestions)){ if(array_key_exists($pos, $offsetquestions)) { if($s != $g){ $s = ''; } }else if($g == 0){ $s = ''; } } else{ //correct question $count++; } } echo ''; } else{ //not show legend echo ''; } } else{ $s = strpos("-ABCDEFGHI", $s); $count++; echo ''; } } echo ""; } echo "
'.$s.' '.$s.'
\r\n"; ?> timefinish){ return $count; } if(count($offsetquestions) != count($correctquestions)){ return $count; } if (!$cm = get_record("course_modules", "id", $id)) { error("Course Module ID was incorrect id=$id"); } echo '
'.get_string('win', 'game').'

'; echo '
'; echo "wwwroot/mod/game/attempt.php?id=$id\">".get_string('nextgame', 'game').'         '; echo "wwwroot/course/view.php?id=$cm->course\">".get_string('finish', 'game').' '; game_updateattempts($game, $attempt, 1, 1); return $count; } function game_sudoku_getquestionlist($offsetquestions){ $questionlist = ''; foreach($offsetquestions as $q){ if($q != 0){ $questionlist .= ','.$q; } } $questionlist = substr( $questionlist, 1); if ($questionlist == '') { error(get_string('no_questions', 'game')); } return $questionlist; } function game_sudoku_getglossaryentries($game, $offsetentries, &$entrylist, $numbers){ global $CFG; $entrylist = implode(',', $offsetentries); if ($entrylist == '') { error(get_string('sudoku_noentriesfound', 'game')); } // Load the questions if (!$entries = get_records_select( 'glossary_entries', "id IN ($entrylist)")) { error(get_string('sudoku_noentriesfound', 'game')); } return $entries; } function game_sudoku_showquestions_quiz($id, $game, $attempt, $sudoku, $offsetquestions, $numbers, $correctquestions, $onlyshow, $showsolution){ $questionlist = game_sudoku_getquestionlist($offsetquestions); $questions = game_sudoku_getquestions($questionlist); //I will sort with the number of each question $questions2 = array(); foreach($questions as $q){ $ofs = $numbers[$q->id]; $questions2[$ofs] = $q; } ksort($questions2); if(count($questions2) == 0){ game_sudoku_showquestion_onfinish($id, $game, $attempt, $sudoku); return; } global $CFG; /// Start the form echo "
wwwroot}/mod/game/attempt.php\" onclick=\"this.autocomplete='off'\">\n"; if( ($onlyshow === false) and ($showsolution === false)){ echo "
"; echo "      "; } // Add a hidden field with the quiz id echo '
'; echo '\n"; echo ''; /// Print all the questions // Add a hidden field with questionids echo '\n"; $number=0; foreach ($questions2 as $question) { $ofs = $numbers[ $question->id]; if(array_key_exists($ofs, $correctquestions)){ continue; //I don't show the correct answers } $number = "A$ofs"; global $QTYPES; unset( $cmoptions); $cmoptions->course = $game->course; $cmoptions->optionflags->optionflags = 0; $cmoptions->id = 0; $cmoptions->shuffleanswers = 1; $attempt = 0; if (!$QTYPES[$question->qtype]->create_session_and_responses($question, $state, $cmoptions, $attempt)) { error('game_sudoku_showquestions_quiz: problem'); } $state->last_graded = new StdClass; $state->last_graded->event = QUESTION_EVENTOPEN; $state->event = QUESTION_EVENTOPEN; $options->scores->score = 0; $question->maxgrade = 100; $state->manualcomment = ''; $cmoptions->optionflags = 0; $options->correct_responses = 0; $options->feedback = 0; $options->readonly = 0; if( $showsolution){ $state->responses = $QTYPES[$question->qtype]->get_correct_responses($question, $state); } print_question($question, $state, $number, $cmoptions, $options); } echo "
"; // Finish the form echo ''; if( ($onlyshow === false) and ($showsolution === false)){ echo "
\n"; } echo "\n"; } //show the sudoku and glossaryentries function game_sudoku_showquestions_glossary($id, $game, $attempt, $sudoku, $offsetentries, $numbers, $correctentries, $onlyshow, $showsolution){ global $CFG; $entries = game_sudoku_getglossaryentries($game, $offsetentries, $questionlist, $numbers); //I will sort with the number of each question $entries2 = array(); foreach($entries as $q){ $ofs = $numbers[$q->id]; $entries2[$ofs] = $q; } ksort($entries2); if(count($entries2) == 0){ game_sudoku_showquestion_onfinish($id, $game, $attempt, $sudoku); return; } /// Start the form echo "
wwwroot}/mod/game/attempt.php\" onclick=\"this.autocomplete='off'\">\n"; if( $onlyshow === false){ echo "
\n"; } // Add a hidden field with the quiz id echo '
'; echo '\n"; echo ''; /// Print all the questions // Add a hidden field with questionids echo '\n"; $number=0; foreach ($entries2 as $entry) { $ofs = $numbers[$entry->id]; if( array_key_exists($ofs,$correctentries)){ continue; //I don't show the correct answers } $s = 'A'.$ofs.'. '.game_filtertext($entry->definition, 0).'
'; if($showsolution){ $s .= get_string('answer').': '; $s .= "id}\" value=\"$entry->concept\"size=30 />
"; } else if( $onlyshow === false){ $s .= get_string('answer').': '; $s .= "id}\" size=30 />
"; } echo $s."
\r\n"; } echo "
"; // Finish the form echo ''; if($onlyshow === false){ echo "
\n"; } echo "
\n"; } function game_sudoku_showquestion_onfinish( $id, $game, $attempt, $sudoku){ if(!set_field('game_attempts', 'finish', 1, 'id', $attempt->id)){ error( "game_sudoku_showquestion_onfinish: Can't update game_attempts id=$attempt->id"); } echo ''.get_string( 'win', 'game').'
'; echo '
'; echo "wwwroot/mod/game/attempt.php?id=$id\">".get_string('nextgame', 'game').'         '; echo "wwwroot?id=$id\">".get_string('finish', 'game').' '; } function game_sudoku_checkanswers(){ $responses = data_submitted(); $actions = question_extract_responses($questions, $responses, $event); } function game_sudoku_check_questions($id, $game, $attempt, $sudoku, $finishattempt){ global $QTYPES, $CFG; $responses = data_submitted(); $offsetquestions = game_sudoku_compute_offsetquestions($game->sourcemodule, $attempt, $numbers, $correctquestions); $questionlist = game_sudoku_getquestionlist($offsetquestions); $questions = game_sudoku_getquestions($questionlist); $actions = question_extract_responses($questions, $responses, QUESTION_EVENTSUBMIT); foreach($questions as $question) { if( !array_key_exists( $question->id, $actions)){ //no answered continue; } unset( $state); unset( $cmoptions); $question->maxgrade = 100; $state->responses = $actions[ $question->id]->responses; $state->event = QUESTION_EVENTGRADE; $cmoptions = array(); $QTYPES[$question->qtype]->grade_responses( $question, $state, $cmoptions); unset($query); $select = "attemptid=$attempt->id and score < 0.5"; $select .= " AND questionid=$question->id"; if(($query->id = get_field_select( 'game_queries', 'id', $select)) == 0){ die("problem game_sudoku_check_questions (select=$select)"); continue; } $answertext = $state->responses[ '']; $grade = $state->raw_grade; if($grade < 50){ //wrong answer game_update_queries($game, $attempt, $query, $grade/100, $answertext); continue; } //correct answer game_update_queries($game, $attempt, $query, 1, $answertext); } game_sudoku_check_last($id, $game, $attempt, $sudoku, $finishattempt); } function game_sudoku_check_glossaryentries($id, $game, $attempt, $sudoku, $finishattempt){ global $QTYPES, $CFG; $responses = data_submitted(); //this function returns offsetentries, numbers, correctquestions $offsetentries = game_sudoku_compute_offsetquestions( $game->sourcemodule, $attempt, $numbers, $correctquestions); $entrieslist = game_sudoku_getquestionlist($offsetentries); // Load the glossary entries if (!($entries = get_records_select('glossary_entries', "id IN ($entrieslist)"))) { error(get_string('noglossaryentriesfound', 'game')); } foreach($entries as $entry) { if(!$answer = optional_param('resp'.$entry->id, '', PARAM_TEXT)) continue; if(game_upper($entry->concept) != game_upper($answer)){ continue; } //correct answer $select = "attemptid=$attempt->id and score < 0.5"; $select .= " AND glossaryentryid=$entry->id"; unset($query); if(($query->id = get_field_select('game_queries', 'id', $select)) == 0){ echo "not found $select
"; continue; } game_update_queries($game, $attempt, $query, 1, $answer); } game_sudoku_check_last($id, $game, $attempt, $sudoku, $finishattempt); } //this is the last function after submiting the answers. function game_sudoku_check_last($id, $game, $attempt, $sudoku, $finishattempt){ global $CFG; $correct = get_field_select('game_queries', 'COUNT(*) AS c', "attemptid=$attempt->id AND score > 0.9"); $all = get_field_select('game_queries', 'COUNT(*) AS c', "attemptid=$attempt->id"); if($all){ $grade = $correct / $all; } else{ $grade = 0; } game_updateattempts($game, $attempt, $grade, $finishattempt); redirect("$CFG->wwwroot/mod/game/attempt.php?id=$id", '', 0); } function game_sudoku_check_number($id, $game, $attempt, $sudoku, $pos, $num){ $textlib = textlib_get_instance(); $correct = $textlib->substr($sudoku->data, $pos-1, 1); if($correct != $num){ game_sudoku_play($id, $game, $attempt, $sudoku); return; } $leng = $textlib->strlen($sudoku->guess); $lend = $textlib->strlen($sudoku->data); if($leng < $lend){ $sudoku->guess .= str_repeat(' ', $lend - $leng); } game_setchar($sudoku->guess, $pos-1, $correct); if(!set_field_select('game_sudoku', 'guess', $sudoku->guess, "id=$sudoku->id")){ error('game_sudoku_check_number: Cannot update table game_sudoku'); } game_sudoku_play($id, $game, $attempt, $sudoku); } ?>