Version 16.251.10

This commit is contained in:
Antonio Cañas Vargas 2017-09-06 23:17:52 +02:00
parent b1e722435d
commit 3964984d31
7 changed files with 70 additions and 471 deletions

View File

@ -587,10 +587,11 @@ CREATE TABLE IF NOT EXISTS games (
-- Table gam_answers: stores the answers to the games
--
CREATE TABLE IF NOT EXISTS gam_answers (
GamCod INT NOT NULL,
QstCod INT NOT NULL,
AnsInd TINYINT NOT NULL,
NumUsrs INT NOT NULL DEFAULT 0,
UNIQUE INDEX(QstCod,AnsInd));
UNIQUE INDEX(GamCod,QstCod,AnsInd));
--
-- Table gam_grp: stores the groups associated to each game
--

View File

@ -238,19 +238,24 @@
/****************************** Public constants *****************************/
/*****************************************************************************/
#define Log_PLATFORM_VERSION "SWAD 16.251.9 (2017-09-06)"
#define Log_PLATFORM_VERSION "SWAD 16.251.10 (2017-09-06)"
#define CSS_FILE "swad16.251.8.css"
#define JS_FILE "swad16.206.3.js"
// Number of lines (includes comments but not blank lines) has been got with the following command:
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*?.h sql/swad*.sql | tail -1
/*
Version 16.251.10:Sep 06, 2017 Listing games for remote control. Not finished. (226913 lines)
2 changes necessary in database:
DROP TABLE IF EXISTS gam_answers;
CREATE TABLE IF NOT EXISTS gam_answers (GamCod INT NOT NULL,QstCod INT NOT NULL,AnsInd TINYINT NOT NULL,NumUsrs INT NOT NULL DEFAULT 0,UNIQUE INDEX(GamCod,QstCod,AnsInd));
Version 16.251.9: Sep 06, 2017 Listing games for remote control. Not finished. (227273 lines)
Version 16.251.8: Sep 06, 2017 Listing games for remote control. Not finished. (227211 lines)
Version 16.251.7: Sep 04, 2017 Listing games for remote control. Not finished. (227218 lines)
Version 16.251.6: Sep 01, 2017 Listing games for remote control. Not finished. (227111 lines)
Version 16.251.5: Sep 01, 2017 Listing games for remote control. Not finished. (227045 lines)
1 change necessary in database:
2 changes necessary in database:
ALTER TABLE gam_answers DROP COLUMN Answer;
UPDATE actions SET Obsolete='Y' WHERE ActCod='1663';

View File

@ -1278,17 +1278,19 @@ mysql> DESCRIBE gam_answers;
+---------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+-------+
| GamCod | int(11) | NO | PRI | NULL | |
| QstCod | int(11) | NO | PRI | NULL | |
| AnsInd | tinyint(4) | NO | PRI | NULL | |
| NumUsrs | int(11) | NO | | 0 | |
+---------+------------+------+-----+---------+-------+
3 rows in set (0,00 sec)
4 rows in set (0,00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_answers ("
"GamCod INT NOT NULL,"
"QstCod INT NOT NULL,"
"AnsInd TINYINT NOT NULL,"
"NumUsrs INT NOT NULL DEFAULT 0,"
"UNIQUE INDEX(QstCod,AnsInd))");
"UNIQUE INDEX(GamCod,QstCod,AnsInd))");
/***** Table gam_grp *****/
/*

View File

@ -136,11 +136,6 @@ static void Rmt_InitQst (struct GameQuestion *GameQst);
static void Rmt_PutParamQstCod (long QstCod);
static long Rmt_GetParamQstCod (void);
static void Rmt_RemAnswersOfAQuestion (long QstCod);
// static Rmt_AnswerType_t Rmt_ConvertFromStrAnsTypDBToAnsTyp (const char *StrAnsTypeBD);
// static bool Rmt_CheckIfAnswerExists (long QstCod,unsigned AnsInd);
// static bool Rmt_AllocateTextChoiceAnswer (struct GameQuestion *GameQst,unsigned NumAns);
// static void Rmt_FreeTextChoiceAnswers (struct GameQuestion *GameQst,unsigned NumAnswers);
// static void Rmt_FreeTextChoiceAnswer (struct GameQuestion *GameQst,unsigned NumAns);
static unsigned Rmt_GetQstIndFromQstCod (long QstCod);
static unsigned Rmt_GetNextQuestionIndexInGame (long GamCod);
@ -156,9 +151,7 @@ static void Rmt_AllocateListSelectedQuestions (void);
static void Rmt_FreeListsSelectedQuestions (void);
static unsigned Rmt_CountNumQuestionsInList (void);
// static void Rmt_WriteQstStem (const char *Stem);
static void Rmt_WriteAnswersOfAQst (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
struct Game *Game,struct GameQuestion *GameQst);
static unsigned Rmt_GetNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd);
static void Rmt_DrawBarNumUsrs (unsigned NumUsrs,unsigned MaxUsrs);
// static void Rmt_PutIconToRemoveOneQst (void);
@ -2629,273 +2622,6 @@ static void Rmt_RemAnswersOfAQuestion (long QstCod)
DB_QueryDELETE (Query,"can not remove the answers of a question");
}
/*****************************************************************************/
/*********** Convert a string with the answer type to answer type ************/
/*****************************************************************************/
/*
static Rmt_AnswerType_t Rmt_ConvertFromStrAnsTypDBToAnsTyp (const char *StrAnsTypeBD)
{
Rmt_AnswerType_t AnsType;
for (AnsType = (Rmt_AnswerType_t) 0;
AnsType < Rmt_NUM_ANS_TYPES;
AnsType++)
if (!strcmp (StrAnsTypeBD,Rmt_StrAnswerTypesDB[AnsType]))
return AnsType;
return (Rmt_AnswerType_t) 0;
}
*/
/*****************************************************************************/
/*********** Check if an answer of a question exists in database *************/
/*****************************************************************************/
/*
static bool Rmt_CheckIfAnswerExists (long QstCod,unsigned AnsInd)
{
char Query[256];
***** Get answers of a question from database *****
sprintf (Query,"SELECT COUNT(*) FROM gam_answers"
" WHERE QstCod=%ld AND AnsInd=%u",
QstCod,AnsInd);
return (DB_QueryCOUNT (Query,"can not check if an answer exists") != 0);
}
*/
/*****************************************************************************/
/**** Get number of users who selected a given answer of a game question *****/
/*****************************************************************************/
unsigned Rmt_GetNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd)
{
char Query[128];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumUsrs = 0; // Default returned value
/***** Get answers of a question from database *****/
sprintf (Query,"SELECT NumUsrs FROM gam_answers"
" WHERE GamCod=%ld AND QstCod=%ld AND AnsInd=%u",
GamCod,QstCod,AnsInd);
DB_QuerySELECT (Query,&mysql_res,"can not get number of users who answered");
row = mysql_fetch_row (mysql_res);
if (row[0]) // There are users who selected this answer
if (sscanf (row[0],"%u",&NumUsrs) != 1)
Lay_ShowErrorAndExit ("Error when getting number of users who answered.");
return NumUsrs;
}
/*****************************************************************************/
/******************* Allocate memory for a choice answer *********************/
/*****************************************************************************/
/*
static bool Rmt_AllocateTextChoiceAnswer (struct GameQuestion *GameQst,unsigned NumAns)
{
Rmt_FreeTextChoiceAnswer (GameQst,NumAns);
if ((GameQst->AnsChoice[NumAns].Text = malloc (Rmt_MAX_BYTES_ANSWER + 1)) == NULL)
{
sprintf (Gbl.Alert.Txt,"Not enough memory to store answer.");
return false;
}
GameQst->AnsChoice[NumAns].Text[0] = '\0';
return true;
}
*/
/*****************************************************************************/
/******************** Free memory of all choice answers **********************/
/*****************************************************************************/
/*
static void Rmt_FreeTextChoiceAnswers (struct GameQuestion *GameQst,unsigned NumAnswers)
{
unsigned NumAns;
for (NumAns = 0;
NumAns < NumAnswers;
NumAns++)
Rmt_FreeTextChoiceAnswer (GameQst,NumAns);
}
*/
/*****************************************************************************/
/********************** Free memory of a choice answer ***********************/
/*****************************************************************************/
/*
static void Rmt_FreeTextChoiceAnswer (struct GameQuestion *GameQst,unsigned NumAns)
{
if (GameQst->AnsChoice[NumAns].Text)
{
free ((void *) GameQst->AnsChoice[NumAns].Text);
GameQst->AnsChoice[NumAns].Text = NULL;
}
}
*/
/*****************************************************************************/
/************************ Receive a question of a game ***********************/
/*****************************************************************************/
/*
void Rmt_ReceiveQst (void)
{
extern const char *Txt_You_must_type_the_stem_of_the_question;
extern const char *Txt_You_can_not_leave_empty_intermediate_answers;
extern const char *Txt_You_must_type_at_least_the_first_two_answers;
extern const char *Txt_The_game_has_been_modified;
char Txt[Cns_MAX_BYTES_TEXT + 1];
char Query[512 + Cns_MAX_BYTES_TEXT];
struct Game Game;
struct GameQuestion GameQst;
unsigned NumAns;
char AnsStr[8 + 10 + 1];
unsigned NumLastAns;
bool ThereIsEndOfAnswers;
bool Error = false;
***** Initialize new question to zero *****
Rmt_InitQst (&GameQst);
***** Get parameters from form *****
* Get game code *
if ((Game.GamCod = Rmt_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing.");
* Get question code *
GameQst.QstCod = Rmt_GetParamQstCod ();
* Get answer type *
GameQst.AnswerType = (Rmt_AnswerType_t)
Par_GetParToUnsignedLong ("AnswerType",
0,
Rmt_NUM_ANS_TYPES - 1,
(unsigned long) Rmt_ANSWER_TYPE_DEFAULT);
* Get question text *
Par_GetParToHTML ("Txt",Txt,Cns_MAX_BYTES_TEXT);
* Get the texts of the answers *
for (NumAns = 0;
NumAns < Rmt_MAX_ANSWERS_PER_QUESTION;
NumAns++)
{
if (!Rmt_AllocateTextChoiceAnswer (&GameQst,NumAns))
Lay_ShowErrorAndExit (Gbl.Alert.Txt);
sprintf (AnsStr,"AnsStr%u",NumAns);
Par_GetParToHTML (AnsStr,GameQst.AnsChoice[NumAns].Text,Rmt_MAX_BYTES_ANSWER);
}
***** Make sure that stem and answer are not empty *****
if (Txt[0])
{
if (GameQst.AnsChoice[0].Text[0]) // If the first answer has been filled
{
for (NumAns = 0, NumLastAns = 0, ThereIsEndOfAnswers = false;
!Error && NumAns < Rmt_MAX_ANSWERS_PER_QUESTION;
NumAns++)
if (GameQst.AnsChoice[NumAns].Text[0])
{
if (ThereIsEndOfAnswers)
{
Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_leave_empty_intermediate_answers);
Error = true;
}
else
NumLastAns = NumAns;
}
else
ThereIsEndOfAnswers = true;
if (!Error)
{
if (NumLastAns < 1)
{
Ale_ShowAlert (Ale_WARNING,Txt_You_must_type_at_least_the_first_two_answers);
Error = true;
}
}
}
else // If first answer is empty
{
Ale_ShowAlert (Ale_WARNING,Txt_You_must_type_at_least_the_first_two_answers);
Error = true;
}
}
else
{
Ale_ShowAlert (Ale_WARNING,Txt_You_must_type_the_stem_of_the_question);
Error = true;
}
if (Error)
Tst_ShowFormAskSelectTstsForGame (Game.GamCod);
else
{
***** Form is received OK ==> insert question and answer in the database *****
if (GameQst.QstCod < 0) // It's a new question
{
GameQst.QstInd = Rmt_GetNextQuestionIndexInGame (Game.GamCod);
* Insert question in the table of questions *
sprintf (Query,"INSERT INTO gam_questions"
" (GamCod,QstInd,AnsType,Stem)"
" VALUES"
" (%ld,%u,'%s','%s')",
Game.GamCod,GameQst.QstInd,Rmt_StrAnswerTypesDB[GameQst.AnswerType],Txt);
GameQst.QstCod = DB_QueryINSERTandReturnCode (Query,"can not create question");
}
else // It's an existing question
{
* Update question *
sprintf (Query,"UPDATE gam_questions SET Stem='%s',AnsType='%s'"
" WHERE QstCod=%ld AND GamCod=%ld",
Txt,Rmt_StrAnswerTypesDB[GameQst.AnswerType],
GameQst.QstCod,Game.GamCod);
DB_QueryUPDATE (Query,"can not update question");
}
* Insert, update or delete answers in the answers table *
for (NumAns = 0;
NumAns < Rmt_MAX_ANSWERS_PER_QUESTION;
NumAns++)
if (Rmt_CheckIfAnswerExists (GameQst.QstCod,NumAns)) // If this answer exists...
{
if (GameQst.AnsChoice[NumAns].Text[0]) // Answer is not empty
{
* Update answer text *
sprintf (Query,"UPDATE gam_answers SET Answer='%s'"
" WHERE QstCod=%ld AND AnsInd=%u",
GameQst.AnsChoice[NumAns].Text,GameQst.QstCod,NumAns);
DB_QueryUPDATE (Query,"can not update answer");
}
else // Answer is empty
{
* Delete answer from database *
sprintf (Query,"DELETE FROM gam_answers"
" WHERE QstCod=%ld AND AnsInd=%u",
GameQst.QstCod,NumAns);
DB_QueryDELETE (Query,"can not delete answer");
}
}
else // If this answer does not exist...
{
if (GameQst.AnsChoice[NumAns].Text[0]) // Answer is not empty
{
* Create answer into database *
sprintf (Query,"INSERT INTO gam_answers"
" (QstCod,AnsInd,NumUsrs,Answer)"
" VALUES"
" (%ld,%u,0,'%s')",
GameQst.QstCod,NumAns,GameQst.AnsChoice[NumAns].Text);
DB_QueryINSERT (Query,"can not create answer");
}
}
***** List the questions of this game, including the new one just inserted into the database *****
Ale_ShowAlert (Ale_SUCCESS,Txt_The_game_has_been_modified);
}
***** Free answers *****
Rmt_FreeTextChoiceAnswers (&GameQst,Rmt_MAX_ANSWERS_PER_QUESTION);
***** Show current game *****
Rmt_ShowOneGame (Game.GamCod,&GameQst,true);
}
*/
/*****************************************************************************/
/******************** Get next question index in a game **********************/
/*****************************************************************************/
@ -3117,14 +2843,12 @@ static void Rmt_ListOneOrMoreQuestionsForEdition (struct Game *Game,
Act_FormStart (ActReqRemGamQst);
Rmt_PutParamGameCod (Game->GamCod);
Rmt_PutParamQstCod (GameQst->QstCod);
// Tst_PutParamQstCod ();
Ico_PutIconRemove ();
Act_FormEnd ();
/* Write icon to edit the question */
Act_FormStart (ActEdiOneTstQst);
Rmt_PutParamQstCod (GameQst->QstCod);
// Tst_PutParamQstCod ();
fprintf (Gbl.F.Out,"<input type=\"image\" src=\"%s/edit64x64.png\""
" alt=\"%s\" title=\"%s\""
" class=\"ICO20x20\" />",
@ -3169,8 +2893,8 @@ static void Rmt_ListOneOrMoreQuestionsForEdition (struct Game *Game,
"TEST_IMG_EDIT_LIST_STEM_CONTAINER",
"TEST_IMG_EDIT_LIST_STEM");
Tst_WriteQstFeedback (row[3],"TEST_EDI_LIGHT");
// Tst_WriteAnswersEdit (Gbl.Test.QstCod);
Rmt_WriteAnswersOfAQst (Tst_SHOW_GAME_RESULT,Game,GameQst);
Tst_WriteAnswersGameResult (Game,GameQst->QstInd,GameQst->QstCod);
fprintf (Gbl.F.Out,"</td>"
"</tr>");
@ -3326,183 +3050,45 @@ static unsigned Rmt_CountNumQuestionsInList (void)
}
/*****************************************************************************/
/****************** Write the heading of a game question *******************/
/*** Get number of users who selected this answer and draw proportional bar **/
/*****************************************************************************/
/*
static void Rmt_WriteQstStem (const char *Stem)
void Rmt_GetAndDrawBarNumUsrsWhoAnswered (struct Game *Game,long QstCod,unsigned AnsInd)
{
char *HeadingRigorousHTML;
size_t Length;
* Convert the stem, that is in HTML, to rigorous HTML *
Length = strlen (Stem) * Str_MAX_BYTES_PER_CHAR;
if ((HeadingRigorousHTML = malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Not enough memory to store stem of question.");
Str_Copy (HeadingRigorousHTML,Stem,
Length);
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
HeadingRigorousHTML,Length,false);
* Write the stem *
fprintf (Gbl.F.Out,"%s",HeadingRigorousHTML);
* Free memory allocated for the stem *
free ((void *) HeadingRigorousHTML);
}
*/
/*****************************************************************************/
/************** Get and write the answers of a game question ***************/
/*****************************************************************************/
static void Rmt_WriteAnswersOfAQst (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
struct Game *Game,struct GameQuestion *GameQst)
{
extern const char *Txt_Question_removed;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
double ScoreThisQst;
bool AnswerIsNotBlank;
/***** Query database *****/
if (Tst_GetOneQuestionByCod (GameQst->QstCod,&mysql_res)) // Question exists
{
/***** Get row of the result of the query *****/
row = mysql_fetch_row (mysql_res);
/*
row[ 0] QstCod
row[ 1] UNIX_TIMESTAMP(EditTime)
row[ 2] AnsType
row[ 3] Shuffle
row[ 4] Stem
row[ 5] Feedback
row[ 6] ImageName
row[ 7] ImageTitle
row[ 8] ImageURL
row[ 9] NumHits
row[10] NumHitsNotBlank
row[11] Score
*/
/***** Write question and answers *****/
Gbl.Games.CurrentGamCod = Game->GamCod;
Tst_WriteQstAndAnsTest (ActionToDoWithQuestions,
GameQst->QstInd,GameQst->QstCod,row,
&ScoreThisQst,&AnswerIsNotBlank);
}
else
/***** Question does not exists *****/
fprintf (Gbl.F.Out,"<tr>"
"<td class=\"TEST_NUM_QST RIGHT_TOP COLOR%u\">"
"%u"
"</td>"
"<td class=\"DAT_LIGHT LEFT_TOP COLOR%u\">"
"%s"
"</td>"
"</tr>",
Gbl.RowEvenOdd,GameQst->QstInd + 1,
Gbl.RowEvenOdd,Txt_Question_removed);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
/*
unsigned NumAnswers;
unsigned NumAns;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumUsrsThisAnswer;
***** Get answers of this question *****
NumAnswers = Rmt_GetNumUsrsWhoAnswered (GameQst->QstCod,&mysql_res); // Result: AnsInd,NumUsrs,Answer
/***** Get number of users who selected this answer *****/
NumUsrsThisAnswer = Rmt_GetNumUsrsWhoAnswered (Game->GamCod,QstCod,AnsInd);
***** Write the answers *****
if (NumAnswers)
/***** Show stats of this answer *****/
if (Game->Status.ICanViewResults)
Rmt_DrawBarNumUsrs (NumUsrsThisAnswer,Game->NumUsrs);
}
/*****************************************************************************/
/**** Get number of users who selected a given answer of a game question *****/
/*****************************************************************************/
static unsigned Rmt_GetNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd)
{
char Query[256];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumUsrs = 0; // Default returned value
/***** Get answers of a question from database *****/
sprintf (Query,"SELECT NumUsrs FROM gam_answers"
" WHERE GamCod=%ld AND QstCod=%ld AND AnsInd=%u",
GamCod,QstCod,AnsInd);
if (DB_QuerySELECT (Query,&mysql_res,"can not get number of users who answered"))
{
* Check number of answers *
if (NumAnswers > Rmt_MAX_ANSWERS_PER_QUESTION)
Lay_ShowErrorAndExit ("Wrong number of answers.");
* Write one row for each answer *
Tbl_StartTable (5);
for (NumAns = 0;
NumAns < NumAnswers;
NumAns++)
{
row = mysql_fetch_row (mysql_res);
* Get number of users who have marked this answer (row[1]) *
if (sscanf (row[1],"%u",&NumUsrsThisAnswer) != 1)
Lay_ShowErrorAndExit ("Error when getting number of users who have marked an answer.");
* Convert the answer (row[2]), that is in HTML, to rigorous HTML *
if (!Rmt_AllocateTextChoiceAnswer (GameQst,NumAns))
Lay_ShowErrorAndExit (Gbl.Alert.Txt);
Str_Copy (GameQst->AnsChoice[NumAns].Text,row[2],
Rmt_MAX_BYTES_ANSWER);
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
GameQst->AnsChoice[NumAns].Text,Rmt_MAX_BYTES_ANSWER,false);
* Selectors and label with the letter of the answer *
fprintf (Gbl.F.Out,"<tr>");
if (PutFormAnswerGame)
{
* Write selector to choice this answer *
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP\">"
"<input type=\"");
if (GameQst->AnswerType == Rmt_ANS_UNIQUE_CHOICE)
fprintf (Gbl.F.Out,"radio\""
" onclick=\"selectUnselectRadio(this,this.form.Ans%010u,%u)\"",
(unsigned) GameQst->QstCod,NumAnswers);
else // GameQst->AnswerType == Rmt_ANS_MULTIPLE_CHOICE
fprintf (Gbl.F.Out,"checkbox\"");
fprintf (Gbl.F.Out," id=\"Ans%010u_%010u\" name=\"Ans%010u\""
" value=\"%u\" />"
"</td>",
(unsigned) GameQst->QstCod,NumAns,(unsigned) GameQst->QstCod,
NumAns);
}
* Write the number of option *
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP\" style=\"width:50px;\">"
"<label for=\"Ans%010u_%010u\" class=\"DAT\">"
"%u)"
"</label>"
"</td>",
(unsigned) GameQst->QstCod,NumAns,NumAns + 1);
* Write the text of the answer *
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP\">"
"<label for=\"Ans%010u_%010u\" class=\"DAT\">%s</label>"
"</td>",
(unsigned) GameQst->QstCod,NumAns,
GameQst->AnsChoice[NumAns].Text);
* Show stats of this answer *
if (Game->Status.ICanViewResults)
Rmt_DrawBarNumUsrs (NumUsrsThisAnswer,Game->NumUsrs);
fprintf (Gbl.F.Out,"</tr>");
* Free memory allocated for the answer *
Rmt_FreeTextChoiceAnswer (GameQst,NumAns);
}
Tbl_EndTable ();
row = mysql_fetch_row (mysql_res);
if (row[0]) // There are users who selected this answer
if (sscanf (row[0],"%u",&NumUsrs) != 1)
Lay_ShowErrorAndExit ("Error when getting number of users who answered.");
}
***** Free structure that stores the query result *****
DB_FreeMySQLResult (&mysql_res);
*/
return NumUsrs;
}
/*****************************************************************************/
@ -3545,9 +3131,7 @@ static void Rmt_DrawBarNumUsrs (unsigned NumUsrs,unsigned MaxUsrs)
BarWidth);
/***** Write the number of users *****/
fprintf (Gbl.F.Out,"%s</td>"
"</tr>",
Gbl.Title);
fprintf (Gbl.F.Out,"%s</td>",Gbl.Title);
}
/*****************************************************************************/

