From 42894e91a44f63688c849dca3f1ade2bedd27155 Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Fri, 19 May 2023 10:25:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B3=A8=E9=87=8A=E4=BC=98=E5=8C=96=EF=BC=8C?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E4=BD=BF=E7=94=A8=E9=9D=9E=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E5=AE=89=E5=85=A8map?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/builtin/room_seat.go | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/game/builtin/room_seat.go b/game/builtin/room_seat.go index 0683feb..e8d2d35 100644 --- a/game/builtin/room_seat.go +++ b/game/builtin/room_seat.go @@ -2,16 +2,17 @@ package builtin import ( "github.com/kercylan98/minotaur/game" + "github.com/kercylan98/minotaur/utils/asynchronization" "github.com/kercylan98/minotaur/utils/hash" "github.com/kercylan98/minotaur/utils/slice" - "github.com/kercylan98/minotaur/utils/synchronization" "sync" ) +// NewRoomSeat 基于特定游戏房间(game.Room)的实现创建一个支持座位号管理的房间实现(RoomSeat) func NewRoomSeat[PlayerID comparable, Player game.Player[PlayerID]](room game.Room[PlayerID, Player], options ...RoomSeatOption[PlayerID, Player]) *RoomSeat[PlayerID, Player] { roomSeat := &RoomSeat[PlayerID, Player]{ Room: room, - seatPS: synchronization.NewMap[PlayerID, int](), + seatPS: asynchronization.NewMap[PlayerID, int](), } for _, option := range options { option(roomSeat) @@ -19,17 +20,21 @@ func NewRoomSeat[PlayerID comparable, Player game.Player[PlayerID]](room game.Ro return roomSeat } +// RoomSeat 包含座位号的默认内置房间实现,依赖于游戏房间(game.Room)实现 +// - 实现了对玩家座位号的管理,分别为自动管理(WithRoomSeatAutoManage)及手工管理,默认清空下为手工管理 type RoomSeat[PlayerID comparable, Player game.Player[PlayerID]] struct { game.Room[PlayerID, Player] mutex sync.RWMutex vacancy []int - seatPS *synchronization.Map[PlayerID, int] + seatPS hash.Map[PlayerID, int] seatSP []*PlayerID duplicateLock bool fillIn bool autoMode sync.Once } +// AddSeat 为特定玩家添加座位 +// - 当座位存在空缺的时候,玩家将会优先在空缺位置坐下,否则将会在末位追加 func (slf *RoomSeat[PlayerID, Player]) AddSeat(id PlayerID) { if slf.seatPS.Exist(id) { return @@ -47,11 +52,15 @@ func (slf *RoomSeat[PlayerID, Player]) AddSeat(id PlayerID) { } } +// AddSeatWithAssign 将玩家添加到特定的座位 +// - 如果位置已经有玩家,将会与其进行更换 func (slf *RoomSeat[PlayerID, Player]) AddSeatWithAssign(id PlayerID, seat int) { slf.AddSeat(id) _ = slf.SetSeat(id, seat) } +// RemovePlayerSeat 删除玩家座位 +// - 受补位模式(WithRoomSeatFillIn)影响 func (slf *RoomSeat[PlayerID, Player]) RemovePlayerSeat(id PlayerID) { if !slf.seatPS.Exist(id) { return @@ -69,6 +78,8 @@ func (slf *RoomSeat[PlayerID, Player]) RemovePlayerSeat(id PlayerID) { slf.seatSP[seat] = nil } +// RemoveSeat 删除特定座位的玩家 +// - 受补位模式(WithRoomSeatFillIn)影响 func (slf *RoomSeat[PlayerID, Player]) RemoveSeat(seat int) { if seat >= len(slf.seatSP) { return @@ -80,6 +91,9 @@ func (slf *RoomSeat[PlayerID, Player]) RemoveSeat(seat int) { slf.RemovePlayerSeat(*playerId) } +// SetSeat 设置玩家的座位号 +// - 如果玩家没有预先添加过座位将会返回错误 +// - 如果位置已经有玩家,将会与其进行更换 func (slf *RoomSeat[PlayerID, Player]) SetSeat(id PlayerID, seat int) error { slf.mutex.Lock() slf.duplicateLock = true @@ -120,6 +134,7 @@ func (slf *RoomSeat[PlayerID, Player]) SetSeat(id PlayerID, seat int) error { return nil } +// GetSeat 获取玩家座位号 func (slf *RoomSeat[PlayerID, Player]) GetSeat(id PlayerID) (int, error) { seat, exist := slf.seatPS.GetExist(id) if !exist { @@ -128,6 +143,7 @@ func (slf *RoomSeat[PlayerID, Player]) GetSeat(id PlayerID) (int, error) { return seat, nil } +// GetPlayerIDWithSeat 获取特定座位号的玩家 func (slf *RoomSeat[PlayerID, Player]) GetPlayerIDWithSeat(seat int) (playerId PlayerID, err error) { if !slf.duplicateLock { slf.mutex.RLock() @@ -143,12 +159,16 @@ func (slf *RoomSeat[PlayerID, Player]) GetPlayerIDWithSeat(seat int) (playerId P return *id, nil } +// GetSeatInfo 获取所有座位号 +// - 在非补位模式(WithRoomSeatFillIn)下由于座位号可能存在缺席的情况,所以需要根据是否为空指针进行判断 func (slf *RoomSeat[PlayerID, Player]) GetSeatInfo() []*PlayerID { slf.mutex.RLock() defer slf.mutex.RUnlock() return slf.seatSP } +// GetSeatInfoMap 获取座位号及其对应的玩家信息 +// - 缺席情况将被忽略 func (slf *RoomSeat[PlayerID, Player]) GetSeatInfoMap() map[int]PlayerID { var seatInfo = make(map[int]PlayerID) slf.mutex.RLock() @@ -162,16 +182,20 @@ func (slf *RoomSeat[PlayerID, Player]) GetSeatInfoMap() map[int]PlayerID { return seatInfo } +// GetSeatInfoMapVacancy 获取座位号及其对应的玩家信息 +// - 缺席情况将不会被忽略 func (slf *RoomSeat[PlayerID, Player]) GetSeatInfoMapVacancy() map[int]*PlayerID { slf.mutex.RLock() defer slf.mutex.RUnlock() return hash.ToMap(slf.seatSP) } +// GetSeatInfoWithPlayerIDMap 获取玩家及其座位号信息 func (slf *RoomSeat[PlayerID, Player]) GetSeatInfoWithPlayerIDMap() map[PlayerID]int { return slf.seatPS.Map() } +// GetFirstSeat 获取第一个未缺席的座位号 func (slf *RoomSeat[PlayerID, Player]) GetFirstSeat() int { for seat, playerId := range slf.seatSP { if playerId != nil { @@ -181,6 +205,7 @@ func (slf *RoomSeat[PlayerID, Player]) GetFirstSeat() int { return -1 } +// GetNextSeat 获取特定座位号下一个未缺席的座位号 func (slf *RoomSeat[PlayerID, Player]) GetNextSeat(seat int) int { l := len(slf.seatSP) if l == 0 || seat >= l || seat < 0 { @@ -201,6 +226,8 @@ func (slf *RoomSeat[PlayerID, Player]) GetNextSeat(seat int) int { } } +// GetNextSeatVacancy 获取特定座位号下一个座位号 +// - 缺席将不会被忽略 func (slf *RoomSeat[PlayerID, Player]) GetNextSeatVacancy(seat int) int { l := len(slf.seatSP) if l == 0 || seat >= l || seat < 0 {