diff --git a/sql/swad.sql b/sql/swad.sql index cebb54749..6156d98a9 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -622,23 +622,35 @@ CREATE TABLE IF NOT EXISTS gam_answers ( NumUsrs INT NOT NULL DEFAULT 0, UNIQUE INDEX(GamCod,QstCod,AnsInd)); -- --- Table gam_grp: stores the groups associated to each game +-- Table gam_grp: stores the groups associated to each match in a game -- CREATE TABLE IF NOT EXISTS gam_grp ( - GamCod INT NOT NULL, + MchCod INT NOT NULL, GrpCod INT NOT NULL, - UNIQUE INDEX(GamCod,GrpCod)); + UNIQUE INDEX(MchCod,GrpCod)); -- --- Table gam_playing: stores the games beeing played currently +-- Table gam_matches: stores the matches (games instances) already played +-- +CREATE TABLE IF NOT EXISTS gam_matches ( + MchCod INT NOT NULL AUTO_INCREMENT, + GamCod INT NOT NULL, + StartTime DATETIME NOT NULL, + EndTime DATETIME NOT NULL, + UsrCod INT NOT NULL, + Title VARCHAR(2047) NOT NULL, + UNIQUE INDEX(MchCod), + INDEX(GamCod)); +-- +-- Table gam_playing: stores the matches (game instances) beeing played currently -- CREATE TABLE IF NOT EXISTS gam_playing ( - GamCod INT NOT NULL, + MchCod INT NOT NULL, QstInd INT NOT NULL DEFAULT 0, QstCod INT NOT NULL DEFAULT -1, ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N', - GamStart DATETIME NOT NULL, + MchStart DATETIME NOT NULL, QstStart DATETIME NOT NULL, - UNIQUE INDEX(GamCod)); + UNIQUE INDEX(MchCod)); -- -- Table gam_questions: stores the questions in the games -- diff --git a/swad_API.c b/swad_API.c index 32f50fadf..a71356d7b 100644 --- a/swad_API.c +++ b/swad_API.c @@ -4504,7 +4504,6 @@ int swad__getGames (struct soap *soap, return SOAP_OK; } - /*****************************************************************************/ /**************** Get lists of groups of an attendance event *****************/ /*****************************************************************************/ diff --git a/swad_action.c b/swad_action.c index 306545b5d..5bdc4fc0f 100644 --- a/swad_action.c +++ b/swad_action.c @@ -605,13 +605,15 @@ Assessment: 453. ActRemSvyQst Confirm the removal of a question of a survey 454. ActSeeGam Show one game - 455. ActStrGamTch Start a game (by a teacher) + 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) 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. ActPlyGamStd Play a game (by a student) + NEW. ActPlyMchStd Play a game (by a student) NEW. ActGamStdCurQst Show current question when playing a game (by a student) NEW. ActRefGamStd Refresh current question when playing a game (by a student) @@ -2141,15 +2143,17 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActSeeGam */{1650,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_SeeOneGame ,NULL}, - /* ActStrGamTch */{1670,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_StartGameTch ,NULL}, - /* ActGamTch1stQst */{1671,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_GameTchFirstQuestion ,NULL}, - /* ActGamTchNxtQst */{1672,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_GameTchNextQuestion ,NULL}, - /* ActGamTchAns */{1673,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_GameTchShowAnswers ,NULL}, - /* ActGamTchEnd */{1781,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_GameTchEnd ,NULL}, + /* 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}, + /* 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}, - /* ActPlyGamStd */{1779,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_PlayGameStd ,NULL}, - /* ActGamStdCurQst */{1780,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,Gam_GetGameBeingPlayed ,Gam_ShowNewGameToMeAsStd ,NULL}, - /* ActRefGamStd */{1782,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_AJAX_RFRESH,Gam_GetGameBeingPlayed ,Gam_RefreshCurrentGameStd ,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}, + /* ActRefGamStd */{1782,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_AJAX_RFRESH,Gam_GetMatchBeingPlayed ,Gam_RefreshCurrentMatchStd ,NULL}, /* ActAnsGam */{1651,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_ReceiveGameAnswers ,NULL}, /* ActFrmNewGam */{1652,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestCreatOrEditGame ,NULL}, @@ -4871,7 +4875,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActAddTstQstToGam, // #1667 ActUp_GamQst, // #1668 ActDwnGamQst, // #1669 - ActStrGamTch, // #1670 + ActFrmNewMch, // #1670 ActGamTch1stQst, // #1671 ActGamTchNxtQst, // #1672 ActGamTchAns, // #1673 @@ -4980,10 +4984,12 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActReqUnlAllPrj, // #1776 ActLckAllPrj, // #1777 ActUnlAllPrj, // #1778 - ActPlyGamStd, // #1779 + ActPlyMchStd, // #1779 ActGamStdCurQst, // #1780 ActGamTchEnd, // #1781 ActRefGamStd, // #1782 + ActReqRemMch, // #1783 + ActRemMch, // #1784 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index 118b7f439..e85831605 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 + 167 + 437 + 176 + 169 + 16 + 67) +#define Act_NUM_ACTIONS (1 + 4 + 64 + 38 + 12 + 42 + 36 + 19 + 110 + 169 + 437 + 176 + 169 + 16 + 67) -#define Act_MAX_ACTION_COD 1782 +#define Act_MAX_ACTION_COD 1784 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 @@ -607,59 +607,61 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActSeeOneTstResOth (ActChgCrsTT1stDay + 115) #define ActSeeGam (ActChgCrsTT1stDay + 116) -#define ActStrGamTch (ActChgCrsTT1stDay + 117) -#define ActGamTch1stQst (ActChgCrsTT1stDay + 118) -#define ActGamTchNxtQst (ActChgCrsTT1stDay + 119) -#define ActGamTchEnd (ActChgCrsTT1stDay + 120) -#define ActGamTchAns (ActChgCrsTT1stDay + 121) -#define ActPlyGamStd (ActChgCrsTT1stDay + 122) -#define ActGamStdCurQst (ActChgCrsTT1stDay + 123) -#define ActRefGamStd (ActChgCrsTT1stDay + 124) -#define ActAnsGam (ActChgCrsTT1stDay + 125) -#define ActFrmNewGam (ActChgCrsTT1stDay + 126) -#define ActEdiOneGam (ActChgCrsTT1stDay + 127) -#define ActNewGam (ActChgCrsTT1stDay + 128) -#define ActChgGam (ActChgCrsTT1stDay + 129) -#define ActReqRemGam (ActChgCrsTT1stDay + 130) -#define ActRemGam (ActChgCrsTT1stDay + 131) -#define ActReqRstGam (ActChgCrsTT1stDay + 132) -#define ActRstGam (ActChgCrsTT1stDay + 133) -#define ActHidGam (ActChgCrsTT1stDay + 134) -#define ActShoGam (ActChgCrsTT1stDay + 135) -#define ActAddOneGamQst (ActChgCrsTT1stDay + 136) -#define ActGamLstTstQst (ActChgCrsTT1stDay + 137) -#define ActAddTstQstToGam (ActChgCrsTT1stDay + 138) -#define ActReqRemGamQst (ActChgCrsTT1stDay + 139) -#define ActRemGamQst (ActChgCrsTT1stDay + 140) -#define ActUp_GamQst (ActChgCrsTT1stDay + 141) -#define ActDwnGamQst (ActChgCrsTT1stDay + 142) +#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 ActSeeSvy (ActChgCrsTT1stDay + 143) -#define ActAnsSvy (ActChgCrsTT1stDay + 144) -#define ActFrmNewSvy (ActChgCrsTT1stDay + 145) -#define ActEdiOneSvy (ActChgCrsTT1stDay + 146) -#define ActNewSvy (ActChgCrsTT1stDay + 147) -#define ActChgSvy (ActChgCrsTT1stDay + 148) -#define ActReqRemSvy (ActChgCrsTT1stDay + 149) -#define ActRemSvy (ActChgCrsTT1stDay + 150) -#define ActReqRstSvy (ActChgCrsTT1stDay + 151) -#define ActRstSvy (ActChgCrsTT1stDay + 152) -#define ActHidSvy (ActChgCrsTT1stDay + 153) -#define ActShoSvy (ActChgCrsTT1stDay + 154) -#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 155) -#define ActRcvSvyQst (ActChgCrsTT1stDay + 156) -#define ActReqRemSvyQst (ActChgCrsTT1stDay + 157) -#define ActRemSvyQst (ActChgCrsTT1stDay + 158) +#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 ActSeeOneExaAnn (ActChgCrsTT1stDay + 159) -#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 160) -#define ActEdiExaAnn (ActChgCrsTT1stDay + 161) -#define ActRcvExaAnn (ActChgCrsTT1stDay + 162) -#define ActPrnExaAnn (ActChgCrsTT1stDay + 163) -#define ActReqRemExaAnn (ActChgCrsTT1stDay + 164) -#define ActRemExaAnn (ActChgCrsTT1stDay + 165) -#define ActHidExaAnn (ActChgCrsTT1stDay + 166) -#define ActShoExaAnn (ActChgCrsTT1stDay + 167) +#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) /*****************************************************************************/ /******************************** Files tab **********************************/ diff --git a/swad_assignment.c b/swad_assignment.c index 17c615155..e5e237e69 100644 --- a/swad_assignment.c +++ b/swad_assignment.c @@ -1280,7 +1280,7 @@ static void Asg_ShowLstGrpsToEditAssignment (long AsgCod) NumGrpTyp < Gbl.Crs.Grps.GrpTypes.Num; NumGrpTyp++) if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) - Grp_ListGrpsToEditAsgAttSvyGam (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp], + Grp_ListGrpsToEditAsgAttSvyMch (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp], AsgCod,Grp_ASSIGNMENT); /***** End table and box *****/ diff --git a/swad_attendance.c b/swad_attendance.c index 79c6242b0..9341e27e9 100644 --- a/swad_attendance.c +++ b/swad_attendance.c @@ -1224,7 +1224,7 @@ static void Att_ShowLstGrpsToEditAttEvent (long AttCod) NumGrpTyp < Gbl.Crs.Grps.GrpTypes.Num; NumGrpTyp++) if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) - Grp_ListGrpsToEditAsgAttSvyGam (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp], + Grp_ListGrpsToEditAsgAttSvyMch (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp], AttCod,Grp_ATT_EVENT); /***** End table and box *****/ diff --git a/swad_changelog.h b/swad_changelog.h index a2e4be0ba..54bcbc3b1 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -429,6 +429,9 @@ Lo de mutear anuncios, en principio prefiero hacer una opci // TODO: Ver cómo recibir un fichero desde el cliente (SWADroid) en gsoap +// 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. + /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ @@ -448,11 +451,22 @@ En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 18.123 (2019-05-22)" +#define Log_PLATFORM_VERSION "SWAD 18.124 (2019-05-28)" #define CSS_FILE "swad18.123.css" #define JS_FILE "swad18.123.js" /* - Version 18.123.1: May 22, 2019 Wait icon while a game has not started. (? lines) + Version 18.124: May 28, 2019 Every game can have several matches (game instances). (243400 lines) + 4 changes necessary in database: +DROP TABLE gam_played,gam_playing,gam_grp; +CREATE TABLE IF NOT EXISTS gam_matches (MchCod INT NOT NULL AUTO_INCREMENT,GamCod INT NOT NULL,StartTime DATETIME NOT NULL,EndTime DATETIME NOT NULL,UsrCod INT NOT NULL,Title VARCHAR(2047) NOT NULL,UNIQUE INDEX(MchCod),INDEX(GamCod)); +CREATE TABLE IF NOT EXISTS gam_playing (MchCod INT NOT NULL,QstInd INT NOT NULL DEFAULT 0,QstCod INT NOT NULL DEFAULT -1,ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N',MchStart DATETIME NOT NULL,QstStart DATETIME NOT NULL,UNIQUE INDEX(MchCod)); +CREATE TABLE IF NOT EXISTS gam_grp (MchCod INT NOT NULL,GrpCod INT NOT NULL,UNIQUE INDEX(MchCod,GrpCod)); + + Version 18.123.2: May 23, 2019 New table with games instances already played. (242829 lines) + 1 change necessary in database: +CREATE TABLE IF NOT EXISTS gam_matches (MchCod INT NOT NULL AUTO_INCREMENT,GamCod INT NOT NULL,Start DATETIME NOT NULL,UNIQUE INDEX(GamPlyCod),INDEX(GamCod)); + + Version 18.123.1: May 22, 2019 Wait icon while a game has not started. (242788 lines) Copy the following icon to icon public directory: sudo cp icon/wait.gif /var/www/html/swad/icon/ @@ -486,7 +500,7 @@ ALTER TABLE games CHANGE COLUMN Cod CrsCod INT NOT NULL DEFAULT -1,ADD INDEX (Cr Version 18.121.2: May 17, 2019 Fixed bug in exporting tests. (242700 lines) Version 18.121.1: May 16, 2019 Fixed bug in renaming of institution. (242697 lines) Version 18.121: May 13, 2019 Module swad_web_service is renamed as swad_API. - New API function getCourses. (242708 lines) + New API function getGames. (242708 lines) Version 18.120.2: Apr 30, 2019 Code refactoring related to boxes. (242465 lines) Version 18.120.1: Apr 25, 2019 Code refactoring related to file browser. (242461 lines) Version 18.120: Apr 25, 2019 Code refactoring related to file browser. (242466 lines) diff --git a/swad_database.c b/swad_database.c index f624a171a..85d02c80b 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1329,7 +1329,7 @@ mysql> DESCRIBE games; "UsrCod INT NOT NULL," "StartTime DATETIME NOT NULL," "EndTime DATETIME NOT NULL," - "Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_SURVEY_TITLE + "Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE "Txt TEXT NOT NULL," // Cns_MAX_BYTES_TEXT "UNIQUE INDEX(GamCod)," "INDEX(CrsCod))"); @@ -1360,15 +1360,40 @@ mysql> DESCRIBE gam_grp; +--------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+---------+------+-----+---------+-------+ -| GamCod | int(11) | NO | PRI | NULL | | +| MchCod | int(11) | NO | PRI | NULL | | | GrpCod | int(11) | NO | PRI | NULL | | +--------+---------+------+-----+---------+-------+ 2 rows in set (0.01 sec) */ DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_grp (" - "GamCod INT NOT NULL," + "MchCod INT NOT NULL," "GrpCod INT NOT NULL," - "UNIQUE INDEX(GamCod,GrpCod))"); + "UNIQUE INDEX(MchCod,GrpCod))"); + + /***** Table gam_matches *****/ +/* +mysql> DESCRIBE gam_matches; ++-----------+---------------+------+-----+---------+----------------+ +| Field | Type | Null | Key | Default | Extra | ++-----------+---------------+------+-----+---------+----------------+ +| MchCod | int(11) | NO | PRI | NULL | auto_increment | +| GamCod | int(11) | NO | MUL | NULL | | +| StartTime | datetime | NO | | NULL | | +| EndTime | datetime | NO | | NULL | | +| UsrCod | int(11) | NO | | NULL | | +| Title | varchar(2047) | NO | | NULL | | ++-----------+---------------+------+-----+---------+----------------+ +6 rows in set (0.00 sec) +*/ + DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_matches (" + "MchCod INT NOT NULL AUTO_INCREMENT," + "GamCod INT NOT NULL," + "StartTime DATETIME NOT NULL," + "EndTime DATETIME NOT NULL," + "UsrCod INT NOT NULL," + "Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE + "UNIQUE INDEX(MchCod)," + "INDEX(GamCod)"); /***** Table gam_playing *****/ /* @@ -1376,23 +1401,23 @@ mysql> DESCRIBE gam_playing; +----------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------+---------------+------+-----+---------+-------+ -| GamCod | int(11) | NO | PRI | NULL | | +| MchCod | int(11) | NO | PRI | NULL | | | QstInd | int(11) | NO | | 0 | | | QstCod | int(11) | NO | | -1 | | | ShowingAnswers | enum('N','Y') | NO | | N | | -| GamStart | datetime | NO | | NULL | | +| MchStart | datetime | NO | | NULL | | | QstStart | datetime | NO | | NULL | | +----------------+---------------+------+-----+---------+-------+ 6 rows in set (0.00 sec) */ DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_playing (" - "GamCod INT NOT NULL," + "MchCod INT NOT NULL," "QstInd INT NOT NULL DEFAULT 0," "QstCod INT NOT NULL DEFAULT -1," "ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N'," - "GamStart DATETIME NOT NULL," + "MchStart DATETIME NOT NULL," "QstStart DATETIME NOT NULL," - "UNIQUE INDEX(GamCod))"); + "UNIQUE INDEX(MchCod))"); /***** Table gam_questions *****/ /* diff --git a/swad_game.c b/swad_game.c index 59670c10e..582af5fa7 100644 --- a/swad_game.c +++ b/swad_game.c @@ -72,16 +72,29 @@ const char *Gam_StrAnswerTypesDB[Gam_NUM_ANS_TYPES] = #define Gam_MAX_SELECTED_QUESTIONS 1000 #define Gam_MAX_BYTES_LIST_SELECTED_QUESTIONS (Gam_MAX_SELECTED_QUESTIONS * (1 + 10 + 1)) +#define Gam_NEW_MATCH_SECTION_ID "new_match" + /*****************************************************************************/ /******************************* Private types *******************************/ /*****************************************************************************/ +struct Match + { + long MchCod; + long GamCod; + long UsrCod; + time_t TimeUTC[2]; + bool Open; + char Title[Gam_MAX_BYTES_TITLE + 1]; + }; + /*****************************************************************************/ /***************************** Private variables *****************************/ /*****************************************************************************/ -long Gam_CurrentGamCod; // Used as parameter in contextual links -long Gam_CurrentQstCod; // Used as parameter in contextual links +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 /*****************************************************************************/ /***************************** Private prototypes ****************************/ @@ -97,29 +110,29 @@ static void Gam_ParamsWhichGroupsToShow (void); static void Gam_ShowOneGame (long GamCod, bool ShowOnlyThisGame, bool ListGameQuestions, - bool PutButtonToStart, + bool PutFormNewMatch, bool PutButtonToPlay); static void Gam_WriteAuthor (struct Game *Game); -static void Gam_WriteStatus (struct Game *Game); +// static void Gam_WriteStatus (struct Game *Game); static void Gam_GetParamGameOrder (void); static void Gam_PutFormsToRemEditOneGame (const struct Game *Game, const char *Anchor); -static void Gam_PutParamsToPlayGame1stQst (void); static void Gam_PutParams (void); +static void Gam_PutParamCurrentMchCod (void); static void Gam_GetGameTxtFromDB (long GamCod,char Txt[Cns_MAX_BYTES_TEXT + 1]); static bool Gam_CheckIfSimilarGameExists (struct Game *Game); -static void Gam_ShowLstGrpsToEditGame (long GamCod); +static void Gam_ShowLstGrpsToEditMatch (void); static void Gam_CreateGame (struct Game *Game,const char *Txt); static void Gam_UpdateGame (struct Game *Game,const char *Txt); -static bool Gam_CheckIfGamIsAssociatedToGrps (long GamCod); -static void Gam_RemoveAllTheGrpsAssociatedToAndGame (long GamCod); -static void Gam_CreateGrps (long GamCod); -static void Gam_GetAndWriteNamesOfGrpsAssociatedToGame (struct Game *Game); -static bool Gam_CheckIfICanDoThisGameBasedOnGrps (long GamCod); +// static bool Gam_CheckIfMatchIsAssociatedToGrps (long MchCod); +// Nstatic void Gam_RemoveAllTheGrpsAssociatedToMatchesOfAGame (long GamCod); +static void Gam_CreateGrps (long MchCod); +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); @@ -134,8 +147,7 @@ static int Gam_GetMaxQuestionIndexInGame (long GamCod); static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd); static int Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd); static void Gam_ListGameQuestions (struct Game *Game); -static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game, - unsigned NumQsts, +static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, MYSQL_RES *mysql_res); static void Gam_PutIconToAddNewQuestions (void); static void Gam_PutButtonToAddNewQuestions (void); @@ -147,24 +159,32 @@ static unsigned Gam_CountNumQuestionsInList (void); static unsigned Gam_GetNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd); static void Gam_DrawBarNumUsrs (unsigned NumUsrs,unsigned MaxUsrs); -// static void Gam_PutIconToRemoveOneQst (void); static void Gam_PutParamsOneQst (void); static void Gam_ExchangeQuestions (long GamCod, unsigned QstIndTop,unsigned QstIndBottom); -static void Gam_PutBigButtonToStartGameTch (long GamCod); -static void Gam_PutBigButtonToPlayGameStd (long GamCod); +static void Gam_ListPlayedMatches (struct Game *Game,bool PutFormNewMatch); +static void Gam_PutIconToPlayNewMatch (void); +static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches, + MYSQL_RES *mysql_res); +static void Gam_GetMatchDataFromRow (MYSQL_RES *mysql_res, + struct Match *Match); +static void Gam_PutButtonNewMatch (long GamCod); -static bool Gam_CheckIfGameIsBeeingPlayed (long GamCod); -static void Gam_UpdateGameQstBeeingPlayed (long GamCod,unsigned QstInd,long QstCod,bool ShowingAnswers); -static void Gam_RemoveGameBeeingPlayed (long GamCod); +static void Gam_PutBigButtonToPlayMatchTch (struct Game *Game); +static void Gam_PutBigButtonToPlayMatchStd (long MchCod); -static void Gam_PlayGameShowQuestionAndAnswers (long GamCod, +static long Gam_CreateMatch (struct Match *Match); +// static bool Gam_CheckIfGameIsBeingPlayed (long GamCod); +static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod,bool ShowingAnswers); +static void Gam_RemoveMatchBeingPlayed (long MchCod); + +static void Gam_PlayGameShowQuestionAndAnswers (long MchCod, unsigned QstInd, bool ShowAnswers); static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, - long GamCod,unsigned QstInd); + long MchCod,unsigned QstInd); static void Gam_PutBigButtonToEnd (long GamCod); static void Gam_ShowQuestionBeingPlayed (void); @@ -201,7 +221,7 @@ static void Gam_ListAllGames (void) extern const char *Txt_START_END_TIME_HELP[Dat_NUM_START_END_TIME]; extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME]; extern const char *Txt_Game; - extern const char *Txt_Status; + // extern const char *Txt_Status; extern const char *Txt_No_games; Gam_Order_t Order; struct Pagination Pagination; @@ -269,12 +289,12 @@ static void Gam_ListAllGames (void) fprintf (Gbl.F.Out,"" "%s" "" - "" - "%s" - "" + // "" + // "%s" + // "" "", - Txt_Game, - Txt_Status); + Txt_Game); + // Txt_Status); /***** Write all the games *****/ for (NumGame = Pagination.FirstItemVisible; @@ -283,7 +303,7 @@ static void Gam_ListAllGames (void) Gam_ShowOneGame (Gbl.Games.LstGamCods[NumGame - 1], false, false, - false, // Do not put button to start game + false, // Do not put form to start new match false); // Do not put button to play /***** End table *****/ @@ -412,7 +432,7 @@ void Gam_SeeOneGame (void) Gam_ShowOneGame (Game.GamCod, true, // Show only this game true, // List game questions - false, // Do not put button to start game + false, // Do not put form to start new match false); // Do not put button to play } @@ -423,7 +443,7 @@ void Gam_SeeOneGame (void) static void Gam_ShowOneGame (long GamCod, bool ShowOnlyThisGame, bool ListGameQuestions, - bool PutButtonToStart, + bool PutFormNewMatch, bool PutButtonToPlay) { extern const char *Hlp_ASSESSMENT_Games; @@ -433,8 +453,8 @@ static void Gam_ShowOneGame (long GamCod, extern const char *Txt_No_of_questions; extern const char *Txt_No_of_users; extern const char *Txt_Play; - extern const char *Txt_Start_game; - extern const char *Txt_View_game_results; + extern const char *Txt_New_match; +// extern const char *Txt_View_game_results; char *Anchor = NULL; static unsigned UniqueId = 0; struct Game Game; @@ -473,26 +493,20 @@ static void Gam_ShowOneGame (long GamCod, switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: - /* Icon to play game */ - Lay_PutContextualLinkOnlyIcon (ActPlyGamStd,NULL, - Gam_PutParams, - "play.svg", - Txt_Play); - break; + /* Icon to play match */ + Lay_PutContextualLinkOnlyIcon (ActPlyMchStd,NULL, + Gam_PutParams, + "play.svg", + Txt_Play); + break; case Rol_NET: case Rol_TCH: - if (ShowOnlyThisGame) - /* Icon to show first question */ - Lay_PutContextualLinkOnlyIcon (ActGamTch1stQst,NULL, - Gam_PutParamsToPlayGame1stQst, - "play.svg", - Txt_Play); - else - /* Icon to start game */ - Lay_PutContextualLinkOnlyIcon (ActStrGamTch,NULL, - Gam_PutParams, - "play.svg", - Txt_Play); + if (ShowOnlyThisGame) + /* Icon to start a new match */ + Lay_PutContextualLinkOnlyIcon (ActFrmNewMch,Gam_NEW_MATCH_SECTION_ID, + Gam_PutParams, + "play.svg", + Txt_New_match); break; default: break; @@ -564,13 +578,10 @@ static void Gam_ShowOneGame (long GamCod, Txt_No_of_users, Game.NumUsrs); - /* Groups whose students can answer this game */ - if (Gbl.Crs.Grps.NumGrps) - Gam_GetAndWriteNamesOfGrpsAssociatedToGame (&Game); - fprintf (Gbl.F.Out,""); /***** Status of the game *****/ +/* fprintf (Gbl.F.Out,""); - /* Possible button to play/start the game */ + * Possible button to play/start the game * if (Game.Status.Open) { switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: - /* Icon to play game */ - Frm_StartForm (ActPlyGamStd); + * Icon to play game * + Frm_StartForm (ActPlyMchStd); Gam_PutParamGameCod (Game.GamCod); Btn_PutCreateButtonInline (Txt_Play); Frm_EndForm (); break; case Rol_NET: case Rol_TCH: - /* Icon to start game */ - Frm_StartForm (ActStrGamTch); + * Icon to start game * + Frm_StartFormAnchor (ActFrmNewMch,Gam_NEW_MATCH_SECTION_ID); Gam_PutParamGameCod (Game.GamCod); - Btn_PutCreateButtonInline (Txt_Start_game); + Btn_PutCreateButtonInline (Txt_New_match); Frm_EndForm (); break; default: @@ -606,7 +617,7 @@ static void Gam_ShowOneGame (long GamCod, } } - /* Possible button to see the result of the game */ + * Possible button to see the result of the game * if (Game.Status.ICanViewResults) { Frm_StartForm (ActSeeGam); @@ -624,24 +635,24 @@ static void Gam_ShowOneGame (long GamCod, { fprintf (Gbl.F.Out,"
"); - /* Possible button to answer this game */ + * Possible button to answer this game * if (Game.Status.ICanAnswer) { switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: - /* Icon to play game */ - Frm_StartForm (ActPlyGamStd); + * Icon to play game * + Frm_StartForm (ActPlyMchStd); Gam_PutParamGameCod (Game.GamCod); Btn_PutCreateButtonInline (Txt_Play); Frm_EndForm (); break; case Rol_NET: case Rol_TCH: - /* Icon to start game */ - Frm_StartForm (ActStrGamTch); + * Icon to start game * + Frm_StartFormAnchor (ActFrmNewMch,Gam_NEW_MATCH_SECTION_ID); Gam_PutParamGameCod (Game.GamCod); - Btn_PutCreateButtonInline (Txt_Start_game); + Btn_PutCreateButtonInline (Txt_New_match); Frm_EndForm (); break; default: @@ -653,7 +664,7 @@ static void Gam_ShowOneGame (long GamCod, } fprintf (Gbl.F.Out,""); - +*/ /***** End 1st row of this game *****/ fprintf (Gbl.F.Out,""); @@ -686,16 +697,6 @@ static void Gam_ShowOneGame (long GamCod, /***** End 2nd row of this game *****/ fprintf (Gbl.F.Out,""); - /***** Write questions of this game *****/ - if (ListGameQuestions) - { - fprintf (Gbl.F.Out,"" - ""); - Gam_ListGameQuestions (&Game); - fprintf (Gbl.F.Out,"" - ""); - } - /***** End table *****/ if (ShowOnlyThisGame) Tbl_EndTable (); @@ -705,17 +706,32 @@ static void Gam_ShowOneGame (long GamCod, /***** Free anchor string *****/ Frm_FreeAnchorStr (Anchor); - /***** Put big button to start game as a teacher *****/ - if (PutButtonToStart) - Gam_PutBigButtonToStartGameTch (Game.GamCod); - - /***** Put big button to play game as a student *****/ - if (PutButtonToPlay) - Gam_PutBigButtonToPlayGameStd (Game.GamCod); - - /***** End box *****/ if (ShowOnlyThisGame) + { + switch (Gbl.Usrs.Me.Role.Logged) + { + case Rol_STD: + /* Put big button to play match */ + if (PutButtonToPlay) + Gam_PutBigButtonToPlayMatchStd (Game.GamCod); // TODO: Change to match !!!!!!!!!!!!!!!!!! + break; + case Rol_NET: + case Rol_TCH: + case Rol_SYS_ADM: + /* List played matches */ + Gam_ListPlayedMatches (&Game,PutFormNewMatch); + break; + default: + break; + } + + /***** Write questions of this game *****/ + if (ListGameQuestions) + Gam_ListGameQuestions (&Game); + + /***** End box *****/ Box_EndBox (); + } } /*****************************************************************************/ @@ -730,7 +746,7 @@ static void Gam_WriteAuthor (struct Game *Game) /*****************************************************************************/ /************************ Write status of a game ***************************/ /*****************************************************************************/ - +/* static void Gam_WriteStatus (struct Game *Game) { extern const char *Txt_Hidden_game; @@ -742,10 +758,10 @@ static void Gam_WriteStatus (struct Game *Game) extern const char *Txt_SURVEY_You_have_already_answered; extern const char *Txt_SURVEY_You_have_not_answered; - /***** Start list with items of status *****/ + ***** Start list with items of status ***** fprintf (Gbl.F.Out,""); } - +*/ /*****************************************************************************/ /********** Get parameter with the type or order in list of games ************/ /*****************************************************************************/ @@ -843,16 +859,6 @@ static void Gam_PutFormsToRemEditOneGame (const struct Game *Game, Ico_PutContextualIconToEdit (ActEdiOneGam,Gam_PutParams); } -/*****************************************************************************/ -/************* Params used to play the first question of a game **************/ -/*****************************************************************************/ - -static void Gam_PutParamsToPlayGame1stQst (void) - { - Gam_PutParams (); - Gam_PutParamQstInd (0); // Start by first question in game - } - /*****************************************************************************/ /******************** Params used to edit/play a game ************************/ /*****************************************************************************/ @@ -867,13 +873,18 @@ static void Gam_PutParams (void) Pag_PutHiddenParamPagNum (Pag_GAMES,Gbl.Games.CurrentPage); } +static void Gam_PutParamCurrentMchCod (void) + { + if (Gam_CurrentMchCod > 0) + Gam_PutParamMatchCod (Gam_CurrentMchCod); + } + /*****************************************************************************/ /*********************** Get list of all the games *************************/ /*****************************************************************************/ void Gam_GetListGames (void) { - char *SubQuery; static const char *OrderBySubQuery[Gam_NUM_ORDERS] = { "StartTime DESC,EndTime DESC,Title DESC", // Gam_ORDER_BY_START_DATE @@ -889,41 +900,12 @@ void Gam_GetListGames (void) Gam_FreeListGames (); /***** Get list of games from database *****/ - /* Fill subquery for course */ - if (Gbl.Crs.Grps.WhichGrps == Grp_ONLY_MY_GROUPS) - { - if (asprintf (&SubQuery,"CrsCod=%ld" - " AND" - "(GamCod NOT IN" - " (SELECT GamCod FROM gam_grp)" - " OR" - " GamCod IN" - " (SELECT gam_grp.GamCod" - " FROM gam_grp,crs_grp_usr" - " WHERE crs_grp_usr.UsrCod=%ld" - " AND gam_grp.GrpCod=crs_grp_usr.GrpCod))", - Gbl.Hierarchy.Crs.CrsCod, - Gbl.Usrs.Me.UsrDat.UsrCod) < 0) - Lay_NotEnoughMemoryExit (); - } - else // Gbl.Crs.Grps.WhichGrps == Grp_ALL_GROUPS - { - if (asprintf (&SubQuery,"CrsCod=%ld", - Gbl.Hierarchy.Crs.CrsCod) < 0) - Lay_NotEnoughMemoryExit (); - } - - /* Make query */ NumRows = DB_QuerySELECT (&mysql_res,"can not get games", "SELECT GamCod FROM games" - " WHERE %s" + " WHERE CrsCod=%ld" " ORDER BY %s", - SubQuery, + Gbl.Hierarchy.Crs.CrsCod, OrderBySubQuery[Gbl.Games.SelectedOrder]); - - /* Free allocated memory for subquery */ - free ((void *) SubQuery); - if (NumRows) // Games found... { Gbl.Games.Num = (unsigned) NumRows; @@ -953,7 +935,7 @@ void Gam_GetListGames (void) } /*****************************************************************************/ -/********************* Get game data using its code ************************/ +/********************** Get game data using its code *************************/ /*****************************************************************************/ void Gam_GetDataOfGameByCod (struct Game *Game) @@ -989,26 +971,22 @@ void Gam_GetDataOfGameByCod (struct Game *Game) Game->UsrCod = Str_ConvertStrCodToLongCod (row[2]); /* Get start date (row[3] holds the start UTC time) */ - Game->TimeUTC[Att_START_TIME] = Dat_GetUNIXTimeFromStr (row[3]); + Game->TimeUTC[Gam_START_TIME] = Dat_GetUNIXTimeFromStr (row[3]); /* Get end date (row[4] holds the end UTC time) */ - Game->TimeUTC[Att_END_TIME ] = Dat_GetUNIXTimeFromStr (row[4]); + Game->TimeUTC[Gam_END_TIME ] = Dat_GetUNIXTimeFromStr (row[4]); /* Get whether the game is open or closed (row(5)) */ Game->Status.Open = (row[5][0] == '1'); /* Get the title of the game (row[6]) */ Str_Copy (Game->Title,row[6], - Gam_MAX_BYTES_SURVEY_TITLE); + Gam_MAX_BYTES_TITLE); /* Get number of questions and number of users who have already answer this game */ Game->NumQsts = Gam_GetNumQstsGame (Game->GamCod); Game->NumUsrs = Gam_GetNumUsrsWhoHaveAnsweredGame (Game->GamCod); - /* Do I belong to valid groups to answer this game? */ - Game->Status.IBelongToScope = Gbl.Usrs.Me.IBelongToCurrentCrs && - Gam_CheckIfICanDoThisGameBasedOnGrps (Game->GamCod); - /* Have I answered this game? */ Game->Status.IHaveAnswered = Gam_CheckIfIHaveAnsweredGame (Game->GamCod); @@ -1017,7 +995,6 @@ void Gam_GetDataOfGameByCod (struct Game *Game) Game->Status.Visible && Game->Status.Open && Gbl.Usrs.Me.Role.Logged == Rol_STD && - Game->Status.IBelongToScope && !Game->Status.IHaveAnswered; /* Can I view results of the game? @@ -1028,7 +1005,6 @@ void Gam_GetDataOfGameByCod (struct Game *Game) Game->Status.ICanViewResults = Game->NumQsts != 0 && Game->Status.Visible && Game->Status.Open && - Game->Status.IBelongToScope && Game->Status.IHaveAnswered; Game->Status.ICanEdit = false; break; @@ -1038,24 +1014,12 @@ void Gam_GetDataOfGameByCod (struct Game *Game) Game->Status.ICanEdit = false; break; case Rol_TCH: - Game->Status.ICanViewResults = Game->NumQsts != 0 && - !Game->Status.ICanAnswer; - Game->Status.ICanEdit = Game->Status.IBelongToScope; - break; case Rol_DEG_ADM: - Game->Status.ICanViewResults = Game->NumQsts != 0 && - !Game->Status.ICanAnswer; - Game->Status.ICanEdit = Game->Status.IBelongToScope; - break; case Rol_CTR_ADM: - Game->Status.ICanViewResults = Game->NumQsts != 0 && - !Game->Status.ICanAnswer; - Game->Status.ICanEdit = Game->Status.IBelongToScope; - break; case Rol_INS_ADM: Game->Status.ICanViewResults = Game->NumQsts != 0 && !Game->Status.ICanAnswer; - Game->Status.ICanEdit = Game->Status.IBelongToScope; + Game->Status.ICanEdit = true; break; case Rol_SYS_ADM: Game->Status.ICanViewResults = Game->NumQsts != 0; @@ -1090,7 +1054,7 @@ void Gam_GetDataOfGameByCod (struct Game *Game) } /*****************************************************************************/ -/**************************** Free list of games ***************************/ +/***************************** Free list of games ****************************/ /*****************************************************************************/ void Gam_FreeListGames (void) @@ -1139,7 +1103,7 @@ static void Gam_GetGameTxtFromDB (long GamCod,char Txt[Cns_MAX_BYTES_TEXT + 1]) } /*****************************************************************************/ -/******************* Write parameter with code of game *********************/ +/******************** Write parameter with code of game **********************/ /*****************************************************************************/ void Gam_PutParamGameCod (long GamCod) @@ -1148,7 +1112,7 @@ void Gam_PutParamGameCod (long GamCod) } /*****************************************************************************/ -/******************** Get parameter with code of game **********************/ +/********************* Get parameter with code of game ***********************/ /*****************************************************************************/ long Gam_GetParamGameCod (void) @@ -1158,7 +1122,26 @@ long Gam_GetParamGameCod (void) } /*****************************************************************************/ -/*************** Ask for confirmation of removing of a game ****************/ +/******************** Write parameter with code of match **********************/ +/*****************************************************************************/ + +void Gam_PutParamMatchCod (long MchCod) + { + Par_PutHiddenParamLong ("MchCod",MchCod); + } + +/*****************************************************************************/ +/********************* Get parameter with code of match **********************/ +/*****************************************************************************/ + +long Gam_GetParamMatchCod (void) + { + /***** Get code of match *****/ + return Par_GetParToLong ("MchCod"); + } + +/*****************************************************************************/ +/*************** Ask for confirmation of removing of a game ******************/ /*****************************************************************************/ void Gam_AskRemGame (void) @@ -1193,7 +1176,7 @@ void Gam_AskRemGame (void) } /*****************************************************************************/ -/****************************** Remove a game ******************************/ +/******************************* Remove a game *******************************/ /*****************************************************************************/ void Gam_RemoveGame (void) @@ -1220,8 +1203,17 @@ void Gam_RemoveGame (void) "DELETE FROM gam_questions WHERE GamCod=%ld", Game.GamCod); - /***** Remove all the groups of this game *****/ - Gam_RemoveAllTheGrpsAssociatedToAndGame (Game.GamCod); + /***** Remove all the matches in this game *****/ + /* Remove groups in matches of the game */ + DB_QueryDELETE ("can not remove the groups associated to matches of a game", + "DELETE FROM gam_grp USING gam_grp,gam_matches" + " WHERE gam_matches.GrpCod=%ld" + " AND gam_matches.MchCod=gam_grp.MchCod", + Game.GamCod); + /* Remove matches of the game */ + DB_QueryDELETE ("can not remove matches of a game", + "DELETE FROM gam_matches WHERE GamCod=%ld", + Game.GamCod); /***** Remove game *****/ DB_QueryDELETE ("can not remove game", @@ -1423,7 +1415,6 @@ void Gam_RequestCreatOrEditGame (void) Game.NumUsrs = 0; Game.Status.Visible = true; Game.Status.Open = true; - Game.Status.IBelongToScope = false; Game.Status.IHaveAnswered = false; Game.Status.ICanAnswer = false; Game.Status.ICanViewResults = false; @@ -1469,7 +1460,7 @@ void Gam_RequestCreatOrEditGame (void) "", The_ClassFormInBox[Gbl.Prefs.Theme], Txt_Title, - Gam_MAX_CHARS_SURVEY_TITLE,Game.Title); + Gam_MAX_CHARS_TITLE,Game.Title); /***** Game start and end dates *****/ Dat_PutFormStartEndClientLocalDateTimes (Game.TimeUTC,Dat_FORM_SECONDS_ON); @@ -1490,9 +1481,6 @@ void Gam_RequestCreatOrEditGame (void) "" ""); - /***** Groups *****/ - Gam_ShowLstGrpsToEditGame (Game.GamCod); - /***** End table, send button and end box *****/ if (ItsANewGame) Box_EndBoxTableWithButton (Btn_CREATE_BUTTON,Txt_Create_game); @@ -1511,7 +1499,7 @@ void Gam_RequestCreatOrEditGame (void) /******************** Show list of groups to edit a game *******************/ /*****************************************************************************/ -static void Gam_ShowLstGrpsToEditGame (long GamCod) +static void Gam_ShowLstGrpsToEditMatch (void) { extern const char *The_ClassFormInBox[The_NUM_THEMES]; extern const char *Txt_Groups; @@ -1540,8 +1528,8 @@ static void Gam_ShowLstGrpsToEditGame (long GamCod) "" @@ -1554,8 +1542,9 @@ static void Gam_ShowLstGrpsToEditGame (long GamCod) NumGrpTyp < Gbl.Crs.Grps.GrpTypes.Num; NumGrpTyp++) if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) - Grp_ListGrpsToEditAsgAttSvyGam (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp], - GamCod,Grp_SURVEY); + Grp_ListGrpsToEditAsgAttSvyMch (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp], + -1L, // -1 means "New match" + Grp_MATCH); /***** End table and box *****/ Box_EndBoxTable (); @@ -1598,7 +1587,7 @@ void Gam_RecFormGame (void) NewGame.TimeUTC[Dat_END_TIME ] = Dat_GetTimeUTCFromForm ("EndTimeUTC" ); /***** Get game title *****/ - Par_GetParToText ("Title",NewGame.Title,Gam_MAX_BYTES_SURVEY_TITLE); + Par_GetParToText ("Title",NewGame.Title,Gam_MAX_BYTES_TITLE); /***** Get game text and insert links *****/ Par_GetParToHTML ("Txt",Txt,Cns_MAX_BYTES_TEXT); // Store in HTML format (not rigorous) @@ -1669,10 +1658,6 @@ static void Gam_CreateGame (struct Game *Game,const char *Txt) Game->Title, Txt); - /***** Create groups *****/ - if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) - Gam_CreateGrps (Game->GamCod); - /***** Write success message *****/ Ale_ShowAlert (Ale_SUCCESS,Txt_Created_new_game_X, Game->Title); @@ -1702,58 +1687,52 @@ static void Gam_UpdateGame (struct Game *Game,const char *Txt) Txt, Game->GamCod); - /***** Update groups *****/ - /* Remove old groups */ - Gam_RemoveAllTheGrpsAssociatedToAndGame (Game->GamCod); - - /* Create new groups */ - if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) - Gam_CreateGrps (Game->GamCod); - /***** Write success message *****/ Ale_ShowAlert (Ale_SUCCESS,Txt_The_game_has_been_modified); } /*****************************************************************************/ -/*************** Check if a game is associated to any group ****************/ +/*************** Check if a match is associated to any group *****************/ +/*****************************************************************************/ +/* +static bool Gam_CheckIfMatchIsAssociatedToGrps (long MchCod) + { + ***** Get if a match is associated to a group from database ***** + return (DB_QueryCOUNT ("can not check if a match is associated to groups", + "SELECT COUNT(*) FROM gam_grp" + " WHERE MchCod=%ld", + MchCod) != 0); + } +*/ +/*****************************************************************************/ +/************* Check if a match is associated to a given group ***************/ /*****************************************************************************/ -static bool Gam_CheckIfGamIsAssociatedToGrps (long GamCod) +bool Gam_CheckIfMatchIsAssociatedToGrp (long MchCod,long GrpCod) { - /***** Get if a game is associated to a group from database *****/ - return (DB_QueryCOUNT ("can not check if a game is associated to groups", + /***** Get if a match is associated to a group from database *****/ + return (DB_QueryCOUNT ("can not check if a match is associated to a group", "SELECT COUNT(*) FROM gam_grp" - " WHERE GamCod=%ld", - GamCod) != 0); + " WHERE MchCod=%ld AND GrpCod=%ld", + MchCod,GrpCod) != 0); } /*****************************************************************************/ -/**************** Check if a game is associated to a group *****************/ +/******************** Remove groups in matches of a game *********************/ /*****************************************************************************/ - -bool Gam_CheckIfGamIsAssociatedToGrp (long GamCod,long GrpCod) +/* +static void Gam_RemoveAllTheGrpsAssociatedToMatchesOfAGame (long GamCod) { - /***** Get if a game is associated to a group from database *****/ - return (DB_QueryCOUNT ("can not check if a game is associated to a group", - "SELECT COUNT(*) FROM gam_grp" - " WHERE GamCod=%ld AND GrpCod=%ld", - GamCod,GrpCod) != 0); - } - -/*****************************************************************************/ -/************************* Remove groups of a game *************************/ -/*****************************************************************************/ - -static void Gam_RemoveAllTheGrpsAssociatedToAndGame (long GamCod) - { - /***** Remove groups of the game *****/ - DB_QueryDELETE ("can not remove the groups associated to a game", - "DELETE FROM gam_grp WHERE GamCod=%ld", + ***** Remove groups of the game ***** + DB_QueryDELETE ("can not remove the groups associated to matches of a game", + "DELETE FROM gam_grp USING gam_grp,gam_matches" + " WHERE gam_matches.GrpCod=%ld" + " AND gam_matches.MchCod=gam_grp.MchCod", GamCod); } - +*/ /*****************************************************************************/ -/******************* Remove one group from all the games *******************/ +/******************** Remove one group from all the games ********************/ /*****************************************************************************/ void Gam_RemoveGroup (long GrpCod) @@ -1766,7 +1745,7 @@ void Gam_RemoveGroup (long GrpCod) } /*****************************************************************************/ -/*************** Remove groups of one type from all the games **************/ +/**************** Remove groups of one type from all the games ***************/ /*****************************************************************************/ void Gam_RemoveGroupsOfType (long GrpTypCod) @@ -1781,31 +1760,31 @@ void Gam_RemoveGroupsOfType (long GrpTypCod) } /*****************************************************************************/ -/************************ Create groups of a game **************************/ +/******************* Create groups associated to a match *********************/ /*****************************************************************************/ -static void Gam_CreateGrps (long GamCod) +static void Gam_CreateGrps (long MchCod) { unsigned NumGrpSel; - /***** Create groups of the game *****/ + /***** Create groups associated to the match *****/ for (NumGrpSel = 0; NumGrpSel < Gbl.Crs.Grps.LstGrpsSel.NumGrps; NumGrpSel++) /* Create group */ - DB_QueryINSERT ("can not associate a group to a game", + DB_QueryINSERT ("can not associate a group to a match", "INSERT INTO gam_grp" - " (GamCod,GrpCod)" + " (MchCod,GrpCod)" " VALUES" " (%ld,%ld)", - GamCod,Gbl.Crs.Grps.LstGrpsSel.GrpCods[NumGrpSel]); + MchCod,Gbl.Crs.Grps.LstGrpsSel.GrpCods[NumGrpSel]); } /*****************************************************************************/ -/************ Get and write the names of the groups of a game **************/ +/************* Get and write the names of the groups of a match **************/ /*****************************************************************************/ -static void Gam_GetAndWriteNamesOfGrpsAssociatedToGame (struct Game *Game) +static void Gam_GetAndWriteNamesOfGrpsAssociatedToMatch (struct Match *Match) { extern const char *Txt_Group; extern const char *Txt_Groups; @@ -1816,20 +1795,18 @@ static void Gam_GetAndWriteNamesOfGrpsAssociatedToGame (struct Game *Game) unsigned long NumRow; unsigned long NumRows; - /***** Get groups associated to a game from database *****/ - NumRows = DB_QuerySELECT (&mysql_res,"can not get groups of a game", + /***** Get groups associated to a match from database *****/ + NumRows = DB_QuerySELECT (&mysql_res,"can not get groups of a match", "SELECT crs_grp_types.GrpTypName,crs_grp.GrpName" " FROM gam_grp,crs_grp,crs_grp_types" - " WHERE gam_grp.GamCod=%ld" + " WHERE gam_grp.MchCod=%ld" " AND gam_grp.GrpCod=crs_grp.GrpCod" " AND crs_grp.GrpTypCod=crs_grp_types.GrpTypCod" " ORDER BY crs_grp_types.GrpTypName,crs_grp.GrpName", - Game->GamCod); + Match->MchCod); /***** Write heading *****/ - fprintf (Gbl.F.Out,"
%s: ", - Game->Status.Visible ? "ASG_GRP" : - "ASG_GRP_LIGHT", + fprintf (Gbl.F.Out,"
%s: ", NumRows == 1 ? Txt_Group : Txt_Groups); @@ -1868,8 +1845,8 @@ static void Gam_GetAndWriteNamesOfGrpsAssociatedToGame (struct Game *Game) } /*****************************************************************************/ -/************ Remove all the games of a place on the hierarchy *************/ -/************ (country, institution, centre, degree or course) *************/ +/************* Remove all the games of a place on the hierarchy **************/ +/************* (country, institution, centre, degree or course) **************/ /*****************************************************************************/ void Gam_RemoveGames (Hie_Level_t Scope,long Cod) @@ -1918,20 +1895,20 @@ void Gam_RemoveGames (Hie_Level_t Scope,long Cod) } /*****************************************************************************/ -/************ Check if I belong to any of the groups of a game *************/ +/************ Check if I belong to any of the groups of a match **************/ /*****************************************************************************/ -static bool Gam_CheckIfICanDoThisGameBasedOnGrps (long GamCod) +static bool Gam_CheckIfIPlayThisMatchBasedOnGrps (long MchCod) { - /***** Get if I can do a game from database *****/ - return (DB_QueryCOUNT ("can not check if I can do a game", - "SELECT COUNT(*) FROM games" - " WHERE GamCod=%ld" - " AND (GamCod NOT IN (SELECT GamCod FROM gam_grp) OR" - " GamCod IN (SELECT gam_grp.GamCod FROM gam_grp,crs_grp_usr" + /***** Get if I can play a match from database *****/ + return (DB_QueryCOUNT ("can not check if I can play a match", + "SELECT COUNT(*) FROM gam_matches" + " WHERE MchCod=%ld" + " AND (MchCod NOT IN (SELECT MchCod FROM gam_grp) OR" + " MchCod IN (SELECT gam_grp.MchCod FROM gam_grp,crs_grp_usr" " WHERE crs_grp_usr.UsrCod=%ld" " AND gam_grp.GrpCod=crs_grp_usr.GrpCod))", - GamCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0); + MchCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0); } /*****************************************************************************/ @@ -1972,7 +1949,7 @@ void Gam_RequestNewQuestion (void) Gam_ShowOneGame (Game.GamCod, true, // Show only this game true, // List game questions - false, // Do not put button to start game + false, // Do not put form to start new match false); // Do not put button to play } @@ -2019,7 +1996,7 @@ static unsigned Gam_GetParamQstInd (void) } /*****************************************************************************/ -/********************* Remove answers of a game question *******************/ +/********************** Remove answers of a game question ********************/ /*****************************************************************************/ static void Gam_RemAnswersOfAQuestion (long QstCod) @@ -2225,7 +2202,7 @@ static void Gam_ListGameQuestions (struct Game *Game) if (NumQsts) { /***** Show the table with the questions *****/ - Gam_ListOneOrMoreQuestionsForEdition (Game,NumQsts,mysql_res); + Gam_ListOneOrMoreQuestionsForEdition (Game->GamCod,NumQsts,mysql_res); if (ActionToDoWithQuestions == Tst_SHOW_GAME_TO_ANSWER) { @@ -2256,8 +2233,7 @@ static void Gam_ListGameQuestions (struct Game *Game) /********************* List game questions for edition ***********************/ /*****************************************************************************/ -static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game, - unsigned NumQsts, +static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, MYSQL_RES *mysql_res) { extern const char *Txt_Questions; @@ -2324,14 +2300,14 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game, Lay_ShowErrorAndExit ("Wrong code of question."); /***** Icons *****/ - Gam_CurrentGamCod = Game->GamCod; + Gam_CurrentGamCod = GamCod; Gam_CurrentQstCod = QstCod; fprintf (Gbl.F.Out,"" "",Gbl.RowEvenOdd); /* Put icon to remove the question */ Frm_StartForm (ActReqRemGamQst); - Gam_PutParamGameCod (Game->GamCod); + Gam_PutParamGameCod (GamCod); Gam_PutParamQstCod (QstCod); Ico_PutIconRemove (); Frm_EndForm (); @@ -2410,7 +2386,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game, Tst_WriteQstFeedback (row[3],"TEST_EDI_LIGHT"); /* Show answers */ - Tst_WriteAnswersGameResult (Game,NumQst,QstCod, + Tst_WriteAnswersGameResult (GamCod,NumQst,QstCod, "TEST_EDI",true); // Show result fprintf (Gbl.F.Out,"" @@ -2518,7 +2494,7 @@ void Gam_AddTstQuestionsToGame (void) Gam_ShowOneGame (Game.GamCod, true, // Show only this game true, // List game questions - false, // Do not put button to start game + false, // Do not put form to start new match false); // Do not put button to play } @@ -2576,16 +2552,15 @@ static unsigned Gam_CountNumQuestionsInList (void) /*** Get number of users who selected this answer and draw proportional bar **/ /*****************************************************************************/ -void Gam_GetAndDrawBarNumUsrsWhoAnswered (struct Game *Game,long QstCod,unsigned AnsInd) +void Gam_GetAndDrawBarNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd,unsigned NumUsrs) { unsigned NumUsrsThisAnswer; /***** Get number of users who selected this answer *****/ - NumUsrsThisAnswer = Gam_GetNumUsrsWhoAnswered (Game->GamCod,QstCod,AnsInd); + NumUsrsThisAnswer = Gam_GetNumUsrsWhoAnswered (GamCod,QstCod,AnsInd); /***** Show stats of this answer *****/ - if (Game->Status.ICanViewResults) - Gam_DrawBarNumUsrs (NumUsrsThisAnswer,Game->NumUsrs); + Gam_DrawBarNumUsrs (NumUsrsThisAnswer,NumUsrs); } /*****************************************************************************/ @@ -2656,15 +2631,6 @@ static void Gam_DrawBarNumUsrs (unsigned NumUsrs,unsigned MaxUsrs) fprintf (Gbl.F.Out,"%s",Gbl.Title); } -/*****************************************************************************/ -/********************* Put icon to remove one question ***********************/ -/*****************************************************************************/ -/* -static void Gam_PutIconToRemoveOneQst (void) - { - Ico_PutContextualIconToRemove (ActReqRemGamQst,Gam_PutParamsRemoveOneQst); - } -*/ /*****************************************************************************/ /**************** Put parameter to move/remove one question ******************/ /*****************************************************************************/ @@ -2687,7 +2653,7 @@ void Gam_RequestRemoveQst (void) long QstCod; unsigned QstInd; - /***** Get parameters from form *****/ + /***** Get parameters *****/ /* Get game code */ if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); @@ -2711,7 +2677,7 @@ void Gam_RequestRemoveQst (void) Gam_ShowOneGame (Game.GamCod, true, // Show only this game true, // List game questions - false, // Do not put button to start game + false, // Do not put form to start new match false); // Do not put button to play } @@ -2726,7 +2692,7 @@ void Gam_RemoveQst (void) long QstCod; unsigned QstInd; - /***** Get parameters from form *****/ + /***** Get parameters *****/ /* Get game code */ if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); @@ -2762,7 +2728,7 @@ void Gam_RemoveQst (void) Gam_ShowOneGame (Game.GamCod, true, // Show only this game true, // List game questions - false, // Do not put button to start game + false, // Do not put form to start new match false); // Do not put button to play } @@ -2778,7 +2744,7 @@ void Gam_MoveUpQst (void) int QstIndTop; int QstIndBottom; - /***** Get parameters from form *****/ + /***** Get parameters *****/ /* Get game code */ if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); @@ -2810,7 +2776,7 @@ void Gam_MoveUpQst (void) Gam_ShowOneGame (Game.GamCod, true, // Show only this game true, // List game questions - false, // Do not put button to start game + false, // Do not put form to start new match false); // Do not put button to play } @@ -2827,7 +2793,7 @@ void Gam_MoveDownQst (void) int QstIndBottom; int MaxQstInd; // -1 if no questions - /***** Get parameters from form *****/ + /***** Get parameters *****/ /* Get game code */ if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); @@ -2863,7 +2829,7 @@ void Gam_MoveDownQst (void) Gam_ShowOneGame (Game.GamCod, true, // Show only this game true, // List game questions - false, // Do not put button to start game + false, // Do not put form to start new match false); // Do not put button to play } @@ -2918,11 +2884,413 @@ static void Gam_ExchangeQuestions (long GamCod, "UNLOCK TABLES"); } +/*****************************************************************************/ +/************************* List the matches of a game ************************/ +/*****************************************************************************/ + +static void Gam_ListPlayedMatches (struct Game *Game,bool PutFormNewMatch) + { + extern const char *Hlp_ASSESSMENT_Games_matches; + extern const char *Txt_Matches; + char *SubQuery; + MYSQL_RES *mysql_res; + unsigned NumMatches; + + /***** Get data of matches from database *****/ + /* Fill subquery for game */ + if (Gbl.Crs.Grps.WhichGrps == Grp_ONLY_MY_GROUPS) + { + if (asprintf (&SubQuery,"GamCod=%ld" + " AND" + "(MchCod NOT IN" + " (SELECT MchCod FROM gam_grp)" + " OR" + " MchCod IN" + " (SELECT gam_grp.MchCod" + " FROM gam_grp,crs_grp_usr" + " WHERE crs_grp_usr.UsrCod=%ld" + " AND gam_grp.GrpCod=crs_grp_usr.GrpCod))", + Game->GamCod, + Gbl.Usrs.Me.UsrDat.UsrCod) < 0) + Lay_NotEnoughMemoryExit (); + } + else // Gbl.Crs.Grps.WhichGrps == Grp_ALL_GROUPS + { + if (asprintf (&SubQuery,"GamCod=%ld", + Game->GamCod) < 0) + Lay_NotEnoughMemoryExit (); + } + + /* Make query */ + NumMatches = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches", + "SELECT MchCod," // row[0] + "GamCod," // row[1] + "UNIX_TIMESTAMP(StartTime)," // row[2] + "UNIX_TIMESTAMP(EndTime)," // row[3] + "NOW() BETWEEN StartTime AND EndTime,"// row[4] + "UsrCod," // row[5] + "Title" // row[6] + " FROM gam_matches" + " WHERE %s" + " ORDER BY MchCod", + SubQuery); + + /* Free allocated memory for subquery */ + free ((void *) SubQuery); + + /***** Start box *****/ + Gam_CurrentGamCod = Game->GamCod; + Box_StartBox (NULL,Txt_Matches,Gam_PutIconToPlayNewMatch, + Hlp_ASSESSMENT_Games_matches,Box_NOT_CLOSABLE); + + if (NumMatches) + /***** Show the table with the matches *****/ + Gam_ListOneOrMoreMatchesForEdition (NumMatches,mysql_res); + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + /***** Put button to play a new match in this game *****/ + if (PutFormNewMatch) + Gam_PutBigButtonToPlayMatchTch (Game); + else + Gam_PutButtonNewMatch (Game->GamCod); + + /***** End box *****/ + Box_EndBox (); + } + +/*****************************************************************************/ +/********************** Get match data using its code ************************/ +/*****************************************************************************/ + +void Gam_GetDataOfMatchByCod (struct Match *Match) + { + MYSQL_RES *mysql_res; + unsigned long NumRows; + + /***** Get data of match from database *****/ + NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches", + "SELECT MchCod," // row[0] + "GamCod," // row[1] + "UNIX_TIMESTAMP(StartTime)," // row[2] + "UNIX_TIMESTAMP(EndTime)," // row[3] + "NOW() BETWEEN StartTime AND EndTime," // row[4] + "UsrCod," // row[5] + "Title" // row[6] + " FROM gam_matches" + " WHERE MchCod=%ld" + " AND GamCod IN" // Extra check + " (SELECT GamCod FROM games" + " WHERE CrsCod='%ld')", + Match->MchCod, + Gbl.Hierarchy.Crs.CrsCod); + if (NumRows) // Match found... + /***** Get match data from row *****/ + Gam_GetMatchDataFromRow (mysql_res,Match); + else + { + /* Initialize to empty match */ + Match->MchCod = -1L; + Match->GamCod = -1L; + Match->UsrCod = -1L; + Match->TimeUTC[Gam_START_TIME] = + Match->TimeUTC[Gam_END_TIME ] = (time_t) 0; + Match->Open = false; + Match->Title[0] = '\0'; + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + } + +/*****************************************************************************/ +/***************** Put icon to add a new questions to game *******************/ +/*****************************************************************************/ + +static void Gam_PutIconToPlayNewMatch (void) + { + extern const char *Txt_New_match; + + /***** Put form to create a new question *****/ + Ico_PutContextualIconToAdd (ActFrmNewMch,Gam_NEW_MATCH_SECTION_ID,Gam_PutParams, + Txt_New_match); + } + +/*****************************************************************************/ +/*********************** List game matches for edition ***********************/ +/*****************************************************************************/ + +static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches, + MYSQL_RES *mysql_res) + { + extern const char *Txt_No_INDEX; + extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS]; + extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME]; + extern const char *Txt_Match; + extern const char *Txt_Today; + unsigned NumMatch; + unsigned UniqueId; + struct Match Match; + + /***** Write the heading *****/ + Tbl_StartTableWideMargin (2); + fprintf (Gbl.F.Out,"" + "" + "" + "%s" + "" + "" + "%s" + "" + "" + "%s" + "" + "" + "%s" + "" + "" + "%s" + "" + "", + Txt_No_INDEX, + Txt_ROLES_SINGUL_Abc[Rol_TCH][Usr_SEX_UNKNOWN], + Txt_START_END_TIME[Gam_ORDER_BY_START_DATE], + Txt_START_END_TIME[Gam_ORDER_BY_END_DATE], + Txt_Match); + + /***** Write rows *****/ + for (NumMatch = 0, UniqueId = 1; + NumMatch < NumMatches; + NumMatch++, UniqueId++) + { + Gbl.RowEvenOdd = NumMatch % 2; + + /***** Get match data from row *****/ + Gam_GetMatchDataFromRow (mysql_res,&Match); + + /***** Icons *****/ + fprintf (Gbl.F.Out,"" + "",Gbl.RowEvenOdd); + + /* Put icon to remove the match */ + Frm_StartForm (ActReqRemMch); + Gam_PutParamMatchCod (Match.MchCod); + Ico_PutIconRemove (); + Frm_EndForm (); + + fprintf (Gbl.F.Out,""); + + /***** Number of match ******/ + fprintf (Gbl.F.Out,"" + "
%u
" + "", + Gbl.RowEvenOdd, + NumMatch + 1); + + /***** Match player *****/ + fprintf (Gbl.F.Out,"", + Gbl.RowEvenOdd); + Usr_WriteAuthor1Line (Match.UsrCod,false); + fprintf (Gbl.F.Out,""); + + /***** Start date/time *****/ + fprintf (Gbl.F.Out,"", + UniqueId, + Match.Open ? "DATE_GREEN" : + "DATE_RED", + Gbl.RowEvenOdd); + fprintf (Gbl.F.Out,"" + "", + UniqueId,Match.TimeUTC[Gam_START_TIME], + (unsigned) Gbl.Prefs.DateFormat,Txt_Today); + + /***** End date/time *****/ + fprintf (Gbl.F.Out,"", + UniqueId, + Match.Open ? "DATE_GREEN" : + "DATE_RED", + Gbl.RowEvenOdd); + fprintf (Gbl.F.Out,"\">" + "" + "", + UniqueId,Match.TimeUTC[Gam_END_TIME], + (unsigned) Gbl.Prefs.DateFormat,Txt_Today); + + /***** Title and groups *****/ + /* Title */ + fprintf (Gbl.F.Out,"%s", + Gbl.RowEvenOdd,Match.Title); + + /* Groups whose students can answer this match */ + if (Gbl.Crs.Grps.NumGrps) + Gam_GetAndWriteNamesOfGrpsAssociatedToMatch (&Match); + + fprintf (Gbl.F.Out,""); + + fprintf (Gbl.F.Out,""); + } + + /***** End table *****/ + Tbl_EndTable (); + } + +/*****************************************************************************/ +/******************** Get game data from a database row **********************/ +/*****************************************************************************/ + +static void Gam_GetMatchDataFromRow (MYSQL_RES *mysql_res, + struct Match *Match) + { + MYSQL_ROW row; + + /***** Get match data *****/ + row = mysql_fetch_row (mysql_res); + /* + row[0] MchCod + row[1] GamCod + row[2] UNIX_TIMESTAMP(StartTime) + row[3] UNIX_TIMESTAMP(EndTime) + row[4] NOW() BETWEEN StartTime AND EndTime + row[5] UsrCod + row[6] Title + */ + /* row[0] holds the code of the match */ + if ((Match->MchCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) + Lay_ShowErrorAndExit ("Wrong code of match."); + + /* row[1] holds the code of the game */ + if ((Match->GamCod = Str_ConvertStrCodToLongCod (row[1])) <= 0) + Lay_ShowErrorAndExit ("Wrong code of game."); + + /* Get start date (row[2] holds the start UTC time) */ + Match->TimeUTC[Gam_START_TIME] = Dat_GetUNIXTimeFromStr (row[2]); + + /* Get end date (row[3] holds the end UTC time) */ + Match->TimeUTC[Gam_END_TIME ] = Dat_GetUNIXTimeFromStr (row[3]); + + /* Get whether the match is open or closed (row(4)) */ + Match->Open = (row[4][0] == '1'); + + /* Get match player (row[5]) */ + Match->UsrCod = Str_ConvertStrCodToLongCod (row[5]); + + /* Get the title of the game (row[6]) */ + if (row[6]) + Str_Copy (Match->Title,row[6], + Gam_MAX_BYTES_TITLE); + else + Match->Title[0] = '\0'; + } + +/*****************************************************************************/ +/************** Request the removal of a match (game instance) ***************/ +/*****************************************************************************/ + +void Gam_RequestRemoveMatch (void) + { + extern const char *Txt_Do_you_really_want_to_remove_the_match_X; + extern const char *Txt_Remove_match; + struct Match Match; + + /***** Get parameters *****/ + /* Get match code */ + if ((Match.MchCod = Gam_GetParamMatchCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of match is missing."); + + /***** Get data of the match from database *****/ + Gam_GetDataOfMatchByCod (&Match); + + /***** Show question and button to remove question *****/ + Gam_CurrentMchCod = Match.MchCod; + Ale_ShowAlertAndButton (ActRemMch,NULL,NULL,Gam_PutParamCurrentMchCod, + Btn_REMOVE_BUTTON,Txt_Remove_match, + Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_match_X, + Match.Title); + + /***** Show current game *****/ + Gam_ShowOneGame (Match.GamCod, + true, // Show only this game + true, // List game questions + false, // Do not put form to start new match + false); // Do not put button to play + } + +/*****************************************************************************/ +/********************** Remove a match (game instance) ***********************/ +/*****************************************************************************/ + +void Gam_RemoveMatch (void) + { + extern const char *Txt_Match_X_removed; + struct Match Match; + + /***** Get parameters *****/ + /* Get match code */ + if ((Match.MchCod = Gam_GetParamMatchCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of match is missing."); + + /***** Get data of the match from database *****/ + Gam_GetDataOfMatchByCod (&Match); + + /***** Remove the match from all the tables *****/ + /* Remove groups associated to the match */ + DB_QueryDELETE ("can not remove the groups associated to matches of a game", + "DELETE FROM gam_grp USING gam_grp,gam_matches,games" + " WHERE gam_grp.MchCod=%ld" + " AND gam_grp.MchCod=gam_matches.MchCod" + " AND gam_matches.GamCod=games.GamCod" + " AND games.CrsCod=%ld", // Extra check + Match.MchCod); + /* Remove the match itself */ + DB_QueryDELETE ("can not remove a match", + "DELETE FROM gam_matches USING gam_matches,games" + " WHERE gam_matches.MchCod=%ld" + " AND gam_matches.GamCod=games.GamCod" + " AND games.CrsCod=%ld", // Extra check + Match.MchCod,Gbl.Hierarchy.Crs.CrsCod); + if (!mysql_affected_rows (&Gbl.mysql)) + Lay_ShowErrorAndExit ("The match to be removed does not exist."); + + /***** Write message *****/ + Ale_ShowAlert (Ale_SUCCESS,Txt_Match_X_removed, + Match.Title); + + /***** Show current game *****/ + Gam_ShowOneGame (Match.GamCod, + true, // Show only this game + true, // List game questions + false, // Do not put form to start new match + false); // Do not put button to play + } + +/*****************************************************************************/ +/********************* Put button to create a new match **********************/ +/*****************************************************************************/ + +static void Gam_PutButtonNewMatch (long GamCod) + { + extern const char *Txt_New_match; + + Frm_StartFormAnchor (ActFrmNewMch,Gam_NEW_MATCH_SECTION_ID); + Gam_PutParamGameCod (GamCod); + Btn_PutConfirmButton (Txt_New_match); + Frm_EndForm (); + } + /*****************************************************************************/ /******************* Start playing a game as a teacher ***********************/ /*****************************************************************************/ -void Gam_StartGameTch (void) +void Gam_RequestNewMatch (void) { long GamCod; @@ -2939,7 +3307,7 @@ void Gam_StartGameTch (void) Gam_ShowOneGame (GamCod, true, // Show only this game false, // Do not list questions - true, // Put button to start game + true, // Put form to start new match false); // Do not put button to play } @@ -2947,63 +3315,109 @@ void Gam_StartGameTch (void) /******************* Start playing a game as a student ***********************/ /*****************************************************************************/ -void Gam_PlayGameStd (void) +void Gam_PlayMatchStd (void) { - long GamCod; + struct Match Match; + bool IBelongToGroups; /***** Get parameters *****/ Gam_GetParamGameOrder (); Grp_GetParamWhichGrps (); Gbl.Games.CurrentPage = Pag_GetParamPagNum (Pag_GAMES); - /***** Get game code *****/ - if ((GamCod = Gam_GetParamGameCod ()) == -1L) - Lay_ShowErrorAndExit ("Code of game is missing."); + /***** Get match code *****/ + if ((Match.MchCod = Gam_GetParamMatchCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of match is missing."); + + /***** Get data of the match from database *****/ + Gam_GetDataOfMatchByCod (&Match); + + /***** Do I belong to valid groups to play this match? *****/ + IBelongToGroups = Gbl.Usrs.Me.IBelongToCurrentCrs && + Gam_CheckIfIPlayThisMatchBasedOnGrps (Match.MchCod); /***** Show game *****/ - Gam_ShowOneGame (GamCod, - true, // Show only this game - false, // Do not list questions - false, // Do not put button to start game - true); // Put button to play + Gam_ShowOneGame (Match.GamCod, + true, // Show only this game + false, // Do not list questions + false, // Do not put form to start new match + IBelongToGroups); // Put button to play } /*****************************************************************************/ -/*************** Put a big button to start game as a teacher *****************/ +/****** Put a big button to play match (start a new match) as a teacher ******/ /*****************************************************************************/ -static void Gam_PutBigButtonToStartGameTch (long GamCod) +static void Gam_PutBigButtonToPlayMatchTch (struct Game *Game) { - extern const char *Txt_Start_game; + extern const char *Hlp_ASSESSMENT_Games_new_match; + extern const char *The_ClassFormInBox[The_NUM_THEMES]; + extern const char *Txt_New_match; + extern const char *Txt_Title; + extern const char *Txt_Play; + + /***** Start section for a new match *****/ + Lay_StartSection (Gam_NEW_MATCH_SECTION_ID); /***** Start form *****/ Frm_StartForm (ActGamTch1stQst); - Gam_PutParamGameCod (GamCod); + Gam_PutParamGameCod (Game->GamCod); Gam_PutParamQstInd (0); // Start by first question in game + /***** Start box and table *****/ + Box_StartBoxTable (NULL,Txt_New_match,NULL, + Hlp_ASSESSMENT_Games_new_match,Box_NOT_CLOSABLE,2); + + /***** Match title *****/ + fprintf (Gbl.F.Out,"" + "" + "" + "" + "" + "" + "" + "", + The_ClassFormInBox[Gbl.Prefs.Theme], + Txt_Title, + Gam_MAX_CHARS_TITLE,Game->Title); + + /***** Groups *****/ + Gam_ShowLstGrpsToEditMatch (); + + /***** End table *****/ + Tbl_EndTable (); + /***** Put icon with link *****/ - Frm_LinkFormSubmit (Txt_Start_game,NULL,NULL); + Frm_LinkFormSubmit (Txt_Play,NULL,NULL); fprintf (Gbl.F.Out,"\"%s\"", - Cfg_URL_ICON_PUBLIC,Txt_Start_game,Txt_Start_game); + Cfg_URL_ICON_PUBLIC,Txt_Play,Txt_Play); fprintf (Gbl.F.Out,""); + /***** End box *****/ + Box_EndBox (); + /***** End form *****/ Frm_EndForm (); + + /***** End section for a new match *****/ + Lay_EndSection (); } /*****************************************************************************/ -/**************** Put a big button to play game as a student *****************/ +/******** Put a big button to play match (join a match) as a student *********/ /*****************************************************************************/ -static void Gam_PutBigButtonToPlayGameStd (long GamCod) +static void Gam_PutBigButtonToPlayMatchStd (long MchCod) { extern const char *Txt_Play; /***** Start form *****/ Frm_StartForm (ActGamStdCurQst); - Gam_PutParamGameCod (GamCod); + Gam_PutParamMatchCod (MchCod); Gam_PutParamQstInd (0); // Start by first question in game /***** Put icon with link *****/ @@ -3019,102 +3433,145 @@ static void Gam_PutBigButtonToPlayGameStd (long GamCod) } /*****************************************************************************/ -/********* Show first question when playing a game (by a teacher) ************/ +/********* Create a new match and show first question (by a teacher) *********/ /*****************************************************************************/ -void Gam_GameTchFirstQuestion (void) +void Gam_CreateAndStartNewMatch (void) { - long GamCod; + struct Match Match; - /***** Get parameters *****/ + /***** Get form parameters *****/ /* Get game code */ - if ((GamCod = Gam_GetParamGameCod ()) == -1L) + if ((Match.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); - /***** Check that the game is not being played *****/ - if (Gam_CheckIfGameIsBeeingPlayed (GamCod)) - Ale_ShowAlert (Ale_WARNING,"Este juego ya está jugándose."); // TODO: Need translation!!!!!! - else - /***** Show questions and possible answers *****/ - Gam_PlayGameShowQuestionAndAnswers (GamCod,0, - false); // Don't show answers + /* Get match title */ + Par_GetParToText ("Title",Match.Title,Gam_MAX_BYTES_TITLE); + + /* Get groups for this games */ + Grp_GetParCodsSeveralGrps (); + + /***** Create a new match *****/ + Match.MchCod = Gam_CreateMatch (&Match); + + /***** Free memory for list of selected groups *****/ + Grp_FreeListCodSelectedGrps (); + + /***** Show questions and possible answers *****/ + Gam_PlayGameShowQuestionAndAnswers (Match.MchCod, + 0, // First question (index is 0) + false); // Don't show answers } /*****************************************************************************/ -/******************** Check if I have answered a game ************************/ +/********************** Create a new match in a game *************************/ /*****************************************************************************/ -static bool Gam_CheckIfGameIsBeeingPlayed (long GamCod) +static long Gam_CreateMatch (struct Match *Match) { - /***** Get if game is being played from database *****/ + long MchCod; + + /***** Create a new match *****/ + MchCod = DB_QueryINSERTandReturnCode ("can not create match", + "INSERT gam_matches" + " (GamCod,StartTime,EndTime,UsrCod,Title)" + " VALUES" + " (%ld,NOW(),NOW(),%ld,'%s')", + Match->GamCod, + Gbl.Usrs.Me.UsrDat.UsrCod, + Match->Title); + + /***** Create groups associated to the match *****/ + if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) + Gam_CreateGrps (MchCod); + + return MchCod; + } + +/*****************************************************************************/ +/******************** Check if I game is being played ************************/ +/*****************************************************************************/ +/* +static bool Gam_CheckIfGameIsBeingPlayed (long GamCod) + { + ***** Get if game is being played from database ***** return (DB_QueryCOUNT ("can not check if game is being played", - "SELECT COUNT(*) FROM gam_playing" - " WHERE GamCod=%ld", + "SELECT COUNT(*)" + " FROM gam_matches,gam_playing" + " WHERE gam_matches.GamCod=%ld" + " AND gam_matches.MchCod=gam_playing.MchCod", GamCod) != 0); } - +*/ /*****************************************************************************/ -/********************** Insert/update game being played **********************/ +/***************** Insert/update a game match being played *******************/ /*****************************************************************************/ -static void Gam_UpdateGameQstBeeingPlayed (long GamCod,unsigned QstInd,long QstCod,bool ShowingAnswers) +static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod,bool ShowingAnswers) { + /***** Update match in table of matches being played currently *****/ if (ShowingAnswers) // Show a question previously shown and its answers - DB_QueryUPDATE ("can not update game beeing played", + DB_QueryUPDATE ("can not update match beeing played", "UPDATE gam_playing" " SET ShowingAnswers='Y'" - " WHERE GamCod=%ld AND QstInd=%u AND QstCod=%ld", - GamCod,QstInd,QstCod); + " WHERE MchCod=%ld" + " AND QstInd=%u AND QstCod=%ld", // Extra checks, not necessary + MchCod,QstInd,QstCod); else // Show a question without answers { if (QstInd == 0) // 1st question beeing shown - DB_QueryINSERT ("can not update game beeing played", + DB_QueryINSERT ("can not create match beeing played", "INSERT gam_playing" - " (GamCod,QstInd,QstCod,ShowingAnswers,GamStart,QstStart)" + " (MchCod,QstInd,QstCod,ShowingAnswers,MchStart,QstStart)" " VALUES" " (%ld,0,%ld,'N',NOW(),NOW())", - GamCod,QstCod); + MchCod,QstCod); else // 2nd, 3rd... question beeing shown - DB_QueryUPDATE ("can not update game beeing played", + DB_QueryUPDATE ("can not update match beeing played", "UPDATE gam_playing" " SET QstInd=%u,QstCod=%ld,ShowingAnswers='N',QstStart=NOW()" - " WHERE GamCod=%ld", - QstInd,QstCod,GamCod); + " WHERE MchCod=%ld", + QstInd,QstCod,MchCod); } + + /***** Update match end time in table of matches already played *****/ + DB_QueryUPDATE ("can not update match end time", + "UPDATE gam_matches SET EndTime=NOW() WHERE MchCod=%ld", + MchCod); } /*****************************************************************************/ -/******************** Remove game from games being played ********************/ +/****************** Remove match from matches being played *******************/ /*****************************************************************************/ -static void Gam_RemoveGameBeeingPlayed (long GamCod) +static void Gam_RemoveMatchBeingPlayed (long MchCod) { /***** Remove game being played from database *****/ - DB_QueryDELETE ("can not remove game being played", + DB_QueryDELETE ("can not remove match being played", "DELETE FROM gam_playing" - " WHERE GamCod=%ld", - GamCod); + " WHERE MchCod=%ld", + MchCod); } /*****************************************************************************/ /********* Show next question when playing a game (by a teacher) *************/ /*****************************************************************************/ -void Gam_GameTchNextQuestion (void) +void Gam_MatchTchNextQuestion (void) { - long GamCod; + long MchCod; unsigned QstInd; /***** Get parameters *****/ - /* Get game code */ - if ((GamCod = Gam_GetParamGameCod ()) == -1L) - Lay_ShowErrorAndExit ("Code of game is missing."); + /* Get match code */ + if ((MchCod = Gam_GetParamMatchCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of match is missing."); /* Get question index */ QstInd = Gam_GetParamQstInd (); /***** Show questions and possible answers *****/ - Gam_PlayGameShowQuestionAndAnswers (GamCod,QstInd, + Gam_PlayGameShowQuestionAndAnswers (MchCod,QstInd, false); // Don't show answers } @@ -3122,29 +3579,29 @@ void Gam_GameTchNextQuestion (void) /************ Show question and its answers when playing a game **************/ /*****************************************************************************/ -void Gam_GameTchShowAnswers (void) +void Gam_MatchTchShowAnswers (void) { - long GamCod; + long MchCod; unsigned QstInd; /***** Get parameters *****/ - /* Get game code */ - if ((GamCod = Gam_GetParamGameCod ()) == -1L) - Lay_ShowErrorAndExit ("Code of game is missing."); + /* Get match code */ + if ((MchCod = Gam_GetParamMatchCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of match is missing."); /* Get question index */ QstInd = Gam_GetParamQstInd (); /***** Show questions and possible answers *****/ - Gam_PlayGameShowQuestionAndAnswers (GamCod,QstInd, + Gam_PlayGameShowQuestionAndAnswers (MchCod,QstInd, true); // Show answers } /*****************************************************************************/ -/************ Show question and its answers when playing a game **************/ +/*********** Show question and its answers when playing a match **************/ /*****************************************************************************/ -static void Gam_PlayGameShowQuestionAndAnswers (long GamCod, +static void Gam_PlayGameShowQuestionAndAnswers (long MchCod, unsigned QstInd, bool ShowAnswers) { @@ -3152,10 +3609,13 @@ static void Gam_PlayGameShowQuestionAndAnswers (long GamCod, MYSQL_ROW row; int NxtQstInd; long QstCod; - struct Game Game; + struct Match Match; + + /***** Get data of the match from database *****/ + Match.MchCod = MchCod; + Gam_GetDataOfMatchByCod (&Match); /***** Get data of question from database *****/ - Game.GamCod = GamCod; if (!DB_QuerySELECT (&mysql_res,"can not get data of a question", "SELECT tst_questions.QstCod," // row[0] "tst_questions.AnsType," // row[1] @@ -3165,7 +3625,7 @@ static void Gam_PlayGameShowQuestionAndAnswers (long GamCod, " WHERE gam_questions.GamCod=%ld" " AND gam_questions.QstInd=%u" " AND gam_questions.QstCod=tst_questions.QstCod", - Game.GamCod,QstInd)) + Match.GamCod,QstInd)) Ale_ShowAlert (Ale_ERROR,"Question doesn't exist."); row = mysql_fetch_row (mysql_res); @@ -3202,7 +3662,7 @@ static void Gam_PlayGameShowQuestionAndAnswers (long GamCod, Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]); /* Write answers */ - Tst_WriteAnswersGameResult (&Game,QstInd,QstCod, + Tst_WriteAnswersGameResult (Match.GamCod,QstInd,QstCod, "GAM_PLAY_TCH_QST",false); // Don't show result } @@ -3213,24 +3673,24 @@ static void Gam_PlayGameShowQuestionAndAnswers (long GamCod, if (ShowAnswers) { /* Get index of the next question */ - NxtQstInd = Gam_GetNextQuestionIndexInGame (Game.GamCod,QstInd); + NxtQstInd = Gam_GetNextQuestionIndexInGame (Match.GamCod,QstInd); if (NxtQstInd >= 0) // Not last question /* Put button to show next question */ - Gam_PutBigButtonToContinue (ActGamTchNxtQst,Game.GamCod,(unsigned) NxtQstInd); + Gam_PutBigButtonToContinue (ActGamTchNxtQst,Match.MchCod,(unsigned) NxtQstInd); else // Last question /* Put button to end */ - Gam_PutBigButtonToEnd (Game.GamCod); + Gam_PutBigButtonToEnd (Match.MchCod); } else /* Put button to show answers */ - Gam_PutBigButtonToContinue (ActGamTchAns,Game.GamCod,QstInd); + Gam_PutBigButtonToContinue (ActGamTchAns,Match.MchCod,QstInd); fprintf (Gbl.F.Out,"
"); /***** End container for question *****/ fprintf (Gbl.F.Out,"
"); /***** Insert/update game in table of games currently being played *****/ - Gam_UpdateGameQstBeeingPlayed (GamCod,QstInd,QstCod,ShowAnswers); + Gam_UpdateMatchBeingPlayed (MchCod,QstInd,QstCod,ShowAnswers); } /*****************************************************************************/ @@ -3238,7 +3698,7 @@ static void Gam_PlayGameShowQuestionAndAnswers (long GamCod, /*****************************************************************************/ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, - long GamCod,unsigned QstInd) + long MchCod,unsigned QstInd) { extern const char *Txt_Continue; @@ -3247,7 +3707,7 @@ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, /***** Start form *****/ Frm_StartForm (NextAction); - Gam_PutParamGameCod (GamCod); + Gam_PutParamMatchCod (MchCod); Gam_PutParamQstInd (QstInd); /***** Put icon with link *****/ @@ -3268,12 +3728,11 @@ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, fprintf (Gbl.F.Out,"
"); } - /*****************************************************************************/ -/************************* Put a big button to end ***************************/ +/********************* Put a big button to end a match ***********************/ /*****************************************************************************/ -static void Gam_PutBigButtonToEnd (long GamCod) +static void Gam_PutBigButtonToEnd (long MchCod) { extern const char *Txt_Finish; @@ -3282,7 +3741,7 @@ static void Gam_PutBigButtonToEnd (long GamCod) /***** Start form *****/ Frm_StartForm (ActGamTchEnd); - Gam_PutParamGameCod (GamCod); + Gam_PutParamMatchCod (MchCod); /***** Put icon with link *****/ Frm_LinkFormSubmit (Txt_Finish,"GAM_PLAY_CONTINUE ICO_HIGHLIGHT",NULL); @@ -3303,44 +3762,43 @@ static void Gam_PutBigButtonToEnd (long GamCod) } /*****************************************************************************/ -/******************** End playing a game (by a teacher) **********************/ +/******************** End playing a match (by a teacher) *********************/ /*****************************************************************************/ -void Gam_GameTchEnd (void) +void Gam_MatchTchEnd (void) { - long GamCod; + long MchCod; - /***** Get parameters *****/ - /* Get game code */ - if ((GamCod = Gam_GetParamGameCod ()) == -1L) - Lay_ShowErrorAndExit ("Code of game is missing."); + /***** Get match code *****/ + if ((MchCod = Gam_GetParamMatchCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of match is missing."); - /***** Remove game being played *****/ - Gam_RemoveGameBeeingPlayed (GamCod); + /***** Remove match being played *****/ + Gam_RemoveMatchBeingPlayed (MchCod); /***** Show alert *****/ - Ale_ShowAlert (Ale_INFO,"Juego finalizado."); // TODO: Need translation!!!!! + Ale_ShowAlert (Ale_INFO,"Partida finalizada."); // TODO: Need translation!!!!! - /***** Button to close *****/ + /***** Button to close browser tab *****/ Btn_PutCloseButton ("Cerrar"); // TODO: Need translation!!!!! } /*****************************************************************************/ -/********************** Get code of game being played ************************/ +/********************** Get code of match being played ************************/ /*****************************************************************************/ -void Gam_GetGameBeingPlayed (void) +void Gam_GetMatchBeingPlayed (void) { - /***** Get game code ****/ - if ((Gbl.Games.GamCodBeingPlayed = Gam_GetParamGameCod ()) == -1L) - Lay_ShowErrorAndExit ("Code of game is missing."); + /***** Get match code ****/ + if ((Gbl.Games.MchCodBeingPlayed = Gam_GetParamMatchCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of match is missing."); } /*****************************************************************************/ /********* Show game being played to me as student in a new window ***********/ /*****************************************************************************/ -void Gam_ShowNewGameToMeAsStd (void) +void Gam_ShowNewMatchToMeAsStd (void) { fprintf (Gbl.F.Out,"
"); Gam_ShowQuestionBeingPlayed (); @@ -3351,7 +3809,7 @@ void Gam_ShowNewGameToMeAsStd (void) /*************** Refresh current game for a student via AJAX *****************/ /*****************************************************************************/ -void Gam_RefreshCurrentGameStd (void) +void Gam_RefreshCurrentMatchStd (void) { if (Gbl.Session.IsOpen) // If session has been closed, do not write anything /***** Get and show current question *****/ @@ -3366,7 +3824,7 @@ static void Gam_ShowQuestionBeingPlayed (void) { MYSQL_RES *mysql_res; MYSQL_ROW row; - // struct Game Game; + bool IBelongToGroups; unsigned QstInd; long QstCod; bool GameIsPlaying; @@ -3374,6 +3832,12 @@ static void Gam_ShowQuestionBeingPlayed (void) unsigned NumOptions; unsigned NumOpt; + /***** Do I belong to valid groups to play this match? *****/ + IBelongToGroups = Gbl.Usrs.Me.IBelongToCurrentCrs && + Gam_CheckIfIPlayThisMatchBasedOnGrps (Gbl.Games.MchCodBeingPlayed); + if (!IBelongToGroups) + Lay_ShowErrorAndExit ("You can not play this match!"); + /***** Get question being played from database *****/ GameIsPlaying = (DB_QuerySELECT (&mysql_res,"can not get question being played", "SELECT QstInd," // row[0] @@ -3382,8 +3846,8 @@ static void Gam_ShowQuestionBeingPlayed (void) "GamStart," // row[3] "QstStart" // row[4] " FROM gam_playing" - " WHERE GamCod=%ld", - Gbl.Games.GamCodBeingPlayed) != 0); + " WHERE MchCod=%ld", + Gbl.Games.MchCodBeingPlayed) != 0); if (GameIsPlaying) { /* Get row */ @@ -3494,7 +3958,7 @@ void Gam_ReceiveGameAnswers (void) Gam_ShowOneGame (Game.GamCod, true, // Show only this game true, // List game questions - false, // Do not put button to start game + false, // Do not put form to start new match false); // Do not put button to play } diff --git a/swad_game.h b/swad_game.h index dad72c12b..7c3420c6c 100644 --- a/swad_game.h +++ b/swad_game.h @@ -33,8 +33,8 @@ /************************** Public types and constants ***********************/ /*****************************************************************************/ -#define Gam_MAX_CHARS_SURVEY_TITLE (128 - 1) // 127 -#define Gam_MAX_BYTES_SURVEY_TITLE ((Gam_MAX_CHARS_SURVEY_TITLE + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047 +#define Gam_MAX_CHARS_TITLE (128 - 1) // 127 +#define Gam_MAX_BYTES_TITLE ((Gam_MAX_CHARS_TITLE + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047 #define Gam_NUM_DATES 2 typedef enum @@ -47,7 +47,7 @@ struct Game { long GamCod; // Game code long UsrCod; // Author code - char Title[Gam_MAX_BYTES_SURVEY_TITLE + 1]; + char Title[Gam_MAX_BYTES_TITLE + 1]; time_t TimeUTC[Gam_NUM_DATES]; unsigned NumQsts; // Number of questions in the game unsigned NumUsrs; // Number of distinct users who have already answered the game @@ -55,7 +55,6 @@ struct Game { bool Visible; // Game is not hidden bool Open; // Start date <= now <= end date - bool IBelongToScope; // I belong to the scope of this game bool IHaveAnswered; // I have already answered this game bool ICanAnswer; bool ICanViewResults; @@ -94,6 +93,8 @@ void Gam_FreeListGames (void); void Gam_PutParamGameCod (long GamCod); long Gam_GetParamGameCod (void); +void Gam_PutParamMatchCod (long MchCod); // TODO: Check if this function can be static +long Gam_GetParamMatchCod (void); // TODO: Check if this function can be static void Gam_AskRemGame (void); void Gam_RemoveGame (void); void Gam_AskResetGame (void); @@ -101,14 +102,14 @@ void Gam_ResetGame (void); void Gam_HideGame (void); void Gam_UnhideGame (void); void Gam_RecFormGame (void); -bool Gam_CheckIfGamIsAssociatedToGrp (long GamCod,long GrpCod); +bool Gam_CheckIfMatchIsAssociatedToGrp (long MchCod,long GrpCod); void Gam_RemoveGroup (long GrpCod); void Gam_RemoveGroupsOfType (long GrpTypCod); void Gam_RemoveGames (Hie_Level_t Scope,long Cod); void Gam_RequestNewQuestion (void); -void Gam_GetAndDrawBarNumUsrsWhoAnswered (struct Game *Game,long QstCod,unsigned AnsInd); +void Gam_GetAndDrawBarNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd,unsigned NumUsrs); void Gam_AddTstQuestionsToGame (void); @@ -118,18 +119,21 @@ void Gam_RemoveQst (void); void Gam_MoveUpQst (void); void Gam_MoveDownQst (void); -void Gam_StartGameTch (void); -void Gam_PlayGameStd (void); +void Gam_RequestRemoveMatch (void); +void Gam_RemoveMatch (void); + +void Gam_RequestNewMatch (void); +void Gam_PlayMatchStd (void); void Gam_ReceiveGameAnswers (void); -void Gam_GameTchFirstQuestion (void); -void Gam_GameTchNextQuestion (void); -void Gam_GameTchShowAnswers (void); -void Gam_GameTchEnd (void); +void Gam_CreateAndStartNewMatch (void); +void Gam_MatchTchNextQuestion (void); +void Gam_MatchTchShowAnswers (void); +void Gam_MatchTchEnd (void); -void Gam_GetGameBeingPlayed (void); -void Gam_ShowNewGameToMeAsStd (void); -void Gam_RefreshCurrentGameStd (void); +void Gam_GetMatchBeingPlayed (void); +void Gam_ShowNewMatchToMeAsStd (void); +void Gam_RefreshCurrentMatchStd (void); unsigned Gam_GetNumCoursesWithGames (Hie_Level_t Scope); unsigned Gam_GetNumGames (Hie_Level_t Scope); diff --git a/swad_global.h b/swad_global.h index 40c3ecff6..a769e5d90 100644 --- a/swad_global.h +++ b/swad_global.h @@ -704,7 +704,7 @@ struct Globals Gam_Order_t SelectedOrder; unsigned CurrentPage; char *ListQuestions; - long GamCodBeingPlayed; // Used to refresh game via AJAX + long MchCodBeingPlayed; // Used to refresh game via AJAX } Games; struct { diff --git a/swad_group.c b/swad_group.c index 81af6ee23..62dbc92a4 100644 --- a/swad_group.c +++ b/swad_group.c @@ -1700,11 +1700,11 @@ static void Grp_WriteHeadingGroups (void) } /*****************************************************************************/ -/********* List groups of a type **********/ -/********* to edit assignments, attendance events, surveys or games **********/ +/******** List groups of a type **********/ +/******** to edit assignments, attendance events, surveys or matches *********/ /*****************************************************************************/ -void Grp_ListGrpsToEditAsgAttSvyGam (struct GroupType *GrpTyp,long Cod, +void Grp_ListGrpsToEditAsgAttSvyMch (struct GroupType *GrpTyp,long Cod, Grp_AsgAttSvyGam_t Grp_AsgAttOrSvy) { struct ListCodGrps LstGrpsIBelong; @@ -1751,8 +1751,8 @@ void Grp_ListGrpsToEditAsgAttSvyGam (struct GroupType *GrpTyp,long Cod, case Grp_SURVEY: AssociatedToGrp = Svy_CheckIfSvyIsAssociatedToGrp (Cod,Grp->GrpCod); break; - case Grp_GAME: - AssociatedToGrp = Gam_CheckIfGamIsAssociatedToGrp (Cod,Grp->GrpCod); + case Grp_MATCH: + AssociatedToGrp = Gam_CheckIfMatchIsAssociatedToGrp (Cod,Grp->GrpCod); break; } if (AssociatedToGrp) diff --git a/swad_group.h b/swad_group.h index 971d6ad52..28f2ac329 100644 --- a/swad_group.h +++ b/swad_group.h @@ -137,7 +137,7 @@ typedef enum Grp_ASSIGNMENT, Grp_ATT_EVENT, Grp_SURVEY, - Grp_GAME, + Grp_MATCH, } Grp_AsgAttSvyGam_t; /*****************************************************************************/ @@ -163,7 +163,7 @@ void Grp_RegisterUsrIntoGroups (struct UsrData *UsrDat,struct ListCodGrps *LstGr unsigned Grp_RemoveUsrFromGroups (struct UsrData *UsrDat,struct ListCodGrps *LstGrps); void Grp_RemUsrFromAllGrpsInCrs (long UsrCod,long CrsCod); void Grp_RemUsrFromAllGrps (long UsrCod); -void Grp_ListGrpsToEditAsgAttSvyGam (struct GroupType *GrpTyp,long Cod, +void Grp_ListGrpsToEditAsgAttSvyMch (struct GroupType *GrpTyp,long Cod, Grp_AsgAttSvyGam_t Grp_AsgOrSvy); void Grp_ReqRegisterInGrps (void); diff --git a/swad_help_URL.c b/swad_help_URL.c index 51153590b..149dbd15b 100644 --- a/swad_help_URL.c +++ b/swad_help_URL.c @@ -1371,17 +1371,17 @@ const char *Hlp_ASSESSMENT_Games_edit_game = const char *Hlp_ASSESSMENT_Games_new_game = #if L==1 - "ASSESSMENT.Games.es#nueva-juego"; + "ASSESSMENT.Games.es#nuevo-juego"; #elif L==2 "ASSESSMENT.Games.en#new-game"; #elif L==3 "ASSESSMENT.Games.en#new-game"; #elif L==4 - "ASSESSMENT.Games.es#nueva-juego"; + "ASSESSMENT.Games.es#nuevo-juego"; #elif L==5 "ASSESSMENT.Games.en#new-game"; #elif L==6 - "ASSESSMENT.Games.es#nueva-juego"; + "ASSESSMENT.Games.es#nuevo-juego"; #elif L==7 "ASSESSMENT.Games.en#new-game"; #elif L==8 @@ -1411,6 +1411,48 @@ const char *Hlp_ASSESSMENT_Games_edit_juego = "ASSESSMENT.Games.en#edit-juego"; #endif +const char *Hlp_ASSESSMENT_Games_matches = +#if L==1 + "ASSESSMENT.Games.es#partidas"; +#elif L==2 + "ASSESSMENT.Games.en#matches"; +#elif L==3 + "ASSESSMENT.Games.en#matches"; +#elif L==4 + "ASSESSMENT.Games.es#partidas"; +#elif L==5 + "ASSESSMENT.Games.en#matches"; +#elif L==6 + "ASSESSMENT.Games.es#partidas"; +#elif L==7 + "ASSESSMENT.Games.en#matches"; +#elif L==8 + "ASSESSMENT.Games.en#matches"; +#elif L==9 + "ASSESSMENT.Games.en#matches"; +#endif + +const char *Hlp_ASSESSMENT_Games_new_match = +#if L==1 + "ASSESSMENT.Games.es#nueva-partida"; +#elif L==2 + "ASSESSMENT.Games.en#new-match"; +#elif L==3 + "ASSESSMENT.Games.en#new-match"; +#elif L==4 + "ASSESSMENT.Games.es#nueva-partida"; +#elif L==5 + "ASSESSMENT.Games.en#new-match"; +#elif L==6 + "ASSESSMENT.Games.es#nueva-partida"; +#elif L==7 + "ASSESSMENT.Games.en#new-match"; +#elif L==8 + "ASSESSMENT.Games.en#new-match"; +#elif L==9 + "ASSESSMENT.Games.en#new-match"; +#endif + const char *Hlp_ASSESSMENT_Games_questions = #if L==1 "ASSESSMENT.Games.es#preguntas"; diff --git a/swad_layout.c b/swad_layout.c index 18c241662..8b6a12c18 100644 --- a/swad_layout.c +++ b/swad_layout.c @@ -794,7 +794,7 @@ static void Lay_WriteScriptParamsAJAX (void) fprintf (Gbl.F.Out,"var RefreshParamNxtActGam = \"act=%ld\";\n" "var RefreshParamGamCod = \"GamCod=%ld\";\n", Act_GetActCod (ActRefGamStd), - Gbl.Games.GamCodBeingPlayed); + Gbl.Games.MchCodBeingPlayed); break; /* Parameter related with clicks refreshing */ case ActLstClk: diff --git a/swad_survey.c b/swad_survey.c index f11855ac8..b3e1c012a 100644 --- a/swad_survey.c +++ b/swad_survey.c @@ -2050,7 +2050,7 @@ static void Svy_ShowLstGrpsToEditSurvey (long SvyCod) NumGrpTyp < Gbl.Crs.Grps.GrpTypes.Num; NumGrpTyp++) if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) - Grp_ListGrpsToEditAsgAttSvyGam (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp], + Grp_ListGrpsToEditAsgAttSvyMch (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp], SvyCod,Grp_SURVEY); /***** End table and box *****/ diff --git a/swad_test.c b/swad_test.c index dc5447f09..93683e903 100644 --- a/swad_test.c +++ b/swad_test.c @@ -157,8 +157,7 @@ static void Tst_ShowTestQuestionsWhenSeeing (MYSQL_RES *mysql_res); static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank,double *TotalScore); static void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions, struct UsrData *UsrDat, - struct Game *Game, - unsigned NumQst,long QstCod,MYSQL_ROW row, + long GamCod,unsigned NumQst,long QstCod,MYSQL_ROW row, double *ScoreThisQst,bool *AnswerIsNotBlank); static void Tst_PutFormToEditQstMedia (struct Media *Media,int NumMediaInForm, bool OptionsDisabled); @@ -210,8 +209,7 @@ static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,bool Shuffle static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat, unsigned NumQst,MYSQL_RES *mysql_res, double *ScoreThisQst,bool *AnswerIsNotBlank); -static void Tst_WriteChoiceAnsViewGame (struct Game *Game, - unsigned NumQst,long QstCod, +static void Tst_WriteChoiceAnsViewGame (long GamCod,unsigned NumQst,long QstCod, const char *Class, bool ShowResult); @@ -866,7 +864,7 @@ static void Tst_ShowTestQuestionsWhenSeeing (MYSQL_RES *mysql_res) Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_TO_ANSWER, &Gbl.Usrs.Me.UsrDat, - NULL,NumQst,QstCod,row, + -1L,NumQst,QstCod,row, &ScoreThisQst, // Not used here &AnswerIsNotBlank); // Not used here } @@ -968,7 +966,7 @@ static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank /***** Write question and answers *****/ Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_RESULT, &Gbl.Usrs.Me.UsrDat, - NULL,NumQst,QstCod,row, + -1L,NumQst,QstCod,row, &ScoreThisQst,&AnswerIsNotBlank); /***** Store test result question in database *****/ @@ -1009,8 +1007,7 @@ static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank static void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions, struct UsrData *UsrDat, - struct Game *Game, - unsigned NumQst,long QstCod,MYSQL_ROW row, + long GamCod,unsigned NumQst,long QstCod,MYSQL_ROW row, double *ScoreThisQst,bool *AnswerIsNotBlank) { extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES]; @@ -1074,11 +1071,11 @@ static void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWith case Tst_SELECT_QUESTIONS_FOR_GAME: break; case Tst_SHOW_GAME_TO_ANSWER: - Tst_WriteAnswersGameResult (Game,NumQst,QstCod, + Tst_WriteAnswersGameResult (GamCod,NumQst,QstCod, "GAM_PLAY_QST",false); // Don't show result break; case Tst_SHOW_GAME_RESULT: - Tst_WriteAnswersGameResult (Game,NumQst,QstCod, + Tst_WriteAnswersGameResult (GamCod,NumQst,QstCod, "GAM_PLAY_QST",true); // Show result break; } @@ -3528,12 +3525,12 @@ static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat, /************** Write answers of a question when viewing a game **************/ /*****************************************************************************/ -void Tst_WriteAnswersGameResult (struct Game *Game,unsigned NumQst,long QstCod, +void Tst_WriteAnswersGameResult (long GamCod,unsigned NumQst,long QstCod, const char *Class,bool ShowResult) { /***** Write answer depending on type *****/ if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE) - Tst_WriteChoiceAnsViewGame (Game,NumQst,QstCod, + Tst_WriteChoiceAnsViewGame (GamCod,NumQst,QstCod, Class,ShowResult); else Ale_ShowAlert (Ale_ERROR,"Type of answer not valid in a game."); @@ -4047,8 +4044,7 @@ static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat, /******** Write single or multiple choice answer when viewing a test *********/ /*****************************************************************************/ -static void Tst_WriteChoiceAnsViewGame (struct Game *Game, - unsigned NumQst,long QstCod, +static void Tst_WriteChoiceAnsViewGame (long GamCod,unsigned NumQst,long QstCod, const char *Class, bool ShowResult) { @@ -4146,7 +4142,8 @@ static void Tst_WriteChoiceAnsViewGame (struct Game *Game, ""); /* Get number of users who selected this answer and draw proportional bar */ - Gam_GetAndDrawBarNumUsrsWhoAnswered (Game,QstCod,AnsInd); + Gam_GetAndDrawBarNumUsrsWhoAnswered (GamCod,QstCod,AnsInd, + 0); // TODO: NumUsrs fprintf (Gbl.F.Out,"" ""); } @@ -8264,7 +8261,7 @@ static void Tst_ShowTestResult (time_t TstTimeUTC) /***** Write questions and answers *****/ Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_RESULT, &Gbl.Usrs.Other.UsrDat, - NULL,NumQst,QstCod,row, + -1L,NumQst,QstCod,row, &ScoreThisQst, // Not used here &AnswerIsNotBlank); // Not used here } diff --git a/swad_test.h b/swad_test.h index 92e8f74e2..d610fff2d 100644 --- a/swad_test.h +++ b/swad_test.h @@ -154,7 +154,7 @@ bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res); void Tst_WriteParamEditQst (void); unsigned Tst_GetNumAnswersQst (long QstCod); unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle); -void Tst_WriteAnswersGameResult (struct Game *Game,unsigned NumQst,long QstCod, +void Tst_WriteAnswersGameResult (long GamCod,unsigned NumQst,long QstCod, const char *Class,bool ShowResult); bool Tst_CheckIfQuestionIsValidForGame (long QstCod); void Tst_WriteAnsTF (char AnsTF); diff --git a/swad_text.c b/swad_text.c index 9f83ce77a..2b8be6b3e 100644 --- a/swad_text.c +++ b/swad_text.c @@ -8889,6 +8889,27 @@ const char *Txt_Do_you_really_want_to_remove_the_group_X_Y_students_ = // Warnin "Ao fazer isso, você removerá %u estudantes desse grupo."; #endif +const char *Txt_Do_you_really_want_to_remove_the_match_X = // Warning: it is very important to include %s in the following sentences +#if L==1 // ca + "De veres voleu eliminar la partida %s?"; +#elif L==2 // de + "Wollen Sie die Spiel %s wirklich entfernen?"; +#elif L==3 // en + "Do you really want to remove the match %s?"; +#elif L==4 // es + "¿Realmente desea eliminar la partida %s?"; +#elif L==5 // fr + "Voulez-vous vraiment supprimer le match %s?"; +#elif L==6 // gn + "¿Realmente desea eliminar la partida %s?"; // Okoteve traducción +#elif L==7 // it + "Vuoi realmente rimuovere la partita %s?"; +#elif L==8 // pl + "Czy na pewno chcesz usunac mecz %s?"; +#elif L==9 // pt + "Você realmente deseja remover o jogo %s?"; +#endif + const char *Txt_Do_you_really_want_to_remove_the_photo_of_X = // Warning: it is very important to include %s in the following sentences #if L==1 // ca "De veres voleu eliminar la foto de %s?"; @@ -17812,9 +17833,72 @@ const char *Txt_Marks_area = "Zona de notas"; #endif +const char *Txt_Match = // of a game +#if L==1 // ca + "Partida"; +#elif L==2 // de + "Spiel"; +#elif L==3 // en + "Match"; +#elif L==4 // es + "Partida"; +#elif L==5 // fr + "Match"; +#elif L==6 // gn + "Partida"; // Okoteve traducción +#elif L==7 // it + "Partita"; +#elif L==8 // pl + "Mecz"; +#elif L==9 // pt + "Jogo"; +#endif + +const char *Txt_Match_X_removed = // Warning: it is very important to include %s in the following sentences +#if L==1 // ca + "Partida %s eliminada."; +#elif L==2 // de + "Spiel %s entfernt."; +#elif L==3 // en + "Match %s removed."; +#elif L==4 // es + "Partida %s eliminada."; +#elif L==5 // fr + "Match %s supprimé."; +#elif L==6 // gn + "Partida %s eliminada."; // Okoteve traducción +#elif L==7 // it + "Partita %s rimossa."; +#elif L==8 // pl + "Mecz %s usunięte."; +#elif L==9 // pt + "Jogo %s removido."; +#endif + +const char *Txt_Matches = // of a game +#if L==1 // ca + "Partides"; +#elif L==2 // de + "Spiele"; +#elif L==3 // en + "Matches"; +#elif L==4 // es + "Partidas"; +#elif L==5 // fr + "Matchs"; +#elif L==6 // gn + "Partidas"; // Okoteve traducción +#elif L==7 // it + "Partite"; +#elif L==8 // pl + "Mecze"; +#elif L==9 // pt + "Jogos"; +#endif + const char *Txt_Materials = #if L==1 // ca - "Materiales"; // Necessita traduccio + "Materials"; #elif L==2 // de "Material"; #elif L==3 // en @@ -23779,6 +23863,27 @@ const char *Txt_New_link = "Nova ligação"; #endif +const char *Txt_New_match = // of a game +#if L==1 // ca + "Nova partida"; +#elif L==2 // de + "Neues Spiel"; +#elif L==3 // en + "New match"; +#elif L==4 // es + "Nueva partida"; +#elif L==5 // fr + "Nouveau match"; +#elif L==6 // gn + "Nueva partida"; // Okoteve traducción +#elif L==7 // it + "Nuova partita"; +#elif L==8 // pl + "Nowy mecz"; +#elif L==9 // pt + "Novo jogo"; +#endif + const char *Txt_New_message = #if L==1 // ca "Nou missatge"; @@ -32034,6 +32139,27 @@ const char *Txt_Remove_logo = "Remover logotipo"; #endif +const char *Txt_Remove_match = // of a game +#if L==1 // ca + "Eliminar partida"; +#elif L==2 // de + "Entfernen Spiel"; +#elif L==3 // en + "Remove match"; +#elif L==4 // es + "Eliminar partida"; +#elif L==5 // fr + "Supprimer match"; +#elif L==6 // gn + "Eliminar partida"; // Okoteve traducción +#elif L==7 // it + "Rimuovere partita"; +#elif L==8 // pl + "Usuń mecz"; +#elif L==9 // pt + "Remover jogo"; +#endif + const char *Txt_Remove_me = #if L==1 // ca "Eliminarme"; @@ -40896,23 +41022,23 @@ const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES] = #endif }; -const char *Txt_Start_game = +const char *Txt_Start_match = #if L==1 // ca - "Començar joc"; + "Començar partida"; #elif L==2 // de "Spiel starten"; #elif L==3 // en - "Start game"; + "Start match"; #elif L==4 // es - "Comenzar juego"; + "Comenzar partida"; #elif L==5 // fr - "Commencer le jeu"; + "Commencer le match"; #elif L==6 // gn "Ñepyrũ ñembosarái"; #elif L==7 // it - "Inizia il gioco"; + "Inizia la partita"; #elif L==8 // pl - "Rozpocznij grę"; + "Rozpocznij mecz"; #elif L==9 // pt "Começar o jogo"; #endif