export function createInitialState() { return { order: true, visuForm: false, visuStriscia: true, modalitaPartita: "3/5", sp: { striscia: [{ serv: 'h', ris: '' }], servHome: true, punt: { home: 0, guest: 0 }, set: { home: 0, guest: 0 }, nomi: { home: "Antoniana", guest: "Guest" }, form: { home: ["1", "2", "3", "4", "5", "6"], guest: ["1", "2", "3", "4", "5", "6"], }, }, } } export function checkVittoria(state) { const puntHome = state.sp.punt.home const puntGuest = state.sp.punt.guest const setHome = state.sp.set.home const setGuest = state.sp.set.guest const totSet = setHome + setGuest const isSetDecisivo = state.modalitaPartita === "2/3" ? totSet >= 2 : totSet >= 4 const punteggioVittoria = isSetDecisivo ? 15 : 25 if (puntHome >= punteggioVittoria && puntHome - puntGuest >= 2) return true if (puntGuest >= punteggioVittoria && puntGuest - puntHome >= 2) return true return false } export function checkVittoriaPartita(state) { const setsToWin = state.modalitaPartita === "2/3" ? 2 : 3 return state.sp.set.home >= setsToWin || state.sp.set.guest >= setsToWin } export function applyAction(state, action) { const s = structuredClone(state) switch (action.type) { case "incPunt": { const team = action.team if (checkVittoria(s)) break const cambioPalla = (team === "home") !== s.sp.servHome s.sp.punt[team]++ s.sp.striscia.at(-1).ris += team === 'home' ? 'h' : 'g' if (cambioPalla) { s.sp.form[team].push(s.sp.form[team].shift()) } s.sp.servHome = team === "home" break } case "decPunt": { const currentSet = s.sp.striscia.at(-1) if (currentSet.ris.length === 0) break const lastScorerShort = currentSet.ris.at(-1) const prevServerShort = currentSet.ris.length >= 2 ? currentSet.ris.at(-2) : currentSet.serv const wasCambioPalla = lastScorerShort !== prevServerShort currentSet.ris = currentSet.ris.slice(0, -1) const lastScorer = lastScorerShort === 'h' ? 'home' : 'guest' const prevServer = prevServerShort === 'h' ? 'home' : 'guest' s.sp.punt[lastScorer]-- s.sp.servHome = prevServerShort === 'h' if (wasCambioPalla) { s.sp.form[lastScorer].unshift(s.sp.form[lastScorer].pop()) } break } case "incSet": { const team = action.team if (s.sp.set[team] === 2) { s.sp.set[team] = 0 } else { s.sp.set[team]++ } break } case "nuovoSet": { const team = action.team if (team !== 'home' && team !== 'guest') break if (checkVittoriaPartita(s)) break const setsToWin = s.modalitaPartita === "2/3" ? 2 : 3 s.sp.set[team]++ if (s.sp.set[team] >= setsToWin) break s.sp.punt.home = 0 s.sp.punt.guest = 0 s.sp.servHome = team === 'home' s.sp.striscia.push({ serv: team === 'home' ? 'h' : 'g', ris: '' }) s.sp.form = { home: ["1", "2", "3", "4", "5", "6"], guest: ["1", "2", "3", "4", "5", "6"], } break } case "cambiaPalla": { if (s.sp.punt.home === 0 && s.sp.punt.guest === 0) { s.sp.servHome = !s.sp.servHome s.sp.striscia.at(-1).serv = s.sp.servHome ? 'h' : 'g' } break } case "resetta": { s.visuForm = false s.sp.punt.home = 0 s.sp.punt.guest = 0 s.sp.set.home = 0 s.sp.set.guest = 0 s.sp.form = { home: ["1", "2", "3", "4", "5", "6"], guest: ["1", "2", "3", "4", "5", "6"], } s.sp.striscia = [{ serv: s.sp.servHome ? 'h' : 'g', ris: '' }] break } case "toggleFormazione": { s.visuForm = !s.visuForm break } case "toggleStriscia": { s.visuStriscia = !s.visuStriscia break } case "toggleOrder": { s.order = !s.order break } case "setNomi": { if (action.home !== undefined) s.sp.nomi.home = action.home if (action.guest !== undefined) s.sp.nomi.guest = action.guest break } case "setModalita": { s.modalitaPartita = action.modalita break } case "setFormazione": { if (action.team && action.form) { s.sp.form[action.team] = [...action.form] } break } case "confermaCambi": { const team = action.team const cambi = action.cambi || [] const form = s.sp.form[team].map((val) => String(val).trim()) const formAggiornata = [...form] let valid = true for (const cambio of cambi) { const cin = (cambio.in || "").trim() const cout = (cambio.out || "").trim() if (!cin || !cout) continue if (!/^\d+$/.test(cin) || !/^\d+$/.test(cout)) { valid = false; break } if (cin === cout) { valid = false; break } if (formAggiornata.includes(cin)) { valid = false; break } if (!formAggiornata.includes(cout)) { valid = false; break } const idx = formAggiornata.findIndex((val) => String(val).trim() === cout) if (idx !== -1) { formAggiornata.splice(idx, 1, cin) } } if (valid) { s.sp.form[team] = formAggiornata } break } default: break } return s }