diff options
| -rw-r--r-- | assets/favicon.ipe | 325 | ||||
| -rw-r--r-- | assets/favicon.svg | 19 | ||||
| -rw-r--r-- | favicon.ico | bin | 0 -> 13054 bytes | |||
| -rw-r--r-- | game.mjs | 60 | ||||
| -rw-r--r-- | index.js | 16 | ||||
| -rw-r--r-- | player.mjs | 7 | ||||
| -rw-r--r-- | utils.mjs | 31 |
7 files changed, 425 insertions, 33 deletions
diff --git a/assets/favicon.ipe b/assets/favicon.ipe new file mode 100644 index 0000000..5d79b35 --- /dev/null +++ b/assets/favicon.ipe @@ -0,0 +1,325 @@ +<?xml version="1.0"?> +<!DOCTYPE ipe SYSTEM "ipe.dtd"> +<ipe version="70218" creator="Ipe 7.2.29"> +<info created="D:20251111165846" modified="D:20251111165846"/> +<ipestyle name="basic"> +<symbol name="arrow/arc(spx)"> +<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen"> +0 0 m +-1 0.333 l +-1 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/farc(spx)"> +<path stroke="sym-stroke" fill="white" pen="sym-pen"> +0 0 m +-1 0.333 l +-1 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/ptarc(spx)"> +<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen"> +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/fptarc(spx)"> +<path stroke="sym-stroke" fill="white" pen="sym-pen"> +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h +</path> +</symbol> +<symbol name="mark/circle(sx)" transformations="translations"> +<path fill="sym-stroke"> +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e +</path> +</symbol> +<symbol name="mark/disk(sx)" transformations="translations"> +<path fill="sym-stroke"> +0.6 0 0 0.6 0 0 e +</path> +</symbol> +<symbol name="mark/fdisk(sfx)" transformations="translations"> +<group> +<path fill="sym-fill"> +0.5 0 0 0.5 0 0 e +</path> +<path fill="sym-stroke" fillrule="eofill"> +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e +</path> +</group> +</symbol> +<symbol name="mark/box(sx)" transformations="translations"> +<path fill="sym-stroke" fillrule="eofill"> +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h +</path> +</symbol> +<symbol name="mark/square(sx)" transformations="translations"> +<path fill="sym-stroke"> +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +</path> +</symbol> +<symbol name="mark/fsquare(sfx)" transformations="translations"> +<group> +<path fill="sym-fill"> +-0.5 -0.5 m +0.5 -0.5 l +0.5 0.5 l +-0.5 0.5 l +h +</path> +<path fill="sym-stroke" fillrule="eofill"> +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h +</path> +</group> +</symbol> +<symbol name="mark/cross(sx)" transformations="translations"> +<group> +<path fill="sym-stroke"> +-0.43 -0.57 m +0.57 0.43 l +0.43 0.57 l +-0.57 -0.43 l +h +</path> +<path fill="sym-stroke"> +-0.43 0.57 m +0.57 -0.43 l +0.43 -0.57 l +-0.57 0.43 l +h +</path> +</group> +</symbol> +<symbol name="arrow/fnormal(spx)"> +<path stroke="sym-stroke" fill="white" pen="sym-pen"> +0 0 m +-1 0.333 l +-1 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/pointed(spx)"> +<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen"> +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/fpointed(spx)"> +<path stroke="sym-stroke" fill="white" pen="sym-pen"> +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/linear(spx)"> +<path stroke="sym-stroke" pen="sym-pen"> +-1 0.333 m +0 0 l +-1 -0.333 l +</path> +</symbol> +<symbol name="arrow/fdouble(spx)"> +<path stroke="sym-stroke" fill="white" pen="sym-pen"> +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/double(spx)"> +<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen"> +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/mid-normal(spx)"> +<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen"> +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/mid-fnormal(spx)"> +<path stroke="sym-stroke" fill="white" pen="sym-pen"> +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/mid-pointed(spx)"> +<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen"> +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/mid-fpointed(spx)"> +<path stroke="sym-stroke" fill="white" pen="sym-pen"> +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/mid-double(spx)"> +<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen"> +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h +</path> +</symbol> +<symbol name="arrow/mid-fdouble(spx)"> +<path stroke="sym-stroke" fill="white" pen="sym-pen"> +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h +</path> +</symbol> +<anglesize name="22.5 deg" value="22.5"/> +<anglesize name="30 deg" value="30"/> +<anglesize name="45 deg" value="45"/> +<anglesize name="60 deg" value="60"/> +<anglesize name="90 deg" value="90"/> +<arrowsize name="large" value="10"/> +<arrowsize name="small" value="5"/> +<arrowsize name="tiny" value="3"/> +<color name="blue" value="0 0 1"/> +<color name="brown" value="0.647 0.165 0.165"/> +<color name="darkblue" value="0 0 0.545"/> +<color name="darkcyan" value="0 0.545 0.545"/> +<color name="darkgray" value="0.663"/> +<color name="darkgreen" value="0 0.392 0"/> +<color name="darkmagenta" value="0.545 0 0.545"/> +<color name="darkorange" value="1 0.549 0"/> +<color name="darkred" value="0.545 0 0"/> +<color name="gold" value="1 0.843 0"/> +<color name="gray" value="0.745"/> +<color name="green" value="0 1 0"/> +<color name="lightblue" value="0.678 0.847 0.902"/> +<color name="lightcyan" value="0.878 1 1"/> +<color name="lightgray" value="0.827"/> +<color name="lightgreen" value="0.565 0.933 0.565"/> +<color name="lightyellow" value="1 1 0.878"/> +<color name="navy" value="0 0 0.502"/> +<color name="orange" value="1 0.647 0"/> +<color name="pink" value="1 0.753 0.796"/> +<color name="purple" value="0.627 0.125 0.941"/> +<color name="red" value="1 0 0"/> +<color name="seagreen" value="0.18 0.545 0.341"/> +<color name="turquoise" value="0.251 0.878 0.816"/> +<color name="violet" value="0.933 0.51 0.933"/> +<color name="yellow" value="1 1 0"/> +<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/> +<dashstyle name="dash dotted" value="[4 2 1 2] 0"/> +<dashstyle name="dashed" value="[4] 0"/> +<dashstyle name="dotted" value="[1 3] 0"/> +<gridsize name="10 pts (~3.5 mm)" value="10"/> +<gridsize name="14 pts (~5 mm)" value="14"/> +<gridsize name="16 pts (~6 mm)" value="16"/> +<gridsize name="20 pts (~7 mm)" value="20"/> +<gridsize name="28 pts (~10 mm)" value="28"/> +<gridsize name="32 pts (~12 mm)" value="32"/> +<gridsize name="4 pts" value="4"/> +<gridsize name="56 pts (~20 mm)" value="56"/> +<gridsize name="8 pts (~3 mm)" value="8"/> +<opacity name="10%" value="0.1"/> +<opacity name="30%" value="0.3"/> +<opacity name="50%" value="0.5"/> +<opacity name="75%" value="0.75"/> +<pen name="fat" value="1.2"/> +<pen name="heavier" value="0.8"/> +<pen name="ultrafat" value="2"/> +<symbolsize name="large" value="5"/> +<symbolsize name="small" value="2"/> +<symbolsize name="tiny" value="1.1"/> +<textsize name="Huge" value="\Huge"/> +<textsize name="LARGE" value="\LARGE"/> +<textsize name="Large" value="\Large"/> +<textsize name="footnote" value="\footnotesize"/> +<textsize name="huge" value="\huge"/> +<textsize name="large" value="\large"/> +<textsize name="script" value="\scriptsize"/> +<textsize name="small" value="\small"/> +<textsize name="tiny" value="\tiny"/> +<textstyle name="center" begin="\begin{center}" end="\end{center}"/> +<textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/> +<textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/> +<tiling name="falling" angle="-60" step="4" width="1"/> +<tiling name="rising" angle="30" step="4" width="1"/> +</ipestyle> +<page> +<layer name="alpha"/> +<view layers="alpha" active="alpha"/> +<text layer="alpha" transformations="translations" pos="16 832" stroke="black" type="label" width="9.132" height="6.808" depth="0" halign="center" valign="center">M</text> +<path stroke="black"> +8 840 m +8 824 l +24 824 l +24 840 l +h +</path> +</page> +</ipe> diff --git a/assets/favicon.svg b/assets/favicon.svg new file mode 100644 index 0000000..ab0b740 --- /dev/null +++ b/assets/favicon.svg @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="18" viewBox="0 0 18 18"> +<defs> +<g> +<g id="glyph-0-0"> +<path d="M 2.40625 -6.59375 C 2.3125 -6.8125 2.28125 -6.8125 2.046875 -6.8125 L 0.375 -6.8125 L 0.375 -6.5 L 0.609375 -6.5 C 1.375 -6.5 1.390625 -6.390625 1.390625 -6.03125 L 1.390625 -1.046875 C 1.390625 -0.78125 1.390625 -0.3125 0.375 -0.3125 L 0.375 0 C 0.71875 -0.015625 1.203125 -0.03125 1.53125 -0.03125 C 1.859375 -0.03125 2.359375 -0.015625 2.703125 0 L 2.703125 -0.3125 C 1.671875 -0.3125 1.671875 -0.78125 1.671875 -1.046875 L 1.671875 -6.421875 L 1.6875 -6.421875 L 4.09375 -0.21875 C 4.140625 -0.09375 4.1875 0 4.28125 0 C 4.390625 0 4.421875 -0.078125 4.46875 -0.1875 L 6.921875 -6.5 L 6.921875 -0.78125 C 6.921875 -0.421875 6.90625 -0.3125 6.140625 -0.3125 L 5.90625 -0.3125 L 5.90625 0 C 6.265625 -0.03125 6.953125 -0.03125 7.34375 -0.03125 C 7.71875 -0.03125 8.390625 -0.03125 8.765625 0 L 8.765625 -0.3125 L 8.515625 -0.3125 C 7.75 -0.3125 7.734375 -0.421875 7.734375 -0.78125 L 7.734375 -6.03125 C 7.734375 -6.390625 7.75 -6.5 8.515625 -6.5 L 8.765625 -6.5 L 8.765625 -6.8125 L 7.078125 -6.8125 C 6.8125 -6.8125 6.8125 -6.796875 6.75 -6.625 L 4.5625 -1 Z M 2.40625 -6.59375 "/> +</g> +</g> +<clipPath id="clip-0"> +<path clip-rule="nonzero" d="M 4.433594 5.59375 L 13.566406 5.59375 L 13.566406 12.402344 L 4.433594 12.402344 Z M 4.433594 5.59375 "/> +</clipPath> +</defs> +<g clip-path="url(#clip-0)"> +<g fill="rgb(0%, 0%, 0%)" fill-opacity="1"> +<use xlink:href="#glyph-0-0" x="4.434" y="12.404"/> +</g> +</g> +<path fill="none" stroke-width="0.4" stroke-linecap="butt" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 8 840 L 8 824 L 24 824 L 24 840 Z M 8 840 " transform="matrix(1, 0, 0, -1, -7, 841)"/> +</svg> diff --git a/favicon.ico b/favicon.ico Binary files differnew file mode 100644 index 0000000..6cb5040 --- /dev/null +++ b/favicon.ico @@ -1,3 +1,5 @@ +import { getMatchCount, shuffle } from "./utils.mjs"; + class Team { constructor(player_1, player_2) { this.player_1 = player_1; @@ -11,7 +13,7 @@ class Team { } } -class Game { +export class Game { constructor(court, team_1, team_2) { this.court_id = court.id; this.court_status = court.status; @@ -29,19 +31,61 @@ class Game { } } +export function generateDummyGames(courts) { + let team = new Team("---", "---"); + let games = []; + for (const court of courts ) { + let game = new Game(court, team, team); + games.push(game); + } + return games; +} + export class Round { - constructor(number, courts) { + constructor(number, games) { this.number = number; - this.courts = courts; + this.games = games; } - render() { - let output = `<h2 class="subtitle"> Round ${this.number} </h3><table class="table is-fullwidth"><thead><tr><th align="center">Court</th><th align="center" colspan='2'>Team 1</th><th colspan='2' align="center">Team 2</th></tr></thead>`; - let team = new Team("---", "---"); - for (const court of this.courts ) { - let game = new Game(court, team, team); + render(description) { + let heading = typeof description !== 'undefined' ? description : "Round " + this.number; + let output = `<h2 class="subtitle">${heading}</h3><table class="table is-fullwidth"><thead><tr><th align="center">Court</th><th align="center" colspan='2'>Team 1</th><th colspan='2' align="center">Team 2</th></tr></thead>`; + for (const game of this.games ) { output += game.render() } output += "</table>"; return output; } +} + +export function proposeGames(players, courts) { + console.log("Proposing new games!"); + let possibleMatches = getMatchCount(players, courts); + let requiredPlayers = possibleMatches * 4; + console.log("Required players are " + requiredPlayers); + const activeCourts = courts.filter(function (c) { return c.status }); + const inactiveCourts = courts.filter(function (c) { return !c.status }); + const activePlayers = players.filter(function (p) { return p.status;}); + console.log("Total reserved courts are " + inactiveCourts.length + "."); + console.log("Total possible matches are " + possibleMatches + "."); + console.log("Active players are:"); + console.log(activePlayers.map((i) => {return i.name;}).join(',')); + const shuffledPlayers = shuffle(activePlayers); + shuffledPlayers.sort((a, b) => a.totalPlayed - b.totalPlayed); + const selectedPlayers = shuffledPlayers.slice(0, requiredPlayers); + selectedPlayers.sort((a, b) => a.level - b.level); + console.log("Selected players are:"); + console.log(selectedPlayers.map((i) => {return i.name;}).join(',')); + console.log("The matches are:"); + let games = []; + for (let index = 0; index < possibleMatches; index++) { + const startIndex = 4 * index; + const endIndex = startIndex + 4; + const courtPlayers = selectedPlayers.slice(startIndex, endIndex); + const team_1 = new Team(courtPlayers[0].name, courtPlayers[3].name); + const team_2 = new Team(courtPlayers[1].name, courtPlayers[2].name); + const game = new Game(activeCourts[index], team_1, team_2); + game.print(); + games.push(game); + } + return games; }
\ No newline at end of file @@ -1,4 +1,4 @@ -import { Round } from "./game.mjs"; +import { Round, generateDummyGames, proposeGames } from "./game.mjs"; import { generateCourts } from "./court.mjs"; import { csvToPlayers, generatePlayers } from "./player.mjs"; import { addToggleBehaviour } from "./utils.mjs"; @@ -12,8 +12,8 @@ addToggleBehaviour(courts, "court_"); let regulars = generatePlayers(); addToggleBehaviour(regulars, "regular_"); const fileInput = document.querySelector("#player-load input[type=file]"); - if (fileInput !== null) { - fileInput.onchange = () => { +if (fileInput !== null) { + fileInput.onchange = () => { if (fileInput.files.length > 0) { const file = fileInput.files[0]; if (file) { @@ -27,12 +27,12 @@ const fileInput = document.querySelector("#player-load input[type=file]"); } } } -}; +} // Game handling -let games = new Round(0, courts); -let renderedHTML = games.render(); -document.getElementById("game_list").innerHTML = renderedHTML; +let round = new Round(0, generateDummyGames(courts)); +document.getElementById("game_list").innerHTML = round.render(); document.getElementById("propose").addEventListener("click", () => { - console.log("Propose new games!"); + round = new Round(0, proposeGames(regulars, courts)); + document.getElementById("game_list").innerHTML = round.render(); })
\ No newline at end of file @@ -1,9 +1,10 @@ export class Player { - constructor(id, name, level, status) { + constructor(id, name, level, status, totalPlayed) { this.id = id; this.name = name; this.level = typeof level !== 'undefined' ? level : 1; this.status = typeof status !== 'undefined' ? status : false; + this.totalPlayed = typeof totalPlayed !== 'undefined' ? status : 0; } toggle() { this.status = !this.status; @@ -31,7 +32,7 @@ function randomStatus() { export function generatePlayers() { let players = []; for (let i = 0; i < 71; i++) { - players.push(new Player(i, "Player " + i, randomLevel(), randomStatus())); + players.push(new Player(i, "Player " + i, randomLevel(), randomStatus(), 0)); } return players; } @@ -41,7 +42,7 @@ function parseLineToPlayer(data) { var id = Number(info[0].trim()); var name = info[1].trim() + " " + info[2].trim(); var level = Number(info[3].trim()); - return new Player(id, name, level, false); + return new Player(id, name, level, false, 0); } export function csvToPlayers(csv) { @@ -12,17 +12,20 @@ export function addToggleBehaviour(list, description) { } } -// document.querySelector("#player-load input[type=file]").onchange = () => { -// if (fileInput.files.length > 0) { -// const file = fileInput.files[0]; -// if (file) { -// const reader = new FileReader(); -// reader.onload = function(e) { -// const content = e.target.result; -// regulars = csvToPlayers(content); -// addToggleBehaviour(regulars, "regular_"); -// }; -// reader.readAsText(file); -// } -// } -// }
\ No newline at end of file +export function getMatchCount(regulars, courts) { + const activeCourts = courts.filter(function (c) { return c.status }); + console.log("There are a total of " + activeCourts.length + " courts available."); + const activePlayers = regulars.filter(function (p) { return p.status;}); + console.log("There are a total of " + activePlayers.length + " players available."); + var possibleMatches = Math.floor(activePlayers.length / 4); + possibleMatches = possibleMatches > activeCourts.length ? activeCourts.length : possibleMatches; + return possibleMatches; +} + +export function shuffle(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array; +}
\ No newline at end of file |
