Version18.127

This commit is contained in:
Antonio Cañas Vargas 2019-05-30 20:52:23 +02:00
parent 03a88663d5
commit ead1645756
5 changed files with 201 additions and 202 deletions

View File

@ -587,7 +587,7 @@ Assessment:
436. ActSeeOneTstResMe Show one test result of me as student 436. ActSeeOneTstResMe Show one test result of me as student
437. ActSeeOneTstResOth Show one test result of other user 437. ActSeeOneTstResOth Show one test result of other user
438. ActSeeSvy Show one survey 438. ActSeeSvy Show one survey
439. ActAnsSvy Answer a survey 439. ActAnsSvy Answer a survey
440. ActFrmNewSvy Form to create a new survey 440. ActFrmNewSvy Form to create a new survey
441. ActEdiOneSvy Edit one survey 441. ActEdiOneSvy Edit one survey
@ -610,8 +610,7 @@ Assessment:
NEW. ActRemMch Confirm the removal of a match (by a teacher) NEW. ActRemMch Confirm the removal of a match (by a teacher)
456. ActNewMch Create a new match showing first question in a new browser tab (by a teacher) 456. ActNewMch Create a new match showing first question in a new browser tab (by a teacher)
NEW. ActResMch Resume an unfinished match showing current question in a new browser tab (by a teacher) NEW. ActResMch Resume an unfinished match showing current question in a new browser tab (by a teacher)
457. ActGamTchNxtQst Show next question when playing a game (by a teacher) 457. ActNxtMch 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. ActEndMch Finish a match (by a teacher) NEW. ActEndMch Finish a match (by a teacher)
NEW. ActPlyMchStd Play a game (by a student) NEW. ActPlyMchStd Play a game (by a student)
@ -2149,8 +2148,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
/* ActRemMch */{1784,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RemoveMatch ,NULL}, /* ActRemMch */{1784,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RemoveMatch ,NULL},
/* ActNewMch */{1671,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_CreateAndStartNewMatch ,NULL}, /* ActNewMch */{1671,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_CreateAndStartNewMatch ,NULL},
/* ActResMch */{1785,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_ResumeUnfinishedMatch ,NULL}, /* ActResMch */{1785,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_ResumeUnfinishedMatch ,NULL},
/* ActGamTchNxtQst */{1672,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchNextQuestion ,NULL}, /* ActNxtMch */{1672,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_NextStatusMatch ,NULL},
/* ActGamTchAns */{1673,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchShowAnswers ,NULL},
/* ActEndMch */{1781,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchEnd ,NULL}, /* ActEndMch */{1781,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchEnd ,NULL},
/* ActPlyMchStd */{1779,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_PlayMatchStd ,NULL}, /* ActPlyMchStd */{1779,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_PlayMatchStd ,NULL},
@ -4879,8 +4877,8 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
ActDwnGamQst, // #1669 ActDwnGamQst, // #1669
ActFrmNewMch, // #1670 ActFrmNewMch, // #1670
ActNewMch, // #1671 ActNewMch, // #1671
ActGamTchNxtQst, // #1672 ActNxtMch, // #1672
ActGamTchAns, // #1673 -1, // #1673 (obsolete action)
ActSeePrj, // #1674 ActSeePrj, // #1674
ActFrmNewPrj, // #1675 ActFrmNewPrj, // #1675
ActEdiOnePrj, // #1676 ActEdiOnePrj, // #1676

View File

