Compare commits

...

7 Commits

Author SHA1 Message Date
fabien
a0271c5112 ajout du nombre d'adversaires joué 2025-01-25 18:32:55 +01:00
fabien
333949f761 choisir le niveau d'alea 2024-09-12 21:05:08 +02:00
fabien
874955b86e esthétisme 2024-09-12 20:53:18 +02:00
fabien
b7e3ebae22 implémentation algo théorique (cela marche ) 2024-09-12 20:23:46 +02:00
fabien
609d1d99d4 écriture algo théorique 2024-08-30 06:59:03 +02:00
fabien
920bb46142 ajout de la contrainte de ne pas rejouer contre les memes (essai raté) 2024-08-23 08:56:59 +02:00
fabien
81e7558b9e selection du mode de tournoi 2024-08-23 06:44:19 +02:00
2 changed files with 226 additions and 36 deletions

52
algo Normal file
View File

@@ -0,0 +1,52 @@
algo un certains nombre N de joueurs
a chaque session, une table joue à un jeu avec T joueurs
le but :
_ faire le moins de sessions possibles
_ chaque joueurs à joué une fois à chaque jeu
_ maximiser la diversité des oppositions
_ minimiser le nombre de table avec le meme jeu
pour chaque session
un joueur à :
_ une liste de jeu possible
_ une liste des opposants déjà rencontrés (pondéré au nombre de rencontres)
le but : former Math.floor(N/T) tables
Js = la liste des joueurs non affectés
TANT QUE Nb_Tables < Math.floor(N/T) et jeux pas vide faire
jeux = map jeu/liste joueurpossible (le joueur n'a pas joué et est présent dans Js)
si moins de T joueurs dispo , jeu pas dans map
pour le jeu dans jeux avec le moins de joueurs (en cas d'égalité celui le moins joué a cette session)
faire table avec T de choisir_joueur( liste_joueur )
retirer les T joueurs de Js
pour chaque joueur de la table retirer le jeu et ajouter la table en oposant
fin tant que
function choisir_joueur (listejoueur) { o(n2)
//probleme des colocataire à T-tuple
//construction de la préférence
pour chaque joueur de listejoueur :
preference[joueur] = { forte:[], faible:[], nulle : [], score:0} //pas rencontré , rencontré 1x rencontré plusieurs fois
pour chaque joueur' de liste joueur:
si joueur= joueur' continuer
si Nb rencontr joueur'<--> joueur ==0
preference[joueur].forte.push(joueur')
si Nb rencontr joueur'<--> joueur ==1
preference[joueur].faible.push(joueur')
sinon
preference[joueur].nulle.push(joueur')
fin pour
Si preference[joueur].forte a T-1 element
trouvé
preference[joueur].score = forte *liste_joueur **2 + faible *liste_joueur + null;
fin pour
//réduction
prendre preference forte et preference faible du joueur au meilleur score
dans faible, prendre par score décroissant.
pour former un T_tuple;
retourner "pas possible";
}

View File

@@ -1,8 +1,9 @@
<!doctype html>
<html> <html>
<head> <head>
</head> </head>
<body> <body>
<script > <script type="text/javascript" >
playerSet = [ "Pierre Moreau", "Thomas Gauthier", "Antoine Nicolas", "Axel Blanc", playerSet = [ "Pierre Moreau", "Thomas Gauthier", "Antoine Nicolas", "Axel Blanc",
"Clément Garcia", "Maël Mercier", "Alexis Chevalier", "Paul Rousseau", "Théo Leroy", "Victor Robert", "Clément Garcia", "Maël Mercier", "Alexis Chevalier", "Paul Rousseau", "Théo Leroy", "Victor Robert",
@@ -17,48 +18,76 @@
gameSet= [ "Splendor", "Azul", "King Domino", "7 wonders architect", "akkroplis"]; gameSet= [ "Splendor", "Azul", "King Domino", "7 wonders architect", "akkroplis"];
function Player(name) {
this.name = name;
this.opponents = [];
this.gamesPlayed = [];
}
Player.prototype.addOpponents = function (players) {
for (var player of players ) {
if (player.name === this.name) {
continue;
}
//showDebug(this.name + " ajoute oposant "+ player.name);
this.opponents.push(player.name);
}
};
function compute() {
function compute() {
document.getElementById("results").innerHTML=""; document.getElementById("results").innerHTML="";
players = playerSet.slice(0,document.getElementById("players").value) ; players = [];
for (name of playerSet.slice(0,document.getElementById("players").value) ) {
players.push(new Player(name) );
};
games = gameSet.slice(0,document.getElementById("games").value) ; games = gameSet.slice(0,document.getElementById("games").value) ;
playerAtTable = document.getElementById("tables").value; playerAtTable = document.getElementById("tables").value;
var finished = false; var finished = false;
session=1; session=1;
maxgameplayed = Math.floor(players.length / playerAtTable); maxgameplayed = Math.floor(players.length / playerAtTable);
show ("Maximum "+ maxgameplayed + " parties joués en même temps"); show ("Maximum "+ maxgameplayed + " parties joués en même temps<br/>");
played ={}; played ={};
for( const player of players ) { for( const player of players ) {
played[player]={}; played[player.name]={};
} }
while(!finished) { while(!finished) { //a chaque session
show("<p><b>Session "+session +"<b><br/>"); show("<p><b>Session "+session +"<b><br/>");
var tables=0; var tables=0;
playerPlayInSession=[]; playersAvailableInSession=players.slice();
for( const game of games ) { gameThisSession=[];
possibleplayers =[];
for( const player of players ) {
if ( typeof played[player][game] === "undefined" && !playerPlayInSession.includes(player) ) {
possibleplayers.push(player);
}
if(possibleplayers.length == playerAtTable) break; //les premiers disponible n'ayant pas joué
}
//youpi , une table faite essai=0;
if(possibleplayers.length == playerAtTable ) { while(tables < maxgameplayed && essai < 10) {
for( const player of possibleplayers ) { essai++;
played[player][game] = session; selectedGame = findgame(playersAvailableInSession, gameThisSession);
playerPlayInSession.push(player); //showDebug( "try for " +selectedGame +", players disponibles "+playersAvailableInSession.length );
} possibleplayers = chooseplayers(playersAvailableInSession, selectedGame);
show( "table "+game+" : " + possibleplayers.join(" , ") +"<br/>");
tables++;
}
if(tables == maxgameplayed) { // showDebug ("players dispo " +possibleplayers.length + " <br/>" );
break;
} //youpi , une table faite
if(possibleplayers.length >= playerAtTable ) {
tablePlayer = possibleplayers.slice(0,playerAtTable) ;
show( "table "+selectedGame+" : ");
//showDebug ("tablePlayer : " +JSON.stringify(tablePlayer) ) ;
for( const player of tablePlayer ) {
played[player.name][selectedGame] = session;
player.gamesPlayed.push(selectedGame);
player.addOpponents(tablePlayer);
show( player.name +", ");
const index = playersAvailableInSession.indexOf(player);
if (index > -1) {
//showDebug("remove "+ player.name + " du pool de session <br/>");
playersAvailableInSession.splice(index, 1); // 2nd parameter means remove one item only
}
}
show( "<br/>");
tables++;
gameThisSession.push(selectedGame);
}
} }
show("</p>"); show("</p>");
session++; session++;
@@ -70,26 +99,135 @@
//verification //verification
show("<p><b>Vérification<b><br/>"); show("<p><b>Vérification<b><br/>");
for( const player in played) { for( const player of players) {
var allplayed = Object.keys(played[player]).length == games.length; var allplayed = player.gamesPlayed.length == games.length;
if (allplayed) { if (allplayed) {
show ("<span style='color:green' >"+ player + " a joué à tous les jeux<span>"); uniqOpponants = new Set(player.opponents);
showPass(player.name + " a joué à tous les jeux &nbsp;&nbsp;&nbsp; avec "+ uniqOpponants.size +" adversaires différents");
}else { }else {
show ("<span style='color:red' >"+ player + " a joué à seulement" + JSON.stringify(played[player]) +"<span>"); showWarning( player.name + " a joué à seulement" + JSON.stringify(player.gamesPlayed) );
} }
show("<br/>");
} }
} }
function show(text) { //pour le jeu dans jeux avec le moins de joueurs (en cas d'égalité celui le moins joué a cette session)
elem = document.getElementById("results"); function findgame(playersAvailableInSession, gameThisSession) {
elem.insertAdjacentHTML( 'beforeend', text); var gameplayer= {};
for( const g of games ) { //init
gameplayer[g]=0;
} }
for ( p of playersAvailableInSession ) {
for ( g of p.gamesPlayed) {
gameplayer[g]++;
}
}
minjoueur = playersAvailableInSession.length +1;
mingame = games[0];
for( const gp in gameplayer ) { //init
if (gameplayer[gp] < minjoueur) {
mingame= gp;
minjoueur = gameplayer[gp];
} else if (gameplayer[gp] === minjoueur) {
//alors le moins joué à cette session
maxplayed = gameThisSession.reduce( (result, game) => game === mingame ? result +1 : result , 0);
gpplayed = gameThisSession.reduce( (result, game) => game === gp ? result +1 : result , 0);
if (gpplayed< maxplayed
|| (gpplayed == maxplayed && Math.random()>0.5 ) ) { //un peu d'aleatoire en cas d'égalité
mingame = gp;
}
}
}
return mingame;
}
function chooseplayers(playersAvailableInSession, selectedGame) {
preference = [];
selectedpreference={ forte:[], faible:[], nulle : [], score:0} ;
selectedjoueur = "";
bestscore=0;
iterateur = playersAvailableInSession.length;
playersorted = playersAvailableInSession
.filter(p=>!p.gamesPlayed.includes(selectedGame));
if ( document.getElementById("shuffle").checked ) {
playersorted = playersorted.sort((a,b) =>0.5 - Math.random());
}
for (player of playersorted ) {
preference[player] = { forte:[], faible:[], nulle : [], score:0} ;
for (opositeplayer of playersorted ) {
if( player === opositeplayer )
continue; //lui-meme, niet!
nbrencontre= player.opponents.filter(o => o ===opositeplayer).length;
if (nbrencontre==0) {
preference[player].forte.push(opositeplayer);
} else if (nbrencontre==1) {
preference[player].faible.push(opositeplayer);
} else {
preference[player].nulle.push(opositeplayer);
}
}
if(preference[player].forte.length >= playerAtTable-1 ) {
preference[player].forte.push(player);
return preference[player].forte;
} else {
score = preference[player].forte.length *iterateur*iterateur+
preference[player].faible.length *iterateur+
preference[player].nulle.length ;
if (score > bestscore) {
bestscore = score;
selectedpreference = preference[player];
selectedjoueur= player;
}
}
}
//le meilleur score
selectedTable=[];
selectedTable.push(selectedjoueur);
selectedTable.push(selectedpreference.forte);
//todo completer
var j=0;
for (i=selectedTable.length ;i<= playerAtTable ; i++) {
if (selectedpreference.faible.length == j) break; //plus de préférence moyenne
selectedTable.push(selectedpreference.faible[j]);
j++;
}
var j=0;
for (i=selectedTable.length ;i<= playerAtTable ; i++) {
if (selectedpreference.nulle.length == j) break; //plus de préférence nulle
selectedTable.push(selectedpreference.nulle[j]);
j++;
}
return selectedTable;
}
function showPass(text){
show ("<span style='color:green' >"+ text +"</span><br/>");
}
function showWarning(text){
show ("<span style='color:red' >"+ text +"</span><br/>");
}
function showDebug(text){
show ("<span style='color:gray' >"+ text +"</span><br/>");
}
function show(text) {
elem = document.getElementById("results");
elem.insertAdjacentHTML( 'beforeend', text);
}
</script> </script>
<div id="param" style="float:left;width:50%; text-align:center"> <div id="param" style="float:left;width:50%; text-align:center">
Nombres de jouers (nom inventés) <input id="players" name="players" placeholder="nombre de joueurs" type ="text"/><br/> Nombres de jouers (nom inventés) <input id="players" name="players" placeholder="nombre de joueurs" type ="text"/><br/>
Nombres de joueurs par tables <input id="tables" name="tables" placeholder="nombre de joueurs par table" type ="text"/><br/> Nombres de joueurs par tables <input id="tables" name="tables" placeholder="nombre de joueurs par table" type ="text"/><br/>
Nombres de jeux à jouer <input id="games" name="games" placeholder="nombre de jeux" type ="text"/><br> Nombres de jeux à jouer <input id="games" name="games" placeholder="nombre de jeux" type ="text"/><br>
Maximiser le nombre d'adversaires ( tournoi rallongé) <input id="shuffle" name="shuffle" type="checkbox"/><br>
<button onclick="compute();" > Calculer</button> <button onclick="compute();" > Calculer</button>
</div> </div>
<div id="results" style="float:left;width:50%;"> <div id="results" style="float:left;width:50%;">
@@ -97,4 +235,4 @@ les sessions de jeu : <br/>
</div> </div>
</body> </body>
</html> </html>