function game_sudoku_check_glossaryentries($id, $game, $attempt, $sudoku, $finishattempt, $course)
{
    global $QTYPES, $DB;
    $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 = $DB->get_records_select('glossary_entries', "id IN ({$entrieslist})"))) {
        print_error(get_string('noglossaryentriesfound', 'game'));
    }
    foreach ($entries as $entry) {
        $answerundefined = optional_param('resp' . $entry->id, 'undefined', PARAM_TEXT);
        if ($answerundefined == 'undefined') {
            continue;
        }
        $answer = optional_param('resp' . $entry->id, '', PARAM_TEXT);
        if ($answer == '') {
            continue;
        }
        if (game_upper($entry->concept) != game_upper($answer)) {
            continue;
        }
        //correct answer
        $select = "attemptid={$attempt->id}";
        $select .= " AND glossaryentryid={$entry->id} AND col>0";
        $select .= " AND questiontext is null";
        // check the student guesses not source glossary entry.
        $query = new stdClass();
        if (($query->id = $DB->get_field_select('game_queries', 'id', $select)) == 0) {
            echo "not found {$select}<br>";
            continue;
        }
        game_update_queries($game, $attempt, $query, 1, $answer);
    }
    game_sudoku_check_last($id, $game, $attempt, $sudoku, $finishattempt, $course);
    return true;
}
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 (!array_key_exists('resp' . $entry->id, $_POST)) {
            continue;
        }
        $answer = $_POST['resp' . $entry->id];
        if ($answer == '') {
            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}<br>";
            continue;
        }
        game_update_queries($game, $attempt, $query, 1, $answer);
    }
    game_sudoku_check_last($id, $game, $attempt, $sudoku, $finishattempt);
}
function game_hiddenpicture_check_questions($id, $game, &$attempt, &$hiddenpicture, $finishattempt)
{
    global $QTYPES, $DB;
    $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);
    $correct = $wrong = 0;
    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}";
        $select .= " AND questionid={$question->id}";
        if (($query->id = $DB->get_field_select('game_queries', 'id', $select)) == 0) {
            print_error("problem game_hiddenpicture_check_questions (select={$select})");
        }
        $answertext = $state->responses[''];
        if ($answertext != '') {
            $grade = $state->raw_grade;
            if ($grade < 50) {
                //wrong answer
                game_update_queries($game, $attempt, $query, $grade / 100, $answertext);
                $wrong++;
            } else {
                //correct answer
                game_update_queries($game, $attempt, $query, 1, $answertext);
                $correct++;
            }
        }
    }
    $hiddenpicture->correct += $correct;
    $hiddenpicture->wrong += $wrong;
    if (!$DB->update_record('game_hiddenpicture', $hiddenpicture)) {
        print_error('game_hiddenpicture_check_questions: error updating in game_hiddenpicture');
    }
    $attempt->score = game_hidden_picture_computescore($game, $hiddenpicture);
    if (!$DB->update_record('game_attempts', $attempt)) {
        print_error('game_hiddenpicture_check_questions: error updating in game_attempt');
    }
    game_sudoku_check_last($id, $game, $attempt, $hiddenpicture, $finishattempt);
    return true;
}
function game_hiddenpicture_play($id, $game, $attempt, $hiddenpicture, $showsolution, $context)
{
    if ($game->toptext != '') {
        echo $game->toptext . '<br>';
    }
    // Show picture.
    $offsetquestions = game_sudoku_compute_offsetquestions($game->sourcemodule, $attempt, $numbers, $correctquestions);
    unset($offsetquestions[0]);
    game_hiddenpicture_showhiddenpicture($id, $game, $attempt, $hiddenpicture, $showsolution, $offsetquestions, $correctquestions, $id, $attempt, $showsolution);
    // Show questions.
    $onlyshow = false;
    $showsolution = false;
    switch ($game->sourcemodule) {
        case 'quiz':
        case 'question':
            game_sudoku_showquestions_quiz($id, $game, $attempt, $hiddenpicture, $offsetquestions, $numbers, $correctquestions, $onlyshow, $showsolution, $context);
            break;
        case 'glossary':
            game_sudoku_showquestions_glossary($id, $game, $attempt, $hiddenpicture, $offsetquestions, $numbers, $correctquestions, $onlyshow, $showsolution);
            break;
    }
    if ($game->bottomtext != '') {
        echo '<br><br>' . $game->bottomtext;
    }
}