diff --git a/sql/swad.sql b/sql/swad.sql index 37f04cf97..1580e0140 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -613,14 +613,14 @@ CREATE TABLE IF NOT EXISTS games ( UNIQUE INDEX(GamCod), INDEX(CrsCod)); -- --- Table gam_answers: stores the answers to the games +-- Table gam_answers: stores the answers to the matches -- CREATE TABLE IF NOT EXISTS gam_answers ( GamCod INT NOT NULL, - QstCod INT NOT NULL, + QstInd INT NOT NULL, AnsInd TINYINT NOT NULL, NumUsrs INT NOT NULL DEFAULT 0, - UNIQUE INDEX(GamCod,QstCod,AnsInd)); + UNIQUE INDEX(GamCod,QstInd,AnsInd)); -- -- Table gam_grp: stores the groups associated to each match in a game -- diff --git a/swad_action.c b/swad_action.c index 5bdc4fc0f..e18f09324 100644 --- a/swad_action.c +++ b/swad_action.c @@ -608,10 +608,11 @@ Assessment: 455. ActFrmNewMch Put form to create a new match (by a teacher) NEW. ActReqRemMch Request the removal of a match (by a teacher) NEW. ActRemMch Confirm the removal of a match (by a teacher) - 456. ActGamTch1stQst Show first question when playing a game (by a teacher) + 456. ActNewMch Create a new match showing first question in a new browser tab (by a teacher) + NEW. ActResMch Resume an unfinished match showing current question in a new browser tab (by a teacher) 457. ActGamTchNxtQst Show next question when playing a game (by a teacher) 458. ActGamTchAns Show answers of current question when playing a game (by a teacher) - NEW. ActGamTchEnd End playing a game (by a teacher) + NEW. ActEndMch Finish a match (by a teacher) NEW. ActPlyMchStd Play a game (by a student) NEW. ActGamStdCurQst Show current question when playing a game (by a student) @@ -2146,10 +2147,11 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActFrmNewMch */{1670,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestNewMatch ,NULL}, /* ActReqRemMch */{1783,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestRemoveMatch ,NULL}, /* ActRemMch */{1784,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RemoveMatch ,NULL}, - /* ActGamTch1stQst */{1671,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_CreateAndStartNewMatch ,NULL}, + /* ActNewMch */{1671,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_CreateAndStartNewMatch ,NULL}, + /* ActResMch */{1785,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_ResumeUnfinishedMatch ,NULL}, /* ActGamTchNxtQst */{1672,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchNextQuestion ,NULL}, /* ActGamTchAns */{1673,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchShowAnswers ,NULL}, - /* ActGamTchEnd */{1781,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchEnd ,NULL}, + /* ActEndMch */{1781,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchEnd ,NULL}, /* ActPlyMchStd */{1779,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_PlayMatchStd ,NULL}, /* ActGamStdCurQst */{1780,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,Gam_GetMatchBeingPlayed ,Gam_ShowNewMatchToMeAsStd ,NULL}, @@ -4876,7 +4878,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActUp_GamQst, // #1668 ActDwnGamQst, // #1669 ActFrmNewMch, // #1670 - ActGamTch1stQst, // #1671 + ActNewMch, // #1671 ActGamTchNxtQst, // #1672 ActGamTchAns, // #1673 ActSeePrj, // #1674 @@ -4986,10 +4988,11 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActUnlAllPrj, // #1778 ActPlyMchStd, // #1779 ActGamStdCurQst, // #1780 - ActGamTchEnd, // #1781 + ActEndMch, // #1781 ActRefGamStd, // #1782 ActReqRemMch, // #1783 ActRemMch, // #1784 + ActResMch, // #1785 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index e85831605..72ee58007 100644 --- a/swad_action.h +++ b/swad_action.h @@ -64,9 +64,9 @@ typedef enum typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action -#define Act_NUM_ACTIONS (1 + 4 + 64 + 38 + 12 + 42 + 36 + 19 + 110 + 169 + 437 + 176 + 169 + 16 + 67) +#define Act_NUM_ACTIONS (1 + 4 + 64 + 38 + 12 + 42 + 36 + 19 + 110 + 170 + 437 + 176 + 169 + 16 + 67) -#define Act_MAX_ACTION_COD 1784 +#define Act_MAX_ACTION_COD 1785 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 @@ -610,58 +610,59 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActFrmNewMch (ActChgCrsTT1stDay + 117) #define ActReqRemMch (ActChgCrsTT1stDay + 118) #define ActRemMch (ActChgCrsTT1stDay + 119) -#define ActGamTch1stQst (ActChgCrsTT1stDay + 120) -#define ActGamTchNxtQst (ActChgCrsTT1stDay + 121) -#define ActGamTchAns (ActChgCrsTT1stDay + 122) -#define ActGamTchEnd (ActChgCrsTT1stDay + 123) -#define ActPlyMchStd (ActChgCrsTT1stDay + 124) -#define ActGamStdCurQst (ActChgCrsTT1stDay + 125) -#define ActRefGamStd (ActChgCrsTT1stDay + 126) -#define ActAnsGam (ActChgCrsTT1stDay + 127) -#define ActFrmNewGam (ActChgCrsTT1stDay + 128) -#define ActEdiOneGam (ActChgCrsTT1stDay + 129) -#define ActNewGam (ActChgCrsTT1stDay + 130) -#define ActChgGam (ActChgCrsTT1stDay + 131) -#define ActReqRemGam (ActChgCrsTT1stDay + 132) -#define ActRemGam (ActChgCrsTT1stDay + 133) -#define ActReqRstGam (ActChgCrsTT1stDay + 134) -#define ActRstGam (ActChgCrsTT1stDay + 135) -#define ActHidGam (ActChgCrsTT1stDay + 136) -#define ActShoGam (ActChgCrsTT1stDay + 137) -#define ActAddOneGamQst (ActChgCrsTT1stDay + 138) -#define ActGamLstTstQst (ActChgCrsTT1stDay + 139) -#define ActAddTstQstToGam (ActChgCrsTT1stDay + 140) -#define ActReqRemGamQst (ActChgCrsTT1stDay + 141) -#define ActRemGamQst (ActChgCrsTT1stDay + 142) -#define ActUp_GamQst (ActChgCrsTT1stDay + 143) -#define ActDwnGamQst (ActChgCrsTT1stDay + 144) +#define ActNewMch (ActChgCrsTT1stDay + 120) +#define ActResMch (ActChgCrsTT1stDay + 121) +#define ActGamTchNxtQst (ActChgCrsTT1stDay + 122) +#define ActGamTchAns (ActChgCrsTT1stDay + 123) +#define ActEndMch (ActChgCrsTT1stDay + 124) +#define ActPlyMchStd (ActChgCrsTT1stDay + 125) +#define ActGamStdCurQst (ActChgCrsTT1stDay + 126) +#define ActRefGamStd (ActChgCrsTT1stDay + 127) +#define ActAnsGam (ActChgCrsTT1stDay + 128) +#define ActFrmNewGam (ActChgCrsTT1stDay + 129) +#define ActEdiOneGam (ActChgCrsTT1stDay + 130) +#define ActNewGam (ActChgCrsTT1stDay + 131) +#define ActChgGam (ActChgCrsTT1stDay + 132) +#define ActReqRemGam (ActChgCrsTT1stDay + 133) +#define ActRemGam (ActChgCrsTT1stDay + 134) +#define ActReqRstGam (ActChgCrsTT1stDay + 135) +#define ActRstGam (ActChgCrsTT1stDay + 136) +#define ActHidGam (ActChgCrsTT1stDay + 137) +#define ActShoGam (ActChgCrsTT1stDay + 138) +#define ActAddOneGamQst (ActChgCrsTT1stDay + 139) +#define ActGamLstTstQst (ActChgCrsTT1stDay + 140) +#define ActAddTstQstToGam (ActChgCrsTT1stDay + 141) +#define ActReqRemGamQst (ActChgCrsTT1stDay + 142) +#define ActRemGamQst (ActChgCrsTT1stDay + 143) +#define ActUp_GamQst (ActChgCrsTT1stDay + 144) +#define ActDwnGamQst (ActChgCrsTT1stDay + 145) -#define ActSeeSvy (ActChgCrsTT1stDay + 145) -#define ActAnsSvy (ActChgCrsTT1stDay + 146) -#define ActFrmNewSvy (ActChgCrsTT1stDay + 147) -#define ActEdiOneSvy (ActChgCrsTT1stDay + 148) -#define ActNewSvy (ActChgCrsTT1stDay + 149) -#define ActChgSvy (ActChgCrsTT1stDay + 150) -#define ActReqRemSvy (ActChgCrsTT1stDay + 151) -#define ActRemSvy (ActChgCrsTT1stDay + 152) -#define ActReqRstSvy (ActChgCrsTT1stDay + 153) -#define ActRstSvy (ActChgCrsTT1stDay + 154) -#define ActHidSvy (ActChgCrsTT1stDay + 155) -#define ActShoSvy (ActChgCrsTT1stDay + 156) -#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 157) -#define ActRcvSvyQst (ActChgCrsTT1stDay + 158) -#define ActReqRemSvyQst (ActChgCrsTT1stDay + 159) -#define ActRemSvyQst (ActChgCrsTT1stDay + 160) +#define ActSeeSvy (ActChgCrsTT1stDay + 146) +#define ActAnsSvy (ActChgCrsTT1stDay + 147) +#define ActFrmNewSvy (ActChgCrsTT1stDay + 148) +#define ActEdiOneSvy (ActChgCrsTT1stDay + 149) +#define ActNewSvy (ActChgCrsTT1stDay + 150) +#define ActChgSvy (ActChgCrsTT1stDay + 151) +#define ActReqRemSvy (ActChgCrsTT1stDay + 152) +#define ActRemSvy (ActChgCrsTT1stDay + 153) +#define ActReqRstSvy (ActChgCrsTT1stDay + 154) +#define ActRstSvy (ActChgCrsTT1stDay + 155) +#define ActHidSvy (ActChgCrsTT1stDay + 156) +#define ActShoSvy (ActChgCrsTT1stDay + 157) +#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 158) +#define ActRcvSvyQst (ActChgCrsTT1stDay + 159) +#define ActReqRemSvyQst (ActChgCrsTT1stDay + 160) +#define ActRemSvyQst (ActChgCrsTT1stDay + 161) -#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 161) -#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 162) -#define ActEdiExaAnn (ActChgCrsTT1stDay + 163) -#define ActRcvExaAnn (ActChgCrsTT1stDay + 164) -#define ActPrnExaAnn (ActChgCrsTT1stDay + 165) -#define ActReqRemExaAnn (ActChgCrsTT1stDay + 166) -#define ActRemExaAnn (ActChgCrsTT1stDay + 167) -#define ActHidExaAnn (ActChgCrsTT1stDay + 168) -#define ActShoExaAnn (ActChgCrsTT1stDay + 169) +#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 162) +#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 163) +#define ActEdiExaAnn (ActChgCrsTT1stDay + 164) +#define ActRcvExaAnn (ActChgCrsTT1stDay + 165) +#define ActPrnExaAnn (ActChgCrsTT1stDay + 166) +#define ActReqRemExaAnn (ActChgCrsTT1stDay + 167) +#define ActRemExaAnn (ActChgCrsTT1stDay + 168) +#define ActHidExaAnn (ActChgCrsTT1stDay + 169) +#define ActShoExaAnn (ActChgCrsTT1stDay + 170) /*****************************************************************************/ /******************************** Files tab **********************************/ diff --git a/swad_changelog.h b/swad_changelog.h index 3bd0cc04a..01680a2c7 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -432,6 +432,8 @@ Lo de mutear anuncios, en principio prefiero hacer una opci // TODO: En Actividades, en Juegos, en Encuestas, en Asistencia poner filtros de Pasados (rojo), Actuales (verde), Futuros (azul). // Pensar si en Agenda se puede poner igual. +// TODO: Cambiar QstInd al rango 1,2,3... (código especial 0 en lugar de -1) en swad_survey + /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ @@ -451,10 +453,31 @@ En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 18.125 (2019-05-29)" +#define Log_PLATFORM_VERSION "SWAD 18.126.1 (2019-05-29)" #define CSS_FILE "swad18.123.css" #define JS_FILE "swad18.123.js" /* + Version 18.126.1: May 30, 2019 New option to resume an unfinished match. (243415 lines) + 11 changes necessary in database: +UPDATE actions SET Txt='Preparar partida (como profesor)' WHERE ActCod='1670' AND Language='es'; +UPDATE actions SET Txt='Comenzar partida (como profesor)' WHERE ActCod='1671' AND Language='es'; +UPDATE actions SET Txt='Mostrar siguiente pregunta en partida (como profesor)' WHERE ActCod='1672' AND Language='es'; +UPDATE actions SET Txt='Mostrar respuestas de pregunta en partida (como profesor)' WHERE ActCod='1673' AND Language='es'; +UPDATE actions SET Txt='Prepararse a jugar (como estudiante)' WHERE ActCod='1779' AND Language='es'; +UPDATE actions SET Txt='Unirse a partida (como estudiante)' WHERE ActCod='1780' AND Language='es'; +UPDATE actions SET Txt='Finalizar partida (como profesor)' WHERE ActCod='1781' AND Language='es'; +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1782','es','N','Refrescar partida (como estudiante)'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1783','es','N','Solicitar eliminar partida (como profesor)'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1784','es','N','Eliminar partida (como profesor)'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1785','es','N','Reanudar partida (como profesor)'); + + Version 18.126: May 30, 2019 Question index range changes from 0,1,2... to 1,2,3... (? lines) + 2 changes necessary in database: +UPDATE gam_questions SET QstInd=QstInd+1; +UPDATE gam_matches SET QstInd=QstInd+1; +DROP TABLE gam_answers; +CREATE TABLE IF NOT EXISTS gam_answers (GamCod INT NOT NULL,QstInd INT NOT NULL,AnsInd TINYINT NOT NULL,NumUsrs INT NOT NULL DEFAULT 0,UNIQUE INDEX(GamCod,QstInd,AnsInd)); + Version 18.125: May 29, 2019 Unification of tables of matches (saved and current) into one table. (243371 lines) 2 changes necessary in database: DROP TABLE gam_matches; diff --git a/swad_database.c b/swad_database.c index 503aa02de..990666e4c 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1341,18 +1341,18 @@ mysql> DESCRIBE gam_answers; | Field | Type | Null | Key | Default | Extra | +---------+------------+------+-----+---------+-------+ | GamCod | int(11) | NO | PRI | NULL | | -| QstCod | int(11) | NO | PRI | NULL | | +| QstInd | int(11) | NO | PRI | NULL | | | AnsInd | tinyint(4) | NO | PRI | NULL | | | NumUsrs | int(11) | NO | | 0 | | +---------+------------+------+-----+---------+-------+ -4 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," + "QstInd INT NOT NULL," "AnsInd TINYINT NOT NULL," "NumUsrs INT NOT NULL DEFAULT 0," - "UNIQUE INDEX(GamCod,QstCod,AnsInd))"); + "UNIQUE INDEX(GamCod,QstInd,AnsInd))"); /***** Table gam_grp *****/ /* diff --git a/swad_game.c b/swad_game.c index 42a567437..0464192c1 100644 --- a/swad_game.c +++ b/swad_game.c @@ -87,7 +87,7 @@ struct Match char Title[Gam_MAX_BYTES_TITLE + 1]; struct { - int QstInd; + unsigned QstInd; // 0 means that the game has not started. First question has index 0. long QstCod; time_t QstStartTimeUTC; bool ShowAnswers; @@ -100,8 +100,8 @@ struct Match /*****************************************************************************/ long Gam_CurrentGamCod = -1L; // Used as parameter in contextual links -long Gam_CurrentQstCod = -1L; // Used as parameter in contextual links long Gam_CurrentMchCod = -1L; // Used as parameter in contextual links +unsigned Gam_CurrentQstInd = 0; // Used as parameter in contextual links /*****************************************************************************/ /***************************** Private prototypes ****************************/ @@ -139,17 +139,15 @@ static void Gam_GetAndWriteNamesOfGrpsAssociatedToMatch (struct Match *Match); static bool Gam_CheckIfIPlayThisMatchBasedOnGrps (long GamCod); static unsigned Gam_GetNumQstsGame (long GamCod); -static void Gam_PutParamQstCod (long QstCod); -static long Gam_GetParamQstCod (void); static void Gam_PutParamQstInd (unsigned QstInd); static unsigned Gam_GetParamQstInd (void); -static void Gam_RemAnswersOfAQuestion (long QstCod); +static unsigned Gam_GetQstIndFromStr (const char *UnsignedStr); +static void Gam_RemAnswersOfAQuestion (long GamCod,unsigned QstInd); -static int Gam_GetQstIndFromQstCod (long GamCod,long QstCod); // TODO: Remove this function because a question code can be repeated static long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd); -static int Gam_GetMaxQuestionIndexInGame (long GamCod); -static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd); -static int Gam_GetNextQuestionIndexInGame (long GamCod,int QstInd); +static unsigned Gam_GetMaxQuestionIndexInGame (long GamCod); +static unsigned Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd); +static unsigned Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd); static void Gam_ListGameQuestions (struct Game *Game); static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, MYSQL_RES *mysql_res); @@ -160,7 +158,7 @@ static void Gam_AllocateListSelectedQuestions (void); static void Gam_FreeListsSelectedQuestions (void); static unsigned Gam_CountNumQuestionsInList (void); -static unsigned Gam_GetNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd); +static unsigned Gam_GetNumUsrsWhoAnswered (long GamCod,unsigned QstInd,unsigned AnsInd); static void Gam_DrawBarNumUsrs (unsigned NumUsrs,unsigned MaxUsrs); static void Gam_PutParamsOneQst (void); @@ -188,7 +186,7 @@ static void Gam_PlayGameShowQuestionAndAnswers (long MchCod, bool ShowAnswers); static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, long MchCod,unsigned QstInd); -static void Gam_PutBigButtonToEnd (long GamCod); +static void Gam_PutBigButtonToFinishMatch (long GamCod); static void Gam_ShowQuestionBeingPlayed (struct Match *Match); @@ -1944,24 +1942,6 @@ void Gam_RequestNewQuestion (void) false); // Do not put button to play } -/*****************************************************************************/ -/****************** Write parameter with code of question ********************/ -/*****************************************************************************/ - -static void Gam_PutParamQstCod (long QstCod) - { - Par_PutHiddenParamLong ("QstCod",QstCod); - } - -/*****************************************************************************/ -/******************* Get parameter with code of question *********************/ -/*****************************************************************************/ - -static long Gam_GetParamQstCod (void) - { - return Par_GetParToLong ("QstCod"); - } - /*****************************************************************************/ /****************** Write parameter with index of question *******************/ /*****************************************************************************/ @@ -1977,55 +1957,39 @@ static void Gam_PutParamQstInd (unsigned QstInd) static unsigned Gam_GetParamQstInd (void) { - long LongInt; + long LongNum; - LongInt = Par_GetParToLong ("QstInd"); - if (LongInt < 0) + LongNum = Par_GetParToLong ("QstInd"); + if (LongNum < 0) Lay_ShowErrorAndExit ("Wrong question index."); - return (unsigned) LongInt; + return (unsigned) LongNum; + } + +/*****************************************************************************/ +/******************* Get parameter with index of question ********************/ +/*****************************************************************************/ + +static unsigned Gam_GetQstIndFromStr (const char *UnsignedStr) + { + long LongNum; + + LongNum = Str_ConvertStrCodToLongCod (UnsignedStr); + return (LongNum > 0) ? (unsigned) LongNum : + 0; } /*****************************************************************************/ /********************** Remove answers of a game question ********************/ /*****************************************************************************/ -static void Gam_RemAnswersOfAQuestion (long QstCod) +static void Gam_RemAnswersOfAQuestion (long GamCod,unsigned QstInd) { /***** Remove answers *****/ DB_QueryDELETE ("can not remove the answers of a question", - "DELETE FROM gam_answers WHERE QstCod=%ld", - QstCod); - } - -/*****************************************************************************/ -/******************** Get next question index in a game **********************/ -/*****************************************************************************/ -// TODO: Remove this function because a question code can be repeated - -static int Gam_GetQstIndFromQstCod (long GamCod,long QstCod) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - int QstInd = -1; - - /***** Get number of games with a field value from database *****/ - if (!DB_QuerySELECT (&mysql_res,"can not get question index", - "SELECT QstInd FROM gam_questions" - " WHERE GamCod=%ld AND QstCod=%ld", - GamCod,QstCod)) - Lay_ShowErrorAndExit ("Error when getting question index."); - - /***** Get question index (row[0]) *****/ - row = mysql_fetch_row (mysql_res); - if (row[0]) - if (sscanf (row[0],"%d",&QstInd) != 1) - Lay_ShowErrorAndExit ("Error when getting question index."); - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - - return QstInd; + "DELETE FROM gam_answers" + " WHERE GamCod=%ld AND QstInd=%u", + GamCod,QstInd); } /*****************************************************************************/ @@ -2059,14 +2023,14 @@ static long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd) /*****************************************************************************/ /****************** Get maximum question index in a game *********************/ /*****************************************************************************/ -// Question index can be 0, 1, 2,... -// Return -1 if no questions +// Question index can be 1, 2, 3... +// Return 0 if no questions -static int Gam_GetMaxQuestionIndexInGame (long GamCod) +static unsigned Gam_GetMaxQuestionIndexInGame (long GamCod) { MYSQL_RES *mysql_res; MYSQL_ROW row; - int QstInd = -1; + unsigned QstInd = 0; /***** Get maximum question index in a game from database *****/ DB_QuerySELECT (&mysql_res,"can not get last question index", @@ -2074,7 +2038,7 @@ static int Gam_GetMaxQuestionIndexInGame (long GamCod) GamCod); row = mysql_fetch_row (mysql_res); if (row[0]) // There are questions - if (sscanf (row[0],"%d",&QstInd) != 1) + if (sscanf (row[0],"%u",&QstInd) != 1) Lay_ShowErrorAndExit ("Error when getting last question index."); /***** Free structure that stores the query result *****/ @@ -2086,28 +2050,28 @@ static int Gam_GetMaxQuestionIndexInGame (long GamCod) /*****************************************************************************/ /*********** Get previous question index to a given index in a game **********/ /*****************************************************************************/ -// Question index can be 0, 1, 2,... -// Return -1 if no previous question +// Question index can be 1, 2, 3... +// Return 0 if no previous question -static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd) +static unsigned Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd) { MYSQL_RES *mysql_res; MYSQL_ROW row; - int PrevQstInd = -1; + unsigned PrevQstInd = 0; /***** Get previous question index in a game from database *****/ // Although indexes are always continuous... // ...this implementation works even with non continuous indexes if (!DB_QuerySELECT (&mysql_res,"can not get previous question index", "SELECT MAX(QstInd) FROM gam_questions" - " WHERE GamCod=%ld AND QstInd<%d", + " WHERE GamCod=%ld AND QstInd<%u", GamCod,QstInd)) Lay_ShowErrorAndExit ("Error: previous question index not found."); /***** Get previous question index (row[0]) *****/ row = mysql_fetch_row (mysql_res); if (row[0]) - if (sscanf (row[0],"%d",&PrevQstInd) != 1) + if (sscanf (row[0],"%u",&PrevQstInd) != 1) Lay_ShowErrorAndExit ("Error when getting previous question index."); /***** Free structure that stores the query result *****/ @@ -2119,28 +2083,28 @@ static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd) /*****************************************************************************/ /************* Get next question index to a given index in a game ************/ /*****************************************************************************/ -// Question index can be 0, 1, 2,... -// Return -1 if no next question +// Question index can be 1, 2, 3... +// Return 0 if no next question -static int Gam_GetNextQuestionIndexInGame (long GamCod,int QstInd) +static unsigned Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd) { MYSQL_RES *mysql_res; MYSQL_ROW row; - int NextQstInd = -1; + unsigned NextQstInd = 0; /***** Get next question index in a game from database *****/ // Although indexes are always continuous... // ...this implementation works even with non continuous indexes if (!DB_QuerySELECT (&mysql_res,"can not get next question index", "SELECT MIN(QstInd) FROM gam_questions" - " WHERE GamCod=%ld AND QstInd>%d", + " WHERE GamCod=%ld AND QstInd>%u", GamCod,QstInd)) Lay_ShowErrorAndExit ("Error: next question index not found."); /***** Get next question index (row[0]) *****/ row = mysql_fetch_row (mysql_res); if (row[0]) - if (sscanf (row[0],"%d",&NextQstInd) != 1) + if (sscanf (row[0],"%u",&NextQstInd) != 1) Lay_ShowErrorAndExit ("Error when getting next question index."); /***** Free structure that stores the query result *****/ @@ -2173,11 +2137,12 @@ static void Gam_ListGameQuestions (struct Game *Game) /***** Get data of questions from database *****/ NumQsts = (unsigned) DB_QuerySELECT (&mysql_res,"can not get data of a question", - "SELECT tst_questions.QstCod," // row[0] - "tst_questions.AnsType," // row[1] - "tst_questions.Stem," // row[2] - "tst_questions.Feedback," // row[3] - "tst_questions.MedCod" // row[4] + "SELECT gam_questions.QstInd," // row[0] + "gam_questions.QstCod," // row[1] + "tst_questions.AnsType," // row[2] + "tst_questions.Stem," // row[3] + "tst_questions.Feedback," // row[4] + "tst_questions.MedCod" // row[5] " FROM gam_questions,tst_questions" " WHERE gam_questions.GamCod=%ld" " AND gam_questions.QstCod=tst_questions.QstCod" @@ -2238,9 +2203,13 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES]; unsigned NumQst; MYSQL_ROW row; - unsigned UniqueId; + unsigned QstInd; + unsigned MaxQstInd; long QstCod; - char StrNumQst[10 + 1]; + char StrQstInd[10 + 1]; + + /***** Get maximum question index *****/ + MaxQstInd = Gam_GetMaxQuestionIndexInGame (GamCod); /***** Write the heading *****/ Tbl_StartTableWideMargin (2); @@ -2265,50 +2234,52 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, Txt_Question); /***** Write rows *****/ - for (NumQst = 0, UniqueId = 1; + for (NumQst = 0; NumQst < NumQsts; - NumQst++, UniqueId++) + NumQst++) { Gbl.RowEvenOdd = NumQst % 2; - snprintf (StrNumQst,sizeof (StrNumQst), - "%u", - NumQst + 1); - row = mysql_fetch_row (mysql_res); /* - row[0] QstCod - row[1] AnsType - row[2] Stem - row[3] Feedback - row[4] MedCod + row[0] QstInd + row[1] QstCod + row[2] AnsType + row[3] Stem + row[4] Feedback + row[5] MedCod */ /***** Create test question *****/ Tst_QstConstructor (); - /* row[0] holds the code of the question */ - if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) - Lay_ShowErrorAndExit ("Wrong code of question."); + /* Get question index (row[0]) */ + QstInd = Gam_GetQstIndFromStr (row[0]); + snprintf (StrQstInd,sizeof (StrQstInd), + "%u", + QstInd); + + /* Get question code (row[1]) */ + QstCod = Str_ConvertStrCodToLongCod (row[1]); /***** Icons *****/ Gam_CurrentGamCod = GamCod; - Gam_CurrentQstCod = QstCod; + Gam_CurrentQstInd = QstInd; fprintf (Gbl.F.Out,"