@ -64,7 +64,7 @@ typedef enum
typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action 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 + 170 + 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 1785 #define Act_MAX_ACTION_COD 1785
@ -612,57 +612,56 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to
#define ActRemMch (ActChgCrsTT1stDay + 119) #define ActRemMch (ActChgCrsTT1stDay + 119)
#define ActNewMch (ActChgCrsTT1stDay + 120) #define ActNewMch (ActChgCrsTT1stDay + 120)
#define ActResMch (ActChgCrsTT1stDay + 121) #define ActResMch (ActChgCrsTT1stDay + 121)
#define ActGamTchNxtQst (ActChgCrsTT1stDay + 122) #define ActNxtMch (ActChgCrsTT1stDay + 122)
#define ActGamTchAns (ActChgCrsTT1stDay + 123) #define ActEndMch (ActChgCrsTT1stDay + 123)
#define ActEndMch (ActChgCrsTT1stDay + 124) #define ActPlyMchStd (ActChgCrsTT1stDay + 124)
#define ActPlyMchStd (ActChgCrsTT1stDay + 125) #define ActGamStdCurQst (ActChgCrsTT1stDay + 125)
#define ActGamStdCurQst (ActChgCrsTT1stDay + 126) #define ActRefGamStd (ActChgCrsTT1stDay + 126)
#define ActRefGamStd (ActChgCrsTT1stDay + 127) #define ActAnsGam (ActChgCrsTT1stDay + 127)
#define ActAnsGam (ActChgCrsTT1stDay + 128) #define ActFrmNewGam (ActChgCrsTT1stDay + 128)
#define ActFrmNewGam (ActChgCrsTT1stDay + 129) #define ActEdiOneGam (ActChgCrsTT1stDay + 129)
#define ActEdiOneGam (ActChgCrsTT1stDay + 130) #define ActNewGam (ActChgCrsTT1stDay + 130)
#define ActNewGam (ActChgCrsTT1stDay + 131) #define ActChgGam (ActChgCrsTT1stDay + 131)
#define ActChgGam (ActChgCrsTT1stDay + 132) #define ActReqRemGam (ActChgCrsTT1stDay + 132)
#define ActReqRemGam (ActChgCrsTT1stDay + 133) #define ActRemGam (ActChgCrsTT1stDay + 133)
#define ActRemGam (ActChgCrsTT1stDay + 134) #define ActReqRstGam (ActChgCrsTT1stDay + 134)
#define ActReqRstGam (ActChgCrsTT1stDay + 135) #define ActRstGam (ActChgCrsTT1stDay + 135)
#define ActRstGam (ActChgCrsTT1stDay + 136) #define ActHidGam (ActChgCrsTT1stDay + 136)
#define ActHidGam (ActChgCrsTT1stDay + 137) #define ActShoGam (ActChgCrsTT1stDay + 137)
#define ActShoGam (ActChgCrsTT1stDay + 138) #define ActAddOneGamQst (ActChgCrsTT1stDay + 138)
#define ActAddOneGamQst (ActChgCrsTT1stDay + 139) #define ActGamLstTstQst (ActChgCrsTT1stDay + 139)
#define ActGamLstTstQst (ActChgCrsTT1stDay + 140) #define ActAddTstQstToGam (ActChgCrsTT1stDay + 140)
#define ActAddTstQstToGam (ActChgCrsTT1stDay + 141) #define ActReqRemGamQst (ActChgCrsTT1stDay + 141)
#define ActReqRemGamQst (ActChgCrsTT1stDay + 142) #define ActRemGamQst (ActChgCrsTT1stDay + 142)
#define ActRemGamQst (ActChgCrsTT1stDay + 143) #define ActUp_GamQst (ActChgCrsTT1stDay + 143)
#define ActUp_GamQst (ActChgCrsTT1stDay + 144) #define ActDwnGamQst (ActChgCrsTT1stDay + 144)
#define ActDwnGamQst (ActChgCrsTT1stDay + 145)
#define ActSeeSvy (ActChgCrsTT1stDay + 146) #define ActSeeSvy (ActChgCrsTT1stDay + 145)
#define ActAnsSvy (ActChgCrsTT1stDay + 147) #define ActAnsSvy (ActChgCrsTT1stDay + 146)
#define ActFrmNewSvy (ActChgCrsTT1stDay + 148) #define ActFrmNewSvy (ActChgCrsTT1stDay + 147)
#define ActEdiOneSvy (ActChgCrsTT1stDay + 149) #define ActEdiOneSvy (ActChgCrsTT1stDay + 148)
#define ActNewSvy (ActChgCrsTT1stDay + 150) #define ActNewSvy (ActChgCrsTT1stDay + 149)
#define ActChgSvy (ActChgCrsTT1stDay + 151) #define ActChgSvy (ActChgCrsTT1stDay + 150)
#define ActReqRemSvy (ActChgCrsTT1stDay + 152) #define ActReqRemSvy (ActChgCrsTT1stDay + 151)
#define ActRemSvy (ActChgCrsTT1stDay + 153) #define ActRemSvy (ActChgCrsTT1stDay + 152)
#define ActReqRstSvy (ActChgCrsTT1stDay + 154) #define ActReqRstSvy (ActChgCrsTT1stDay + 153)
#define ActRstSvy (ActChgCrsTT1stDay + 155) #define ActRstSvy (ActChgCrsTT1stDay + 154)
#define ActHidSvy (ActChgCrsTT1stDay + 156) #define ActHidSvy (ActChgCrsTT1stDay + 155)
#define ActShoSvy (ActChgCrsTT1stDay + 157) #define ActShoSvy (ActChgCrsTT1stDay + 156)
#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 158) #define ActEdiOneSvyQst (ActChgCrsTT1stDay + 157)
#define ActRcvSvyQst (ActChgCrsTT1stDay + 159) #define ActRcvSvyQst (ActChgCrsTT1stDay + 158)
#define ActReqRemSvyQst (ActChgCrsTT1stDay + 160) #define ActReqRemSvyQst (ActChgCrsTT1stDay + 159)
#define ActRemSvyQst (ActChgCrsTT1stDay + 161) #define ActRemSvyQst (ActChgCrsTT1stDay + 160)
#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 162) #define ActSeeOneExaAnn (ActChgCrsTT1stDay + 161)
#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 163) #define ActSeeDatExaAnn (ActChgCrsTT1stDay + 162)
#define ActEdiExaAnn (ActChgCrsTT1stDay + 164) #define ActEdiExaAnn (ActChgCrsTT1stDay + 163)
#define ActRcvExaAnn (ActChgCrsTT1stDay + 165) #define ActRcvExaAnn (ActChgCrsTT1stDay + 164)
#define ActPrnExaAnn (ActChgCrsTT1stDay + 166) #define ActPrnExaAnn (ActChgCrsTT1stDay + 165)
#define ActReqRemExaAnn (ActChgCrsTT1stDay + 167) #define ActReqRemExaAnn (ActChgCrsTT1stDay + 166)
#define ActRemExaAnn (ActChgCrsTT1stDay + 168) #define ActRemExaAnn (ActChgCrsTT1stDay + 167)
#define ActHidExaAnn (ActChgCrsTT1stDay + 169) #define ActHidExaAnn (ActChgCrsTT1stDay + 168)
#define ActShoExaAnn (ActChgCrsTT1stDay + 170) #define ActShoExaAnn (ActChgCrsTT1stDay + 169)
/*****************************************************************************/ /*****************************************************************************/
/******************************** Files tab **********************************/ /******************************** Files tab **********************************/

