Version19.89

This commit is contained in:
Antonio Cañas Vargas 2019-12-10 21:52:22 +01:00
parent 5137e9f5a9
commit 05db22eb5e
10 changed files with 223 additions and 174 deletions

View File

@ -13097,7 +13097,7 @@ SELECT projects.PrjCod,COUNT(prj_usr.UsrCod) AS NumStds FROM projects LEFT JOIN
SELECT COUNT(*) FROM tst_answers,gam_questions WHERE gam_questions.GamCod=6 AND gam_questions.QstCod=tst_answers.QstCod; SELECT COUNT(*) FROM tst_answers,gam_questions WHERE gam_questions.GamCod=6 AND gam_questions.QstCod=tst_answers.QstCod;
SELECT MIN(QstInd) FROM gam_questions WHERE GamCod=47 AND QstInd>5;

View File

@ -639,7 +639,7 @@ CREATE TABLE IF NOT EXISTS mch_matches (
Title VARCHAR(2047) NOT NULL, Title VARCHAR(2047) NOT NULL,
QstInd INT NOT NULL DEFAULT 0, QstInd INT NOT NULL DEFAULT 0,
QstCod INT NOT NULL DEFAULT -1, QstCod INT NOT NULL DEFAULT -1,
Showing ENUM('nothing','stem','answers','results') NOT NULL DEFAULT 'nothing', Showing ENUM('start','stem','answers','results','end') NOT NULL DEFAULT 'start',
NumCols INT NOT NULL DEFAULT 1, NumCols INT NOT NULL DEFAULT 1,
ShowQstResults ENUM('N','Y') NOT NULL DEFAULT 'N', ShowQstResults ENUM('N','Y') NOT NULL DEFAULT 'N',
ShowUsrResults ENUM('N','Y') NOT NULL DEFAULT 'N', ShowUsrResults ENUM('N','Y') NOT NULL DEFAULT 'N',

View File

@ -4811,9 +4811,9 @@ int swad__getMatchStatus (struct soap *soap,
"Type of answer not valid in a game."); "Type of answer not valid in a game.");
/***** Join match *****/ /***** Join match *****/
getMatchStatusOut->matchCode = 0; // == 0 ==> wait getMatchStatusOut->matchCode = 0; // == 0 ==> wait
if (Match.Status.Playing && // Match is being played if (Match.Status.Playing && // Match is being played
Match.Status.QstInd < Mch_AFTER_LAST_QUESTION) // Unfinished Match.Status.Showing != Mch_END) // Unfinished
/* Update players */ /* Update players */
getMatchStatusOut->matchCode = Mch_RegisterMeAsPlayerInMatch (&Match) ? matchCode : // > 0 ==> OK getMatchStatusOut->matchCode = Mch_RegisterMeAsPlayerInMatch (&Match) ? matchCode : // > 0 ==> OK
-1; // < 0 ==> can not join this match -1; // < 0 ==> can not join this match

View File

@ -2166,7 +2166,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
[ActJoiMch ] = {1780,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,Mch_GetMatchBeingPlayed ,Mch_JoinMatchAsStd ,NULL}, [ActJoiMch ] = {1780,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,Mch_GetMatchBeingPlayed ,Mch_JoinMatchAsStd ,NULL},
[ActSeeMchAnsQstStd ] = {1808,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_JoinMatchAsStd ,NULL}, [ActSeeMchAnsQstStd ] = {1808,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_JoinMatchAsStd ,NULL},
[ActRemMchAnsQstStd ] = {1809,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_RemoveQuestionAnswer ,NULL}, [ActRemMchAnsQstStd ] = {1809,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_RemoveMyQuestionAnswer ,NULL},
[ActAnsMchQstStd ] = {1651,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_ReceiveQuestionAnswer ,NULL}, [ActAnsMchQstStd ] = {1651,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_ReceiveQuestionAnswer ,NULL},
[ActRefMchStd ] = {1782,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_AJAX_RFRESH,Mch_GetMatchBeingPlayed ,Mch_RefreshMatchStd ,NULL}, [ActRefMchStd ] = {1782,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_AJAX_RFRESH,Mch_GetMatchBeingPlayed ,Mch_RefreshMatchStd ,NULL},

View File

