mirror of
https://github.com/acanas/swad-core.git
synced 2024-06-14 12:44:09 +02:00
Version19.40
This commit is contained in:
parent
9ba70c00cf
commit
0b3d21b9e3
|
@ -2804,56 +2804,30 @@ a:hover img.CENTRE_PHOTO_SHOW
|
||||||
width:25%;
|
width:25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.MATCH_PODIUM
|
.MATCH_SCORE_SCO
|
||||||
{
|
{
|
||||||
display:table;
|
width:5%;
|
||||||
box-sizing:border-box;
|
text-align:right;
|
||||||
width:100%;
|
vertical-align:middle;
|
||||||
text-align:center;
|
height:12px;
|
||||||
}
|
font-size:7pt;
|
||||||
.MATCH_PODIUM_POSITION
|
|
||||||
{
|
|
||||||
color:white;
|
|
||||||
font-size:32pt;
|
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
}
|
}
|
||||||
.MATCH_PODIUM_SCORE
|
.MATCH_SCORE_NUM
|
||||||
{
|
{
|
||||||
color:white;
|
width:95%;
|
||||||
font-size:24pt;
|
text-align:left;
|
||||||
|
vertical-align:middle;
|
||||||
|
background:white;
|
||||||
|
height:12px;
|
||||||
|
font-size:7pt;
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
}
|
}
|
||||||
.MATCH_PODIUM_1
|
.MATCH_SCORE_BAR
|
||||||
{
|
{
|
||||||
display:table-cell;
|
display:inline-block;
|
||||||
box-sizing:border-box;
|
height:10px;
|
||||||
float:left;
|
vertical-align:middle;
|
||||||
width:33%;
|
|
||||||
margin-top:200px;
|
|
||||||
height:200px;
|
|
||||||
margin-top:200px;
|
|
||||||
background:grey;
|
|
||||||
}
|
|
||||||
.MATCH_PODIUM_0
|
|
||||||
{
|
|
||||||
display:table-cell;
|
|
||||||
box-sizing:border-box;
|
|
||||||
float:left;
|
|
||||||
width:34%;
|
|
||||||
margin-top:100px;
|
|
||||||
height:300px;
|
|
||||||
margin-top:100px;
|
|
||||||
background:grey;
|
|
||||||
}
|
|
||||||
.MATCH_PODIUM_2
|
|
||||||
{
|
|
||||||
display:table-cell;
|
|
||||||
box-sizing:border-box;
|
|
||||||
float:left;
|
|
||||||
width:33%;
|
|
||||||
height:100px;
|
|
||||||
margin-top:300px;
|
|
||||||
background:grey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.MATCH_TCH_BUTTON_TD
|
.MATCH_TCH_BUTTON_TD
|
|
@ -13094,7 +13094,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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -487,13 +487,14 @@ 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.39.2 (2019-10-18)"
|
#define Log_PLATFORM_VERSION "SWAD 19.40 (2019-10-21)"
|
||||||
#define CSS_FILE "swad19.39.css"
|
#define CSS_FILE "swad19.40.css"
|
||||||
#define JS_FILE "swad19.39.js"
|
#define JS_FILE "swad19.39.js"
|
||||||
/*
|
/*
|
||||||
// TODO: Perico: poner un candado de bloqueo de creación/edición de proyectos (por ejemplo en asignaturas obsoletas)
|
// TODO: Perico: poner un candado de bloqueo de creación/edición de proyectos (por ejemplo en asignaturas obsoletas)
|
||||||
// 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.)
|
||||||
|
|
||||||
|
Version 19.40: Oct 21, 2019 Match podium has been replaced by score table. (245741 lines)
|
||||||
Version 19.39.2: Oct 18, 2019 Fixed HTML bug in listing of registration requests. (245659 lines)
|
Version 19.39.2: Oct 18, 2019 Fixed HTML bug in listing of registration requests. (245659 lines)
|
||||||
Version 19.39.1: Oct 18, 2019 Changes in layout and behaviour of matches. (245656 lines)
|
Version 19.39.1: Oct 18, 2019 Changes in layout and behaviour of matches. (245656 lines)
|
||||||
Version 19.39: Oct 17, 2019 Keyboard/presenter is allowed for playing matches. (245657 lines)
|
Version 19.39: Oct 17, 2019 Keyboard/presenter is allowed for playing matches. (245657 lines)
|
||||||
|
|
42
swad_game.c
42
swad_game.c
|
@ -2545,3 +2545,45 @@ static long Gam_GetParamCurrentGamCod (void)
|
||||||
{
|
{
|
||||||
return Gam_CurrentGamCod;
|
return Gam_CurrentGamCod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/*************** Get maximum score of a game from database *******************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Gam_GetScoreRange (long GamCod,double *MinScore,double *MaxScore)
|
||||||
|
{
|
||||||
|
MYSQL_RES *mysql_res;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
unsigned NumRows;
|
||||||
|
unsigned NumRow;
|
||||||
|
unsigned NumAnswers;
|
||||||
|
|
||||||
|
/***** Get maximum score of a game from database *****/
|
||||||
|
NumRows = (unsigned)
|
||||||
|
DB_QuerySELECT (&mysql_res,"can not get data of a question",
|
||||||
|
"SELECT COUNT(tst_answers.AnsInd) AS N"
|
||||||
|
" FROM tst_answers,gam_questions"
|
||||||
|
" WHERE gam_questions.GamCod=%ld"
|
||||||
|
" AND gam_questions.QstCod=tst_answers.QstCod"
|
||||||
|
" GROUP BY tst_answers.QstCod",
|
||||||
|
GamCod);
|
||||||
|
for (NumRow = 0, *MinScore = *MaxScore = 0.0;
|
||||||
|
NumRow < NumRows;
|
||||||
|
NumRow++)
|
||||||
|
{
|
||||||
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
|
/* Get min answers (row[0]) */
|
||||||
|
if (sscanf (row[0],"%u",&NumAnswers) != 1)
|
||||||
|
NumAnswers = 0;
|
||||||
|
|
||||||
|
/* Accumulate minimum and maximum score */
|
||||||
|
if (NumAnswers < 2)
|
||||||
|
Lay_ShowErrorAndExit ("Wrong number of answers.");
|
||||||
|
*MinScore += -1.0 / (double) (NumAnswers - 1);
|
||||||
|
*MaxScore += 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Free structure that stores the query result *****/
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
}
|
||||||
|
|
|
@ -130,4 +130,6 @@ void Gam_ShowTstTagsPresentInAGame (long GamCod);
|
||||||
|
|
||||||
void Gam_SetParamCurrentGamCod (long GamCod);
|
void Gam_SetParamCurrentGamCod (long GamCod);
|
||||||
|
|
||||||
|
void Gam_GetScoreRange (long GamCod,double *MinScore,double *MaxScore);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
191
swad_match.c
191
swad_match.c
|
@ -160,7 +160,10 @@ static void Mch_PutCheckboxResult (struct Match *Match);
|
||||||
static void Mch_ShowMatchTitle (struct Match *Match);
|
static void Mch_ShowMatchTitle (struct Match *Match);
|
||||||
static void Mch_ShowQuestionAndAnswersTch (struct Match *Match);
|
static void Mch_ShowQuestionAndAnswersTch (struct Match *Match);
|
||||||
static void Mch_ShowQuestionAndAnswersStd (struct Match *Match);
|
static void Mch_ShowQuestionAndAnswersStd (struct Match *Match);
|
||||||
static void Mch_ShowMatchPodium (struct Match *Match);
|
|
||||||
|
static void Mch_ShowMatchScore (struct Match *Match);
|
||||||
|
static void Mch_DrawEmptyRowScore (unsigned NumRow,double MinScore,double MaxScore);
|
||||||
|
static void Mch_DrawScoreRow (double Score,unsigned MaxUsrs,unsigned NumUsrs);
|
||||||
|
|
||||||
static void Mch_PutParamNumOpt (unsigned NumOpt);
|
static void Mch_PutParamNumOpt (unsigned NumOpt);
|
||||||
static unsigned Mch_GetParamNumOpt (void);
|
static unsigned Mch_GetParamNumOpt (void);
|
||||||
|
@ -2134,7 +2137,7 @@ static void Mch_ShowRightColumnTch (struct Match *Match)
|
||||||
if (Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) // Not finished
|
if (Match->Status.QstInd < Mch_AFTER_LAST_QUESTION) // Not finished
|
||||||
Mch_ShowQuestionAndAnswersTch (Match);
|
Mch_ShowQuestionAndAnswersTch (Match);
|
||||||
else // Finished
|
else // Finished
|
||||||
Mch_ShowMatchPodium (Match);
|
Mch_ShowMatchScore (Match);
|
||||||
|
|
||||||
/***** End right container *****/
|
/***** End right container *****/
|
||||||
fprintf (Gbl.F.Out,"</div>");
|
fprintf (Gbl.F.Out,"</div>");
|
||||||
|
@ -2482,91 +2485,173 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***************************** Show match podium *****************************/
|
/***************************** Show match scores *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Mch_ShowMatchPodium (struct Match *Match)
|
#define Mch_NUM_ROWS_SCORE 41
|
||||||
|
|
||||||
|
static void Mch_ShowMatchScore (struct Match *Match)
|
||||||
{
|
{
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
unsigned NumRows;
|
unsigned NumScores;
|
||||||
unsigned NumRow;
|
unsigned NumScore;
|
||||||
struct
|
double MinScore;
|
||||||
{
|
double MaxScore;
|
||||||
|
double Range;
|
||||||
|
double NumRowsPerScorePoint;
|
||||||
double Score;
|
double Score;
|
||||||
|
unsigned MaxUsrs = 0;
|
||||||
unsigned NumUsrs;
|
unsigned NumUsrs;
|
||||||
} Podium[3];
|
unsigned NumRowForThisScore;
|
||||||
unsigned i;
|
unsigned NumRow;
|
||||||
static const unsigned Position[3] =
|
|
||||||
{
|
|
||||||
1, // 2nd position
|
|
||||||
0, // 1st position
|
|
||||||
2 // 3rd position
|
|
||||||
};
|
|
||||||
|
|
||||||
/***** Get podium from database *****/
|
/***** Get minimum and maximum scores *****/
|
||||||
NumRows = (unsigned)
|
Gam_GetScoreRange (Match->GamCod,&MinScore,&MaxScore);
|
||||||
DB_QuerySELECT (&mysql_res,"can not get data of a question",
|
Range = MaxScore - MinScore;
|
||||||
|
if (Range == 0.0)
|
||||||
|
return;
|
||||||
|
NumRowsPerScorePoint = (double) Mch_NUM_ROWS_SCORE / Range;
|
||||||
|
|
||||||
|
/***** Get maximum number of users *****/
|
||||||
|
if (DB_QuerySELECT (&mysql_res,"can not get max users",
|
||||||
|
"SELECT MAX(NumUsrs)"
|
||||||
|
" FROM "
|
||||||
|
"(SELECT COUNT(*) AS NumUsrs" // row[1]
|
||||||
|
" FROM mch_results"
|
||||||
|
" WHERE MchCod=%ld"
|
||||||
|
" GROUP BY Score"
|
||||||
|
" ORDER BY Score) AS Scores",
|
||||||
|
Match->MchCod))
|
||||||
|
{
|
||||||
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
|
/* Get maximum number of users (row[0]) *****/
|
||||||
|
if (row)
|
||||||
|
if (row[0])
|
||||||
|
if (sscanf (row[0],"%u",&MaxUsrs) != 1)
|
||||||
|
MaxUsrs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free structure that stores the query result */
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
|
/***** Get scores from database *****/
|
||||||
|
NumScores = (unsigned)
|
||||||
|
DB_QuerySELECT (&mysql_res,"can not get scores",
|
||||||
"SELECT Score," // row[0]
|
"SELECT Score," // row[0]
|
||||||
"COUNT(*) AS NumUsrs" // row[1]
|
"COUNT(*) AS NumUsrs" // row[1]
|
||||||
" FROM mch_results"
|
" FROM mch_results"
|
||||||
" WHERE MchCod=%ld"
|
" WHERE MchCod=%ld"
|
||||||
" GROUP BY Score"
|
" GROUP BY Score"
|
||||||
" ORDER BY Score DESC LIMIT 3",
|
" ORDER BY Score DESC",
|
||||||
Match->MchCod);
|
Match->MchCod);
|
||||||
|
|
||||||
/* Get podium */
|
/***** Begin table ****/
|
||||||
for (NumRow = 0;
|
Tbl_TABLE_BeginWide ();
|
||||||
NumRow < NumRows;
|
|
||||||
NumRow++)
|
/***** Get and draw scores *****/
|
||||||
|
for (NumScore = 0, NumRow = 0;
|
||||||
|
NumScore < NumScores;
|
||||||
|
NumScore++)
|
||||||
{
|
{
|
||||||
|
/***** Get score and number of users from database *****/
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
/* Get score (row[0]) */
|
/* Get score (row[0]) */
|
||||||
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
|
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
|
||||||
if (sscanf (row[0],"%lf",&(Podium[NumRow].Score)) != 1)
|
if (sscanf (row[0],"%lf",&Score) != 1)
|
||||||
Podium[NumRow].Score = 0.0;
|
Score = 0.0;
|
||||||
Str_SetDecimalPointToLocal (); // Return to local system
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
|
|
||||||
/* Get number of users (row[1]) *****/
|
/* Get number of users (row[1]) *****/
|
||||||
if (sscanf (row[1],"%u",&(Podium[NumRow].NumUsrs)) != 1)
|
if (sscanf (row[1],"%u",&NumUsrs) != 1)
|
||||||
Podium[NumRow].NumUsrs = 0;
|
NumUsrs = 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset remaining positions */
|
/***** Draw empty rows until reaching the adequate row *****/
|
||||||
|
NumRowForThisScore = (unsigned) ((MaxScore - Score) * NumRowsPerScorePoint);
|
||||||
for (;
|
for (;
|
||||||
NumRow < 3;
|
NumRow < NumRowForThisScore;
|
||||||
NumRow++)
|
NumRow++)
|
||||||
{
|
Mch_DrawEmptyRowScore (NumRow,MinScore,MaxScore);
|
||||||
/* Score */
|
|
||||||
Podium[NumRow].Score = 0.0;
|
|
||||||
|
|
||||||
/* Number of users */
|
/***** Draw row for this score *****/
|
||||||
Podium[NumRow].NumUsrs = 0;
|
Mch_DrawScoreRow (Score,MaxUsrs,NumUsrs);
|
||||||
|
NumRow++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Show podium *****/
|
/***** Draw final empty rows *****/
|
||||||
fprintf (Gbl.F.Out,"<div class=\"MATCH_BOTTOM\">"); // Bottom
|
for (;
|
||||||
|
NumRow < Mch_NUM_ROWS_SCORE;
|
||||||
|
NumRow++)
|
||||||
|
Mch_DrawEmptyRowScore (NumRow,MinScore,MaxScore);
|
||||||
|
|
||||||
fprintf (Gbl.F.Out,"<div class=\"MATCH_PODIUM\">"); // Podium
|
/***** End table *****/
|
||||||
|
Tbl_TABLE_End ();
|
||||||
|
|
||||||
for (i = 0;
|
/***** Free structure that stores the query result *****/
|
||||||
i < 3;
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
i++)
|
|
||||||
{
|
|
||||||
fprintf (Gbl.F.Out,"<div class=\"MATCH_PODIUM_%u\">",Position[i]);
|
|
||||||
if (Podium[Position[i]].NumUsrs)
|
|
||||||
fprintf (Gbl.F.Out,"<div class=\"MATCH_PODIUM_POSITION\">%u</div>"
|
|
||||||
"<div class=\"MATCH_PODIUM_SCORE\">%.2lf (%u)</div>",
|
|
||||||
Position[i] + 1,
|
|
||||||
Podium[Position[i]].Score,
|
|
||||||
Podium[Position[i]].NumUsrs);
|
|
||||||
fprintf (Gbl.F.Out,"</div>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (Gbl.F.Out,"</div>"); // Podium
|
static void Mch_DrawEmptyRowScore (unsigned NumRow,double MinScore,double MaxScore)
|
||||||
|
{
|
||||||
|
/***** Draw row *****/
|
||||||
|
Tbl_TR_Begin (NULL);
|
||||||
|
|
||||||
fprintf (Gbl.F.Out,"</div>"); // Bottom
|
/* Write score */
|
||||||
|
Tbl_TD_Begin ("class=\"MATCH_SCORE_SCO\"");
|
||||||
|
if (NumRow == 0)
|
||||||
|
{
|
||||||
|
Str_WriteFloatNumToFile (Gbl.F.Out,MaxScore);
|
||||||
|
fprintf (Gbl.F.Out," ");
|
||||||
|
}
|
||||||
|
else if (NumRow == Mch_NUM_ROWS_SCORE - 1)
|
||||||
|
{
|
||||||
|
Str_WriteFloatNumToFile (Gbl.F.Out,MinScore);
|
||||||
|
fprintf (Gbl.F.Out," ");
|
||||||
|
}
|
||||||
|
Tbl_TD_End ();
|
||||||
|
|
||||||
|
/* Empty column with bar and number of users */
|
||||||
|
Tbl_TD_Begin ("class=\"MATCH_SCORE_NUM\"");
|
||||||
|
Tbl_TD_End ();
|
||||||
|
|
||||||
|
Tbl_TR_End ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Mch_DrawScoreRow (double Score,unsigned MaxUsrs,unsigned NumUsrs)
|
||||||
|
{
|
||||||
|
unsigned BarWidth;
|
||||||
|
|
||||||
|
/***** Compute bar width *****/
|
||||||
|
if (MaxUsrs > 0)
|
||||||
|
{
|
||||||
|
BarWidth = (unsigned) (((NumUsrs * 95.0) / MaxUsrs) + 0.5);
|
||||||
|
if (BarWidth == 0)
|
||||||
|
BarWidth = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
BarWidth = 0;
|
||||||
|
|
||||||
|
/***** Draw row *****/
|
||||||
|
Tbl_TR_Begin (NULL);
|
||||||
|
|
||||||
|
/* Write score */
|
||||||
|
Tbl_TD_Begin ("class=\"MATCH_SCORE_SCO\"");
|
||||||
|
Str_WriteFloatNumToFile (Gbl.F.Out,Score);
|
||||||
|
fprintf (Gbl.F.Out," ");
|
||||||
|
Tbl_TD_End ();
|
||||||
|
|
||||||
|
/* Draw bar and write number of users for this score */
|
||||||
|
Tbl_TD_Begin ("class=\"MATCH_SCORE_NUM\"");
|
||||||
|
fprintf (Gbl.F.Out,"<img src=\"%s/o1x1.png\"" // Background
|
||||||
|
" alt=\"\" class=\"MATCH_SCORE_BAR\""
|
||||||
|
" style=\"width:%u%%;\" />"
|
||||||
|
" %u",
|
||||||
|
Cfg_URL_ICON_PUBLIC,BarWidth,NumUsrs);
|
||||||
|
Tbl_TD_End ();
|
||||||
|
|
||||||
|
Tbl_TR_End ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -908,7 +908,7 @@ void Str_FloatNumToStr (char **Str,float Number)
|
||||||
double FractionaryPart;
|
double FractionaryPart;
|
||||||
char *Format;
|
char *Format;
|
||||||
|
|
||||||
FractionaryPart = modf ((double) Number,&IntegerPart);
|
FractionaryPart = fabs (modf ((double) Number,&IntegerPart));
|
||||||
|
|
||||||
if (FractionaryPart == 0.0)
|
if (FractionaryPart == 0.0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user