Separa app in client-server con WebSocket
- Aggiunto server Express + WebSocket (server.js) - Creata pagina Display (solo visualizzazione punteggio) - Creata pagina Controller (pannello comandi da mobile) - Aggiunto Vue Router con rotte / e /controller - Estratta logica di gioco condivisa in gameState.js
This commit is contained in:
204
src/gameState.js
Normal file
204
src/gameState.js
Normal file
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* Shared game logic for segnapunti.
|
||||
* Used by both the WebSocket server and the client-side for local preview.
|
||||
*/
|
||||
|
||||
export function createInitialState() {
|
||||
return {
|
||||
order: true,
|
||||
visuForm: false,
|
||||
visuStriscia: true,
|
||||
modalitaPartita: "3/5",
|
||||
sp: {
|
||||
striscia: { home: [0], guest: [0] },
|
||||
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"],
|
||||
},
|
||||
storicoServizio: [],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
let isSetDecisivo = false
|
||||
if (state.modalitaPartita === "2/3") {
|
||||
isSetDecisivo = totSet >= 2
|
||||
} else {
|
||||
isSetDecisivo = 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 applyAction(state, action) {
|
||||
// Deep-clone to avoid mutation issues (server-side)
|
||||
// Returns new state
|
||||
const s = JSON.parse(JSON.stringify(state))
|
||||
|
||||
switch (action.type) {
|
||||
case "incPunt": {
|
||||
const team = action.team
|
||||
if (checkVittoria(s)) break
|
||||
|
||||
s.sp.storicoServizio.push({
|
||||
servHome: s.sp.servHome,
|
||||
cambioPalla: (team === "home" && !s.sp.servHome) || (team === "guest" && s.sp.servHome),
|
||||
})
|
||||
|
||||
s.sp.punt[team]++
|
||||
if (team === "home") {
|
||||
s.sp.striscia.home.push(s.sp.punt.home)
|
||||
s.sp.striscia.guest.push(" ")
|
||||
} else {
|
||||
s.sp.striscia.guest.push(s.sp.punt.guest)
|
||||
s.sp.striscia.home.push(" ")
|
||||
}
|
||||
|
||||
const cambioPalla = (team === "home" && !s.sp.servHome) || (team === "guest" && s.sp.servHome)
|
||||
if (cambioPalla) {
|
||||
s.sp.form[team].push(s.sp.form[team].shift())
|
||||
}
|
||||
|
||||
s.sp.servHome = team === "home"
|
||||
break
|
||||
}
|
||||
|
||||
case "decPunt": {
|
||||
if (s.sp.striscia.home.length > 1 && s.sp.storicoServizio.length > 0) {
|
||||
const tmpHome = s.sp.striscia.home.pop()
|
||||
s.sp.striscia.guest.pop()
|
||||
const statoServizio = s.sp.storicoServizio.pop()
|
||||
|
||||
if (tmpHome === " ") {
|
||||
s.sp.punt.guest--
|
||||
if (statoServizio.cambioPalla) {
|
||||
s.sp.form.guest.unshift(s.sp.form.guest.pop())
|
||||
}
|
||||
} else {
|
||||
s.sp.punt.home--
|
||||
if (statoServizio.cambioPalla) {
|
||||
s.sp.form.home.unshift(s.sp.form.home.pop())
|
||||
}
|
||||
}
|
||||
s.sp.servHome = statoServizio.servHome
|
||||
}
|
||||
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 "cambiaPalla": {
|
||||
if (s.sp.punt.home === 0 && s.sp.punt.guest === 0) {
|
||||
s.sp.servHome = !s.sp.servHome
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case "resetta": {
|
||||
s.visuForm = false
|
||||
s.sp.punt.home = 0
|
||||
s.sp.punt.guest = 0
|
||||
s.sp.form = {
|
||||
home: ["1", "2", "3", "4", "5", "6"],
|
||||
guest: ["1", "2", "3", "4", "5", "6"],
|
||||
}
|
||||
s.sp.striscia = { home: [0], guest: [0] }
|
||||
s.sp.storicoServizio = []
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user