」 feat(tournament): logic

This commit is contained in:
y-syo
2025-10-23 23:05:44 +02:00
parent d20597ee6a
commit 10e4eeae55
7 changed files with 444 additions and 94 deletions

View File

@ -27,8 +27,10 @@ export default class extends Aview {
<div class="bg-neutral-200 dark:bg-neutral-800 text-center pb-10 pt-5 px-10 reverse-border flex flex-col items-center"> <div class="bg-neutral-200 dark:bg-neutral-800 text-center pb-10 pt-5 px-10 reverse-border flex flex-col items-center">
<form method="dialog" class="space-y-4"> <form method="dialog" class="space-y-4">
<h1 class="text-gray-900 dark:text-white text-lg pt-0 pb-4">welcome back ! please login.</h1> <h1 class="text-gray-900 dark:text-white text-lg pt-0 pb-4">welcome back ! please login.</h1>
<input type="text" id="username" placeholder="username" class="bg-white text-neutral-900 px-4 py-2 input-border" required></input> <div class="flex flex-row justify-between space-x-4">
<input type="password" id="password" placeholder="password" class="bg-white text-neutral-900 px-4 py-2 input-border" required></input> <input type="text" id="username" placeholder="username" class="bg-white text-neutral-900 px-4 py-2 input-border" required></input>
<input type="password" id="password" placeholder="password" class="bg-white text-neutral-900 px-4 py-2 input-border" required></input>
</div>
<button id="login-button" type="submit" class="default-button w-full">login</button> <button id="login-button" type="submit" class="default-button w-full">login</button>
</form> </form>

View File

@ -59,6 +59,9 @@ export default class extends Aview {
let p1_name: string; let p1_name: string;
let p2_name: string; let p2_name: string;
let p1_displayName: string;
let p2_displayName: string;
let countdown: number = 3; let countdown: number = 3;
let countdownTimer: number = 0; let countdownTimer: number = 0;
@ -203,8 +206,8 @@ export default class extends Aview {
ctx.font = "24px Kubasta"; ctx.font = "24px Kubasta";
let text_score = `${p1_score} - ${p2_score}`; let text_score = `${p1_score} - ${p2_score}`;
ctx.fillText(text_score, canvas.width / 2 - (ctx.measureText(text_score).width / 2), 25); ctx.fillText(text_score, canvas.width / 2 - (ctx.measureText(text_score).width / 2), 25);
ctx.fillText(p1_name, canvas.width / 4 - (ctx.measureText(p1_name).width / 2), 45); ctx.fillText(p1_displayName, canvas.width / 4 - (ctx.measureText(p1_name).width / 2), 45);
ctx.fillText(p2_name, (canvas.width / 4 * 3) - (ctx.measureText(p2_name).width / 2), 45); ctx.fillText(p2_displayName, (canvas.width / 4 * 3) - (ctx.measureText(p2_name).width / 2), 45);
if (match_over) if (match_over)
{ {
@ -273,23 +276,46 @@ export default class extends Aview {
if (await isLogged()) if (await isLogged())
{ {
uuid = document.cookie.match(new RegExp('(^| )' + "uuid" + '=([^;]+)'))[2]; uuid = document.cookie.match(new RegExp('(^| )' + "uuid" + '=([^;]+)'))[2];
const userdata_req = await fetch(`http://localhost:3002/users/${uuid}`, {
method: "GET", p1_input.value = uuid;
credentials: "include",
});
if (userdata_req.status == 404)
{
console.error("invalid user");
return ;
}
let userdata = await userdata_req.json();
p1_input.value = userdata.displayName;
p1_input.readOnly = true; p1_input.readOnly = true;
} }
else else
p1_input.value = "player 1"; p1_input.value = "player 1";
document.getElementById("game-start")?.addEventListener("click", () => { document.getElementById("game-start")?.addEventListener("click", async () => {
let p1_isvalid = true;
let p2_isvalid = true;
if (await isLogged()) {
const p1_req = await fetch(`http://localhost:3002/users/${p1_input.value}`, {
method: "GET",
credentials: "include",
});
const p2_req = await fetch(`http://localhost:3002/users/${p2_input.value}`, {
method: "GET",
credentials: "include",
});
if (p1_req.status != 200)
p1_isvalid = false;
else
p1_displayName = (await p1_req.json()).displayName;
if (p2_req.status != 200)
p2_isvalid = false;
else
p2_displayName = (await p2_req.json()).displayName;
}
else
p1_isvalid = p2_isvalid = false;
p1_name = p1_input.value;
p2_name = p2_input.value;
if (!p1_isvalid)
p1_displayName = p1_name;
if (!p2_isvalid)
p2_displayName = p2_name;
p1_displayName = p1_displayName.length > 16 ? p1_displayName.substring(0, 16) + "." : p1_displayName;
p2_displayName = p2_displayName.length > 16 ? p2_displayName.substring(0, 16) + "." : p2_displayName;
p1_name = p1_input.value.length > 16 ? p1_input.value.substring(0, 16) + "." : p1_input.value; p1_name = p1_input.value.length > 16 ? p1_input.value.substring(0, 16) + "." : p1_input.value;
p2_name = p2_input.value.length > 16 ? p2_input.value.substring(0, 16) + "." : p2_input.value; p2_name = p2_input.value.length > 16 ? p2_input.value.substring(0, 16) + "." : p2_input.value;
document.getElementById("player-inputs").remove(); document.getElementById("player-inputs").remove();

View File

@ -78,6 +78,12 @@ export default class extends Aview {
if (matches.matchHistory) { if (matches.matchHistory) {
for (let match of matches.matchHistory) { for (let match of matches.matchHistory) {
const p2_req = await fetch(`http://localhost:3002/users/${match.score.p2}`, {
method: "GET",
credentials: "include",
});
match.score.p1 = userdata.displayName;
match.score.p2 = (await p2_req.json()).displayName;
const newEntry = document.createElement("li"); const newEntry = document.createElement("li");
newEntry.classList.add("m-1", "default-button", "bg-neutral-200", "dark:bg-neutral-800", "text-neutral-900", "dark:text-white"); newEntry.classList.add("m-1", "default-button", "bg-neutral-200", "dark:bg-neutral-800", "text-neutral-900", "dark:text-white");
newEntry.innerHTML = match.score.p1Score > match.score.p2Score ? `${match.score.p1} - winner` : `${match.score.p2} - winner`; newEntry.innerHTML = match.score.p1Score > match.score.p2Score ? `${match.score.p1} - winner` : `${match.score.p2} - winner`;
@ -134,6 +140,15 @@ export default class extends Aview {
if (matches.matchHistory) { if (matches.matchHistory) {
for (let match of matches.matchHistory) { for (let match of matches.matchHistory) {
if (match.score.p2 != undefined)
{
const p2_req = await fetch(`http://localhost:3002/users/${match.score.p2}`, {
method: "GET",
credentials: "include",
});
match.score.p2 = (await p2_req.json()).displayName;
}
match.score.p1 = userdata.displayName;
const newEntry = document.createElement("li"); const newEntry = document.createElement("li");
newEntry.classList.add("m-1", "default-button", "bg-neutral-200", "dark:bg-neutral-800", "text-neutral-900", "dark:text-white"); newEntry.classList.add("m-1", "default-button", "bg-neutral-200", "dark:bg-neutral-800", "text-neutral-900", "dark:text-white");
newEntry.innerHTML = match.score.p2 != undefined ? newEntry.innerHTML = match.score.p2 != undefined ?

View File

@ -68,19 +68,20 @@ export default class extends Aview {
`; `;
} }
requestAnimationFrame(async () => {
document.getElementById("profile-items").innerHTML = await getMainHTML();
document.getElementById("profile-items").innerHTML = await getMainHTML(); document.getElementById("menu-logout").addEventListener("click", async () => {
let req = await fetch("http://localhost:3001/logout", {
document.getElementById("menu-logout").addEventListener("click", async () => { method: "GET",
let req = await fetch("http://localhost:3001/logout", { credentials: "include",
method: "GET", });
credentials: "include", isLogged();
if (req.status === 200)
this.run();
else
console.error("logout failed");
}); });
isLogged();
if (req.status === 200)
this.run();
else
console.error("logout failed");
}); });
} }
} }

View File

@ -27,8 +27,10 @@ export default class extends Aview {
<div class="bg-neutral-200 dark:bg-neutral-800 text-center pb-10 pt-5 px-10 reverse-border flex flex-col items-center"> <div class="bg-neutral-200 dark:bg-neutral-800 text-center pb-10 pt-5 px-10 reverse-border flex flex-col items-center">
<form method="dialog" class="space-y-4"> <form method="dialog" class="space-y-4">
<h1 class="text-gray-900 dark:text-white text-lg pt-0 pb-4">welcome ! please register.</h1> <h1 class="text-gray-900 dark:text-white text-lg pt-0 pb-4">welcome ! please register.</h1>
<input type="text" id="username" placeholder="username" class="bg-white text-neutral-900 px-4 py-2 input-border" required></input> <div class="flex flex-row justify-between space-x-4">
<input type="password" id="password" placeholder="password" class="bg-white text-neutral-900 px-4 py-2 input-border" required></input> <input type="text" id="username" placeholder="username" class="bg-white text-neutral-900 px-4 py-2 input-border" required></input>
<input type="password" id="password" placeholder="password" class="bg-white text-neutral-900 px-4 py-2 input-border" required></input>
</div>
<button id="register-button" type="submit" class="default-button w-full">register</button> <button id="register-button" type="submit" class="default-button w-full">register</button>
</form> </form>
@ -75,7 +77,6 @@ export default class extends Aview {
}); });
let uuid = await uuid_req.json(); let uuid = await uuid_req.json();
document.cookie = `uuid=${uuid.user};max-ages=${60*60*24*7}`; document.cookie = `uuid=${uuid.user};max-ages=${60*60*24*7}`;
console.log(document.cookie);
isLogged(); isLogged();
navigationManager("/"); navigationManager("/");
} }

View File

@ -65,6 +65,8 @@ export default class extends Aview {
let p2_score: number = 0; let p2_score: number = 0;
let p1_name: string; let p1_name: string;
let p2_name: string; let p2_name: string;
let p1_displayName: string;
let p2_displayName: string;
const view = this; const view = this;
@ -861,7 +863,7 @@ export default class extends Aview {
ctx.fillRect(4, 4, 120, 60); ctx.fillRect(4, 4, 120, 60);
ctx.fillStyle = "#fff"; ctx.fillStyle = "#fff";
ctx.font = "12px Kubasta"; ctx.font = "12px Kubasta";
ctx.fillText(`${this.id == 0 ? p1_name : p2_name}: ${this.id == 0 ? p1_score : p2_score}`, 8, 20); ctx.fillText(`${this.id == 0 ? p1_displayName : p2_displayName}: ${this.id == 0 ? p1_score : p2_score}`, 8, 20);
ctx.fillText(`score: ${this.score}`, 8, 36); ctx.fillText(`score: ${this.score}`, 8, 36);
ctx.fillText(`lines: ${this.lines}`, 8, 52); ctx.fillText(`lines: ${this.lines}`, 8, 52);
@ -931,26 +933,48 @@ export default class extends Aview {
p2_input.value = "player 2"; p2_input.value = "player 2";
if (await isLogged()) if (await isLogged())
{ {
uuid = document.cookie.match(new RegExp('(^| )' + "uuid" + '=([^;]+)'))[2]; uuid = document.cookie.match(new RegExp('(^| )' + "uuid" + '=([^;]+)'))[2];
const userdata_req = await fetch(`http://localhost:3002/users/${uuid}`, { p1_input.value = uuid;
method: "GET",
credentials: "include",
});
if (userdata_req.status == 404)
{
console.error("invalid user");
return ;
}
let userdata = await userdata_req.json();
p1_input.value = userdata.displayName;
p1_input.readOnly = true; p1_input.readOnly = true;
} }
else else
p1_input.value = "player 1"; p1_input.value = "player 1";
document.getElementById("game-start")?.addEventListener("click", () => { document.getElementById("game-start")?.addEventListener("click", async () => {
p1_name = p1_input.value.length > 16 ? p1_input.value.substring(0, 16) + "." : p1_input.value; let p1_isvalid = true;
p2_name = p2_input.value.length > 16 ? p2_input.value.substring(0, 16) + "." : p2_input.value; let p2_isvalid = true;
if (await isLogged()) {
const p1_req = await fetch(`http://localhost:3002/users/${p1_input.value}`, {
method: "GET",
credentials: "include",
});
const p2_req = await fetch(`http://localhost:3002/users/${p2_input.value}`, {
method: "GET",
credentials: "include",
});
if (p1_req.status != 200)
p1_isvalid = false;
else
p1_displayName = (await p1_req.json()).displayName;
if (p2_req.status != 200)
p2_isvalid = false;
else
p2_displayName = (await p2_req.json()).displayName;
}
else
p1_isvalid = p2_isvalid = false;
p1_name = p1_input.value;
p2_name = p2_input.value;
if (!p1_isvalid)
p1_displayName = p1_name;
if (!p2_isvalid)
p2_displayName = p2_name;
p1_displayName = p1_displayName.length > 16 ? p1_displayName.substring(0, 16) + "." : p1_displayName;
p2_displayName = p2_displayName.length > 16 ? p2_displayName.substring(0, 16) + "." : p2_displayName;
document.getElementById("player-inputs").remove(); document.getElementById("player-inputs").remove();
document.getElementById("game-boards").classList.remove("hidden"); document.getElementById("game-boards").classList.remove("hidden");
game1 = new Game("board1", 0); game1 = new Game("board1", 0);

View File

@ -1,14 +1,17 @@
import Aview from "./Aview.ts" import Aview from "./Aview.ts"
import { isLogged } from "../main.js"
import { dragElement } from "./drag.ts"; import { dragElement } from "./drag.ts";
import { setOnekoState, setBallPos } from "../oneko.ts" import { setOnekoState, setBallPos, setOnekoOffset } from "../oneko.ts"
export default class extends Aview { export default class extends Aview {
running: boolean;
constructor() constructor()
{ {
super(); super();
this.setTitle("Tournament"); this.setTitle("Tournament");
setOnekoState("default"); setOnekoState("default");
this.running = true;
} }
async getHTML() { async getHTML() {
@ -23,7 +26,8 @@ export default class extends Aview {
</div> </div>
</div> </div>
<div class="bg-neutral-200 dark:bg-neutral-800 text-center p-10 pt-5 space-y-4 reverse-border"> <div id="main-div" class="bg-neutral-200 dark:bg-neutral-800 text-center p-10 pt-5 space-y-4 reverse-border">
<div id="tournament-id">
<p class="text-neutral-900 dark:text-white text-lg font-bold pb-4">how many players ?</p> <p class="text-neutral-900 dark:text-white text-lg font-bold pb-4">how many players ?</p>
<div class="flex flex-col space-y-4"> <div class="flex flex-col space-y-4">
<select id="playerNumber" class="bg-white text-shadow-neutral-900 p-2 input-border"> <select id="playerNumber" class="bg-white text-shadow-neutral-900 p-2 input-border">
@ -37,28 +41,285 @@ export default class extends Aview {
<button type="submit" id="bracket-generate" class="default-button">create the bracket</button> <button type="submit" id="bracket-generate" class="default-button">create the bracket</button>
<div id="bracket" class="flex flex-col space-y-6 items-center"></div> <div id="bracket" class="flex flex-col space-y-6 items-center"></div>
</div> </div>
</div>
</div> </div>
</div> </div>
`; `;
} }
async runGame(p1_id: number, p2_id: number, players: string[]): Promise<number> {
return new Promise<number>(async (resolve) => {
console.log(p1_id, p2_id, players, players[p1_id], players[p2_id]);
let p1_name = players[p1_id];
let p2_name = players[p2_id];
let uuid: string;
let start: number = 0;
let elapsed: number;
let game_playing: boolean = false;
let match_over: boolean = false;
let p1_score: number = 0;
let p2_score: number = 0;
let p1_displayName: string;
let p2_displayName: string;
let countdown: number = 3;
let countdownTimer: number = 0;
let canvas: HTMLCanvasElement;
let ctx: CanvasRenderingContext2D;
const paddleOffset: number = 15;
const paddleHeight: number = 100;
const paddleWidth: number = 10;
const ballSize: number = 10;
const paddleSpeed: number = 727 * 0.69;
let leftPaddleY: number;
let rightPaddleY: number;
let ballX: number;
let ballY: number;
let ballSpeed: number = 200;
let ballSpeedX: number = 300;
let ballSpeedY: number = 10;
const keys: Record<string, boolean> = {};
document.addEventListener("keydown", e => { keys[e.key] = true; });
document.addEventListener("keyup", e => { keys[e.key] = false; });
function movePaddles() {
if ((keys["w"] || keys["W"]) && leftPaddleY > 0)
leftPaddleY -= paddleSpeed * elapsed;
if ((keys["s"] || keys["S"]) && leftPaddleY < canvas.height - paddleHeight)
leftPaddleY += paddleSpeed * elapsed;
if (keys["ArrowUp"] && rightPaddleY > 0)
rightPaddleY -= paddleSpeed * elapsed;
if (keys["ArrowDown"] && rightPaddleY < canvas.height - paddleHeight)
rightPaddleY += paddleSpeed * elapsed;
}
function getBounceVelocity(paddleY: number) {
const paddleCenterY = paddleY + paddleHeight / 2;
let n = (ballY - paddleCenterY) / (paddleHeight / 2);
n = Math.max(-1, Math.min(1, n));
let theta = n * ((75 * Math.PI) / 180);
ballSpeedY = ballSpeed * Math.sin(theta);
}
async function moveBall() {
let length = Math.sqrt(ballSpeedX * ballSpeedX + ballSpeedY * ballSpeedY);
let scale = ballSpeed / length;
ballX += (ballSpeedX * scale) * elapsed;
ballY += (ballSpeedY * scale) * elapsed;
if (ballY <= 0 || ballY >= canvas.height - ballSize)
ballSpeedY *= -1;
if (ballX <= paddleWidth + paddleOffset && ballX >= paddleOffset &&
ballY > leftPaddleY && ballY < leftPaddleY + paddleHeight) {
ballSpeedX *= -1;
ballX = paddleWidth + paddleOffset;
getBounceVelocity(leftPaddleY);
ballSpeed += 10;
}
if (ballX >= canvas.width - paddleWidth - ballSize - paddleOffset && ballX <= canvas.width - ballSize - paddleOffset &&
ballY > rightPaddleY && ballY < rightPaddleY + paddleHeight) {
ballSpeedX *= -1;
ballX = canvas.width - paddleWidth - ballSize - paddleOffset;
getBounceVelocity(rightPaddleY);
ballSpeed += 10;
}
// scoring
if (ballX < 0 || ballX > canvas.width - ballSize) {
setOnekoState("default");
game_playing = false;
if (ballX < 0)
p2_score++;
else
p1_score++;
if (p1_score === 3 || p2_score === 3) {
if (await isLogged()) {
let uuid = document.cookie.match(new RegExp('(^| )' + "uuid" + '=([^;]+)'))[2];
fetch(`http://localhost:3002/users/${uuid}/matchHistory?game=pong`, {
method: "POST",
headers: { "Content-Type": "application/json", },
credentials: "include",
body: JSON.stringify({
"game": "pong",
"opponent": p2_name,
"myScore": p1_score,
"opponentScore": p2_score,
"date": Date.now(),
}),
});
resolve(p1_score == 3 ? p1_id : p2_id);
}
match_over = true;
}
else {
countdown = 3;
countdownTimer = performance.now();
}
ballX = canvas.width / 2;
ballY = canvas.height / 2;
ballSpeed = 200;
ballSpeedX = 300 * ((ballSpeedX > 0) ? 1 : -1);
ballSpeedY = 10;
ballSpeedX = -ballSpeedX;
leftPaddleY = canvas.height / 2 - paddleHeight / 2;
rightPaddleY = canvas.height / 2 - paddleHeight / 2;
}
setBallPos(ballX, ballY);
}
function draw() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = "white";
ctx.beginPath();
ctx.setLineDash([5, 10]);
ctx.moveTo(canvas.width / 2, 0);
ctx.lineTo(canvas.width / 2, canvas.height);
ctx.stroke();
ctx.fillStyle = "white";
ctx.fillRect(paddleOffset, leftPaddleY, paddleWidth, paddleHeight);
ctx.fillRect(canvas.width - paddleWidth - paddleOffset, rightPaddleY, paddleWidth, paddleHeight);
ctx.fillStyle = "white";
if (game_playing)
ctx.fillRect(ballX, ballY, ballSize, ballSize);
ctx.font = "24px Kubasta";
let text_score = `${p1_score} - ${p2_score}`;
ctx.fillText(text_score, canvas.width / 2 - (ctx.measureText(text_score).width / 2), 25);
ctx.fillText(p1_displayName, canvas.width / 4 - (ctx.measureText(p1_name).width / 2), 45);
ctx.fillText(p2_displayName, (canvas.width / 4 * 3) - (ctx.measureText(p2_name).width / 2), 45);
if (match_over) {
ctx.font = "32px Kubasta";
const winner = `${p1_score > p2_score ? p1_name : p2_name} won :D`;
ctx.fillText(winner, canvas.width / 2 - (ctx.measureText(winner).width / 2), canvas.height / 2 + 16);
document.getElementById("game-buttons")?.classList.remove("hidden");
}
}
function startCountdown() {
const now = performance.now();
if (countdown > 0) {
if (now - countdownTimer >= 500) {
countdown--;
countdownTimer = now;
}
ctx.font = "48px Kubasta";
ctx.fillText(countdown.toString(), canvas.width / 2 - 10, canvas.height / 2 + 24);
}
else if (countdown === 0) {
ctx.font = "48px Kubasta";
ctx.fillText("Go!", canvas.width / 2 - 30, canvas.height / 2 + 24);
setTimeout(() => {
game_playing = true;
countdown = -1;
}, 500);
}
}
const gameLoop = async (timestamp: number) => {
elapsed = (timestamp - start) / 1000;
start = timestamp;
if (game_playing) {
movePaddles();
await moveBall();
}
draw();
if (!game_playing)
startCountdown();
if (this.running)
requestAnimationFrame(gameLoop);
};
document.getElementById("game-retry")?.addEventListener("click", () => {
setOnekoState("pong");
document.getElementById("game-buttons")?.classList.add("hidden");
game_playing = false;
match_over = false;
p1_score = 0;
p2_score = 0;
countdown = 3;
countdownTimer = performance.now();
});
let p1_isvalid = true;
let p2_isvalid = true;
if (await isLogged()) {
const p1_req = await fetch(`http://localhost:3002/users/${p1_name}`, {
method: "GET",
credentials: "include",
});
const p2_req = await fetch(`http://localhost:3002/users/${p2_name}`, {
method: "GET",
credentials: "include",
});
if (p1_req.status != 200)
p1_displayName = p1_name;
else
p1_displayName = (await p1_req.json()).displayName;
if (p2_req.status != 200)
p2_displayName = p2_name;
else
p2_displayName = (await p2_req.json()).displayName;
}
p1_displayName = p1_displayName.length > 16 ? p1_displayName.substring(0, 16) + "." : p1_displayName;
p2_displayName = p2_displayName.length > 16 ? p2_displayName.substring(0, 16) + "." : p2_displayName;
p1_name = p1_name.length > 16 ? p1_name.substring(0, 16) + "." : p1_name;
p2_name = p2_name.length > 16 ? p2_name.substring(0, 16) + "." : p2_name;
document.getElementById("tournament-ui")?.classList.add("hidden");
canvas = document.createElement("canvas");
canvas.id = "gameCanvas";
canvas.classList.add("reverse-border");
document.getElementById("main-div")?.prepend(canvas);
ctx = canvas.getContext("2d", { alpha: false }) as CanvasRenderingContext2D;
ctx.canvas.width = 600;
ctx.canvas.height = 600;
leftPaddleY = canvas.height / 2 - paddleHeight / 2;
rightPaddleY = canvas.height / 2 - paddleHeight / 2;
ballX = canvas.width / 2;
ballY = canvas.height / 2;
setOnekoState("pong");
setOnekoOffset();
requestAnimationFrame(gameLoop);
});
}
async run() { async run() {
dragElement(document.getElementById("window")); dragElement(document.getElementById("window"));
const generateBracket = async (playerCount: number) => { const generateBracket = async (playerCount: number) => {
let initPlayerCount = playerCount;
document.getElementById("bracket").innerHTML = ""; document.getElementById("bracket").innerHTML = "";
const rounds = Math.ceil(Math.log2(playerCount)); const rounds: number = Math.ceil(Math.log2(playerCount));
const totalSlots = 2 ** rounds; const totalSlots: number = 2 ** rounds;
const byes = totalSlots - playerCount; let odd: number = 0;
let notPowPlayersCount: number = 0;
let odd = 0; let tournament: number[][] = [];
if (playerCount > 9 || (playerCount != 3 && playerCount % 2 != 0))
{
console.error("odd numbers are temporarily invalids");
return ;
}
let notPowPlayersCount = 0;
if ((playerCount & (playerCount - 1)) != 0) if ((playerCount & (playerCount - 1)) != 0)
notPowPlayersCount = playerCount - (2 ** Math.floor(Math.log2(playerCount))); notPowPlayersCount = playerCount - (2 ** Math.floor(Math.log2(playerCount)));
@ -74,20 +335,33 @@ export default class extends Aview {
const playerInputColumn = document.createElement("div"); const playerInputColumn = document.createElement("div");
playerInputColumn.className = `flex flex-col mt-${(notPowPlayersCount + odd) * 28} space-y-4`; playerInputColumn.className = `flex flex-col mt-${(notPowPlayersCount + odd) * 28} space-y-4`;
tournament.push([]);
initialPlayers.forEach((name, i) => { initialPlayers.forEach((name, i) => {
const input = document.createElement("input"); const input = document.createElement("input");
input.type = "text"; input.type = "text";
input.id = `playerName${i}`; input.id = `playerName${i}`;
input.value = ""; input.value = name;
input.placeholder = name; input.placeholder = name;
if (i == 0)
{
isLogged().then((value) => {
if (value) {
let uuid = document.cookie.match(new RegExp('(^| )' + "uuid" + '=([^;]+)'))[2];
input.value = uuid;
input.readOnly = true;
}
});
}
input.className = "w-32 h-10 p-2 text-sm bg-white disabled:bg-gray-200 input-border"; input.className = "w-32 h-10 p-2 text-sm bg-white disabled:bg-gray-200 input-border";
playerInputColumn.appendChild(input); playerInputColumn.appendChild(input);
tournament[0].push(i);
}); });
bracketWrapper.appendChild(playerInputColumn); bracketWrapper.appendChild(playerInputColumn);
let currentRound = initialPlayers; let currentRound = initialPlayers;
let previousPadding = 4; let previousPadding = 4;
tournament.push([]);
for (let round = 1; round <= rounds; round++) for (let round = 1; round <= rounds; round++)
{ {
const roundColumn = document.createElement("div"); const roundColumn = document.createElement("div");
@ -96,34 +370,17 @@ export default class extends Aview {
const nextRound: string[] = []; const nextRound: string[] = [];
if (!notPowPlayersCount) while (notPowPlayersCount) {
{ tournament[1].push(playerCount);
if (odd) const input = document.createElement("input");
{ input.type = "text";
const input = document.createElement("input"); input.id = `playerName${playerCount}`;
input.type = "text"; input.value = `player ${playerCount + 1}`;
input.id = `playerName${playerCount}`; input.placeholder = `player ${++playerCount}`;
input.value = `player ${++playerCount}`; input.className =
input.placeholder = `player ${++playerCount}`; "w-32 h-10 p-2 text-sm bg-white disabled:bg-gray-200 input-border";
input.className = roundColumn.appendChild(input);
"w-32 h-10 p-2 text-sm bg-white disabled:bg-gray-200 input-border"; --notPowPlayersCount;
roundColumn.appendChild(input);
odd--;
nextRound.push("");
}
}
while (notPowPlayersCount)
{
const input = document.createElement("input");
input.type = "text";
input.id = `playerName${playerCount}`;
input.value = "";
input.placeholder = `player ${++playerCount}`;
input.className =
"w-32 h-10 p-2 text-sm bg-white disabled:bg-gray-200 input-border";
roundColumn.appendChild(input);
--notPowPlayersCount;
nextRound.push(""); nextRound.push("");
} }
@ -146,13 +403,37 @@ export default class extends Aview {
currentRound = nextRound; currentRound = nextRound;
} }
document.getElementById("bracket").appendChild(document.createElement("hr")).classList.add("my-4", "mb-8", "w-64", "reverse-border"); document.getElementById("bracket")?.appendChild(document.createElement("hr")).classList.add("my-4", "mb-8", "w-64", "reverse-border");
document.getElementById("bracket").appendChild(bracketWrapper); document.getElementById("bracket")?.appendChild(bracketWrapper);
const btn = document.getElementById("bracket").appendChild(document.createElement("button")); const btn = document.getElementById("bracket")?.appendChild(document.createElement("button"));
if (!btn) return;
btn.classList.add("default-button", "w-full"); btn.classList.add("default-button", "w-full");
btn.id = "tournament-play"; btn.id = "tournament-play";
btn.onclick = () => { btn.onclick = async () => {
console.log("ok");
let players: string[] = [];
for (let i of Array(initPlayerCount).keys()) {
players.push((document.getElementById(`playerName${i}`) as HTMLInputElement).value);
}
while (tournament[0].length > 1)
{
while(tournament[0].length > 0)
{
console.log(tournament[0]);
const p1 = tournament[0].shift() as number;
const p2 = tournament[0].shift() as number;
document.getElementById("tournament-id")?.classList.add("hidden");
const result = await this.runGame(p1, p2, players);
document.getElementById("gameCanvas").remove();
document.getElementById("tournament-id")?.classList.remove("hidden");
tournament[1].push(result);
}
tournament[0] = tournament[1];
tournament[1] = [];
}
console.log(`winner: ${tournament[0][0]}`);
}; };
btn.innerText = "start tournament !!"; btn.innerText = "start tournament !!";