Version19.40

This commit is contained in:
Antonio Cañas Vargas 2019-10-21 13:36:28 +02:00
parent 9ba70c00cf
commit 0b3d21b9e3
7 changed files with 213 additions and 109 deletions

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -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 NumScore;
double MinScore;
double MaxScore;
double Range;
double NumRowsPerScorePoint;
double Score;
unsigned MaxUsrs = 0;
unsigned NumUsrs;
unsigned NumRowForThisScore;
unsigned NumRow; unsigned NumRow;
struct
{
double Score;
unsigned NumUsrs;
} Podium[3];
unsigned i;
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;
"SELECT Score," // row[0] if (Range == 0.0)
"COUNT(*) AS NumUsrs" // row[1] return;
" FROM mch_results" NumRowsPerScorePoint = (double) Mch_NUM_ROWS_SCORE / Range;
" WHERE MchCod=%ld"
" GROUP BY Score"
" ORDER BY Score DESC LIMIT 3",
Match->MchCod);
/* Get podium */ /***** Get maximum number of users *****/
for (NumRow = 0; if (DB_QuerySELECT (&mysql_res,"can not get max users",
NumRow < NumRows; "SELECT MAX(NumUsrs)"
NumRow++) " 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); 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]
"COUNT(*) AS NumUsrs" // row[1]
" FROM mch_results"
" WHERE MchCod=%ld"
" GROUP BY Score"
" ORDER BY Score DESC",
Match->MchCod);
/***** Begin table ****/
Tbl_TABLE_BeginWide ();
/***** 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);
/* 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;
/***** Draw empty rows until reaching the adequate row *****/
NumRowForThisScore = (unsigned) ((MaxScore - Score) * NumRowsPerScorePoint);
for (;
NumRow < NumRowForThisScore;
NumRow++)
Mch_DrawEmptyRowScore (NumRow,MinScore,MaxScore);
/***** Draw row for this score *****/
Mch_DrawScoreRow (Score,MaxUsrs,NumUsrs);
NumRow++;
} }
/* Reset remaining positions */ /***** Draw final empty rows *****/
for (; for (;
NumRow < 3; NumRow < Mch_NUM_ROWS_SCORE;
NumRow++) NumRow++)
Mch_DrawEmptyRowScore (NumRow,MinScore,MaxScore);
/***** End table *****/
Tbl_TABLE_End ();
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
static void Mch_DrawEmptyRowScore (unsigned NumRow,double MinScore,double MaxScore)
{
/***** Draw row *****/
Tbl_TR_Begin (NULL);
/* Write score */
Tbl_TD_Begin ("class=\"MATCH_SCORE_SCO\"");
if (NumRow == 0)
{ {
/* Score */ Str_WriteFloatNumToFile (Gbl.F.Out,MaxScore);
Podium[NumRow].Score = 0.0; fprintf (Gbl.F.Out,"&nbsp;");
/* Number of users */
Podium[NumRow].NumUsrs = 0;
} }
else if (NumRow == Mch_NUM_ROWS_SCORE - 1)
/***** Show podium *****/
fprintf (Gbl.F.Out,"<div class=\"MATCH_BOTTOM\">"); // Bottom
fprintf (Gbl.F.Out,"<div class=\"MATCH_PODIUM\">"); // Podium
for (i = 0;
i < 3;
i++)
{ {
fprintf (Gbl.F.Out,"<div class=\"MATCH_PODIUM_%u\">",Position[i]); Str_WriteFloatNumToFile (Gbl.F.Out,MinScore);
if (Podium[Position[i]].NumUsrs) fprintf (Gbl.F.Out,"&nbsp;");
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>");
} }
Tbl_TD_End ();
fprintf (Gbl.F.Out,"</div>"); // Podium /* Empty column with bar and number of users */
Tbl_TD_Begin ("class=\"MATCH_SCORE_NUM\"");
Tbl_TD_End ();
fprintf (Gbl.F.Out,"</div>"); // Bottom 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,"&nbsp;");
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%%;\" />"
"&nbsp;%u",
Cfg_URL_ICON_PUBLIC,BarWidth,NumUsrs);
Tbl_TD_End ();
Tbl_TR_End ();
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -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)
{ {