View File

@ -453,10 +453,17 @@ En OpenSWAD:
ps2pdf source.ps destination.pdf ps2pdf source.ps destination.pdf
*/ */
#define Log_PLATFORM_VERSION "SWAD 18.126.2 (2019-05-29)" #define Log_PLATFORM_VERSION "SWAD 18.127 (2019-05-30)"
#define CSS_FILE "swad18.123.css" #define CSS_FILE "swad18.123.css"
#define JS_FILE "swad18.123.js" #define JS_FILE "swad18.123.js"
/* /*
1. ¿Qué ocurre si se está jugando una partida en una pestaña y se reanuda la misma en otra pestaña (da igual otra pestaña que otro navegador u ordenador)?
¿Cómo deben avanzar las dos instancias de la misma partida?
2. ¿Puede un profesor reanudar una partida comenzada por otro profesor?
Version 18.127: May 30, 2019 Changes in game matches. (243481 lines)
1 change necessary in database:
UPDATE actions SET Obsolete='Y' WHERE ActCod=1673;
Version 18.126.2: May 30, 2019 New column in list of matches for match status. (? lines) Version 18.126.2: May 30, 2019 New column in list of matches for match status. (? lines)
Version 18.126.1: May 30, 2019 New option to resume an unfinished match. (243415 lines) Version 18.126.1: May 30, 2019 New option to resume an unfinished match. (243415 lines)
11 changes necessary in database: 11 changes necessary in database:

View File

@ -90,7 +90,7 @@ struct Match
unsigned QstInd; // 0 means that the game has not started. First question has index 0. unsigned QstInd; // 0 means that the game has not started. First question has index 0.
long QstCod; long QstCod;
time_t QstStartTimeUTC; time_t QstStartTimeUTC;
bool ShowAnswers; bool ShowingAnswers;
bool Finished; bool Finished;
} Status; } Status;
}; };
@ -178,15 +178,11 @@ static void Gam_PutButtonNewMatch (long GamCod);
static void Gam_PutBigButtonToPlayMatchTch (struct Game *Game); static void Gam_PutBigButtonToPlayMatchTch (struct Game *Game);
static void Gam_PutBigButtonToPlayMatchStd (long MchCod); static void Gam_PutBigButtonToPlayMatchStd (long MchCod);
static long Gam_CreateMatch (struct Match *Match); static void Gam_CreateMatch (struct Match *Match);
static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod, static void Gam_UpdateMatchBeingPlayed (struct Match *Match);
bool ShowingAnswers);
static void Gam_PlayGameShowQuestionAndAnswers (long MchCod, static void Gam_PlayGameShowQuestionAndAnswers (struct Match *Match);
unsigned QstInd, static void Gam_PutBigButtonToContinue (long MchCod);
bool ShowAnswers);
static void Gam_PutBigButtonToContinue (Act_Action_t NextAction,
long MchCod,unsigned QstInd);
static void Gam_PutBigButtonToFinishMatch (long GamCod); static void Gam_PutBigButtonToFinishMatch (long GamCod);
static void Gam_ShowQuestionBeingPlayed (struct Match *Match); static void Gam_ShowQuestionBeingPlayed (struct Match *Match);
@ -2975,7 +2971,7 @@ void Gam_GetDataOfMatchByCod (struct Match *Match)
Match->Status.QstInd = 0; Match->Status.QstInd = 0;
Match->Status.QstCod = -1L; Match->Status.QstCod = -1L;
Match->Status.QstStartTimeUTC = (time_t) 0; Match->Status.QstStartTimeUTC = (time_t) 0;
Match->Status.ShowAnswers = false; Match->Status.ShowingAnswers = false;
Match->Status.Finished = false; Match->Status.Finished = false;
} }
@ -3213,7 +3209,7 @@ static void Gam_GetMatchDataFromRow (MYSQL_RES *mysql_res,
Match->Status.QstStartTimeUTC = Dat_GetUNIXTimeFromStr (row[8]); Match->Status.QstStartTimeUTC = Dat_GetUNIXTimeFromStr (row[8]);
/* Get whether to show question answers or not (row(9)) */ /* Get whether to show question answers or not (row(9)) */
Match->Status.ShowAnswers = (row[9][0] == 'Y'); Match->Status.ShowingAnswers = (row[9][0] == 'Y');
/* Get whether the match is finished or not (row(10)) */ /* Get whether the match is finished or not (row(10)) */
Match->Status.Finished = (row[10][0] == 'Y'); Match->Status.Finished = (row[10][0] == 'Y');
@ -3467,7 +3463,6 @@ static void Gam_PutBigButtonToPlayMatchStd (long MchCod)
void Gam_CreateAndStartNewMatch (void) void Gam_CreateAndStartNewMatch (void)
{ {
struct Match Match; struct Match Match;
unsigned QstInd;
/***** Get form parameters *****/ /***** Get form parameters *****/
/* Get game code */ /* Get game code */
@ -3481,43 +3476,55 @@ void Gam_CreateAndStartNewMatch (void)
Grp_GetParCodsSeveralGrps (); Grp_GetParCodsSeveralGrps ();
/***** Create a new match *****/ /***** Create a new match *****/
Match.MchCod = Gam_CreateMatch (&Match); Gam_CreateMatch (&Match);
/***** Free memory for list of selected groups *****/ /***** Free memory for list of selected groups *****/
Grp_FreeListCodSelectedGrps (); Grp_FreeListCodSelectedGrps ();
/***** Show questions and possible answers *****/ /***** Show questions and possible answers *****/
QstInd = Gam_GetFirstQuestionIndexInGame (Match.GamCod); Gam_PlayGameShowQuestionAndAnswers (&Match);
Gam_PlayGameShowQuestionAndAnswers (Match.MchCod,
QstInd, // First question
false); // Don't show answers
} }
/*****************************************************************************/ /*****************************************************************************/
/********************** Create a new match in a game *************************/ /********************** Create a new match in a game *************************/
/*****************************************************************************/ /*****************************************************************************/
static long Gam_CreateMatch (struct Match *Match) static void Gam_CreateMatch (struct Match *Match)
{ {
long MchCod; /***** Initialize new match *****/
Match->UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod; // Player (me)
Match->Status.QstInd = Gam_GetFirstQuestionIndexInGame (Match->GamCod);
if (Match->Status.QstInd > 0)
{
Match->Status.QstCod = Gam_GetQstCodFromQstInd (Match->GamCod,Match->Status.QstInd);
Match->Status.ShowingAnswers = false; // Don't show answers initially
Match->Status.Finished = false; // Game not finished
}
else // The game has no questions!
{
Match->Status.QstCod = -1L; // Non-existent question
Match->Status.ShowingAnswers = false; // Don't show answers initially
Match->Status.Finished = true; // Game not finished
}
/***** Create a new match *****/ /***** Insert this new match into database *****/
MchCod = DB_QueryINSERTandReturnCode ("can not create match", Match->MchCod = DB_QueryINSERTandReturnCode ("can not create match",
"INSERT gam_matches" "INSERT gam_matches"
" (GamCod,UsrCod,StartTime,EndTime,Title," " (GamCod,UsrCod,StartTime,EndTime,Title,"
"QstInd,QstCod,QstStartTime,ShowingAnswers,Finished)" "QstInd,QstCod,QstStartTime,ShowingAnswers,Finished)"
" VALUES" " VALUES"
" (%ld,%ld,NOW(),NOW(),'%s'," " (%ld,%ld,NOW(),NOW(),'%s',"
"0,-1,FROM_UNIXTIME(0),'N','N')", "%u,%ld,NOW(),'%c','%c')",
Match->GamCod, Match->GamCod,Match->UsrCod,Match->Title,
Gbl.Usrs.Me.UsrDat.UsrCod, Match->Status.QstInd,Match->Status.QstCod,
Match->Title); Match->Status.ShowingAnswers ? 'Y' :
'N',
Match->Status.Finished ? 'Y' :
'N');
/***** Create groups associated to the match *****/ /***** Create groups associated to the match *****/
if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) if (Gbl.Crs.Grps.LstGrpsSel.NumGrps)
Gam_CreateGrps (MchCod); Gam_CreateGrps (Match->MchCod);
return MchCod;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -3528,7 +3535,6 @@ void Gam_ResumeUnfinishedMatch (void)
{ {
extern const char *Txt_Finished_match; extern const char *Txt_Finished_match;
struct Match Match; struct Match Match;
unsigned QstInd;
/***** Get parameters *****/ /***** Get parameters *****/
/* Get match code */ /* Get match code */
@ -3552,16 +3558,10 @@ void Gam_ResumeUnfinishedMatch (void)
if (Match.Status.QstInd == 0) if (Match.Status.QstInd == 0)
/* If current question index is 0 ==> /* If current question index is 0 ==>
start playing the first question */ start playing the first question */
QstInd = Gam_GetFirstQuestionIndexInGame (Match.GamCod); Match.Status.QstInd = Gam_GetFirstQuestionIndexInGame (Match.GamCod);
else
/* If current question index is >0 ==>
show again current question, without answers */
QstInd = Match.Status.QstInd;
/***** Show questions and possible answers *****/ /***** Show questions and possible answers *****/
Gam_PlayGameShowQuestionAndAnswers (Match.MchCod, Gam_PlayGameShowQuestionAndAnswers (&Match);
QstInd,
false); // Don't show answers
} }
} }
@ -3569,107 +3569,109 @@ void Gam_ResumeUnfinishedMatch (void)
/***************** Insert/update a game match being played *******************/ /***************** Insert/update a game match being played *******************/
/*****************************************************************************/ /*****************************************************************************/
static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod, static void Gam_UpdateMatchBeingPlayed (struct Match *Match)
bool ShowingAnswers)
{ {
/***** Update match in table of matches being played currently *****/ /***** Update match status in database *****/
if (ShowingAnswers) // Show a question previously shown and its answers DB_QueryUPDATE ("can not update match being played",
DB_QueryUPDATE ("can not update match being played", "UPDATE gam_matches,games"
"UPDATE gam_matches,games" " SET gam_matches.EndTime=NOW(),"
" SET gam_matches.EndTime=NOW()," "gam_matches.QstInd=%u,"
"gam_matches.ShowingAnswers='Y'" "gam_matches.QstCod=%ld,"
" WHERE gam_matches.MchCod=%ld" "gam_matches.ShowingAnswers='%c',"
" AND gam_matches.GamCod=games.GamCod" "gam_matches.QstStartTime=NOW()"
" AND games.CrsCod=%ld", // Extra check " WHERE gam_matches.MchCod=%ld"
MchCod,Gbl.Hierarchy.Crs.CrsCod); " AND gam_matches.GamCod=games.GamCod"
else // Show a question without answers " AND games.CrsCod=%ld", // Extra check
DB_QueryUPDATE ("can not update match being played", Match->Status.QstInd,Match->Status.QstCod,
"UPDATE gam_matches,games" Match->Status.ShowingAnswers ? 'Y' :
" SET gam_matches.EndTime=NOW()," 'N',
"gam_matches.QstInd=%u," Match->MchCod,Gbl.Hierarchy.Crs.CrsCod);
"gam_matches.QstCod=%ld,"
"gam_matches.ShowingAnswers='N',"
"gam_matches.QstStartTime=NOW()"
" WHERE gam_matches.MchCod=%ld"
" AND gam_matches.GamCod=games.GamCod"
" AND games.CrsCod=%ld", // Extra check
QstInd,QstCod,
MchCod,Gbl.Hierarchy.Crs.CrsCod);
} }
/*****************************************************************************/ /*****************************************************************************/
/********* Show next question when playing a game (by a teacher) *************/ /*** Show next match status (show next question, answers...) (by a teacher) **/
/*****************************************************************************/ /*****************************************************************************/
void Gam_MatchTchNextQuestion (void) void Gam_NextStatusMatch (void)
{ {
long MchCod; extern const char *Txt_Finished_match;
unsigned QstInd; struct Match Match;
long NxtQstInd;
/***** Get parameters *****/ /***** Get parameters *****/
/* Get match code */ /* Get match code */
if ((MchCod = Gam_GetParamMatchCod ()) == -1L) if ((Match.MchCod = Gam_GetParamMatchCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of match is missing."); Lay_ShowErrorAndExit ("Code of match is missing.");
/* Get question index */ /***** Get data of the match from database *****/
QstInd = Gam_GetParamQstInd (); Gam_GetDataOfMatchByCod (&Match);
/***** Show questions and possible answers *****/ /***** If not yet finished, update status *****/
Gam_PlayGameShowQuestionAndAnswers (MchCod,QstInd, if (!Match.Status.Finished)
false); // Don't show answers {
} if (Match.Status.ShowingAnswers) // Showing answers currently
{
/* Get index of the next question */
NxtQstInd = Gam_GetNextQuestionIndexInGame (Match.GamCod,
Match.Status.QstInd);
if (NxtQstInd) // Not last question
{
Match.Status.QstInd = NxtQstInd; // Go to the next question
Match.Status.QstCod = Gam_GetQstCodFromQstInd (Match.GamCod,
Match.Status.QstInd);
Match.Status.ShowingAnswers = false; // Don't show answers
Match.Status.Finished = false; // Game is not finished
}
else // No more questions
{
Match.Status.QstInd = 0; // No more questions
Match.Status.QstCod = -1L; // No more questions
Match.Status.ShowingAnswers = false; // Don't show answers
Match.Status.Finished = true; // Game is finished
}
}
else
{
Match.Status.ShowingAnswers = true; // Show answers
Match.Status.Finished = false; // Game is not finished
}
/*****************************************************************************/ /* Update match status in database */
/************ Show question and its answers when playing a game **************/ Gam_UpdateMatchBeingPlayed (&Match);
/*****************************************************************************/ }
void Gam_MatchTchShowAnswers (void) /***** Show status and questions *****/
{ if (Match.Status.Finished)
long MchCod; {
unsigned QstInd; /* Show alert */
Ale_ShowAlert (Ale_WARNING,Txt_Finished_match);
/***** Get parameters *****/ /* Button to close browser tab */
/* Get match code */ Btn_PutCloseButton ("Cerrar"); // TODO: Need translation!!!!!
if ((MchCod = Gam_GetParamMatchCod ()) == -1L) }
Lay_ShowErrorAndExit ("Code of match is missing."); else
/* Show questions and possible answers */
/* Get question index */ Gam_PlayGameShowQuestionAndAnswers (&Match);
QstInd = Gam_GetParamQstInd ();
/***** Show questions and possible answers *****/
Gam_PlayGameShowQuestionAndAnswers (MchCod,QstInd,
true); // Show answers
} }
/*****************************************************************************/ /*****************************************************************************/
/*********** Show question and its answers when playing a match **************/ /*********** Show question and its answers when playing a match **************/
/*****************************************************************************/ /*****************************************************************************/
static void Gam_PlayGameShowQuestionAndAnswers (long MchCod, static void Gam_PlayGameShowQuestionAndAnswers (struct Match *Match)
unsigned QstInd,
bool ShowAnswers)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
unsigned NxtQstInd; unsigned NxtQstInd;
long QstCod;
struct Match Match;
/***** Get data of the match from database *****/
Match.MchCod = MchCod;
Gam_GetDataOfMatchByCod (&Match);
/***** Get data of question from database *****/ /***** Get data of question from database *****/
if (!DB_QuerySELECT (&mysql_res,"can not get data of a question", if (!DB_QuerySELECT (&mysql_res,"can not get data of a question",
"SELECT tst_questions.QstCod," // row[0] "SELECT AnsType," // row[0]
"tst_questions.AnsType," // row[1] "Stem," // row[1]
"tst_questions.Stem," // row[2] "MedCod" // row[2]
"tst_questions.MedCod" // row[3] " FROM tst_questions"
" FROM gam_questions,tst_questions" " WHERE QstCod=%ld",
" WHERE gam_questions.GamCod=%ld" Match->Status.QstCod))
" AND gam_questions.QstInd=%u"
" AND gam_questions.QstCod=tst_questions.QstCod",
Match.GamCod,QstInd))
Ale_ShowAlert (Ale_ERROR,"Question doesn't exist."); Ale_ShowAlert (Ale_ERROR,"Question doesn't exist.");
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
@ -3678,19 +3680,20 @@ static void Gam_PlayGameShowQuestionAndAnswers (long MchCod,
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_CONTAINER\">");
/* Write number of question */ /* Write number of question */
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_NUM_QST\">%u</div>",QstInd); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_NUM_QST\">%u</div>",
Match->Status.QstInd);
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_QST_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_QST_CONTAINER\">");
/* Get question code (row[0]) */ /* Get answer type (row[0]) */
if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
Lay_ShowErrorAndExit ("Error: wrong question code."); // TODO: Check that answer type is correct (unique choice)
/* Write stem (row[2]) */ /* Write stem (row[1]) */
Tst_WriteQstStem (row[2],"GAM_PLAY_TCH_QST"); Tst_WriteQstStem (row[1],"GAM_PLAY_TCH_QST");
/* Get media (row[3]) */ /* Get media (row[2]) */
Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[3]); Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[2]);
Med_GetMediaDataByCod (&Gbl.Test.Media); Med_GetMediaDataByCod (&Gbl.Test.Media);
/* Show media */ /* Show media */
@ -3699,49 +3702,43 @@ static void Gam_PlayGameShowQuestionAndAnswers (long MchCod,
"TEST_MED_EDIT_LIST_STEM"); "TEST_MED_EDIT_LIST_STEM");
/* Write answers? */ /* Write answers? */
if (ShowAnswers) if (Match->Status.ShowingAnswers)
{
/* Get answer type (row[1]) */
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
/* Write answers */ /* Write answers */
Tst_WriteAnswersGameResult (Match.GamCod,QstInd,QstCod, Tst_WriteAnswersGameResult (Match->GamCod,
Match->Status.QstInd,
Match->Status.QstCod,
"GAM_PLAY_TCH_QST",false); // Don't show result "GAM_PLAY_TCH_QST",false); // Don't show result
}
fprintf (Gbl.F.Out,"</div>"); fprintf (Gbl.F.Out,"</div>");
/***** Put button to continue *****/ /***** Put button to continue *****/
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_NXT_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_NXT_CONTAINER\">");
if (ShowAnswers) if (Match->Status.ShowingAnswers)
{ {
/* Get index of the next question */ /* Get index of the next question */
NxtQstInd = Gam_GetNextQuestionIndexInGame (Match.GamCod,Match.Status.QstInd); NxtQstInd = Gam_GetNextQuestionIndexInGame (Match->GamCod,
Match->Status.QstInd);
if (NxtQstInd) // Not last question if (NxtQstInd) // Not last question
/* Put button to show next question */ /* Put button to show next question */
Gam_PutBigButtonToContinue (ActGamTchNxtQst,Match.MchCod,(unsigned) NxtQstInd); Gam_PutBigButtonToContinue (Match->MchCod);
else // Last question else // Last question
/* Put button to end */ /* Put button to end */
Gam_PutBigButtonToFinishMatch (Match.MchCod); Gam_PutBigButtonToFinishMatch (Match->MchCod);
} }
else else
/* Put button to show answers */ /* Put button to show answers */
Gam_PutBigButtonToContinue (ActGamTchAns,Match.MchCod,QstInd); Gam_PutBigButtonToContinue (Match->MchCod);
fprintf (Gbl.F.Out,"</div>"); fprintf (Gbl.F.Out,"</div>");
/***** End container for question *****/ /***** End container for question *****/
fprintf (Gbl.F.Out,"</div>"); fprintf (Gbl.F.Out,"</div>");
/***** Insert/update game in table of games currently being played *****/
Gam_UpdateMatchBeingPlayed (MchCod,QstInd,QstCod,ShowAnswers);
} }
/*****************************************************************************/ /*****************************************************************************/
/*********************** Put a big button to continue ************************/ /*********************** Put a big button to continue ************************/
/*****************************************************************************/ /*****************************************************************************/
static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, static void Gam_PutBigButtonToContinue (long MchCod)
long MchCod,unsigned QstInd)
{ {
extern const char *Txt_Continue; extern const char *Txt_Continue;
@ -3749,9 +3746,8 @@ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction,
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_CONTINUE_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_CONTINUE_CONTAINER\">");
/***** Start form *****/ /***** Start form *****/
Frm_StartForm (NextAction); Frm_StartForm (ActNxtMch);
Gam_PutParamMatchCod (MchCod); Gam_PutParamMatchCod (MchCod);
Gam_PutParamQstInd (QstInd);
/***** Put icon with link *****/ /***** Put icon with link *****/
Frm_LinkFormSubmit (Txt_Continue,"GAM_PLAY_TCH_CONTINUE ICO_HIGHLIGHT",NULL); Frm_LinkFormSubmit (Txt_Continue,"GAM_PLAY_TCH_CONTINUE ICO_HIGHLIGHT",NULL);
@ -3909,7 +3905,7 @@ static void Gam_ShowQuestionBeingPlayed (struct Match *Match)
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_STD_QST_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_STD_QST_CONTAINER\">");
/* Write answers? */ /* Write answers? */
if (Match->Status.ShowAnswers) if (Match->Status.ShowingAnswers)
{ {
if (Tst_CheckIfQuestionIsValidForGame (Match->Status.QstCod)) if (Tst_CheckIfQuestionIsValidForGame (Match->Status.QstCod))
{ {

View File

@ -128,8 +128,7 @@ void Gam_PlayMatchStd (void);
void Gam_ReceiveGameAnswers (void); void Gam_ReceiveGameAnswers (void);
void Gam_CreateAndStartNewMatch (void); void Gam_CreateAndStartNewMatch (void);
void Gam_ResumeUnfinishedMatch (void); void Gam_ResumeUnfinishedMatch (void);
void Gam_MatchTchNextQuestion (void); void Gam_NextStatusMatch (void);
void Gam_MatchTchShowAnswers (void);
void Gam_MatchTchEnd (void); void Gam_MatchTchEnd (void);
void Gam_GetMatchBeingPlayed (void); void Gam_GetMatchBeingPlayed (void);