import { computed } from "vue"; function setPoints(page, set){ let points = [0, 0]; // need to get updated for more player let ret; const m = page.game.sets.length-1; for (const i in page.game.sets) { const set = page.game.sets[i]; const points = legPoints(page, set, set.legs[set.legs.length-1]); const winner = getWinner(points, page.legs); if (winner > -1) points[winner] += 1; else return points; if (set == set){ return points; } } return points; } function legPoints(page, set, leg){ let points = [0, 0]; // need to get updated for more player let ret; const m = set.legs.length-1; for (const i in set.legs) { const l = set.legs[i]; if (l.visits[l.visits.length-1].toGo === undefined) { return points; } if (l.visits[l.visits.length-1].toGo[0] == 0) points[0] += 1; else if (l.visits[l.visits.length-1].toGo[1] == 0) points[1] += 1; if (l == leg){ return points; } } return points; } export const getFinalWinner = (page) => { const points = setPoints(page, page.sets[page.sets.length-1]); return getWinner(points, page.sets); }; export function getGameProps(page, current_set, current_leg) { const ret = {}; if (current_set === undefined) { current_set = computed(() => { if (page.game != undefined) { return page.game.sets[page.game.sets.length - 1] } return undefined; }); } ret.current_set = current_set; if (current_leg === undefined) { current_leg = computed(() => { if (current_set.value != undefined) { return current_set.value.legs[current_set.value.legs.length - 1] } return undefined; }); } ret.current_leg = current_leg; const current_toGo = computed(() => { if (current_leg.value != undefined) { if (current_leg.value.visits.length < 2) { return [page.modus, page.modus] } else { const end = current_leg.value.visits[current_leg.value.visits.length - 1].toGo; if (end) return end; return current_leg.value.visits[current_leg.value.visits.length - 2].toGo; } } return [0, 0]; // need to get updated for more player }); ret.current_toGo = current_toGo; const current_set_points = computed(() => { if (current_set.value != undefined) { return setPoints(page, current_set.value); } return undefined; }); ret.current_set_points = current_set_points; const current_leg_points = computed(() => { if (current_set.value != undefined || current_leg.value != undefined) { return legPoints(page, current_set.value, current_leg.value); } return undefined; }); ret.current_leg_points = current_leg_points; const current_player = computed(() => { if (current_leg.value != undefined) { const len = current_leg.value.visits.length; return current_leg.value.visits[len - 1].player == page.players[1].uuid; } return undefined; }); ret.current_player = current_player; const getVal = (tr) => { const val = tr.trim(); if (val == "") { return 0; } if (val == "SB") { return 25; } if (val == "DB") { return 50; } if (val[0] == "S" || val[0] == "O" || val[0] == "I") { return parseFloat(val.substring(1)); } if (val[0] == "D") { return 2 * parseFloat(val.substring(1)); } if (val[0] == "T") { return 3 * parseFloat(val.substring(1)); } if (val[0] == "M") { return 0; } else { // TODO: Check for Na return parseFloat(val); } } const verifySum = (sum) => { if (sum > 180 || [179, 178, 176, 175, 173, 172, 169, 166, 163].indexOf(sum) > -1) { return -1; } else if (current_toGo.value[current_player.value * 1] - sum < 0) { return -2; } if (current_toGo.value[current_player.value * 1] - sum == 0) { // bogey numbers if (page.out == "Double" && (sum > 170 || [169, 168, 166, 165, 163, 162, 159].indexOf(sum) > -1)) { return -1; } return 0; } else if (current_toGo.value[current_player.value * 1] - sum <= 50) { return 1; } else if (page.in != "Straight" && current_toGo.value[current_player.value * 1] == page.modus && sum != 0) { return 3; } return 2; } const checkVisit = (throws) => { const tr = throws.split(","); let sum = 0; tr.forEach((t, i) => { sum += getVal(t); }); const res = verifySum(sum); return [res, sum]; } ret.checkVisit = checkVisit; return ret; } function newPlayerStats(player) { return { player: player.uuid, average: [0, 0], first9: [0, 0], checkouts: [0, 0], checkins: [0, 0], checkinPoints: [], checkoutPoints: [], "60+": 0, "100+": 0, "140+": 0, "180": 0 }; } function addNewSetStats(stats, players) { stats["sets"].push(newStats(players)); stats["sets"][0]["legs"] = []; return stats; } function addNewLegStats(stats, players) { stats["sets"].at(-1)["legs"].push(newStats(players)); return stats; } function newStats(players) { const stats = { stats: [] } players.forEach((player, i) => { const n = newPlayerStats(player); stats.stats.push(n); }); return stats; } export function initStats(page) { const stats = newStats(page.players); stats.sets = []; addNewSetStats(stats, page.players); addNewLegStats(stats, page.players); page.stats = stats; } function newVisit(playerUUID, round) { return { player: playerUUID, throws: [], visit: round, checkoutTries: 0, checkinTries: 0, numDarts: 0, }; } export function initGame(page) { page.game = { sets: [{ points: new Array(page.players.length).fill(0), legs: [{ points: new Array(page.players.length).fill(0), visits: [newVisit(page.players[0].uuid, 1)] }] }] } } function updateStats(page, visit){ const playerUUIDs = page.players.map((p) => p.uuid); const k = playerUUIDs.indexOf(visit.player); const todos = [page.stats["stats"][k]]; todos.push(page.stats["sets"].at(-1)["stats"][k]); todos.push(page.stats["sets"].at(-1)["legs"].at(-1)["stats"][k]); todos.forEach((value, i) => { todos[i]["average"][0] += visit["sum"]; todos[i]["average"][1] += visit["numDarts"]; if (visit["visit"] < 4) { todos[i]["first9"][0] += visit["sum"]; todos[i]["first9"][1] += visit["numDarts"]; } if (visit["toGo"][k] == 0) { todos[i]["checkouts"][0] += 1; todos[i]["checkoutPoints"].push(visit["sum"]); } if (visit["checkinTries"] != 0 && visit["sum"] != 0) { todos[i]["checkins"][0] += 1; todos[i]["checkinPoints"].push(visit["sum"]); } todos[i]["checkouts"][1] += visit["checkoutTries"]; todos[i]["checkins"][1] += visit["checkinTries"]; if (visit["sum"] == 180) { todos[i]["180"] += 1; } else if (visit["sum"] >= 140) { todos[i]["140+"] += 1; } else if (visit["sum"] >= 100) { todos[i]["100+"] += 1; } else if (visit["sum"] >= 60) { todos[i]["60+"] += 1; } }); } function getWinner(points, mode) { const sorted = [...points].map((e,i) => [e,i]).sort((a, b) => b[0] - a[0]); const k = points.length; const sum = points.reduce((a,c) => a+c, 0); if (sum < mode && sorted[0][0] <= mode/k){ // not over yet return -1; } if (sorted[0][0] == sorted[1][0]){ // Draw return -2; } // winner id return sorted[0][1]; } export const formatDate = (d) => { return `${d.getFullYear()}-${(d.getMonth()+1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')} ${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`; }; function addNewSet(page, points){ const playerUUIDs = page.players.map((p) => p.uuid); const set = page.game.sets[page.game.sets.length-1]; const leg = set.legs[set.legs.length-1]; const k = playerUUIDs.indexOf(set.legs[0].visits[0].player); const p = playerUUIDs[(k+1)%playerUUIDs.length]; page.game.sets.push({ // points: [...points], legs: [{ points: Array(playerUUIDs.length).fill(0), visits: [newVisit(p, 1)] }] }); } function addNewLeg(page){ const playerUUIDs = page.players.map((p) => p.uuid); const set = page.game.sets[page.game.sets.length-1]; const leg = set.legs[set.legs.length-1]; const k = playerUUIDs.indexOf(leg.visits[0].player); const p = playerUUIDs[(k+1)%playerUUIDs.length]; page.game.sets[page.game.sets.length-1].legs.push({ // points: [...points], visits: [newVisit(p, 1)] }); } function clearLastVisit(page){ const set = page.game.sets[page.game.sets.length-1]; const leg = set.legs[set.legs.length-1]; const visit = leg.visits[leg.visits.length-1]; const ret = visit["throws"]; visit["throws"] = []; visit["checkoutTries"] = 0; visit["checkinTries"] = 0; visit["numDarts"] = 0; delete visit["sum"]; delete visit["toGo"]; return ret; } export function recalcStats(page){ const set = page.game.sets[page.game.sets.length-1]; // const leg = set.legs[set.legs.length-1]; // const visit = leg.visits[leg.visits.length-1]; initStats(page); const lastset = page.game["sets"].length-1; page.game["sets"].forEach((set, i) => { const lastleg = set.legs.length-1; set.legs.forEach((leg, j) => { const lastvisit = leg["visits"].length-1; leg.visits.forEach((visit, k) => { if (!(k == lastvisit && j == lastleg && i == lastset)) { updateStats(page, visit); } if (k == lastvisit && j != lastleg) { addNewLegStats(page.stats, page.players); } }); if (j == lastleg && i != lastset) { addNewSetStats(page.stats, page.players); } }); }); } export function removeLastVisit(page){ const set = page.game.sets[page.game.sets.length-1]; const leg = set.legs[set.legs.length-1]; const visit = leg.visits[leg.visits.length-1]; // delete last visit. leg["visits"].pop(); if (leg["visits"].length == 0){ set["legs"].pop(); if (set["legs"].length == 0){ page.game["sets"].pop(); if (page.game["sets"].length == 0){ initGame(page); return; } } } // clearLastVisit const ret = clearLastVisit(page); recalcStats(page); return ret; } export function storeVisit(page, throws, sum, numDarts, outTries, inTries=0) { const set = page.game.sets[page.game.sets.length-1]; const leg = set.legs[set.legs.length-1]; const visit = leg.visits[leg.visits.length-1]; visit["numDarts"] = numDarts; visit["throws"] = throws; visit["checkoutTries"] = outTries; visit["checkinTries"] = inTries; visit["sum"] = sum const playerUUIDs = page.players.map((p) => p.uuid); const k = playerUUIDs.indexOf(visit["player"]); let toGo; if (leg["visits"].length-2 < 0) { toGo = Array(playerUUIDs.length).fill(page.modus); } else { toGo = [...leg["visits"][leg["visits"].length-2]["toGo"]]; } const rest = toGo[k] - visit["sum"]; if (rest < 0 || (page.out == "Double" && rest == 1)) { visit["sum"] = 0; } else { toGo[k] = rest; } visit["toGo"] = toGo; if (page.in != "Straight" && page.modus == toGo[k] && visit["sum"] == 0) { visit["checkinTries"] = 3; } // update stats updateStats(page, visit); let update = []; if (rest != 0) { // Normal case...next players turn const nextPlayer = playerUUIDs[(k+1)%playerUUIDs.length]; const nVisit = newVisit(nextPlayer, visit["visit"]+1*(leg.visits[0]["player"] == nextPlayer)); leg.visits.push(nVisit); } else { // rest == 0 leg finished const newlegp = legPoints(page, set, leg); let winner = getWinner(newlegp, page.legs); if (winner == -1) { // new Leg addNewLeg(page); addNewLegStats(page.stats, page.players); } else { // new set? const newsetp = setPoints(page, set); winner = getWinner(newsetp, page.sets); if (winner == -1) { // new Set addNewSet(page); addNewSetStats(page.stats, page.players); addNewLegStats(page.stats, page.players); } else { // ask for continue or game over if (winner == -2) { page.stats["winner"] = "DRAW"; } else { page.stats["winner"] = visit["player"]; } page.enddate = formatDate(new Date(Date.now())); return [newsetp, newlegp]; } } } return false; } export function endGame(page){ // const set = page.game.sets[page.game.sets.length-1]; // const leg = set.legs[set.legs.length-1]; // const visit = leg.visits[leg.visits.length-1]; // const winner = getWinner(newsetp, page.sets); // set["points"] = newsetp; // leg["points"] = newlegp; } export function extension(page){ const set = page.game.sets[page.game.sets.length-1]; const leg = set.legs[set.legs.length-1]; // leg["points"] = newlegp; // new Leg addNewLeg(page); addNewLegStats(page.stats, page.players); }