diff --git a/config/Constants.go b/config/Constants.go index 5dba1d0..0a8609c 100644 --- a/config/Constants.go +++ b/config/Constants.go @@ -28,6 +28,7 @@ const ( GameMsgType int = iota TableOrderMsgType GameResultMsgType + GetReadyMsgType RoomControl ChatMsgType ) diff --git a/container/ConnManager.go b/container/ConnManager.go index 3767bb4..d5a2126 100644 --- a/container/ConnManager.go +++ b/container/ConnManager.go @@ -16,19 +16,22 @@ type ConnManager struct { gameSendCh chan message.GameMsgSend tableOrderCh chan int gameResultCh chan message.GameResultMsg + getReadyCh chan message.GetReadyMsg } func NewConnManager(playersCount int, gameRecvCh chan message.GameMsgRecv, gameSendCh chan message.GameMsgSend, tableOrderCh chan int, - gameResultCh chan message.GameResultMsg) *ConnManager { + gameResultCh chan message.GameResultMsg, + getReadyCh chan message.GetReadyMsg) *ConnManager { connManager := ConnManager{playersCount: playersCount, conns: make([]websocket.Conn, 0), gameRecvCh: gameRecvCh, gameSendCh: gameSendCh, tableOrderCh: tableOrderCh, gameResultCh: gameResultCh, + getReadyCh: getReadyCh, } go connManager.Broadcaster() return &connManager @@ -61,6 +64,11 @@ func (m *ConnManager) Broadcaster() { for _, conn := range m.conns { conn.WriteJSON(msg) } + case msg := <-m.getReadyCh: + log.Println("broadcast ready message") + for _, conn := range m.conns { + conn.WriteJSON(msg) + } } } } diff --git a/container/Room.go b/container/Room.go index bd3e2e3..c714c1a 100644 --- a/container/Room.go +++ b/container/Room.go @@ -15,6 +15,7 @@ type Room struct { gameSendCh chan message.GameMsgSend tableOrderCh chan int gameResultCh chan message.GameResultMsg + getReadyCh chan message.GetReadyMsg password string playerCount int @@ -25,13 +26,15 @@ func NewRoom(rule rule.MahjongRule) *Room { gameSendChannel := make(chan message.GameMsgSend) tableOrderChannel := make(chan int) gameResultChannel := make(chan message.GameResultMsg) + getReadyChannel := make(chan message.GetReadyMsg) return &Room{ gameRecvCh: gameRecvChannel, gameSendCh: gameSendChannel, tableOrderCh: tableOrderChannel, gameResultCh: gameResultChannel, - connManager: NewConnManager(4, gameRecvChannel, gameSendChannel, tableOrderChannel, gameResultChannel), - mahjongManager: game.NewMahjongManager(gameRecvChannel, gameSendChannel, tableOrderChannel, gameResultChannel, rule), + getReadyCh: getReadyChannel, + connManager: NewConnManager(4, gameRecvChannel, gameSendChannel, tableOrderChannel, gameResultChannel, getReadyChannel), + mahjongManager: game.NewMahjongManager(gameRecvChannel, gameSendChannel, tableOrderChannel, gameResultChannel, getReadyChannel, rule), } } diff --git a/game/MahjongManager.go b/game/MahjongManager.go index 7152178..33bc12f 100644 --- a/game/MahjongManager.go +++ b/game/MahjongManager.go @@ -18,11 +18,13 @@ type MahjongManager struct { gameSendCh chan message.GameMsgSend tableOrderCh chan int gameResultCh chan message.GameResultMsg + getReadyCh chan message.GetReadyMsg lastTableOrder int currentTableOrder int cancelList [4]bool + readyList [4]bool lastMsgRecv message.GameMsgRecv } @@ -32,6 +34,7 @@ func NewMahjongManager(gameRecvCh chan message.GameMsgRecv, gameSendCh chan message.GameMsgSend, tableOrderCh chan int, gameResultCh chan message.GameResultMsg, + getReadyCh chan message.GetReadyMsg, r rule.MahjongRule) *MahjongManager { mahjong := MahjongManager{} mahjong.rules = r @@ -42,6 +45,7 @@ func NewMahjongManager(gameRecvCh chan message.GameMsgRecv, mahjong.gameSendCh = gameSendCh mahjong.tableOrderCh = tableOrderCh mahjong.gameResultCh = gameResultCh + mahjong.getReadyCh = getReadyCh return &mahjong } @@ -62,7 +66,9 @@ func (m *MahjongManager) gameLoop(gameRecvCh chan message.GameMsgRecv, gameSendC case config.Start: //inform each player their order m.tableOrderCh <- m.firstPlayer - m.handleStart(msg) + m.handleStart() + case config.Ready: + m.handleReady(msg) case config.Discard: m.handleDiscard(msg, true) case config.Chow: @@ -83,8 +89,9 @@ func (m *MahjongManager) gameLoop(gameRecvCh chan message.GameMsgRecv, gameSendC } } -func (m *MahjongManager) handleStart(msg message.GameMsgRecv) { +func (m *MahjongManager) handleStart() { m.resetCancelList() + m.resetReadyList() m.dealTile() //m.dealTileTest() @@ -94,18 +101,18 @@ func (m *MahjongManager) handleStart(msg message.GameMsgRecv) { return } //TODO:判断第一张牌能否碰、杠、胡 - availableActions := m.getAvailableActions(m.playerTile[msg.TableOrder].HandTiles, m.playerTile[msg.TableOrder].ShownTiles, newTile) - m.playerTile[msg.TableOrder].HandTiles = append(m.playerTile[msg.TableOrder].HandTiles, newTile) - model.SortTiles(m.playerTile[msg.TableOrder].HandTiles) + availableActions := m.getAvailableActions(m.playerTile[m.firstPlayer].HandTiles, m.playerTile[m.firstPlayer].ShownTiles, newTile) + m.playerTile[m.firstPlayer].HandTiles = append(m.playerTile[m.firstPlayer].HandTiles, newTile) + model.SortTiles(m.playerTile[m.firstPlayer].HandTiles) var msgSend message.GameMsgSend msgSend = message.GameMsgSend{ MsgType: config.GameMsgType, TableOrder: -1, - CurrentTurn: msg.TableOrder, + CurrentTurn: m.firstPlayer, CurrentTile: newTile, AvailableActions: availableActions, - LastTurn: msg.TableOrder, + LastTurn: m.firstPlayer, LastAction: config.Draw, PlayerTile: m.playerTile, WallCount: m.wall.Length(), @@ -113,6 +120,21 @@ func (m *MahjongManager) handleStart(msg message.GameMsgRecv) { m.gameSendCh <- msgSend } +func (m *MahjongManager) handleReady(msg message.GameMsgRecv) { + m.readyList[msg.TableOrder] = true + msgSend := message.GetReadyMsg{ + MsgType: config.GetReadyMsgType, + ReadyList: m.readyList, + } + m.getReadyCh <- msgSend + if canStartGame(m.readyList[:]) { + //TODO: start game + //inform each player their order + m.tableOrderCh <- m.firstPlayer + m.handleStart() + } +} + func (m *MahjongManager) Draw(hand []model.Tile, shown []model.ShownTile, newTile model.Tile) { } @@ -503,6 +525,13 @@ func (m *MahjongManager) resetCancelList() { m.cancelList[3] = false } +func (m *MahjongManager) resetReadyList() { + m.readyList[0] = false + m.readyList[1] = false + m.readyList[2] = false + m.readyList[3] = false +} + func getTieResult() message.GameResultMsg { return message.GameResultMsg{ MsgType: config.GameResultMsgType, @@ -511,6 +540,15 @@ func getTieResult() message.GameResultMsg { } } +func canStartGame(readyList []bool) bool { + for _, ready := range readyList { + if !ready { + return false + } + } + return true +} + func (m *MahjongManager) dealTile() { for i := 0; i < 3; i++ { m.playerTile[0].HandTiles = append(m.playerTile[0].HandTiles, m.wall.FrontDraw()) diff --git a/message/RoomControlMessage.go b/message/RoomControlMessage.go index e80552b..21d3316 100644 --- a/message/RoomControlMessage.go +++ b/message/RoomControlMessage.go @@ -16,3 +16,8 @@ type GameResultMsg struct { Winner int `json:"winner"` FinalTile model.Tile `json:"final_tile"` } + +type GetReadyMsg struct { + MsgType int `json:"msg_type"` + ReadyList [4]bool `json:"ready_list"` +}