补杠功能的实现
接下来,我们来实现补杠功能。补杠是指在已经碰牌的情况下,又摸到一张相同的牌,可以组成杠。
功能设计
-
自摸补杠:
-
如果玩家自摸到一张牌,且这张牌可以与已碰的牌组成杠,则可以进行自摸补杠。
-
自摸补杠后,玩家需要从牌堆中再摸一张牌。
-
-
吃牌补杠:
-
如果玩家通过吃牌形成杠,则称为吃牌补杠。
-
吃牌补杠后,玩家不需要再摸牌,直接出牌即可。
-
实现步骤
-
判断是否可以补杠:
-
检查玩家是否已经碰牌。
-
检查新摸到的牌是否可以与已碰的牌组成杠。
-
-
执行补杠操作:
-
如果可以补杠,更新玩家的牌组。
-
发送补杠操作的消息给所有玩家。
-
-
处理自摸和吃牌的区别:
-
自摸补杠后,玩家从牌堆中再摸一张牌。
-
吃牌补杠后,玩家直接出牌。
-
代码实现
// 判断是否可以补杠
func canPung(user *User, card int) bool {for _, record := range user.Records {if record.Type == "pung" && record.Card == card {return true}}return false
}// 执行补杠操作
func pung(user *User, card int) {if canPung(user, card) {// 添加杠操作记录user.Records = append(user.Records, Record{Type: "pung", Card: card})// 发送补杠消息msg := &Message{Type: 5,Data: map[string]interface{}{"userId": user.Id,"card": card,},}user.Room.Broadcast(msg)// 自摸补杠,再摸一张牌if user.LastDrawnCard == card {user.DrawCard()}}
}
托管功能的实现
接下来,我们来实现托管功能。托管是指在倒计时结束后,系统自动为玩家出牌。
功能设计
-
倒计时:
-
每个玩家在操作时都有一个倒计时。
-
如果倒计时结束,玩家还没有操作,则触发托管。
-
-
自动出牌:
-
如果玩家可以弃牌,则自动弃牌。
-
如果玩家有其他操作,则不做任何操作。
-
实现步骤
-
设置倒计时:
-
在玩家操作时,设置一个倒计时定时器。
-
定时器每秒触发一次,检查倒计时是否结束。
-
-
触发托管:
-
如果倒计时结束,触发托管操作。
-
根据玩家的牌组,选择一个合适的牌进行操作。
-
-
取消定时器:
-
如果玩家在倒计时内进行了操作,则取消定时器。
-
代码实现
// 设置倒计时
func startTimer(user *User, duration int) {user.Timer = time.NewTimer(time.Duration(duration) * time.Second)go func() {<-user.Timer.Cif user.NeedAutoPlay() {autoPlay(user)}}()
}// 自动出牌
func autoPlay(user *User) {if user.CanDiscard() {user.DiscardCard()}
}// 取消定时器
func cancelTimer(user *User) {if user.Timer != nil {user.Timer.Stop()user.Timer = nil}
}