View File

@ -113,7 +113,7 @@ void Rmt_RemoveGames (Sco_Scope_t Scope,long Cod);
void Rmt_RequestEditQuestion (void);
// void Rmt_ReceiveQst (void);
unsigned Rmt_GetNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd);
void Rmt_GetAndDrawBarNumUsrsWhoAnswered (struct Game *Game,long QstCod,unsigned AnsInd);
void Rmt_AddTstQuestionsToGame (void);

View File

@ -194,7 +194,6 @@ static void Tst_WriteAnswersEdit (long QstCod);
static void Tst_WriteAnswersTestToAnswer (unsigned NumQst,long QstCod,bool Shuffle);
static void Tst_WriteAnswersTestResult (unsigned NumQst,long QstCod,
double *ScoreThisQst,bool *AnswerIsNotBlank);
static void Tst_WriteAnswersGameResult (unsigned NumQst,long QstCod);
static void Tst_WriteTFAnsViewTest (unsigned NumQst);
static void Tst_WriteTFAnsAssessTest (unsigned NumQst,MYSQL_RES *mysql_res,
@ -203,7 +202,7 @@ static void Tst_WriteTFAnsAssessTest (unsigned NumQst,MYSQL_RES *mysql_res,
static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,bool Shuffle);
static void Tst_WriteChoiceAnsAssessTest (unsigned NumQst,MYSQL_RES *mysql_res,
double *ScoreThisQst,bool *AnswerIsNotBlank);
static void Tst_WriteChoiceAnsViewGame (unsigned NumQst,long QstCod);
static void Tst_WriteChoiceAnsViewGame (struct Game *Game,unsigned NumQst,long QstCod);
static void Tst_WriteTextAnsViewTest (unsigned NumQst);
static void Tst_WriteTextAnsAssessTest (unsigned NumQst,MYSQL_RES *mysql_res,
@ -833,7 +832,7 @@ static void Tst_ShowTestQuestionsWhenSeeing (MYSQL_RES *mysql_res)
Lay_ShowErrorAndExit ("Wrong code of question.");
Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_TO_ANSWER,
NumQst,QstCod,row,
NULL,NumQst,QstCod,row,
&ScoreThisQst, // Not used here
&AnswerIsNotBlank); // Not used here
}
@ -934,7 +933,7 @@ static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank
/***** Write question and answers *****/
Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_RESULT,
NumQst,QstCod,row,
NULL,NumQst,QstCod,row,
&ScoreThisQst,&AnswerIsNotBlank);
/***** Store test result question in database *****/
@ -974,6 +973,7 @@ static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank
/*****************************************************************************/
void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
struct Game *Game,
unsigned NumQst,long QstCod,MYSQL_ROW row,
double *ScoreThisQst,bool *AnswerIsNotBlank)
{
@ -1041,7 +1041,7 @@ void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestio
Tst_WriteAnswersTestToAnswer (NumQst,QstCod,(row[3][0] == 'Y'));
break;
case Tst_SHOW_GAME_RESULT:
Tst_WriteAnswersGameResult (NumQst,QstCod);
Tst_WriteAnswersGameResult (Game,NumQst,QstCod);
break;
}
fprintf (Gbl.F.Out,"</td>"
@ -3545,7 +3545,7 @@ static void Tst_WriteAnswersTestResult (unsigned NumQst,long QstCod,
/************** Write answers of a question when viewing a game **************/
/*****************************************************************************/
static void Tst_WriteAnswersGameResult (unsigned NumQst,long QstCod)
void Tst_WriteAnswersGameResult (struct Game *Game,unsigned NumQst,long QstCod)
{
/***** Write parameter with question code *****/
Tst_WriteParamQstCod (NumQst,QstCod);
@ -3561,7 +3561,7 @@ static void Tst_WriteAnswersGameResult (unsigned NumQst,long QstCod)
break;
case Tst_ANS_UNIQUE_CHOICE:
case Tst_ANS_MULTIPLE_CHOICE:
Tst_WriteChoiceAnsViewGame (NumQst,QstCod);
Tst_WriteChoiceAnsViewGame (Game,NumQst,QstCod);
break;
default:
break;
@ -4045,12 +4045,12 @@ static void Tst_WriteChoiceAnsAssessTest (unsigned NumQst,MYSQL_RES *mysql_res,
/******** Write single or multiple choice answer when viewing a test *********/
/*****************************************************************************/
static void Tst_WriteChoiceAnsViewGame (unsigned NumQst,long QstCod)
static void Tst_WriteChoiceAnsViewGame (struct Game *Game,unsigned NumQst,long QstCod)
{
unsigned NumOpt;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned Index;
unsigned AnsInd;
bool ErrorInIndex = false;
/***** Get answers of a question from database *****/
@ -4082,9 +4082,9 @@ static void Tst_WriteChoiceAnsViewGame (unsigned NumQst,long QstCod)
/***** Assign index (row[0]).
Index is 0,1,2,3... if no shuffle
or 1,3,0,2... (example) if shuffle *****/
if (sscanf (row[0],"%u",&Index) == 1)
if (sscanf (row[0],"%u",&AnsInd) == 1)
{
if (Index >= Tst_MAX_OPTIONS_PER_QUESTION)
if (AnsInd >= Tst_MAX_OPTIONS_PER_QUESTION)
ErrorInIndex = true;
}
else
@ -4122,8 +4122,11 @@ static void Tst_WriteChoiceAnsViewGame (unsigned NumQst,long QstCod)
Img_ShowImage (&Gbl.Test.Answer.Options[NumOpt].Image,
"TEST_IMG_SHOW_ANS_CONTAINER",
"TEST_IMG_SHOW_ANS");
fprintf (Gbl.F.Out,"</td>"
"</tr>");
fprintf (Gbl.F.Out,"</td>");
/* Get number of users who selected this answer and draw proportional bar */
Rmt_GetAndDrawBarNumUsrsWhoAnswered (Game,QstCod,AnsInd);
fprintf (Gbl.F.Out,"</tr>");
}
/***** End table *****/
@ -8311,7 +8314,7 @@ static void Tst_ShowTestResult (time_t TstTimeUTC)
/***** Write questions and answers *****/
Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_RESULT,
NumQst,QstCod,row,
NULL,NumQst,QstCod,row,
&ScoreThisQst, // Not used here
&AnswerIsNotBlank); // Not used here
}

View File

@ -27,6 +27,8 @@
/********************************* Headers ***********************************/
/*****************************************************************************/
#include "swad_remote_control.h"
/*****************************************************************************/
/***************************** Public constants ******************************/
/*****************************************************************************/
@ -143,6 +145,7 @@ void Tst_ShowNewTest (void);
void Tst_AssessTest (void);
void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
struct Game *Game,
unsigned NumQst,long QstCod,MYSQL_ROW row,
double *ScoreThisQst,bool *AnswerIsNotBlank);
void Tst_WriteQstStem (const char *Stem,const char *ClassStem);
@ -156,6 +159,7 @@ void Tst_ListQuestionsToSelect (void);
bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res);
void Tst_WriteParamEditQst (void);
unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle);
void Tst_WriteAnswersGameResult (struct Game *Game,unsigned NumQst,long QstCod);
void Tst_WriteAnsTF (char AnsTF);
void Tst_CheckIfNumberOfAnswersIsOne (void);