@ -490,13 +490,19 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD: En OpenSWAD:
ps2pdf source.ps destination.pdf ps2pdf source.ps destination.pdf
*/ */
#define Log_PLATFORM_VERSION "SWAD 19.88.11 (2019-12-10)" #define Log_PLATFORM_VERSION "SWAD 19.89 (2019-12-10)"
#define CSS_FILE "swad19.88.5.css" #define CSS_FILE "swad19.88.5.css"
#define JS_FILE "swad19.70.js" #define JS_FILE "swad19.70.js"
/* /*
// TODO: Hacer un nuevo rol en los TFG: tutor externo (profesor de áreas no vinculadas con el centro, profesionales de empresas, etc.) // TODO: Hacer un nuevo rol en los TFG: tutor externo (profesor de áreas no vinculadas con el centro, profesionales de empresas, etc.)
// TODO: Impedir la creación y edición de proyectos si no son editables. // TODO: Impedir la creación y edición de proyectos si no son editables.
// TODO: ¿Poner en color rojo las fechas de los juegos que tengan todas las partidas terminadas?
Version 19.89: Dec 10, 2019 Game dates are in red colour if all their matches are finished or ot don't have matches. (248186 lines)
4 changes necessary in database:
ALTER TABLE mch_matches CHANGE COLUMN Showing Showing ENUM('nothing','stem','answers','results','start','end') NOT NULL DEFAULT 'nothing';
UPDATE mch_matches SET Showing='start' WHERE QstInd='0' AND Showing='nothing';
UPDATE mch_matches SET Showing='end' WHERE QstInd='2147483647' AND Showing='nothing';
ALTER TABLE mch_matches CHANGE COLUMN Showing Showing ENUM('start','stem','answers','results','end') NOT NULL DEFAULT 'start';
Version 19.88.11: Dec 10, 2019 Fixed bug in selection of groups. (248141 lines) Version 19.88.11: Dec 10, 2019 Fixed bug in selection of groups. (248141 lines)
Version 19.88.10: Dec 10, 2019 Fixed bug in matches results. (248145 lines) Version 19.88.10: Dec 10, 2019 Fixed bug in matches results. (248145 lines)

View File

@ -1372,23 +1372,23 @@ 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 | |
| Showing | enum('nothing','stem','answers','results') | NO | | nothing | | | Showing | enum('start','stem','answers','results','end') | NO | | start | |
| NumCols | int(11) | NO | | 1 | | | NumCols | int(11) | NO | | 1 | |
| ShowQstResults | enum('N','Y') | NO | | N | | | ShowQstResults | enum('N','Y') | NO | | N | |
| ShowUsrResults | enum('N','Y') | NO | | N | | | ShowUsrResults | enum('N','Y') | NO | | N | |
+----------------+--------------------------------------------+------+-----+---------+----------------+ +----------------+------------------------------------------------+------+-----+---------+----------------+
12 rows in set (0.01 sec) 12 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS mch_matches (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS mch_matches ("
"MchCod INT NOT NULL AUTO_INCREMENT," "MchCod INT NOT NULL AUTO_INCREMENT,"
@ -1399,7 +1399,7 @@ mysql> DESCRIBE mch_matches;
"Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE "Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE
"QstInd INT NOT NULL DEFAULT 0," "QstInd INT NOT NULL DEFAULT 0,"
"QstCod INT NOT NULL DEFAULT -1," "QstCod INT NOT NULL DEFAULT -1,"
"Showing ENUM('nothing','stem','answers','results') NOT NULL DEFAULT 'nothing'," "Showing ENUM('start','stem','answers','results','end') NOT NULL DEFAULT 'start',"
"NumCols INT NOT NULL DEFAULT 1," "NumCols INT NOT NULL DEFAULT 1,"
"ShowQstResults ENUM('N','Y') NOT NULL DEFAULT 'N'," "ShowQstResults ENUM('N','Y') NOT NULL DEFAULT 'N',"
"ShowUsrResults ENUM('N','Y') NOT NULL DEFAULT 'N'," "ShowUsrResults ENUM('N','Y') NOT NULL DEFAULT 'N',"

View File

@ -160,7 +160,7 @@ static void Gam_PutParamsOneQst (void);
static void Gam_ExchangeQuestions (long GamCod, static void Gam_ExchangeQuestions (long GamCod,
unsigned QstIndTop,unsigned QstIndBottom); unsigned QstIndTop,unsigned QstIndBottom);
static bool Gam_GetNumMchsGameAndCheckIfEditable (struct Game *Game); static bool Gam_CheckIfEditable (const struct Game *Game);
static long Gam_GetCurrentGamCod (void); static long Gam_GetCurrentGamCod (void);
@ -251,8 +251,8 @@ static void Gam_ListAllGames (void)
HTM_TR_End (); HTM_TR_End ();
/***** Write all the games *****/ /***** Write all games *****/
for (NumGame = Pagination.FirstItemVisible; for (NumGame = Pagination.FirstItemVisible;
NumGame <= Pagination.LastItemVisible; NumGame <= Pagination.LastItemVisible;
NumGame++) NumGame++)
{ {
@ -442,6 +442,7 @@ static void Gam_ShowOneGame (struct Game *Game,bool ShowOnlyThisGame)
static unsigned UniqueId = 0; static unsigned UniqueId = 0;
char *Id; char *Id;
Dat_StartEndTime_t StartEndTime; Dat_StartEndTime_t StartEndTime;
const char *Color;
char Txt[Cns_MAX_BYTES_TEXT + 1]; char Txt[Cns_MAX_BYTES_TEXT + 1];
/***** Set anchor string *****/ /***** Set anchor string *****/
@ -470,21 +471,22 @@ static void Gam_ShowOneGame (struct Game *Game,bool ShowOnlyThisGame)
/***** Start/end date/time *****/ /***** Start/end date/time *****/
UniqueId++; UniqueId++;
for (StartEndTime = (Dat_StartEndTime_t) 0; for (StartEndTime = (Dat_StartEndTime_t) 0;
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1); StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
StartEndTime++) StartEndTime++)
{ {
if (asprintf (&Id,"gam_date_%u_%u",(unsigned) StartEndTime,UniqueId) < 0) if (asprintf (&Id,"gam_date_%u_%u",(unsigned) StartEndTime,UniqueId) < 0)
Lay_NotEnoughMemoryExit (); Lay_NotEnoughMemoryExit ();
Color = Game->NumUnfinishedMchs ? (Game->Hidden ? "DATE_GREEN_LIGHT":
"DATE_GREEN") :
(Game->Hidden ? "DATE_RED_LIGHT":
"DATE_RED");
if (ShowOnlyThisGame) if (ShowOnlyThisGame)
HTM_TD_Begin ("id=\"%s\" class=\"%s LT\"", HTM_TD_Begin ("id=\"%s\" class=\"%s LT\"",
Id,Game->Hidden ? "DATE_GREEN_LIGHT": Id,Color);
"DATE_GREEN");
else else
HTM_TD_Begin ("id=\"%s\" class=\"%s LT COLOR%u\"", HTM_TD_Begin ("id=\"%s\" class=\"%s LT COLOR%u\"",
Id,Game->Hidden ? "DATE_GREEN_LIGHT": Id,Color,Gbl.RowEvenOdd);
"DATE_GREEN",
Gbl.RowEvenOdd);
if (Game->TimeUTC[Dat_START_TIME]) if (Game->TimeUTC[Dat_START_TIME])
Dat_WriteLocalDateHMSFromUTC (Id,Game->TimeUTC[StartEndTime], Dat_WriteLocalDateHMSFromUTC (Id,Game->TimeUTC[StartEndTime],
Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK,
@ -934,6 +936,9 @@ void Gam_GetDataOfGameByCod (struct Game *Game)
/* Get number of matches */ /* Get number of matches */
Game->NumMchs = Mch_GetNumMchsInGame (Game->GamCod); Game->NumMchs = Mch_GetNumMchsInGame (Game->GamCod);
/* Get number of unfinished matches */
Game->NumUnfinishedMchs = Mch_GetNumUnfinishedMchsInGame (Game->GamCod);
} }
else else
/* Initialize to empty game */ /* Initialize to empty game */
@ -989,6 +994,7 @@ static void Gam_ResetGame (struct Game *Game)
Game->Title[0] = '\0'; Game->Title[0] = '\0';
Game->NumQsts = 0; Game->NumQsts = 0;
Game->NumMchs = 0; Game->NumMchs = 0;
Game->NumUnfinishedMchs = 0;
Game->Hidden = false; Game->Hidden = false;
} }
@ -1514,7 +1520,7 @@ void Gam_RequestNewQuestion (void)
Gam_GetDataOfGameByCod (&Game); Gam_GetDataOfGameByCod (&Game);
/***** Check if game has matches *****/ /***** Check if game has matches *****/
if (Gam_GetNumMchsGameAndCheckIfEditable (&Game)) if (Gam_CheckIfEditable (&Game))
{ {
/***** Show form to create a new question in this game *****/ /***** Show form to create a new question in this game *****/
Gam_SetCurrentGamCod (Game.GamCod); // Used to pass parameter Gam_SetCurrentGamCod (Game.GamCod); // Used to pass parameter
@ -1540,9 +1546,10 @@ void Gam_ListTstQuestionsToSelect (void)
/***** Get parameters *****/ /***** Get parameters *****/
if ((Game.GamCod = Gam_GetParams ()) == -1L) if ((Game.GamCod = Gam_GetParams ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
Gam_GetDataOfGameByCod (&Game);
/***** Check if game has matches *****/ /***** Check if game has matches *****/
if (Gam_GetNumMchsGameAndCheckIfEditable (&Game)) if (Gam_CheckIfEditable (&Game))
{ {
/***** List several test questions for selection *****/ /***** List several test questions for selection *****/
Gam_SetCurrentGamCod (Game.GamCod); // Used to pass parameter Gam_SetCurrentGamCod (Game.GamCod); // Used to pass parameter
@ -1683,9 +1690,10 @@ unsigned Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd)
/***** Get previous question index (row[0]) *****/ /***** Get previous question index (row[0]) *****/
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
if (row[0]) if (row)
if (sscanf (row[0],"%u",&PrevQstInd) != 1) if (row[0])
Lay_ShowErrorAndExit ("Error when getting previous question index."); if (sscanf (row[0],"%u",&PrevQstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting previous question index.");
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res); DB_FreeMySQLResult (&mysql_res);
@ -1716,9 +1724,10 @@ unsigned Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd)
/***** Get next question index (row[0]) *****/ /***** Get next question index (row[0]) *****/
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
if (row[0]) if (row)
if (sscanf (row[0],"%u",&NextQstInd) != 1) if (row[0])
Lay_ShowErrorAndExit ("Error when getting next question index."); if (sscanf (row[0],"%u",&NextQstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting next question index.");
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res); DB_FreeMySQLResult (&mysql_res);
@ -1737,7 +1746,7 @@ static void Gam_ListGameQuestions (struct Game *Game)
extern const char *Txt_This_game_has_no_questions; extern const char *Txt_This_game_has_no_questions;
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
unsigned NumQsts; unsigned NumQsts;
bool ICanEditQuestions = Gam_GetNumMchsGameAndCheckIfEditable (Game); bool ICanEditQuestions = Gam_CheckIfEditable (Game);
/***** 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",
@ -1996,7 +2005,7 @@ void Gam_AddTstQuestionsToGame (void)
Gam_GetDataOfGameByCod (&Game); Gam_GetDataOfGameByCod (&Game);
/***** Check if game has matches *****/ /***** Check if game has matches *****/
if (Gam_GetNumMchsGameAndCheckIfEditable (&Game)) if (Gam_CheckIfEditable (&Game))
{ {
/***** Get selected questions *****/ /***** Get selected questions *****/
/* Allocate space for selected question codes */ /* Allocate space for selected question codes */
@ -2122,7 +2131,7 @@ void Gam_RequestRemoveQst (void)
Gam_GetDataOfGameByCod (&Game); Gam_GetDataOfGameByCod (&Game);
/***** Check if game has matches *****/ /***** Check if game has matches *****/
if (Gam_GetNumMchsGameAndCheckIfEditable (&Game)) if (Gam_CheckIfEditable (&Game))
{ {
/***** Get question index *****/ /***** Get question index *****/
QstInd = Gam_GetParamQstInd (); QstInd = Gam_GetParamQstInd ();
@ -2160,7 +2169,7 @@ void Gam_RemoveQst (void)
Gam_GetDataOfGameByCod (&Game); Gam_GetDataOfGameByCod (&Game);
/***** Check if game has matches *****/ /***** Check if game has matches *****/
if (Gam_GetNumMchsGameAndCheckIfEditable (&Game)) if (Gam_CheckIfEditable (&Game))
{ {
/***** Get question index *****/ /***** Get question index *****/
QstInd = Gam_GetParamQstInd (); QstInd = Gam_GetParamQstInd ();
@ -2220,7 +2229,7 @@ void Gam_MoveUpQst (void)
Gam_GetDataOfGameByCod (&Game); Gam_GetDataOfGameByCod (&Game);
/***** Check if game has matches *****/ /***** Check if game has matches *****/
if (Gam_GetNumMchsGameAndCheckIfEditable (&Game)) if (Gam_CheckIfEditable (&Game))
{ {
/***** Get question index *****/ /***** Get question index *****/
QstIndBottom = Gam_GetParamQstInd (); QstIndBottom = Gam_GetParamQstInd ();
@ -2271,7 +2280,7 @@ void Gam_MoveDownQst (void)
Gam_GetDataOfGameByCod (&Game); Gam_GetDataOfGameByCod (&Game);
/***** Check if game has matches *****/ /***** Check if game has matches *****/
if (Gam_GetNumMchsGameAndCheckIfEditable (&Game)) if (Gam_CheckIfEditable (&Game))
{ {
/***** Get question index *****/ /***** Get question index *****/
QstIndTop = Gam_GetParamQstInd (); QstIndTop = Gam_GetParamQstInd ();
@ -2365,16 +2374,13 @@ static void Gam_ExchangeQuestions (long GamCod,
/*****************************************************************************/ /*****************************************************************************/
/*********** Get number of matches and check is edition is possible **********/ /*********** Get number of matches and check is edition is possible **********/
/*****************************************************************************/ /*****************************************************************************/
// Games with matches should not be edited // Before calling this function, number of matches must be calculated
static bool Gam_GetNumMchsGameAndCheckIfEditable (struct Game *Game) static bool Gam_CheckIfEditable (const struct Game *Game)
{ {
/***** Get number of matches *****/
Game->NumMchs = Mch_GetNumMchsInGame (Game->GamCod);
if (Gam_CheckIfICanEditGames ()) if (Gam_CheckIfICanEditGames ())
/***** Questions are editable only if game has no matches *****/ /***** Questions are editable only if game has no matches *****/
return (bool) (Game->NumMchs == 0); return (bool) (Game->NumMchs == 0); // Games with matches should not be edited
else else
return false; // Questions are not editable return false; // Questions are not editable
} }

View File

@ -45,17 +45,18 @@ struct GameSelected
struct Game struct Game
{ {
long GamCod; // Game code long GamCod; // Game code
long CrsCod; // Course code long CrsCod; // Course code
long UsrCod; // Author code long UsrCod; // Author code
double MaxGrade; // Score range [0...max.score] double MaxGrade; // Score range [0...max.score]
// will be converted to // will be converted to
// grade range [0...max.grade] // grade range [0...max.grade]
char Title[Gam_MAX_BYTES_TITLE + 1]; char Title[Gam_MAX_BYTES_TITLE + 1];
time_t TimeUTC[Dat_NUM_START_END_TIME]; time_t TimeUTC[Dat_NUM_START_END_TIME];
bool Hidden; // Game is hidden bool Hidden; // Game is hidden
unsigned NumQsts; // Number of questions in the game unsigned NumQsts; // Number of questions in the game
unsigned NumMchs; // Number of matches in the game unsigned NumMchs; // Number of matches in the game
unsigned NumUnfinishedMchs; // Number of unfinished matches in the game
}; };
#define Gam_NUM_ORDERS 3 #define Gam_NUM_ORDERS 3

View File

@ -77,10 +77,11 @@ typedef enum
const char *Mch_ShowingStringsDB[Mch_NUM_SHOWING] = const char *Mch_ShowingStringsDB[Mch_NUM_SHOWING] =
{ {
"nothing", [Mch_START ] = "start",
"stem", [Mch_STEM ] = "stem",
"answers", [Mch_ANSWERS] = "answers",
"results", [Mch_RESULTS] = "results",
[Mch_END ] = "end",
}; };
#define Mch_MAX_COLS 4 #define Mch_MAX_COLS 4
@ -205,7 +206,7 @@ static void Mch_SetMatchAsNotBeingPlayed (long MchCod);
static bool Mch_GetIfMatchIsBeingPlayed (long MchCod); static bool Mch_GetIfMatchIsBeingPlayed (long MchCod);
static void Mch_GetNumPlayers (struct Match *Match); static void Mch_GetNumPlayers (struct Match *Match);
static void Mch_RemoveAnswerToMatchQuestion (const struct Match *Match); static void Mch_RemoveMyAnswerToMatchQuestion (const struct Match *Match);
static double Mch_ComputeScore (unsigned NumQsts); static double Mch_ComputeScore (unsigned NumQsts);
@ -357,7 +358,7 @@ void Mch_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.Showing = Mch_STEM; Match->Status.Showing = Mch_START;
Match->Status.Playing = false; Match->Status.Playing = false;
Match->Status.NumPlayers = 0; Match->Status.NumPlayers = 0;
Match->Status.NumCols = Mch_NUM_COLS_DEFAULT; Match->Status.NumCols = Mch_NUM_COLS_DEFAULT;
@ -576,8 +577,8 @@ static void Mch_ListOneOrMoreMatchesTimes (const struct Match *Match,unsigned Un
Lay_NotEnoughMemoryExit (); Lay_NotEnoughMemoryExit ();
HTM_TD_Begin ("id=\"%s\" class=\"%s LT COLOR%u\"", HTM_TD_Begin ("id=\"%s\" class=\"%s LT COLOR%u\"",
Id, Id,
Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION ? "DATE_RED" : Match->Status.Showing == Mch_END ? "DATE_RED" :
"DATE_GREEN", "DATE_GREEN",
Gbl.RowEvenOdd); Gbl.RowEvenOdd);
Dat_WriteLocalDateHMSFromUTC (Id,Match->TimeUTC[StartEndTime], Dat_WriteLocalDateHMSFromUTC (Id,Match->TimeUTC[StartEndTime],
Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK,
@ -703,7 +704,7 @@ static void Mch_ListOneOrMoreMatchesStatus (const struct Match *Match,unsigned N
HTM_TD_Begin ("class=\"DAT CT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT CT COLOR%u\"",Gbl.RowEvenOdd);
if (Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) // Unfinished match if (Match->Status.Showing != Mch_END) // Match not over
{ {
/* Current question index / total of questions */ /* Current question index / total of questions */
HTM_DIV_Begin ("class=\"DAT\""); HTM_DIV_Begin ("class=\"DAT\"");
@ -717,8 +718,8 @@ static void Mch_ListOneOrMoreMatchesStatus (const struct Match *Match,unsigned N
ActResMch, ActResMch,
NULL, NULL,
Mch_PutParamsPlay, Mch_PutParamsPlay,
Match->Status.QstInd < Mch_AFTER_LAST_QUESTION ? "play.svg" : Match->Status.Showing == Mch_END ? "flag-checkered.svg" :
"flag-checkered.svg", "play.svg",
Gbl.Usrs.Me.Role.Logged == Rol_STD ? Txt_Play : Gbl.Usrs.Me.Role.Logged == Rol_STD ? Txt_Play :
Txt_Resume); Txt_Resume);
@ -915,9 +916,9 @@ static void Mch_GetMatchDataFromRow (MYSQL_RES *mysql_res,
Match->Status.ShowUsrResults = (row[11][0] == 'Y'); Match->Status.ShowUsrResults = (row[11][0] == 'Y');
/***** 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.Showing == Mch_END) // Match over
Match->Status.Playing = false; Match->Status.Playing = false;
else // Unfinished else // Match not over
Match->Status.Playing = Mch_GetIfMatchIsBeingPlayed (Match->MchCod); Match->Status.Playing = Mch_GetIfMatchIsBeingPlayed (Match->MchCod);
} }
@ -1680,8 +1681,8 @@ static void Mch_UpdateElapsedTimeInQuestion (const struct Match *Match)
{ {
/***** Update elapsed time in current question in database *****/ /***** Update elapsed time in current question in database *****/
if (Match->Status.Playing && // Match is being played if (Match->Status.Playing && // Match is being played
Match->Status.QstInd > 0 && Match->Status.Showing != Mch_START &&
Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) Match->Status.Showing != Mch_END)
DB_QueryINSERT ("can not update elapsed time in question", DB_QueryINSERT ("can not update elapsed time in question",
"INSERT INTO mch_times (MchCod,QstInd,ElapsedTime)" "INSERT INTO mch_times (MchCod,QstInd,ElapsedTime)"
" VALUES (%ld,%u,SEC_TO_TIME(%u))" " VALUES (%ld,%u,SEC_TO_TIME(%u))"
@ -1786,11 +1787,11 @@ void Mch_PlayPauseMatch (void)
/***** Update status *****/ /***** Update status *****/
if (Match.Status.Playing) // Match is being played ==> pause it if (Match.Status.Playing) // Match is being played ==> pause it
Match.Status.Playing = false; // Pause match Match.Status.Playing = false; // Pause match
else // Match is paused, not being played ==> play it else // Match is paused, not being played ==> play it
/* If unfinished, update status */ /* If not over, update status */
if (Match.Status.QstInd < Mch_AFTER_LAST_QUESTION) // Unfinished if (Match.Status.Showing != Mch_END) // Match not over
Match.Status.Playing = true; // Start/resume match Match.Status.Playing = true; // Start/resume match
/***** Update match status in database *****/ /***** Update match status in database *****/
Mch_UpdateMatchStatusInDB (&Match); Mch_UpdateMatchStatusInDB (&Match);
@ -1931,24 +1932,22 @@ void Mch_ForwardMatch (void)
static void Mch_SetMatchStatusToPrev (struct Match *Match) static void Mch_SetMatchStatusToPrev (struct Match *Match)
{ {
/***** What to show *****/ /***** What to show *****/
if (Match->Status.QstInd == 0) // Start switch (Match->Status.Showing)
Mch_SetMatchStatusToStart (Match); {
else if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // End case Mch_START:
Mch_SetMatchStatusToPrevQst (Match); Mch_SetMatchStatusToStart (Match);
else // Between start and end break;
switch (Match->Status.Showing) case Mch_STEM:
{ case Mch_END:
case Mch_NOTHING: Mch_SetMatchStatusToPrevQst (Match);
case Mch_STEM: break;
Mch_SetMatchStatusToPrevQst (Match); case Mch_ANSWERS:
break; Match->Status.Showing = Mch_STEM;
case Mch_ANSWERS: break;
Match->Status.Showing = Mch_STEM; case Mch_RESULTS:
break; Match->Status.Showing = Mch_ANSWERS;
case Mch_RESULTS: break;
Match->Status.Showing = Mch_ANSWERS; }
break;
}
} }
static void Mch_SetMatchStatusToPrevQst (struct Match *Match) static void Mch_SetMatchStatusToPrevQst (struct Match *Match)
@ -1956,15 +1955,15 @@ static void Mch_SetMatchStatusToPrevQst (struct Match *Match)
/***** Get index of the previous question *****/ /***** Get index of the previous question *****/
Match->Status.QstInd = Gam_GetPrevQuestionIndexInGame (Match->GamCod, Match->Status.QstInd = Gam_GetPrevQuestionIndexInGame (Match->GamCod,
Match->Status.QstInd); Match->Status.QstInd);
if (Match->Status.QstInd == 0) // Start of questions has been reached if (Match->Status.QstInd) // Start of questions not reached
Mch_SetMatchStatusToStart (Match);
else
{ {
Match->Status.QstCod = Gam_GetQstCodFromQstInd (Match->GamCod, Match->Status.QstCod = Gam_GetQstCodFromQstInd (Match->GamCod,
Match->Status.QstInd); Match->Status.QstInd);
Match->Status.Showing = Match->Status.ShowQstResults ? Mch_RESULTS : Match->Status.Showing = Match->Status.ShowQstResults ? Mch_RESULTS :
Mch_ANSWERS; Mch_ANSWERS;
} }
else // Start of questions reached
Mch_SetMatchStatusToStart (Match);
} }
static void Mch_SetMatchStatusToStart (struct Match *Match) static void Mch_SetMatchStatusToStart (struct Match *Match)
@ -1972,7 +1971,7 @@ static void Mch_SetMatchStatusToStart (struct Match *Match)
Match->Status.QstInd = 0; // Before first question Match->Status.QstInd = 0; // Before first question
Match->Status.QstCod = -1L; Match->Status.QstCod = -1L;
Match->Status.Playing = false; Match->Status.Playing = false;
Match->Status.Showing = Mch_NOTHING; Match->Status.Showing = Mch_START;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1982,29 +1981,27 @@ static void Mch_SetMatchStatusToStart (struct Match *Match)
static void Mch_SetMatchStatusToNext (struct Match *Match) static void Mch_SetMatchStatusToNext (struct Match *Match)
{ {
/***** What to show *****/ /***** What to show *****/
if (Match->Status.QstInd == 0) // Start switch (Match->Status.Showing)
Mch_SetMatchStatusToNextQst (Match); {
else if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // End case Mch_START:
Mch_SetMatchStatusToEnd (Match); Mch_SetMatchStatusToNextQst (Match);
else // Between start and end break;
switch (Match->Status.Showing) case Mch_STEM:
{ Match->Status.Showing = Mch_ANSWERS;
case Mch_NOTHING: break;
Match->Status.Showing = Mch_STEM; case Mch_ANSWERS:
break; if (Match->Status.ShowQstResults)
case Mch_STEM: Match->Status.Showing = Mch_RESULTS;
Match->Status.Showing = Mch_ANSWERS; else
break;
case Mch_ANSWERS:
if (Match->Status.ShowQstResults)
Match->Status.Showing = Mch_RESULTS;
else
Mch_SetMatchStatusToNextQst (Match);
break;
case Mch_RESULTS:
Mch_SetMatchStatusToNextQst (Match); Mch_SetMatchStatusToNextQst (Match);
break; break;
} case Mch_RESULTS:
Mch_SetMatchStatusToNextQst (Match);
break;
case Mch_END:
Mch_SetMatchStatusToEnd (Match);
break;
}
} }
static void Mch_SetMatchStatusToNextQst (struct Match *Match) static void Mch_SetMatchStatusToNextQst (struct Match *Match)
@ -2014,14 +2011,14 @@ static void Mch_SetMatchStatusToNextQst (struct Match *Match)
Match->Status.QstInd); Match->Status.QstInd);
/***** Get question code *****/ /***** Get question code *****/
if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // Finished if (Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) // End of questions not reached
Mch_SetMatchStatusToEnd (Match);
else // Unfinished
{ {
Match->Status.QstCod = Gam_GetQstCodFromQstInd (Match->GamCod, Match->Status.QstCod = Gam_GetQstCodFromQstInd (Match->GamCod,
Match->Status.QstInd); Match->Status.QstInd);
Match->Status.Showing = Mch_STEM; Match->Status.Showing = Mch_STEM;
} }
else // End of questions reached
Mch_SetMatchStatusToEnd (Match);
} }
static void Mch_SetMatchStatusToEnd (struct Match *Match) static void Mch_SetMatchStatusToEnd (struct Match *Match)
@ -2029,7 +2026,7 @@ static void Mch_SetMatchStatusToEnd (struct Match *Match)
Match->Status.QstInd = Mch_AFTER_LAST_QUESTION; // After last question Match->Status.QstInd = Mch_AFTER_LAST_QUESTION; // After last question
Match->Status.QstCod = -1L; Match->Status.QstCod = -1L;
Match->Status.Playing = false; Match->Status.Playing = false;
Match->Status.Showing = Mch_NOTHING; Match->Status.Showing = Mch_END;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -2074,7 +2071,7 @@ static void Mch_ShowMatchStatusForStd (struct Match *Match,Mch_Update_t Update)
} }
/*****************************************************************************/ /*****************************************************************************/
/******************* Get number of questions of a game *********************/ /********************** Get number of matches in a game **********************/
/*****************************************************************************/ /*****************************************************************************/
unsigned Mch_GetNumMchsInGame (long GamCod) unsigned Mch_GetNumMchsInGame (long GamCod)
@ -2091,6 +2088,24 @@ unsigned Mch_GetNumMchsInGame (long GamCod)
GamCod); GamCod);
} }
/*****************************************************************************/
/*************** Get number of unfinished matches in a game ******************/
/*****************************************************************************/
unsigned Mch_GetNumUnfinishedMchsInGame (long GamCod)
{
/***** Trivial check *****/
if (GamCod < 0) // A non-existing game...
return 0; // ...has no matches
/***** Get number of matches in a game from database *****/
return
(unsigned) DB_QueryCOUNT ("can not get number of unfinished matches of a game",
"SELECT COUNT(*) FROM mch_matches"
" WHERE GamCod=%ld AND Showing<>'%s'",
GamCod,Mch_ShowingStringsDB[Mch_END]);
}
/*****************************************************************************/ /*****************************************************************************/
/************ Check if I belong to any of the groups of a match **************/ /************ Check if I belong to any of the groups of a match **************/
/*****************************************************************************/ /*****************************************************************************/
@ -2176,8 +2191,8 @@ static void Mch_ShowRefreshablePartTch (struct Match *Match)
/***** Write elapsed time in question *****/ /***** Write elapsed time in question *****/
HTM_DIV_Begin ("class=\"MCH_TIME_QST\""); HTM_DIV_Begin ("class=\"MCH_TIME_QST\"");
if (Match->Status.QstInd > 0 && if (Match->Status.Showing != Mch_START &&
Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) Match->Status.Showing != Mch_END)
{ {
Mch_GetElapsedTimeInQuestion (Match,&Time); Mch_GetElapsedTimeInQuestion (Match,&Time);
Dat_WriteHoursMinutesSeconds (&Time); Dat_WriteHoursMinutesSeconds (&Time);
@ -2193,8 +2208,8 @@ static void Mch_ShowRefreshablePartTch (struct Match *Match)
HTM_Txt (Txt_MATCH_respond); HTM_Txt (Txt_MATCH_respond);
HTM_BR (); HTM_BR ();
HTM_STRONG_Begin (); HTM_STRONG_Begin ();
if (Match->Status.QstInd > 0 && if (Match->Status.Showing != Mch_START &&
Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) Match->Status.Showing != Mch_END)
HTM_Unsigned (NumAnswerersQst); HTM_Unsigned (NumAnswerersQst);
else else
HTM_Hyphen (); HTM_Hyphen ();
@ -2223,10 +2238,10 @@ static void Mch_ShowRightColumnTch (const struct Match *Match)
Mch_ShowMatchTitle (Match); Mch_ShowMatchTitle (Match);
/***** Bottom row: current question and possible answers *****/ /***** Bottom row: current question and possible answers *****/
if (Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) // Not finished if (Match->Status.Showing == Mch_END) // Match over
Mch_ShowQuestionAndAnswersTch (Match);
else // Finished
Mch_ShowMatchScore (Match); Mch_ShowMatchScore (Match);
else // Match not over
Mch_ShowQuestionAndAnswersTch (Match);
/***** End right container *****/ /***** End right container *****/
HTM_DIV_End (); HTM_DIV_End ();
@ -2251,8 +2266,8 @@ static void Mch_ShowLeftColumnStd (const struct Match *Match,
/***** Write number of question *****/ /***** Write number of question *****/
Mch_ShowNumQstInMatch (Match); Mch_ShowNumQstInMatch (Match);
if (Match->Status.QstInd > 0 && if (Match->Status.Showing != Mch_START &&
Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) Match->Status.Showing != Mch_END)
{ {
/***** Write whether question is answered or not *****/ /***** Write whether question is answered or not *****/
Mch_PutIfAnswered (Match,Answered); Mch_PutIfAnswered (Match,Answered);
@ -2285,9 +2300,11 @@ static void Mch_ShowRightColumnStd (struct Match *Match,
Mch_ShowMatchTitle (Match); Mch_ShowMatchTitle (Match);
/***** Bottom row *****/ /***** Bottom row *****/
if (Match->Status.Playing) // Match is being played if (Match->Status.Playing) // Match is being played
{ {
if (Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) // Match not over if (Match->Status.Showing == Mch_END) // Match over
Mch_ShowWaitImage (Txt_Please_wait_);
else // Match not over
{ {
HTM_DIV_Begin ("class=\"MCH_BOTTOM\""); HTM_DIV_Begin ("class=\"MCH_BOTTOM\"");
@ -2304,10 +2321,8 @@ static void Mch_ShowRightColumnStd (struct Match *Match,
HTM_DIV_End (); HTM_DIV_End ();
} }
else // Match over
Mch_ShowWaitImage (Txt_Please_wait_);
} }
else // Match is not being played else // Match is not being played
Mch_ShowWaitImage (Txt_Please_wait_); Mch_ShowWaitImage (Txt_Please_wait_);
/***** End right container *****/ /***** End right container *****/
@ -2325,12 +2340,18 @@ static void Mch_ShowNumQstInMatch (const struct Match *Match)
unsigned NumQsts = Gam_GetNumQstsGame (Match->GamCod); unsigned NumQsts = Gam_GetNumQstsGame (Match->GamCod);
HTM_DIV_Begin ("class=\"MCH_NUM_QST\""); HTM_DIV_Begin ("class=\"MCH_NUM_QST\"");
if (Match->Status.QstInd == 0) // Not started switch (Match->Status.Showing)
HTM_Txt (Txt_MATCH_Start); {
else if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // Finished case Mch_START: // Not started
HTM_Txt (Txt_MATCH_End); HTM_Txt (Txt_MATCH_Start);
else break;
HTM_TxtF ("%u/%u",Match->Status.QstInd,NumQsts); case Mch_END: // Match over
HTM_Txt (Txt_MATCH_End);
break;
default:
HTM_TxtF ("%u/%u",Match->Status.QstInd,NumQsts);
break;
}
HTM_DIV_End (); HTM_DIV_End ();
} }
@ -2351,7 +2372,7 @@ static void Mch_PutMatchControlButtons (const struct Match *Match)
/***** Left button *****/ /***** Left button *****/
HTM_DIV_Begin ("class=\"MCH_BUTTON_LEFT_CONTAINER\""); HTM_DIV_Begin ("class=\"MCH_BUTTON_LEFT_CONTAINER\"");
if (Match->Status.QstInd == 0) if (Match->Status.Showing == Mch_START)
/* Put button to close browser tab */ /* Put button to close browser tab */
Mch_PutBigButtonClose (); Mch_PutBigButtonClose ();
else else
@ -2368,23 +2389,31 @@ static void Mch_PutMatchControlButtons (const struct Match *Match)
Mch_ICON_PAUSE,Txt_Pause); Mch_ICON_PAUSE,Txt_Pause);
else // Match is paused, not being played else // Match is paused, not being played
{ {
if (Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) // Not finished switch (Match->Status.Showing)
/* Put button to play match */ {
Mch_PutBigButton (ActPlyPauMch,"play_pause",Match->MchCod, case Mch_START: // Match just started, before first question
Mch_ICON_PLAY,Match->Status.QstInd == 0 ? Txt_Start : /* Put button to start playing match */
Txt_Resume); Mch_PutBigButton (ActPlyPauMch,"play_pause",Match->MchCod,
else // Finished Mch_ICON_PLAY,Txt_Start);
/* Put disabled button to play match */ break;
Mch_PutBigButtonOff (Mch_ICON_PLAY); case Mch_END: // Match over
/* Put disabled button to play match */
Mch_PutBigButtonOff (Mch_ICON_PLAY);
break;
default:
/* Put button to resume match */
Mch_PutBigButton (ActPlyPauMch,"play_pause",Match->MchCod,
Mch_ICON_PLAY,Txt_Resume);
}
} }
HTM_DIV_End (); HTM_DIV_End ();
/***** Right button *****/ /***** Right button *****/
HTM_DIV_Begin ("class=\"MCH_BUTTON_RIGHT_CONTAINER\""); HTM_DIV_Begin ("class=\"MCH_BUTTON_RIGHT_CONTAINER\"");
if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // Finished if (Match->Status.Showing == Mch_END) // Match over
/* Put button to close browser tab */ /* Put button to close browser tab */
Mch_PutBigButtonClose (); Mch_PutBigButtonClose ();
else else // Match not over
/* Put button to show answers */ /* Put button to show answers */
Mch_PutBigButton (ActFwdMch,"forward",Match->MchCod, Mch_PutBigButton (ActFwdMch,"forward",Match->MchCod,
Mch_ICON_NEXT,Txt_Go_forward); Mch_ICON_NEXT,Txt_Go_forward);
@ -2584,8 +2613,8 @@ static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match)
MYSQL_ROW row; MYSQL_ROW row;
/***** Trivial check: question index should be correct *****/ /***** Trivial check: question index should be correct *****/
if (Match->Status.QstInd == 0 || if (Match->Status.Showing == Mch_START ||
Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) Match->Status.Showing == Mch_END)
return; return;
/***** Get data of question from database *****/ /***** Get data of question from database *****/
@ -2625,7 +2654,9 @@ static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match)
/***** Write answers? *****/ /***** Write answers? *****/
switch (Match->Status.Showing) switch (Match->Status.Showing)
{ {
case Mch_NOTHING: case Mch_START:
/* Don't write anything */
break;
case Mch_STEM: case Mch_STEM:
/* Don't write anything */ /* Don't write anything */
break; break;
@ -2644,6 +2675,9 @@ static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match)
"MCH_TCH_ANS", "MCH_TCH_ANS",
true); // Show result true); // Show result
break; break;
case Mch_END:
/* Don't write anything */
break;
} }
HTM_DIV_End (); // Bottom HTM_DIV_End (); // Bottom
@ -3114,7 +3148,7 @@ bool Mch_RegisterMeAsPlayerInMatch (struct Match *Match)
return false; return false;
/***** Trivial check: match must not be over *****/ /***** Trivial check: match must not be over *****/
if (Match->Status.QstInd >= Mch_AFTER_LAST_QUESTION) // Finished if (Match->Status.Showing == Mch_END) // Match over
return false; return false;
/***** Trivial check: only a student can join a match *****/ /***** Trivial check: only a student can join a match *****/
@ -3161,7 +3195,7 @@ void Mch_JoinMatchAsStd (void)
/****** Remove student's answer to a question and show match as student ******/ /****** Remove student's answer to a question and show match as student ******/
/*****************************************************************************/ /*****************************************************************************/
void Mch_RemoveQuestionAnswer (void) void Mch_RemoveMyQuestionAnswer (void)
{ {
struct Match Match; struct Match Match;
unsigned QstInd; unsigned QstInd;
@ -3179,7 +3213,7 @@ void Mch_RemoveQuestionAnswer (void)
Match.Status.Showing == Mch_ANSWERS && // Teacher's screen is showing answers Match.Status.Showing == Mch_ANSWERS && // Teacher's screen is showing answers
QstInd == Match.Status.QstInd) // Removing answer to the current question being played QstInd == Match.Status.QstInd) // Removing answer to the current question being played
/***** Remove answer to this question *****/ /***** Remove answer to this question *****/
Mch_RemoveAnswerToMatchQuestion (&Match); Mch_RemoveMyAnswerToMatchQuestion (&Match);
/***** Show current match status *****/ /***** Show current match status *****/
HTM_DIV_Begin ("id=\"match\" class=\"MCH_CONT\""); HTM_DIV_Begin ("id=\"match\" class=\"MCH_CONT\"");
@ -3392,7 +3426,7 @@ void Mch_ReceiveQuestionAnswer (void)
/********************* Remove answer to match question ***********************/ /********************* Remove answer to match question ***********************/
/*****************************************************************************/ /*****************************************************************************/
static void Mch_RemoveAnswerToMatchQuestion (const struct Match *Match) static void Mch_RemoveMyAnswerToMatchQuestion (const struct Match *Match)
{ {
DB_QueryDELETE ("can not remove your answer to the match question", DB_QueryDELETE ("can not remove your answer to the match question",
"DELETE FROM mch_answers" "DELETE FROM mch_answers"

View File

@ -37,15 +37,16 @@
#define Mch_AFTER_LAST_QUESTION ((unsigned)((1UL << 31) - 1)) // 2^31 - 1, don't change this number because it is used in database to indicate that a match is finished #define Mch_AFTER_LAST_QUESTION ((unsigned)((1UL << 31) - 1)) // 2^31 - 1, don't change this number because it is used in database to indicate that a match is finished
#define Mch_NUM_SHOWING 4 #define Mch_NUM_SHOWING 5
typedef enum typedef enum
{ {
Mch_NOTHING, // Don't show anything Mch_START, // Start: 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_END, // End: don't show anything
} Mch_Showing_t; } Mch_Showing_t;
#define Mch_SHOWING_DEFAULT Mch_NOTHING #define Mch_SHOWING_DEFAULT Mch_START
struct Match struct Match
{ {
@ -109,13 +110,14 @@ void Mch_BackMatch (void);
void Mch_ForwardMatch (void); void Mch_ForwardMatch (void);
unsigned Mch_GetNumMchsInGame (long GamCod); unsigned Mch_GetNumMchsInGame (long GamCod);
unsigned Mch_GetNumUnfinishedMchsInGame (long GamCod);
bool Mch_CheckIfICanPlayThisMatchBasedOnGrps (const struct Match *Match); bool Mch_CheckIfICanPlayThisMatchBasedOnGrps (const struct Match *Match);
bool Mch_RegisterMeAsPlayerInMatch (struct Match *Match); bool Mch_RegisterMeAsPlayerInMatch (struct Match *Match);
void Mch_GetMatchBeingPlayed (void); void Mch_GetMatchBeingPlayed (void);
void Mch_JoinMatchAsStd (void); void Mch_JoinMatchAsStd (void);
void Mch_RemoveQuestionAnswer (void); void Mch_RemoveMyQuestionAnswer (void);
void Mch_RefreshMatchTch (void); void Mch_RefreshMatchTch (void);
void Mch_RefreshMatchStd (void); void Mch_RefreshMatchStd (void);