mirror of https://github.com/acanas/swad-core.git
Version19.79
This commit is contained in:
parent
5073200f8e
commit
83f9250c25
|
@ -604,8 +604,8 @@ CREATE TABLE IF NOT EXISTS gam_games (
|
||||||
GamCod INT NOT NULL AUTO_INCREMENT,
|
GamCod INT NOT NULL AUTO_INCREMENT,
|
||||||
CrsCod INT NOT NULL DEFAULT -1,
|
CrsCod INT NOT NULL DEFAULT -1,
|
||||||
Hidden ENUM('N','Y') NOT NULL DEFAULT 'N',
|
Hidden ENUM('N','Y') NOT NULL DEFAULT 'N',
|
||||||
NumNotif INT NOT NULL DEFAULT 0,
|
|
||||||
UsrCod INT NOT NULL,
|
UsrCod INT NOT NULL,
|
||||||
|
MaxGrade DOUBLE PRECISION NOT NULL DEFAULT 1,
|
||||||
Title VARCHAR(2047) NOT NULL,
|
Title VARCHAR(2047) NOT NULL,
|
||||||
Txt TEXT NOT NULL,
|
Txt TEXT NOT NULL,
|
||||||
UNIQUE INDEX(GamCod),
|
UNIQUE INDEX(GamCod),
|
||||||
|
|
|
@ -490,7 +490,7 @@ 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.78.3 (2019-11-27)"
|
#define Log_PLATFORM_VERSION "SWAD 19.79 (2019-11-27)"
|
||||||
#define CSS_FILE "swad19.78.1.css"
|
#define CSS_FILE "swad19.78.1.css"
|
||||||
#define JS_FILE "swad19.70.js"
|
#define JS_FILE "swad19.70.js"
|
||||||
/*
|
/*
|
||||||
|
@ -498,6 +498,12 @@ ps2pdf source.ps destination.pdf
|
||||||
// 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: En cada juego, poder listar los resultados en una tabla como la de resultados globales
|
// TODO: En cada juego, poder listar los resultados en una tabla como la de resultados globales
|
||||||
|
|
||||||
|
Version 19.79: Nov 27, 2019 Storing maximum grade in a game into database. (247197 lines)
|
||||||
|
1 change necessary in database:
|
||||||
|
ALTER TABLE gam_games DROP COLUMN NumNotif;
|
||||||
|
ALTER TABLE gam_games ADD COLUMN MaxGrade DOUBLE PRECISION NOT NULL DEFAULT 1 AFTER UsrCod;
|
||||||
|
|
||||||
|
Version 19.78.4: Nov 27, 2019 Getting maximum grade from game form. Not finished. (? lines)
|
||||||
Version 19.78.3: Nov 27, 2019 Getting maximum grade from game form. Not finished. (247159 lines)
|
Version 19.78.3: Nov 27, 2019 Getting maximum grade from game form. Not finished. (247159 lines)
|
||||||
Version 19.78.2: Nov 27, 2019 New field maximum grade in game form. Not finished. (247168 lines)
|
Version 19.78.2: Nov 27, 2019 New field maximum grade in game form. Not finished. (247168 lines)
|
||||||
Version 19.78.1: Nov 27, 2019 Changes in edition of games, attendance, events, assignments. (247123 lines)
|
Version 19.78.1: Nov 27, 2019 Changes in edition of games, attendance, events, assignments. (247123 lines)
|
||||||
|
|
|
@ -1313,8 +1313,8 @@ mysql> DESCRIBE gam_games;
|
||||||
| GamCod | int(11) | NO | PRI | NULL | auto_increment |
|
| GamCod | int(11) | NO | PRI | NULL | auto_increment |
|
||||||
| CrsCod | int(11) | NO | MUL | -1 | |
|
| CrsCod | int(11) | NO | MUL | -1 | |
|
||||||
| Hidden | enum('N','Y') | NO | | N | |
|
| Hidden | enum('N','Y') | NO | | N | |
|
||||||
| NumNotif | int(11) | NO | | 0 | |
|
|
||||||
| UsrCod | int(11) | NO | | NULL | |
|
| UsrCod | int(11) | NO | | NULL | |
|
||||||
|
| MaxGrade | double | NO | | 1 | |
|
||||||
| Title | varchar(2047) | NO | | NULL | |
|
| Title | varchar(2047) | NO | | NULL | |
|
||||||
| Txt | text | NO | | NULL | |
|
| Txt | text | NO | | NULL | |
|
||||||
+----------+---------------+------+-----+---------+----------------+
|
+----------+---------------+------+-----+---------+----------------+
|
||||||
|
@ -1324,8 +1324,8 @@ mysql> DESCRIBE gam_games;
|
||||||
"GamCod INT NOT NULL AUTO_INCREMENT,"
|
"GamCod INT NOT NULL AUTO_INCREMENT,"
|
||||||
"CrsCod INT NOT NULL DEFAULT -1,"
|
"CrsCod INT NOT NULL DEFAULT -1,"
|
||||||
"Hidden ENUM('N','Y') NOT NULL DEFAULT 'N',"
|
"Hidden ENUM('N','Y') NOT NULL DEFAULT 'N',"
|
||||||
"NumNotif INT NOT NULL DEFAULT 0,"
|
|
||||||
"UsrCod INT NOT NULL,"
|
"UsrCod INT NOT NULL,"
|
||||||
|
"MaxGrade DOUBLE PRECISION NOT NULL DEFAULT 1," // Scale from score [0...num.answers] to grade [0...MaxGrade]
|
||||||
"Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE
|
"Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE
|
||||||
"Txt TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
|
"Txt TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
|
||||||
"UNIQUE INDEX(GamCod),"
|
"UNIQUE INDEX(GamCod),"
|
||||||
|
|
95
swad_game.c
95
swad_game.c
|
@ -62,6 +62,38 @@ extern struct Globals Gbl;
|
||||||
#define Gam_MAX_SELECTED_QUESTIONS 1000
|
#define Gam_MAX_SELECTED_QUESTIONS 1000
|
||||||
#define Gam_MAX_BYTES_LIST_SELECTED_QUESTIONS (Gam_MAX_SELECTED_QUESTIONS * (Cns_MAX_DECIMAL_DIGITS_LONG + 1))
|
#define Gam_MAX_BYTES_LIST_SELECTED_QUESTIONS (Gam_MAX_SELECTED_QUESTIONS * (Cns_MAX_DECIMAL_DIGITS_LONG + 1))
|
||||||
|
|
||||||
|
/* Score range [0...max.score]
|
||||||
|
will be converted to
|
||||||
|
grade range [0...max.grade]
|
||||||
|
Example: Game with 5 questions, unique-choice, 4 options per question
|
||||||
|
max.score = 5 * 1 = 5
|
||||||
|
min.score = 5 * (-0.33) = -1,67
|
||||||
|
max.grade given by teacher = 0.2 ==> min.grade = -0,067
|
||||||
|
|
||||||
|
grade
|
||||||
|
^
|
||||||
|
| /
|
||||||
|
max.grade--> +---------+
|
||||||
|
| /|
|
||||||
|
| / |
|
||||||
|
| / |
|
||||||
|
| / |
|
||||||
|
| / |
|
||||||
|
| / |
|
||||||
|
| / |
|
||||||
|
| / |
|
||||||
|
|/ |
|
||||||
|
------+---0-+---------+---------> score
|
||||||
|
^ /0 ^
|
||||||
|
min.score/ | max.score
|
||||||
|
| / | (num.questions)
|
||||||
|
| / |
|
||||||
|
|/ |
|
||||||
|
+-----+ <--min.grade
|
||||||
|
/ |
|
||||||
|
*/
|
||||||
|
#define Gam_MAX_GRADE_DEFAULT 1.0
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************************* Private types *******************************/
|
/******************************* Private types *******************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -800,7 +832,8 @@ void Gam_GetDataOfGameByCod (struct Game *Game)
|
||||||
"gam_games.CrsCod," // row[1]
|
"gam_games.CrsCod," // row[1]
|
||||||
"gam_games.Hidden," // row[2]
|
"gam_games.Hidden," // row[2]
|
||||||
"gam_games.UsrCod," // row[3]
|
"gam_games.UsrCod," // row[3]
|
||||||
"gam_games.Title" // row[4]
|
"gam_games.MaxGrade," // row[4]
|
||||||
|
"gam_games.Title" // row[5]
|
||||||
" FROM gam_games"
|
" FROM gam_games"
|
||||||
" LEFT JOIN mch_matches"
|
" LEFT JOIN mch_matches"
|
||||||
" ON gam_games.GamCod=mch_matches.GamCod"
|
" ON gam_games.GamCod=mch_matches.GamCod"
|
||||||
|
@ -823,8 +856,11 @@ void Gam_GetDataOfGameByCod (struct Game *Game)
|
||||||
/* Get author of the game (row[3]) */
|
/* Get author of the game (row[3]) */
|
||||||
Game->UsrCod = Str_ConvertStrCodToLongCod (row[3]);
|
Game->UsrCod = Str_ConvertStrCodToLongCod (row[3]);
|
||||||
|
|
||||||
/* Get the title of the game (row[4]) */
|
/* Get maximum grade (row[4]) */
|
||||||
Str_Copy (Game->Title,row[4],
|
Game->MaxGrade = Str_GetDoubleFromStr (row[4]);
|
||||||
|
|
||||||
|
/* Get the title of the game (row[5]) */
|
||||||
|
Str_Copy (Game->Title,row[5],
|
||||||
Gam_MAX_BYTES_TITLE);
|
Gam_MAX_BYTES_TITLE);
|
||||||
|
|
||||||
/* Get number of questions */
|
/* Get number of questions */
|
||||||
|
@ -878,9 +914,10 @@ void Gam_GetDataOfGameByCod (struct Game *Game)
|
||||||
static void Gam_ResetGame (struct Game *Game)
|
static void Gam_ResetGame (struct Game *Game)
|
||||||
{
|
{
|
||||||
/***** Initialize to empty game *****/
|
/***** Initialize to empty game *****/
|
||||||
Game->GamCod = -1L;
|
Game->GamCod = -1L;
|
||||||
Game->CrsCod = -1L;
|
Game->CrsCod = -1L;
|
||||||
Game->UsrCod = -1L;
|
Game->UsrCod = -1L;
|
||||||
|
Game->MaxGrade = Gam_MAX_GRADE_DEFAULT;
|
||||||
Game->TimeUTC[Dat_START_TIME] = (time_t) 0;
|
Game->TimeUTC[Dat_START_TIME] = (time_t) 0;
|
||||||
Game->TimeUTC[Dat_END_TIME ] = (time_t) 0;
|
Game->TimeUTC[Dat_END_TIME ] = (time_t) 0;
|
||||||
Game->Title[0] = '\0';
|
Game->Title[0] = '\0';
|
||||||
|
@ -1222,7 +1259,7 @@ static void Gam_PutFormsEditionGame (struct Game *Game,bool ItsANewGame)
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
HTM_TD_Begin ("class=\"LM\"");
|
HTM_TD_Begin ("class=\"LM\"");
|
||||||
HTM_INPUT_FLOAT ("MaxGrade",(double) 0.0,(double) DBL_MAX,(double) 0.01,(double) 10.0,false,
|
HTM_INPUT_FLOAT ("MaxGrade",(double) 0.0,(double) DBL_MAX,(double) 0.01,Game->MaxGrade,false,
|
||||||
"required=\"required\"");
|
"required=\"required\"");
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
@ -1269,50 +1306,39 @@ void Gam_RecFormGame (void)
|
||||||
{
|
{
|
||||||
extern const char *Txt_Already_existed_a_game_with_the_title_X;
|
extern const char *Txt_Already_existed_a_game_with_the_title_X;
|
||||||
extern const char *Txt_You_must_specify_the_title_of_the_game;
|
extern const char *Txt_You_must_specify_the_title_of_the_game;
|
||||||
struct Game OldGame;
|
struct Game Game;
|
||||||
struct Game NewGame;
|
|
||||||
bool ItsANewGame;
|
bool ItsANewGame;
|
||||||
bool NewGameIsCorrect = true;
|
bool NewGameIsCorrect = true;
|
||||||
char MaxGradeStr[64];
|
char MaxGradeStr[64];
|
||||||
double MaxGrade;
|
|
||||||
char Txt[Cns_MAX_BYTES_TEXT + 1];
|
char Txt[Cns_MAX_BYTES_TEXT + 1];
|
||||||
|
|
||||||
/***** Get the code of the game *****/
|
/***** Get the code of the game *****/
|
||||||
NewGame.GamCod = Gam_GetParamGameCod ();
|
Game.GamCod = Gam_GetParamGameCod ();
|
||||||
|
|
||||||
/***** Check if game has matches *****/
|
/***** Check if game has matches *****/
|
||||||
if (Gam_CheckIfICanEditGames ())
|
if (Gam_CheckIfICanEditGames ())
|
||||||
{
|
{
|
||||||
ItsANewGame = (NewGame.GamCod < 0);
|
ItsANewGame = (Game.GamCod < 0);
|
||||||
if (!ItsANewGame)
|
|
||||||
{
|
|
||||||
/* Get data of the old (current) game from database */
|
|
||||||
OldGame.GamCod = NewGame.GamCod;
|
|
||||||
Gam_GetDataOfGameByCod (&OldGame);
|
|
||||||
if (!Gam_CheckIfICanEditGames ())
|
|
||||||
Lay_NoPermissionExit ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** Get game title *****/
|
/***** Get game title *****/
|
||||||
Par_GetParToText ("Title",NewGame.Title,Gam_MAX_BYTES_TITLE);
|
Par_GetParToText ("Title",Game.Title,Gam_MAX_BYTES_TITLE);
|
||||||
|
|
||||||
/***** Get maximum grade *****/
|
/***** Get maximum grade *****/
|
||||||
Par_GetParToText ("MaxGrade",MaxGradeStr,sizeof (MaxGradeStr) - 1);
|
Par_GetParToText ("MaxGrade",MaxGradeStr,sizeof (MaxGradeStr) - 1);
|
||||||
MaxGrade = Str_GetDoubleFromStr (MaxGradeStr);
|
Game.MaxGrade = Str_GetDoubleFromStr (MaxGradeStr);
|
||||||
Ale_ShowAlert (Ale_INFO,"DEBUG: MaxGrade = %lg",MaxGrade); // TODO: Remove this line
|
|
||||||
|
|
||||||
/***** Get game text and insert links *****/
|
/***** Get game text and insert links *****/
|
||||||
Par_GetParToHTML ("Txt",Txt,Cns_MAX_BYTES_TEXT); // Store in HTML format (not rigorous)
|
Par_GetParToHTML ("Txt",Txt,Cns_MAX_BYTES_TEXT); // Store in HTML format (not rigorous)
|
||||||
|
|
||||||
/***** Check if title is correct *****/
|
/***** Check if title is correct *****/
|
||||||
if (NewGame.Title[0]) // If there's a game title
|
if (Game.Title[0]) // If there's a game title
|
||||||
{
|
{
|
||||||
/* If title of game was in database... */
|
/* If title of game was in database... */
|
||||||
if (Gam_CheckIfSimilarGameExists (&NewGame))
|
if (Gam_CheckIfSimilarGameExists (&Game))
|
||||||
{
|
{
|
||||||
NewGameIsCorrect = false;
|
NewGameIsCorrect = false;
|
||||||
Ale_ShowAlert (Ale_WARNING,Txt_Already_existed_a_game_with_the_title_X,
|
Ale_ShowAlert (Ale_WARNING,Txt_Already_existed_a_game_with_the_title_X,
|
||||||
NewGame.Title);
|
Game.Title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // If there is not a game title
|
else // If there is not a game title
|
||||||
|
@ -1325,15 +1351,15 @@ void Gam_RecFormGame (void)
|
||||||
if (NewGameIsCorrect)
|
if (NewGameIsCorrect)
|
||||||
{
|
{
|
||||||
if (ItsANewGame)
|
if (ItsANewGame)
|
||||||
Gam_CreateGame (&NewGame,Txt); // Add new game to database
|
Gam_CreateGame (&Game,Txt); // Add new game to database
|
||||||
else
|
else
|
||||||
Gam_UpdateGame (&NewGame,Txt);
|
Gam_UpdateGame (&Game,Txt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Gam_RequestCreatOrEditGame ();
|
Gam_RequestCreatOrEditGame ();
|
||||||
|
|
||||||
/***** Put forms to create/edit a game *****/
|
/***** Put forms to create/edit a game *****/
|
||||||
Gam_PutFormsEditionGame (&NewGame,false);
|
Gam_PutFormsEditionGame (&Game,false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Lay_NoPermissionExit ();
|
Lay_NoPermissionExit ();
|
||||||
|
@ -1351,16 +1377,19 @@ static void Gam_CreateGame (struct Game *Game,const char *Txt)
|
||||||
extern const char *Txt_Created_new_game_X;
|
extern const char *Txt_Created_new_game_X;
|
||||||
|
|
||||||
/***** Create a new game *****/
|
/***** Create a new game *****/
|
||||||
|
Str_SetDecimalPointToUS (); // To write the decimal point as a dot
|
||||||
Game->GamCod =
|
Game->GamCod =
|
||||||
DB_QueryINSERTandReturnCode ("can not create new game",
|
DB_QueryINSERTandReturnCode ("can not create new game",
|
||||||
"INSERT INTO gam_games"
|
"INSERT INTO gam_games"
|
||||||
" (CrsCod,Hidden,UsrCod,Title,Txt)"
|
" (CrsCod,Hidden,UsrCod,MaxGrade,Title,Txt)"
|
||||||
" VALUES"
|
" VALUES"
|
||||||
" (%ld,'N',%ld,'%s','%s')",
|
" (%ld,'N',%ld,%lg,'%s','%s')",
|
||||||
Gbl.Hierarchy.Crs.CrsCod,
|
Gbl.Hierarchy.Crs.CrsCod,
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||||
|
Game->MaxGrade,
|
||||||
Game->Title,
|
Game->Title,
|
||||||
Txt);
|
Txt);
|
||||||
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
|
|
||||||
/***** Write success message *****/
|
/***** Write success message *****/
|
||||||
Ale_ShowAlert (Ale_SUCCESS,Txt_Created_new_game_X,
|
Ale_ShowAlert (Ale_SUCCESS,Txt_Created_new_game_X,
|
||||||
|
@ -1376,16 +1405,20 @@ static void Gam_UpdateGame (struct Game *Game,const char *Txt)
|
||||||
extern const char *Txt_The_game_has_been_modified;
|
extern const char *Txt_The_game_has_been_modified;
|
||||||
|
|
||||||
/***** Update the data of the game *****/
|
/***** Update the data of the game *****/
|
||||||
|
Str_SetDecimalPointToUS (); // To write the decimal point as a dot
|
||||||
DB_QueryUPDATE ("can not update game",
|
DB_QueryUPDATE ("can not update game",
|
||||||
"UPDATE gam_games"
|
"UPDATE gam_games"
|
||||||
" SET CrsCod=%ld,"
|
" SET CrsCod=%ld,"
|
||||||
|
"MaxGrade=%lg,"
|
||||||
"Title='%s',"
|
"Title='%s',"
|
||||||
"Txt='%s'"
|
"Txt='%s'"
|
||||||
" WHERE GamCod=%ld",
|
" WHERE GamCod=%ld",
|
||||||
Gbl.Hierarchy.Crs.CrsCod,
|
Gbl.Hierarchy.Crs.CrsCod,
|
||||||
|
Game->MaxGrade,
|
||||||
Game->Title,
|
Game->Title,
|
||||||
Txt,
|
Txt,
|
||||||
Game->GamCod);
|
Game->GamCod);
|
||||||
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
|
|
||||||
/***** Write success message *****/
|
/***** Write success message *****/
|
||||||
Ale_ShowAlert (Ale_SUCCESS,Txt_The_game_has_been_modified);
|
Ale_ShowAlert (Ale_SUCCESS,Txt_The_game_has_been_modified);
|
||||||
|
|
|
@ -48,6 +48,9 @@ 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]
|
||||||
|
// will be converted to
|
||||||
|
// 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
|
||||||
|
|
Loading…
Reference in New Issue