Version19.5

This commit is contained in:
Antonio Cañas Vargas 2019-09-17 15:42:41 +02:00
parent 2ca71e4120
commit e07fbb1e72
6 changed files with 146 additions and 102 deletions

View File

@ -640,7 +640,7 @@ CREATE TABLE IF NOT EXISTS mch_matches (
QstCod INT NOT NULL DEFAULT -1, QstCod INT NOT NULL DEFAULT -1,
QstStartTime DATETIME NOT NULL, QstStartTime DATETIME NOT NULL,
ShowResults ENUM('N','Y') NOT NULL DEFAULT 'Y', ShowResults ENUM('N','Y') NOT NULL DEFAULT 'Y',
Showing ENUM('stem','answers','results') NOT NULL DEFAULT 'stem', Showing ENUM('nothing','stem','answers','results') NOT NULL DEFAULT 'nothing',
UNIQUE INDEX(MchCod), UNIQUE INDEX(MchCod),
INDEX(GamCod)); INDEX(GamCod));
-- --

View File

@ -462,12 +462,23 @@ ps2pdf source.ps destination.pdf
/* /*
can not remove the groups associated to matches of a game can not remove the groups associated to matches of a game
Type of answer not valid in a game. Type of answer not valid in a game.
¿Eliminar botón de reset en un juego? Tal vez , para simplificar. No tiene sentido resetear todas las partidas de un juego.
¿Poner botón de reset en una partida? No parece necesario, basta con eliminarla y crear otra
*/ */
#define Log_PLATFORM_VERSION "SWAD 19.4.2 (2019-09-17)" #define Log_PLATFORM_VERSION "SWAD 19.5 (2019-09-17)"
#define CSS_FILE "swad19.3.css" #define CSS_FILE "swad19.3.css"
#define JS_FILE "swad18.130.2.js" #define JS_FILE "swad18.130.2.js"
/* /*
Version 19.5: Sep 17, 2019 Fixed bugs related with edition of games.
Fixed bugs related with behaviour of matches. (244691 lines)
2 changes necessary in database:
ALTER TABLE mch_matches DROP COLUMN Showing;
ALTER TABLE mch_matches ADD COLUMN Showing ENUM('nothing','stem','answers','results') NOT NULL DEFAULT 'nothing' AFTER ShowResults;
Version 19.4.2: Sep 17, 2019 Fixed bug when removing a question in a game. (244654 lines) Version 19.4.2: Sep 17, 2019 Fixed bug when removing a question in a game. (244654 lines)
Version 19.4.1: Sep 17, 2019 Fixed bug when removing a question in a game. (244650 lines) Version 19.4.1: Sep 17, 2019 Fixed bug when removing a question in a game. (244650 lines)
Version 19.4: Sep 17, 2019 Changes in games ans matches tables. (244644 lines) Version 19.4: Sep 17, 2019 Changes in games ans matches tables. (244644 lines)

View File

@ -1369,21 +1369,21 @@ mysql> DESCRIBE mch_groups;
/***** Table mch_matches *****/ /***** Table mch_matches *****/
/* /*
mysql> DESCRIBE mch_matches; mysql> DESCRIBE mch_matches;
+--------------+----------------------------------+------+-----+---------+----------------+ +--------------+--------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra | | Field | Type | Null | Key | Default | Extra |
+--------------+----------------------------------+------+-----+---------+----------------+ +--------------+--------------------------------------------+------+-----+---------+----------------+
| MchCod | int(11) | NO | PRI | NULL | auto_increment | | MchCod | int(11) | NO | PRI | NULL | auto_increment |
| GamCod | int(11) | NO | MUL | NULL | | | GamCod | int(11) | NO | MUL | NULL | |
| UsrCod | int(11) | NO | | NULL | | | UsrCod | int(11) | NO | | NULL | |
| StartTime | datetime | NO | | NULL | | | StartTime | datetime | NO | | NULL | |
| EndTime | datetime | NO | | NULL | | | EndTime | datetime | NO | | NULL | |
| Title | varchar(2047) | NO | | NULL | | | Title | varchar(2047) | NO | | NULL | |
| QstInd | int(11) | NO | | 0 | | | QstInd | int(11) | NO | | 0 | |
| QstCod | int(11) | NO | | -1 | | | QstCod | int(11) | NO | | -1 | |
| QstStartTime | datetime | NO | | NULL | | | QstStartTime | datetime | NO | | NULL | |
| ShowResults | enum('N','Y') | NO | | Y | | | ShowResults | enum('N','Y') | NO | | Y | |
| Showing | enum('stem','answers','results') | NO | | stem | | | Showing | enum('nothing','stem','answers','results') | NO | | nothing | |
+--------------+----------------------------------+------+-----+---------+----------------+ +--------------+--------------------------------------------+------+-----+---------+----------------+
11 rows in set (0.00 sec) 11 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS mch_matches (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS mch_matches ("
@ -1397,7 +1397,7 @@ mysql> DESCRIBE mch_matches;
"QstCod INT NOT NULL DEFAULT -1," "QstCod INT NOT NULL DEFAULT -1,"
"QstStartTime DATETIME NOT NULL," "QstStartTime DATETIME NOT NULL,"
"ShowResults ENUM('N','Y') NOT NULL DEFAULT 'Y'," "ShowResults ENUM('N','Y') NOT NULL DEFAULT 'Y',"
"Showing ENUM('stem','answers','request','results') NOT NULL DEFAULT 'stem'," "Showing ENUM('nothing','stem','answers','results') NOT NULL DEFAULT 'nothing',"
"UNIQUE INDEX(MchCod)," "UNIQUE INDEX(MchCod),"
"INDEX(GamCod)"); "INDEX(GamCod)");

View File

@ -1604,18 +1604,17 @@ static void Gam_ListGameQuestions (struct Game *Game)
extern const char *Hlp_ASSESSMENT_Games_questions; extern const char *Hlp_ASSESSMENT_Games_questions;
extern const char *Txt_Questions; extern const char *Txt_Questions;
extern const char *Txt_This_game_has_no_questions; extern const char *Txt_This_game_has_no_questions;
extern const char *Txt_Done;
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
unsigned NumQsts; unsigned NumQsts;
bool Editing = (Gbl.Action.Act == ActEdiOneGam || bool Editing = (Gbl.Action.Act == ActEdiOneGam ||
Gbl.Action.Act == ActAddOneGamQst); Gbl.Action.Act == ActAddOneGamQst); // TODO: Ampliar casos en los que se está editando para que se muestre el botón de Añadir preguntas
Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions; // Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions;
/***** How to show the questions ******/ /***** How to show the questions ******/
if (Editing) // if (Editing)
ActionToDoWithQuestions = Tst_SHOW_GAME_RESULT; // ActionToDoWithQuestions = Tst_SHOW_GAME_RESULT;
else //else
ActionToDoWithQuestions = Tst_SHOW_GAME_TO_ANSWER; // ActionToDoWithQuestions = Tst_SHOW_GAME_TO_ANSWER;
/***** Get data of questions from database *****/ /***** Get data of questions from database *****/
NumQsts = (unsigned) DB_QuerySELECT (&mysql_res,"can not get data of a question", NumQsts = (unsigned) DB_QuerySELECT (&mysql_res,"can not get data of a question",
@ -1638,19 +1637,8 @@ static void Gam_ListGameQuestions (struct Game *Game)
Hlp_ASSESSMENT_Games_questions,Box_NOT_CLOSABLE); Hlp_ASSESSMENT_Games_questions,Box_NOT_CLOSABLE);
if (NumQsts) if (NumQsts)
{
/***** Show the table with the questions *****/ /***** Show the table with the questions *****/
Gam_ListOneOrMoreQuestionsForEdition (Game->GamCod,NumQsts,mysql_res); Gam_ListOneOrMoreQuestionsForEdition (Game->GamCod,NumQsts,mysql_res);
if (ActionToDoWithQuestions == Tst_SHOW_GAME_TO_ANSWER)
{
/***** Button to create/modify game *****/
Btn_PutConfirmButton (Txt_Done);
/***** End form *****/
Frm_EndForm ();
}
}
else // This game has no questions else // This game has no questions
Ale_ShowAlert (Ale_INFO,Txt_This_game_has_no_questions); Ale_ShowAlert (Ale_INFO,Txt_This_game_has_no_questions);
@ -1844,10 +1832,10 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
Tbl_EndTable (); Tbl_EndTable ();
/***** Button to add a new question *****/ /***** Button to add a new question *****/
Gam_PutButtonToAddNewQuestions (); // Gam_PutButtonToAddNewQuestions ();
/***** End box *****/ /***** End box *****/
Box_EndBox (); // Box_EndBox ();
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -68,14 +68,15 @@ extern struct Globals Gbl;
/******************************* Private types *******************************/ /******************************* Private types *******************************/
/*****************************************************************************/ /*****************************************************************************/
#define Mch_NUM_SHOWING 3 #define Mch_NUM_SHOWING 4
typedef enum typedef enum
{ {
Mch_NOTHING, // Don't show anything
Mch_STEM, // Showing only the question stem Mch_STEM, // Showing only the question stem
Mch_ANSWERS, // Showing the question stem and the answers Mch_ANSWERS, // Showing the question stem and the answers
Mch_RESULTS, // Showing the results Mch_RESULTS, // Showing the results
} Mch_Showing_t; } Mch_Showing_t;
#define Mch_SHOWING_DEFAULT Mch_STEM #define Mch_SHOWING_DEFAULT Mch_NOTHING
struct Match struct Match
{ {
@ -91,7 +92,7 @@ struct Match
time_t QstStartTimeUTC; time_t QstStartTimeUTC;
bool ShowResults; bool ShowResults;
Mch_Showing_t Showing; Mch_Showing_t Showing;
bool BeingPlayed; bool Playing;
unsigned NumPlayers; unsigned NumPlayers;
} Status; } Status;
}; };
@ -102,6 +103,7 @@ struct Match
const char *Mch_ShowingStringsDB[Mch_NUM_SHOWING] = const char *Mch_ShowingStringsDB[Mch_NUM_SHOWING] =
{ {
"nothing",
"stem", "stem",
"answers", "answers",
"results", "results",
@ -150,7 +152,13 @@ static void Mch_GetElapsedTime (unsigned NumRows,MYSQL_RES *mysql_res,
struct Time *Time); struct Time *Time);
static void Mch_SetMatchStatusToPrev (struct Match *Match); static void Mch_SetMatchStatusToPrev (struct Match *Match);
static void Mch_SetMatchStatusToPrevQst (struct Match *Match);
static void Mch_SetMatchStatusToStart (struct Match *Match);
static void Mch_SetMatchStatusToNext (struct Match *Match); static void Mch_SetMatchStatusToNext (struct Match *Match);
static void Mch_SetMatchStatusToNextQst (struct Match *Match);
static void Mch_SetMatchStatusToEnd (struct Match *Match);
static void Mch_ShowMatchStatusForTch (struct Match *Match); static void Mch_ShowMatchStatusForTch (struct Match *Match);
static void Mch_ShowMatchStatusForStd (struct Match *Match); static void Mch_ShowMatchStatusForStd (struct Match *Match);
static bool Mch_CheckIfIPlayThisMatchBasedOnGrps (long MchCod); static bool Mch_CheckIfIPlayThisMatchBasedOnGrps (long MchCod);
@ -318,7 +326,7 @@ static void Mch_GetDataOfMatchByCod (struct Match *Match)
Match->Status.QstStartTimeUTC = (time_t) 0; Match->Status.QstStartTimeUTC = (time_t) 0;
Match->Status.ShowResults = true; Match->Status.ShowResults = true;
Match->Status.Showing = Mch_STEM; Match->Status.Showing = Mch_STEM;
Match->Status.BeingPlayed = false; Match->Status.Playing = false;
} }
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
@ -642,9 +650,9 @@ static void Mch_GetMatchDataFromRow (MYSQL_RES *mysql_res,
/***** Get whether the match is being played or not *****/ /***** Get whether the match is being played or not *****/
if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // Finished if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // Finished
Match->Status.BeingPlayed = false; Match->Status.Playing = false;
else // Unfinished else // Unfinished
Match->Status.BeingPlayed = Mch_GetIfMatchIsBeingPlayed (Match->MchCod); Match->Status.Playing = Mch_GetIfMatchIsBeingPlayed (Match->MchCod);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1074,7 +1082,7 @@ static void Mch_UpdateMatchStatusInDB (struct Match *Match)
Mch_ShowingStringsDB[Match->Status.Showing], Mch_ShowingStringsDB[Match->Status.Showing],
Match->MchCod,Gbl.Hierarchy.Crs.CrsCod); Match->MchCod,Gbl.Hierarchy.Crs.CrsCod);
if (Match->Status.BeingPlayed) if (Match->Status.Playing)
/* Update match as being played */ /* Update match as being played */
Mch_UpdateMatchAsBeingPlayed (Match->MchCod); Mch_UpdateMatchAsBeingPlayed (Match->MchCod);
else else
@ -1089,7 +1097,7 @@ static void Mch_UpdateMatchStatusInDB (struct Match *Match)
static void Mch_UpdateElapsedTimeInQuestion (struct Match *Match) static void Mch_UpdateElapsedTimeInQuestion (struct Match *Match)
{ {
/***** Update elapsed time in current question in database *****/ /***** Update elapsed time in current question in database *****/
if (Match->Status.BeingPlayed && if (Match->Status.Playing &&
Match->Status.QstInd > 0 && Match->Status.QstInd > 0 &&
Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) Match->Status.QstInd < Mch_AFTER_LAST_QUESTION)
DB_QueryINSERT ("can not update elapsed time in question", DB_QueryINSERT ("can not update elapsed time in question",
@ -1194,7 +1202,7 @@ void Mch_PauseMatchTch (void)
Mch_GetDataOfMatchByCod (&Match); Mch_GetDataOfMatchByCod (&Match);
/***** Update status *****/ /***** Update status *****/
Match.Status.BeingPlayed = false; // Resume match Match.Status.Playing = false; // Pause match
/***** Update match status in database *****/ /***** Update match status in database *****/
Mch_UpdateMatchStatusInDB (&Match); Mch_UpdateMatchStatusInDB (&Match);
@ -1226,7 +1234,7 @@ void Mch_ResumeMatchTch (void)
{ {
if (Match.Status.QstInd == 0) // Match has been created, but it has not started if (Match.Status.QstInd == 0) // Match has been created, but it has not started
Mch_SetMatchStatusToNext (&Match); Mch_SetMatchStatusToNext (&Match);
Match.Status.BeingPlayed = true; // Start/resume match Match.Status.Playing = true; // Start/resume match
} }
/***** Update match status in database *****/ /***** Update match status in database *****/
@ -1332,33 +1340,50 @@ void Mch_ForwardMatchTch (void)
static void Mch_SetMatchStatusToPrev (struct Match *Match) static void Mch_SetMatchStatusToPrev (struct Match *Match)
{ {
/***** What to show *****/ /***** What to show *****/
switch (Match->Status.Showing) if (Match->Status.QstInd == 0) // Start
{ Mch_SetMatchStatusToStart (Match);
case Mch_STEM: else if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // End
Match->Status.Showing = Match->Status.ShowResults ? Mch_RESULTS : Mch_SetMatchStatusToPrevQst (Match);
Mch_ANSWERS; else // Between start and end
switch (Match->Status.Showing)
{
case Mch_NOTHING:
case Mch_STEM:
Mch_SetMatchStatusToPrevQst (Match);
break;
case Mch_ANSWERS:
Match->Status.Showing = Mch_STEM;
break;
case Mch_RESULTS:
Match->Status.Showing = Mch_ANSWERS;
break;
}
}
/***** Get index of the previous question *****/ static void Mch_SetMatchStatusToPrevQst (struct Match *Match)
Match->Status.QstInd = Gam_GetPrevQuestionIndexInGame (Match->GamCod, {
Match->Status.QstInd); /***** Get index of the previous question *****/
if (Match->Status.QstInd == 0) // Start of questions has been reached Match->Status.QstInd = Gam_GetPrevQuestionIndexInGame (Match->GamCod,
{ Match->Status.QstInd);
Match->Status.QstCod = -1L; // No previous questions if (Match->Status.QstInd == 0) // Start of questions has been reached
Match->Status.BeingPlayed = false; // Match is not being played Mch_SetMatchStatusToStart (Match);
} else
else {
Match->Status.QstCod = Gam_GetQstCodFromQstInd (Match->GamCod, Match->Status.QstCod = Gam_GetQstCodFromQstInd (Match->GamCod,
Match->Status.QstInd); Match->Status.QstInd);
break; Match->Status.Showing = Match->Status.ShowResults ? Mch_RESULTS :
case Mch_ANSWERS: Mch_ANSWERS;
Match->Status.Showing = Mch_STEM;
break;
case Mch_RESULTS:
Match->Status.Showing = Mch_ANSWERS;
break;
} }
} }
static void Mch_SetMatchStatusToStart (struct Match *Match)
{
Match->Status.QstInd = 0; // Before first question
Match->Status.QstCod = -1L;
Match->Status.Playing = false;
Match->Status.Showing = Mch_NOTHING;
}
/*****************************************************************************/ /*****************************************************************************/
/**************** Set match status to next (forward) status ******************/ /**************** Set match status to next (forward) status ******************/
/*****************************************************************************/ /*****************************************************************************/
@ -1366,37 +1391,56 @@ static void Mch_SetMatchStatusToPrev (struct Match *Match)
static void Mch_SetMatchStatusToNext (struct Match *Match) static void Mch_SetMatchStatusToNext (struct Match *Match)
{ {
/***** What to show *****/ /***** What to show *****/
switch (Match->Status.Showing) if (Match->Status.QstInd == 0) // Start
{ Mch_SetMatchStatusToNextQst (Match);
case Mch_STEM: else if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // End
Match->Status.Showing = Mch_ANSWERS; Mch_SetMatchStatusToEnd (Match);
break; else // Between start and end
case Mch_ANSWERS: switch (Match->Status.Showing)
Match->Status.Showing = Match->Status.ShowResults ? Mch_RESULTS :
Mch_STEM;
break;
case Mch_RESULTS:
Match->Status.Showing = Mch_STEM;
break;
}
/***** Go to next question? *****/
if (Match->Status.Showing == Mch_STEM)
{
/***** Get index of the next question *****/
Match->Status.QstInd = Gam_GetNextQuestionIndexInGame (Match->GamCod,
Match->Status.QstInd);
if (Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) // Unfinished
Match->Status.QstCod = Gam_GetQstCodFromQstInd (Match->GamCod,
Match->Status.QstInd);
else // Finished
{ {
Match->Status.QstCod = -1L; // No more questions case Mch_NOTHING:
Match->Status.BeingPlayed = false; Match->Status.Showing = Mch_STEM;
break;
case Mch_STEM:
Match->Status.Showing = Mch_ANSWERS;
break;
case Mch_ANSWERS:
if (Match->Status.ShowResults)
Match->Status.Showing = Mch_RESULTS;
else
Mch_SetMatchStatusToNextQst (Match);
break;
case Mch_RESULTS:
Mch_SetMatchStatusToNextQst (Match);
break;
} }
}
static void Mch_SetMatchStatusToNextQst (struct Match *Match)
{
/***** Get index of the next question *****/
Match->Status.QstInd = Gam_GetNextQuestionIndexInGame (Match->GamCod,
Match->Status.QstInd);
/***** Get question code *****/
if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // Finished
Mch_SetMatchStatusToEnd (Match);
else // Unfinished
{
Match->Status.QstCod = Gam_GetQstCodFromQstInd (Match->GamCod,
Match->Status.QstInd);
Match->Status.Showing = Mch_STEM;
} }
} }
static void Mch_SetMatchStatusToEnd (struct Match *Match)
{
Match->Status.QstInd = Mch_AFTER_LAST_QUESTION; // After last question
Match->Status.QstCod = -1L;
Match->Status.Playing = false;
Match->Status.Showing = Mch_NOTHING;
}
/*****************************************************************************/ /*****************************************************************************/
/******* Show current match status (number, question, answers, button) *******/ /******* Show current match status (number, question, answers, button) *******/
/*****************************************************************************/ /*****************************************************************************/
@ -1459,7 +1503,7 @@ static void Mch_ShowMatchStatusForStd (struct Match *Match)
/***** Update players ******/ /***** Update players ******/
Mch_RegisterMeAsPlayerInMatch (Match->MchCod); Mch_RegisterMeAsPlayerInMatch (Match->MchCod);
if (Match->Status.BeingPlayed) if (Match->Status.Playing)
/* Show current question and possible answers */ /* Show current question and possible answers */
Mch_ShowQuestionAndAnswersStd (Match); Mch_ShowQuestionAndAnswersStd (Match);
else // Not being played else // Not being played
@ -1536,7 +1580,7 @@ static void Mch_ShowLeftColumnTch (struct Match *Match)
Mch_ShowNumPlayers (Match); Mch_ShowNumPlayers (Match);
/***** Number of users who have answered this question *****/ /***** Number of users who have answered this question *****/
if (Match->Status.BeingPlayed) if (Match->Status.Playing)
{ {
NumAnswerersQst = Mch_GetNumUsrsWhoHaveAnswerQst (Match->MchCod, NumAnswerersQst = Mch_GetNumUsrsWhoHaveAnswerQst (Match->MchCod,
Match->Status.QstInd); Match->Status.QstInd);
@ -1619,7 +1663,7 @@ static void Mch_PutMatchControlButtons (struct Match *Match)
/***** Center button *****/ /***** Center button *****/
fprintf (Gbl.F.Out,"<div class=\"MATCH_BUTTON_CENTER_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"MATCH_BUTTON_CENTER_CONTAINER\">");
if (Match->Status.BeingPlayed) // Being played if (Match->Status.Playing) // Being played
/* Put button to pause match */ /* Put button to pause match */
Mch_PutBigButton (ActPauMchTch, Mch_PutBigButton (ActPauMchTch,
Match->MchCod, Match->MchCod,
@ -1768,11 +1812,12 @@ static void Mch_ShowQuestionAndAnswersTch (struct Match *Match)
/* Write answers? */ /* Write answers? */
switch (Match->Status.Showing) switch (Match->Status.Showing)
{ {
case Mch_NOTHING:
case Mch_STEM: case Mch_STEM:
/* Don't write anything */ /* Don't write anything */
break; break;
case Mch_ANSWERS: case Mch_ANSWERS:
if (Match->Status.BeingPlayed) // Being played if (Match->Status.Playing) // Being played
/* Write answers */ /* Write answers */
Tst_WriteAnswersMatchResult (Match->MchCod, Tst_WriteAnswersMatchResult (Match->MchCod,
Match->Status.QstInd, Match->Status.QstInd,

View File

@ -71,7 +71,7 @@ typedef enum
typedef enum typedef enum
{ {
Tst_SHOW_TEST_TO_ANSWER, // Showing a test to a student Tst_SHOW_TEST_TO_ANSWER, // Showing a test to a student
Tst_SHOW_TEST_RESULT, // Showing the assessment of a test Tst_SHOW_TEST_RESULT, // Showing the assessment of a test
Tst_EDIT_TEST, // Editing test questions Tst_EDIT_TEST, // Editing test questions
Tst_SELECT_QUESTIONS_FOR_GAME, // Selecting test questions for a game Tst_SELECT_QUESTIONS_FOR_GAME, // Selecting test questions for a game
Tst_SHOW_GAME_TO_ANSWER, // Showing a game to a student Tst_SHOW_GAME_TO_ANSWER, // Showing a game to a student