133 lines
4.0 KiB
Go
133 lines
4.0 KiB
Go
package ws
|
|
|
|
import "hakemsho/internal/game"
|
|
|
|
// inboundMsg پیام دریافتی از کلاینت.
|
|
type inboundMsg struct {
|
|
Type string `json:"type"` // join_queue | choose_trump | play_card | leave
|
|
Mode string `json:"mode"` // برای join_queue
|
|
Tier string `json:"tier"` // برای join_queue: نوع میز (beginner/pro/...)
|
|
Suit string `json:"suit"` // برای choose_trump: hearts|spades|diamonds|clubs
|
|
Card string `json:"card"` // برای play_card: مثل "AS"
|
|
}
|
|
|
|
// PlayerInfo اطلاعات عمومی یک بازیکن سر میز.
|
|
type PlayerInfo struct {
|
|
Seat int `json:"seat"`
|
|
Name string `json:"name"`
|
|
Bot bool `json:"bot"`
|
|
Connected bool `json:"connected"`
|
|
}
|
|
|
|
// matchedMsg به کلاینت پس از تشکیل میز.
|
|
type matchedMsg struct {
|
|
Type string `json:"type"` // "matched"
|
|
Room string `json:"room"`
|
|
Seat int `json:"seat"`
|
|
Players []PlayerInfo `json:"players"`
|
|
}
|
|
|
|
// trickView یک کارت روی زمین.
|
|
type trickView struct {
|
|
Seat int `json:"seat"`
|
|
Card string `json:"card"`
|
|
}
|
|
|
|
// stateMsg نمای مجاز بازی برای یک بازیکن خاص.
|
|
type stateMsg struct {
|
|
Type string `json:"type"` // "state"
|
|
Room string `json:"room"`
|
|
Phase string `json:"phase"`
|
|
YourSeat int `json:"your_seat"`
|
|
Hakem int `json:"hakem"`
|
|
Turn int `json:"turn"`
|
|
Trump string `json:"trump,omitempty"` // فقط پس از انتخاب حکم
|
|
TrickDone bool `json:"trick_done"` // دستِ کامل در حال نمایش (بازی ممنوع)
|
|
YourHand []string `json:"your_hand"`
|
|
HandCounts [4]int `json:"hand_counts"`
|
|
Trick []trickView `json:"trick"`
|
|
LeadSuit string `json:"lead_suit,omitempty"`
|
|
TricksWon [2]int `json:"tricks_won"`
|
|
Scores [2]int `json:"scores"`
|
|
TargetScore int `json:"target_score"`
|
|
Players []PlayerInfo `json:"players"`
|
|
}
|
|
|
|
// handOverMsg نتیجه یک هَند.
|
|
type handOverMsg struct {
|
|
Type string `json:"type"` // "hand_over"
|
|
WinnerTeam int `json:"winner_team"`
|
|
Kot bool `json:"kot"`
|
|
HakemKot bool `json:"hakem_kot"`
|
|
Points int `json:"points"`
|
|
Scores [2]int `json:"scores"`
|
|
}
|
|
|
|
// gameOverMsg پایان بازی.
|
|
type gameOverMsg struct {
|
|
Type string `json:"type"` // "game_over"
|
|
WinnerTeam int `json:"winner_team"`
|
|
Scores [2]int `json:"scores"`
|
|
}
|
|
|
|
// errorMsg خطا برای کلاینت.
|
|
type errorMsg struct {
|
|
Type string `json:"type"` // "error"
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
// playerLeftMsg خروج دائمی یک بازیکن (تبدیل به بات).
|
|
type playerLeftMsg struct {
|
|
Type string `json:"type"` // "player_left"
|
|
Seat int `json:"seat"`
|
|
}
|
|
|
|
// playerStatusMsg تغییر وضعیت اتصال یک بازیکن (موقت).
|
|
type playerStatusMsg struct {
|
|
Type string `json:"type"` // "player_disconnected" | "player_reconnected"
|
|
Seat int `json:"seat"`
|
|
}
|
|
|
|
// buildState نمای بازی را برای جایگاه seat میسازد (کارت بقیه مخفی میماند).
|
|
func buildState(g *game.Game, roomID string, seat int, players []PlayerInfo) stateMsg {
|
|
hand := g.Hand(seat)
|
|
handStr := make([]string, len(hand))
|
|
for i, c := range hand {
|
|
handStr[i] = c.String()
|
|
}
|
|
|
|
var counts [4]int
|
|
for s := 0; s < 4; s++ {
|
|
counts[s] = g.HandCount(s)
|
|
}
|
|
|
|
trick := make([]trickView, 0, len(g.Trick))
|
|
for _, tc := range g.Trick {
|
|
trick = append(trick, trickView{Seat: tc.Seat, Card: tc.Card.String()})
|
|
}
|
|
|
|
st := stateMsg{
|
|
Type: "state",
|
|
Room: roomID,
|
|
Phase: g.Phase.String(),
|
|
TrickDone: g.TrickDone,
|
|
YourSeat: seat,
|
|
Hakem: g.Hakem,
|
|
Turn: g.Turn,
|
|
YourHand: handStr,
|
|
HandCounts: counts,
|
|
Trick: trick,
|
|
TricksWon: g.TricksWon,
|
|
Scores: g.Scores,
|
|
TargetScore: g.TargetScore,
|
|
Players: players,
|
|
}
|
|
if g.TrumpChosen {
|
|
st.Trump = g.Trump.String()
|
|
}
|
|
if len(g.Trick) > 0 {
|
|
st.LeadSuit = g.LeadSuit.String()
|
|
}
|
|
return st
|
|
}
|