diff --git a/game/room/errors.go b/game/room/errors.go deleted file mode 100644 index 5d849b9..0000000 --- a/game/room/errors.go +++ /dev/null @@ -1,14 +0,0 @@ -package room - -import "errors" - -var ( - // ErrRoomNotExist 房间不存在 - ErrRoomNotExist = errors.New("room not exist") - // ErrRoomPlayerFull 房间人数已满 - ErrRoomPlayerFull = errors.New("room player full") - // ErrPlayerNotInRoom 玩家不在房间中 - ErrPlayerNotInRoom = errors.New("player not in room") - // ErrRoomOrPlayerNotExist 房间不存在或玩家不在房间中 - ErrRoomOrPlayerNotExist = errors.New("room or player not exist") -) diff --git a/game/room/events.go b/game/room/events.go deleted file mode 100644 index 8a27232..0000000 --- a/game/room/events.go +++ /dev/null @@ -1,266 +0,0 @@ -package room - -import "github.com/kercylan98/minotaur/game" - -type ( - // PlayerJoinRoomEventHandle 玩家加入房间事件处理函数 - PlayerJoinRoomEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, player P) - // PlayerLeaveRoomEventHandle 玩家离开房间事件处理函数 - PlayerLeaveRoomEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, player P) - // PlayerKickedOutEventHandle 玩家被踢出房间事件处理函数 - PlayerKickedOutEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, executor, kicked P, reason string) - // PlayerUpgradeOwnerEventHandle 玩家成为房主事件处理函数 - PlayerUpgradeOwnerEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, oldOwner, newOwner P) - // CancelOwnerEventHandle 取消房主事件处理函数 - CancelOwnerEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, oldOwner P) - // ChangePlayerLimitEventHandle 改变房间人数上限事件处理函数 - ChangePlayerLimitEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, oldLimit, newLimit int) - // PlayerSeatChangeEventHandle 玩家座位改变事件处理函数 - PlayerSeatChangeEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, player P, oldSeat, newSeat int) - // PlayerSeatSetEventHandle 玩家座位设置事件处理函数 - PlayerSeatSetEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, player P, seat int) - // PlayerSeatCancelEventHandle 玩家座位取消事件处理函数 - PlayerSeatCancelEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, player P, seat int) - // CreateEventHandle 房间创建事件处理函数 - CreateEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, helper *Helper[PID, P, R]) -) - -func newEvent[PID comparable, P game.Player[PID], R Room]() *event[PID, P, R] { - return &event[PID, P, R]{ - playerJoinRoomEventRoomHandles: make(map[int64][]PlayerJoinRoomEventHandle[PID, P, R]), - playerLeaveRoomEventRoomHandles: make(map[int64][]PlayerLeaveRoomEventHandle[PID, P, R]), - playerKickedOutEventRoomHandles: make(map[int64][]PlayerKickedOutEventHandle[PID, P, R]), - playerUpgradeOwnerEventRoomHandles: make(map[int64][]PlayerUpgradeOwnerEventHandle[PID, P, R]), - cancelOwnerEventRoomHandles: make(map[int64][]CancelOwnerEventHandle[PID, P, R]), - changePlayerLimitEventRoomHandles: make(map[int64][]ChangePlayerLimitEventHandle[PID, P, R]), - playerSeatChangeEventRoomHandles: make(map[int64][]PlayerSeatChangeEventHandle[PID, P, R]), - playerSeatSetEventRoomHandles: make(map[int64][]PlayerSeatSetEventHandle[PID, P, R]), - } -} - -type event[PID comparable, P game.Player[PID], R Room] struct { - playerJoinRoomEventHandles []PlayerJoinRoomEventHandle[PID, P, R] - playerJoinRoomEventRoomHandles map[int64][]PlayerJoinRoomEventHandle[PID, P, R] - playerLeaveRoomEventHandles []PlayerLeaveRoomEventHandle[PID, P, R] - playerLeaveRoomEventRoomHandles map[int64][]PlayerLeaveRoomEventHandle[PID, P, R] - playerKickedOutEventHandles []PlayerKickedOutEventHandle[PID, P, R] - playerKickedOutEventRoomHandles map[int64][]PlayerKickedOutEventHandle[PID, P, R] - playerUpgradeOwnerEventHandles []PlayerUpgradeOwnerEventHandle[PID, P, R] - playerUpgradeOwnerEventRoomHandles map[int64][]PlayerUpgradeOwnerEventHandle[PID, P, R] - cancelOwnerEventHandles []CancelOwnerEventHandle[PID, P, R] - cancelOwnerEventRoomHandles map[int64][]CancelOwnerEventHandle[PID, P, R] - changePlayerLimitEventHandles []ChangePlayerLimitEventHandle[PID, P, R] - changePlayerLimitEventRoomHandles map[int64][]ChangePlayerLimitEventHandle[PID, P, R] - playerSeatChangeEventHandles []PlayerSeatChangeEventHandle[PID, P, R] - playerSeatChangeEventRoomHandles map[int64][]PlayerSeatChangeEventHandle[PID, P, R] - playerSeatSetEventHandles []PlayerSeatSetEventHandle[PID, P, R] - playerSeatSetEventRoomHandles map[int64][]PlayerSeatSetEventHandle[PID, P, R] - playerSeatCancelEventHandles []PlayerSeatCancelEventHandle[PID, P, R] - playerSeatCancelEventRoomHandles map[int64][]PlayerSeatCancelEventHandle[PID, P, R] - roomCreateEventHandles []CreateEventHandle[PID, P, R] -} - -func (slf *event[PID, P, R]) unReg(guid int64) { - delete(slf.playerJoinRoomEventRoomHandles, guid) - delete(slf.playerLeaveRoomEventRoomHandles, guid) - delete(slf.playerKickedOutEventRoomHandles, guid) - delete(slf.playerUpgradeOwnerEventRoomHandles, guid) - delete(slf.cancelOwnerEventRoomHandles, guid) - delete(slf.changePlayerLimitEventRoomHandles, guid) - delete(slf.playerSeatChangeEventRoomHandles, guid) - delete(slf.playerSeatSetEventRoomHandles, guid) - delete(slf.playerSeatCancelEventRoomHandles, guid) -} - -// RegPlayerJoinRoomEvent 玩家进入房间时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerJoinRoomEvent(handle PlayerJoinRoomEventHandle[PID, P, R]) { - slf.playerJoinRoomEventHandles = append(slf.playerJoinRoomEventHandles, handle) -} - -// OnPlayerJoinRoomEvent 玩家进入房间时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) OnPlayerJoinRoomEvent(room R, player P) { - for _, handle := range slf.playerJoinRoomEventHandles { - handle(room, player) - } - for _, handle := range slf.playerJoinRoomEventRoomHandles[room.GetGuid()] { - handle(room, player) - } -} - -// RegPlayerJoinRoomEventWithRoom 玩家进入房间时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerJoinRoomEventWithRoom(room R, handle PlayerJoinRoomEventHandle[PID, P, R]) { - slf.playerJoinRoomEventRoomHandles[room.GetGuid()] = append(slf.playerJoinRoomEventRoomHandles[room.GetGuid()], handle) -} - -// RegPlayerLeaveRoomEvent 玩家离开房间时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerLeaveRoomEvent(handle PlayerLeaveRoomEventHandle[PID, P, R]) { - slf.playerLeaveRoomEventHandles = append(slf.playerLeaveRoomEventHandles, handle) -} - -// RegPlayerLeaveRoomEventWithRoom 玩家离开房间时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerLeaveRoomEventWithRoom(room R, handle PlayerLeaveRoomEventHandle[PID, P, R]) { - slf.playerLeaveRoomEventRoomHandles[room.GetGuid()] = append(slf.playerLeaveRoomEventRoomHandles[room.GetGuid()], handle) -} - -// OnPlayerLeaveRoomEvent 玩家离开房间时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) OnPlayerLeaveRoomEvent(room R, player P) { - for _, handle := range slf.playerLeaveRoomEventHandles { - handle(room, player) - } - for _, handle := range slf.playerLeaveRoomEventRoomHandles[room.GetGuid()] { - handle(room, player) - } -} - -// RegPlayerKickedOutEvent 玩家被踢出房间时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerKickedOutEvent(handle PlayerKickedOutEventHandle[PID, P, R]) { - slf.playerKickedOutEventHandles = append(slf.playerKickedOutEventHandles, handle) -} - -// RegPlayerKickedOutEventWithRoom 玩家被踢出房间时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerKickedOutEventWithRoom(room R, handle PlayerKickedOutEventHandle[PID, P, R]) { - slf.playerKickedOutEventRoomHandles[room.GetGuid()] = append(slf.playerKickedOutEventRoomHandles[room.GetGuid()], handle) -} - -// OnPlayerKickedOutEvent 玩家被踢出房间时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) OnPlayerKickedOutEvent(room R, executor, kicked P, reason string) { - for _, handle := range slf.playerKickedOutEventHandles { - handle(room, executor, kicked, reason) - } - for _, handle := range slf.playerKickedOutEventRoomHandles[room.GetGuid()] { - handle(room, executor, kicked, reason) - } -} - -// RegPlayerUpgradeOwnerEvent 玩家成为房主时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerUpgradeOwnerEvent(handle PlayerUpgradeOwnerEventHandle[PID, P, R]) { - slf.playerUpgradeOwnerEventHandles = append(slf.playerUpgradeOwnerEventHandles, handle) -} - -// RegPlayerUpgradeOwnerEventWithRoom 玩家成为房主时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerUpgradeOwnerEventWithRoom(room R, handle PlayerUpgradeOwnerEventHandle[PID, P, R]) { - slf.playerUpgradeOwnerEventRoomHandles[room.GetGuid()] = append(slf.playerUpgradeOwnerEventRoomHandles[room.GetGuid()], handle) -} - -// OnPlayerUpgradeOwnerEvent 玩家成为房主时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) OnPlayerUpgradeOwnerEvent(room R, executor, newOwner P) { - for _, handle := range slf.playerUpgradeOwnerEventHandles { - handle(room, executor, newOwner) - } - for _, handle := range slf.playerUpgradeOwnerEventRoomHandles[room.GetGuid()] { - handle(room, executor, newOwner) - } -} - -// RegCancelOwnerEvent 取消房主时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegCancelOwnerEvent(handle CancelOwnerEventHandle[PID, P, R]) { - slf.cancelOwnerEventHandles = append(slf.cancelOwnerEventHandles, handle) -} - -// RegCancelOwnerEventWithRoom 取消房主时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegCancelOwnerEventWithRoom(room R, handle CancelOwnerEventHandle[PID, P, R]) { - slf.cancelOwnerEventRoomHandles[room.GetGuid()] = append(slf.cancelOwnerEventRoomHandles[room.GetGuid()], handle) -} - -// OnCancelOwnerEvent 取消房主时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) OnCancelOwnerEvent(room R, oldOwner P) { - for _, handle := range slf.cancelOwnerEventHandles { - handle(room, oldOwner) - } - for _, handle := range slf.cancelOwnerEventRoomHandles[room.GetGuid()] { - handle(room, oldOwner) - } -} - -// RegChangePlayerLimitEvent 修改玩家上限时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegChangePlayerLimitEvent(handle ChangePlayerLimitEventHandle[PID, P, R]) { - slf.changePlayerLimitEventHandles = append(slf.changePlayerLimitEventHandles, handle) -} - -// RegChangePlayerLimitEventWithRoom 修改玩家上限时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegChangePlayerLimitEventWithRoom(room R, handle ChangePlayerLimitEventHandle[PID, P, R]) { - slf.changePlayerLimitEventRoomHandles[room.GetGuid()] = append(slf.changePlayerLimitEventRoomHandles[room.GetGuid()], handle) -} - -// OnChangePlayerLimitEvent 修改玩家上限时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) OnChangePlayerLimitEvent(room R, oldLimit, newLimit int) { - for _, handle := range slf.changePlayerLimitEventHandles { - handle(room, oldLimit, newLimit) - } - for _, handle := range slf.changePlayerLimitEventRoomHandles[room.GetGuid()] { - handle(room, oldLimit, newLimit) - } -} - -// RegPlayerSeatChangeEvent 玩家座位改变时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerSeatChangeEvent(handle PlayerSeatChangeEventHandle[PID, P, R]) { - slf.playerSeatChangeEventHandles = append(slf.playerSeatChangeEventHandles, handle) -} - -// RegPlayerSeatChangeEventWithRoom 玩家座位改变时将立即执行被注册的事件处理函数 -// - 当玩家之前没有座位时,oldSeat 为 NoSeat -func (slf *event[PID, P, R]) RegPlayerSeatChangeEventWithRoom(room R, handle PlayerSeatChangeEventHandle[PID, P, R]) { - slf.playerSeatChangeEventRoomHandles[room.GetGuid()] = append(slf.playerSeatChangeEventRoomHandles[room.GetGuid()], handle) -} - -// OnPlayerSeatChangeEvent 玩家座位改变时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) OnPlayerSeatChangeEvent(room R, player P, oldSeat, newSeat int) { - for _, handle := range slf.playerSeatChangeEventHandles { - handle(room, player, oldSeat, newSeat) - } - for _, handle := range slf.playerSeatChangeEventRoomHandles[room.GetGuid()] { - handle(room, player, oldSeat, newSeat) - } -} - -// RegPlayerSeatSetEvent 玩家座位设置时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerSeatSetEvent(handle PlayerSeatSetEventHandle[PID, P, R]) { - slf.playerSeatSetEventHandles = append(slf.playerSeatSetEventHandles, handle) -} - -// RegPlayerSeatSetEventWithRoom 玩家座位设置时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerSeatSetEventWithRoom(room R, handle PlayerSeatSetEventHandle[PID, P, R]) { - slf.playerSeatSetEventRoomHandles[room.GetGuid()] = append(slf.playerSeatSetEventRoomHandles[room.GetGuid()], handle) -} - -// OnPlayerSeatSetEvent 玩家座位设置时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) OnPlayerSeatSetEvent(room R, player P, seat int) { - for _, handle := range slf.playerSeatSetEventHandles { - handle(room, player, seat) - } - for _, handle := range slf.playerSeatSetEventRoomHandles[room.GetGuid()] { - handle(room, player, seat) - } -} - -// RegPlayerSeatCancelEvent 玩家座位取消时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerSeatCancelEvent(handle PlayerSeatCancelEventHandle[PID, P, R]) { - slf.playerSeatCancelEventHandles = append(slf.playerSeatCancelEventHandles, handle) -} - -// RegPlayerSeatCancelEventWithRoom 玩家座位取消时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegPlayerSeatCancelEventWithRoom(room R, handle PlayerSeatCancelEventHandle[PID, P, R]) { - slf.playerSeatCancelEventRoomHandles[room.GetGuid()] = append(slf.playerSeatCancelEventRoomHandles[room.GetGuid()], handle) -} - -// OnPlayerSeatCancelEvent 玩家座位取消时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) OnPlayerSeatCancelEvent(room R, player P, seat int) { - for _, handle := range slf.playerSeatCancelEventHandles { - handle(room, player, seat) - } - for _, handle := range slf.playerSeatCancelEventRoomHandles[room.GetGuid()] { - handle(room, player, seat) - } -} - -// RegRoomCreateEvent 房间创建时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) RegRoomCreateEvent(handle CreateEventHandle[PID, P, R]) { - slf.roomCreateEventHandles = append(slf.roomCreateEventHandles, handle) -} - -// OnRoomCreateEvent 房间创建时将立即执行被注册的事件处理函数 -func (slf *event[PID, P, R]) OnRoomCreateEvent(room R, helper *Helper[PID, P, R]) { - for _, handle := range slf.roomCreateEventHandles { - handle(room, helper) - } -} diff --git a/game/room/helper.go b/game/room/helper.go deleted file mode 100644 index bf41c24..0000000 --- a/game/room/helper.go +++ /dev/null @@ -1,171 +0,0 @@ -package room - -import ( - "github.com/kercylan98/minotaur/game" - "github.com/kercylan98/minotaur/utils/hash" - "github.com/kercylan98/minotaur/utils/slice" -) - -// NewHelper 创建房间助手 -func NewHelper[PID comparable, P game.Player[PID], R Room](manager *Manager[PID, P, R], room R) *Helper[PID, P, R] { - return &Helper[PID, P, R]{ - m: manager, - room: room, - Seat: manager.GetSeatInfo(room.GetGuid()), - } -} - -// Helper 易于快捷使用的房间助手 -type Helper[PID comparable, P game.Player[PID], R Room] struct { - m *Manager[PID, P, R] - *Seat[PID, P, R] - room R -} - -// Room 获取房间 -func (slf *Helper[PID, P, R]) Room() R { - return slf.room -} - -// GetPlayer 获取玩家 -func (slf *Helper[PID, P, R]) GetPlayer(playerId PID) P { - return slf.m.GetRoomPlayer(slf.room.GetGuid(), playerId) -} - -// GetPlayers 获取房间中的所有玩家 -func (slf *Helper[PID, P, R]) GetPlayers() map[PID]P { - return slf.m.GetRoomPlayers(slf.room.GetGuid()) -} - -// GetPlayerCount 获取房间中的玩家数量 -func (slf *Helper[PID, P, R]) GetPlayerCount() int { - return slf.m.GetRoomPlayerCount(slf.room.GetGuid()) -} - -// GetPlayerLimit 获取房间中的玩家数量上限 -func (slf *Helper[PID, P, R]) GetPlayerLimit() int { - return slf.m.GetRoomPlayerLimit(slf.room.GetGuid()) -} - -// GetPlayerRooms 获取玩家所在的所有房间 -func (slf *Helper[PID, P, R]) GetPlayerRooms(playerId PID) map[int64]R { - return slf.m.GetPlayerRooms(playerId) -} - -// GetPlayerRoomHelpers 获取玩家所在的所有房间助手 -func (slf *Helper[PID, P, R]) GetPlayerRoomHelpers(playerId PID) map[int64]*Helper[PID, P, R] { - return slf.m.GetPlayerRoomHelpers(playerId) -} - -// GetPlayersSlice 获取房间中的所有玩家 -func (slf *Helper[PID, P, R]) GetPlayersSlice() []P { - seat := slf.GetSeatInfoMap() - var players = make([]P, 0, len(seat)) - for _, v := range seat { - players = append(players, slf.GetPlayer(v)) - } - return players -} - -// Broadcast 向房间中的所有玩家广播消息 -func (slf *Helper[PID, P, R]) Broadcast(handle func(player P), except ...PID) { - var exceptMap = slice.ToSet(except) - for _, player := range slf.GetPlayers() { - if hash.Exist(exceptMap, player.GetID()) { - continue - } - handle(player) - } -} - -// BroadcastSeat 向房间中所有座位上的玩家广播消息 -func (slf *Helper[PID, P, R]) BroadcastSeat(handle func(player P), except ...PID) { - var exceptMap = slice.ToSet(except) - for _, playerId := range slf.GetSeatInfoMap() { - if hash.Exist(exceptMap, playerId) { - continue - } - handle(slf.GetPlayer(playerId)) - } -} - -// BroadcastExcept 向房间中的所有玩家广播消息,根据特定表达式排除指定玩家 -// - 当 except 返回 true 时,排除该玩家 -func (slf *Helper[PID, P, R]) BroadcastExcept(handle func(player P), except func(player P) bool) { - for _, player := range slf.GetPlayers() { - if except(player) { - continue - } - handle(player) - } -} - -// SetPlayerLimit 设置房间中的玩家数量上限 -func (slf *Helper[PID, P, R]) SetPlayerLimit(limit int) { - slf.m.SetPlayerLimit(slf.room.GetGuid(), limit) -} - -// GetPlayerIDs 获取房间中的所有玩家ID -func (slf *Helper[PID, P, R]) GetPlayerIDs() []PID { - return hash.KeyToSlice(slf.GetPlayers()) -} - -// SetOwner 设置房主 -func (slf *Helper[PID, P, R]) SetOwner(playerId PID) { - slf.m.SetOwner(slf.room.GetGuid(), playerId) -} - -// CancelOwner 取消房主 -func (slf *Helper[PID, P, R]) CancelOwner() { - slf.manager.CancelOwner(slf.room.GetGuid()) -} - -// HasPlayer 是否有玩家 -func (slf *Helper[PID, P, R]) HasPlayer(playerId PID) bool { - return slf.m.InRoom(slf.room.GetGuid(), playerId) -} - -// IsFull 房间是否已满 -func (slf *Helper[PID, P, R]) IsFull() bool { - return slf.GetPlayerCount() == slf.GetPlayerLimit() -} - -// IsEmpty 房间是否为空 -func (slf *Helper[PID, P, R]) IsEmpty() bool { - return slf.GetPlayerCount() == 0 -} - -// GetRemainder 获取房间还可以容纳多少玩家 -func (slf *Helper[PID, P, R]) GetRemainder() int { - return slf.GetPlayerLimit() - slf.GetPlayerCount() -} - -// IsOwner 是否是房主 -func (slf *Helper[PID, P, R]) IsOwner(playerId PID) bool { - return slf.m.IsOwner(slf.room.GetGuid(), playerId) -} - -// HasOwner 是否有房主 -func (slf *Helper[PID, P, R]) HasOwner() bool { - return slf.m.HasOwner(slf.room.GetGuid()) -} - -// GetOwner 获取房主 -func (slf *Helper[PID, P, R]) GetOwner() P { - return slf.m.GetOwner(slf.room.GetGuid()) -} - -// Join 加入房间 -func (slf *Helper[PID, P, R]) Join(player P) error { - return slf.m.Join(slf.room.GetGuid(), player) -} - -// Leave 离开房间 -func (slf *Helper[PID, P, R]) Leave(player P) { - slf.m.Leave(slf.room.GetGuid(), player) -} - -// KickOut 踢出房间 -func (slf *Helper[PID, P, R]) KickOut(executor, kicked PID, reason string) error { - return slf.m.KickOut(slf.room.GetGuid(), executor, kicked, reason) -} diff --git a/game/room/info.go b/game/room/info.go deleted file mode 100644 index 06d1305..0000000 --- a/game/room/info.go +++ /dev/null @@ -1,10 +0,0 @@ -package room - -import "github.com/kercylan98/minotaur/game" - -type Info[PlayerID comparable, P game.Player[PlayerID], R Room] struct { - room R - playerLimit int // 玩家人数上限, <= 0 表示无限制 - owner *PlayerID // 房主 - seat *Seat[PlayerID, P, R] -} diff --git a/game/room/manager.go b/game/room/manager.go deleted file mode 100644 index 09077ee..0000000 --- a/game/room/manager.go +++ /dev/null @@ -1,460 +0,0 @@ -package room - -import ( - "github.com/kercylan98/minotaur/game" - "github.com/kercylan98/minotaur/utils/concurrent" - "github.com/kercylan98/minotaur/utils/generic" -) - -// NewManager 创建房间管理器 -func NewManager[PID comparable, P game.Player[PID], R Room]() *Manager[PID, P, R] { - manager := &Manager[PID, P, R]{ - event: newEvent[PID, P, R](), - rooms: concurrent.NewBalanceMap[int64, *Info[PID, P, R]](), - players: concurrent.NewBalanceMap[PID, P](), - pr: concurrent.NewBalanceMap[PID, map[int64]struct{}](), - rp: concurrent.NewBalanceMap[int64, map[PID]struct{}](), - helpers: concurrent.NewBalanceMap[int64, *Helper[PID, P, R]](), - } - - return manager -} - -// Manager 房间管理器 -type Manager[PID comparable, P game.Player[PID], R Room] struct { - *event[PID, P, R] - rooms *concurrent.BalanceMap[int64, *Info[PID, P, R]] // 所有房间 - players *concurrent.BalanceMap[PID, P] // 所有加入房间的玩家 - pr *concurrent.BalanceMap[PID, map[int64]struct{}] // 玩家所在房间 - rp *concurrent.BalanceMap[int64, map[PID]struct{}] // 房间中的玩家 - helpers *concurrent.BalanceMap[int64, *Helper[PID, P, R]] // 房间助手 -} - -// GetHelper 获取房间助手 -func (slf *Manager[PID, P, R]) GetHelper(room R) *Helper[PID, P, R] { - if generic.IsNil(room) { - return nil - } - helper, exist := slf.helpers.GetExist(room.GetGuid()) - if exist { - return helper - } - helper = NewHelper[PID, P, R](slf, room) - slf.helpers.Set(room.GetGuid(), helper) - return helper -} - -// CreateRoom 创建房间 -func (slf *Manager[PID, P, R]) CreateRoom(room R, options ...Option[PID, P, R]) { - roomInfo := &Info[PID, P, R]{ - room: room, - seat: newSeat[PID, P, R](slf, room, slf.event), - } - for _, option := range options { - option(roomInfo) - } - slf.rooms.Set(room.GetGuid(), roomInfo) - slf.OnRoomCreateEvent(room, slf.GetHelper(room)) -} - -// ReleaseRoom 释放房间 -func (slf *Manager[PID, P, R]) ReleaseRoom(guid int64) { - slf.unReg(guid) - slf.rooms.Delete(guid) - slf.helpers.Delete(guid) - slf.rp.Atom(func(m map[int64]map[PID]struct{}) { - players := m[guid] - slf.pr.Atom(func(m map[PID]map[int64]struct{}) { - for playerId := range players { - delete(m[playerId], guid) - if len(m[playerId]) == 0 { - slf.players.Delete(playerId) - } - } - }) - }) - slf.rp.Delete(guid) -} - -// SetPlayerLimit 设置房间人数上限 -func (slf *Manager[PID, P, R]) SetPlayerLimit(roomId int64, limit int) { - if limit <= 0 { - return - } - var room R - var oldLimit int - slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) { - info, ok := m[roomId] - if !ok { - return - } - oldLimit = info.playerLimit - info.playerLimit = limit - }) - if oldLimit == limit { - return - } - slf.OnChangePlayerLimitEvent(room, oldLimit, limit) -} - -// CancelOwner 取消房主 -func (slf *Manager[PID, P, R]) CancelOwner(roomId int64) { - var room R - var oldOwner P - slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) { - info, ok := m[roomId] - if !ok { - return - } - room = info.room - if info.owner != nil { - oldOwner = slf.GetRoomPlayer(roomId, *info.owner) - info.owner = nil - } - }) - if !generic.IsNil(oldOwner) { - slf.OnCancelOwnerEvent(room, oldOwner) - } -} - -// GetPlayerRooms 获取玩家所在的房间 -func (slf *Manager[PID, P, R]) GetPlayerRooms(playerId PID) (rooms map[int64]R) { - rooms = map[int64]R{} - slf.pr.Atom(func(m map[PID]map[int64]struct{}) { - for roomId := range m[playerId] { - room, ok := slf.rooms.GetExist(roomId) - if !ok { - continue - } - rooms[roomId] = room.room - } - }) - return -} - -// GetPlayerRoomHelpers 获取玩家所在的房间助手 -func (slf *Manager[PID, P, R]) GetPlayerRoomHelpers(playerId PID) (helpers map[int64]*Helper[PID, P, R]) { - helpers = map[int64]*Helper[PID, P, R]{} - slf.pr.Atom(func(m map[PID]map[int64]struct{}) { - for roomId := range m[playerId] { - room, ok := slf.rooms.GetExist(roomId) - if !ok { - continue - } - helpers[roomId] = slf.GetHelper(room.room) - } - }) - return -} - -// IsOwner 检查玩家是否是房主 -func (slf *Manager[PID, P, R]) IsOwner(roomId int64, playerId PID) bool { - var isOwner bool - slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) { - info, ok := m[roomId] - if !ok { - return - } - isOwner = info.owner != nil && *info.owner == playerId - }) - return isOwner -} - -// HasOwner 检查房间是否有房主 -func (slf *Manager[PID, P, R]) HasOwner(roomId int64) bool { - var hasOwner bool - slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) { - info, ok := m[roomId] - if !ok { - return - } - hasOwner = info.owner != nil - }) - return hasOwner -} - -// GetOwner 获取房主 -func (slf *Manager[PID, P, R]) GetOwner(roomId int64) (player P) { - slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) { - info, ok := m[roomId] - if !ok || info.owner == nil { - return - } - player = slf.GetRoomPlayer(roomId, *info.owner) - }) - return -} - -// SetOwner 设置房主 -func (slf *Manager[PID, P, R]) SetOwner(roomId int64, owner PID) { - var oldOwner, newOwner P - var room R - slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) { - info, ok := m[roomId] - if !ok { - return - } - room = info.room - if info.owner != nil { - oldOwner = slf.GetRoomPlayer(roomId, *info.owner) - } - newOwner = slf.GetRoomPlayer(roomId, owner) - if generic.IsNil(newOwner) { - return - } - info.owner = &owner - }) - if generic.IsNil(newOwner) { - return - } - slf.OnPlayerUpgradeOwnerEvent(room, oldOwner, newOwner) -} - -// GetRoom 获取房间 -func (slf *Manager[PID, P, R]) GetRoom(guid int64) (r R) { - if room := slf.rooms.Get(guid); room != nil { - r = room.room - } - return r -} - -// Exist 检查房间是否存在 -func (slf *Manager[PID, P, R]) Exist(guid int64) bool { - return slf.rooms.Exist(guid) -} - -// GetRooms 获取所有房间 -func (slf *Manager[PID, P, R]) GetRooms() map[int64]R { - var rooms = make(map[int64]R) - slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) { - for id, info := range m { - rooms[id] = info.room - } - }) - return rooms -} - -// GetRoomCount 获取房间数量 -func (slf *Manager[PID, P, R]) GetRoomCount() int { - return slf.rooms.Size() -} - -// GetRoomPlayerCount 获取房间中玩家数量 -func (slf *Manager[PID, P, R]) GetRoomPlayerCount(guid int64) int { - var count int - slf.rp.Atom(func(m map[int64]map[PID]struct{}) { - count = len(m[guid]) - }) - return count -} - -// ExistPlayer 检查玩家是否在任一房间内 -func (slf *Manager[PID, P, R]) ExistPlayer(id PID) bool { - return slf.players.Exist(id) -} - -// InRoom 检查玩家是否在指定房间内 -func (slf *Manager[PID, P, R]) InRoom(guid int64, id PID) bool { - var in bool - slf.pr.Atom(func(m map[PID]map[int64]struct{}) { - rooms, exist := m[id] - if !exist { - return - } - _, in = rooms[guid] - }) - return in -} - -// GetPlayer 获取玩家 -func (slf *Manager[PID, P, R]) GetPlayer(id PID) P { - return slf.players.Get(id) -} - -// GetPlayers 获取所有玩家 -func (slf *Manager[PID, P, R]) GetPlayers() *concurrent.BalanceMap[PID, P] { - return slf.players -} - -// GetPlayerCount 获取玩家数量 -func (slf *Manager[PID, P, R]) GetPlayerCount() int { - return slf.players.Size() -} - -// GetPlayerRoom 获取玩家所在房间 -func (slf *Manager[PID, P, R]) GetPlayerRoom(id PID) []R { - var result = make([]R, 0) - slf.pr.Atom(func(m map[PID]map[int64]struct{}) { - rooms, exist := m[id] - if !exist { - return - } - for id := range rooms { - result = append(result, slf.rooms.Get(id).room) - } - }) - return result -} - -// GetPlayerRoomCount 获取玩家所在房间数量 -func (slf *Manager[PID, P, R]) GetPlayerRoomCount(id PID) int { - var count int - slf.pr.Atom(func(m map[PID]map[int64]struct{}) { - count = len(m[id]) - }) - return count -} - -// GetRoomPlayer 获取房间中的玩家 -func (slf *Manager[PID, P, R]) GetRoomPlayer(roomId int64, playerId PID) P { - var player P - slf.rp.Atom(func(m map[int64]map[PID]struct{}) { - players, exist := m[roomId] - if !exist { - return - } - _, exist = players[playerId] - if !exist { - return - } - player = slf.players.Get(playerId) - }) - return player -} - -// GetRoomPlayers 获取房间中的玩家 -func (slf *Manager[PID, P, R]) GetRoomPlayers(guid int64) map[PID]P { - var result = make(map[PID]P) - slf.rp.Atom(func(m map[int64]map[PID]struct{}) { - players, exist := m[guid] - if !exist { - return - } - for id := range players { - result[id] = slf.players.Get(id) - } - }) - return result -} - -// GetRoomPlayerLimit 获取房间中的玩家数量上限 -func (slf *Manager[PID, P, R]) GetRoomPlayerLimit(guid int64) int { - return slf.rooms.Get(guid).playerLimit -} - -// Leave 使玩家离开房间 -func (slf *Manager[PID, P, R]) Leave(roomId int64, player P) { - var roomInfo *Info[PID, P, R] - slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) { - room, exist := m[roomId] - if !exist { - return - } - roomInfo = room - }) - if roomInfo == nil { - return - } - slf.OnPlayerLeaveRoomEvent(roomInfo.room, player) - seat := roomInfo.seat.GetSeat(player.GetID()) - if seat != NoSeat && slf.IsOwner(roomId, player.GetID()) && slf.GetPlayerCount() > 1 { - slf.SetOwner(roomId, roomInfo.seat.GetPlayerIDWithSeat(roomInfo.seat.GetNextSeat(seat))) - } - roomInfo.seat.RemoveSeat(player.GetID()) - slf.pr.Atom(func(m map[PID]map[int64]struct{}) { - rooms, exist := m[player.GetID()] - if !exist { - return - } - delete(rooms, roomId) - if len(rooms) == 0 { - slf.players.Delete(player.GetID()) - } - }) - slf.rp.Atom(func(m map[int64]map[PID]struct{}) { - players, exist := m[roomId] - if !exist { - return - } - delete(players, player.GetID()) - }) -} - -// Join 使玩家加入房间 -func (slf *Manager[PID, P, R]) Join(roomId int64, player P) error { - var err error - var roomInfo *Info[PID, P, R] - slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) { - room, exist := m[roomId] - if !exist { - err = ErrRoomNotExist - return - } - if room.playerLimit > 0 && room.playerLimit <= slf.GetRoomPlayerCount(roomId) { - err = ErrRoomPlayerFull - return - } - slf.pr.Atom(func(m map[PID]map[int64]struct{}) { - rooms, exist := m[player.GetID()] - if !exist { - rooms = make(map[int64]struct{}) - m[player.GetID()] = rooms - } - rooms[roomId] = struct{}{} - }) - slf.rp.Atom(func(m map[int64]map[PID]struct{}) { - players, exist := m[roomId] - if !exist { - players = make(map[PID]struct{}) - m[roomId] = players - } - players[player.GetID()] = struct{}{} - }) - slf.players.Set(player.GetID(), player) - roomInfo = room - }) - if roomInfo.seat.autoSitDown { - roomInfo.seat.AddSeat(player.GetID()) - } - slf.OnPlayerJoinRoomEvent(roomInfo.room, player) - return err -} - -// KickOut 以某种原因踢出特定玩家 -// - 该函数不会校验任何权限相关的内容,调用后将直接踢出玩家 -func (slf *Manager[PID, P, R]) KickOut(roomId int64, executor, kicked PID, reason string) error { - var err error - var room R - var executorPlayer, kickedPlayer P - slf.rp.Atom(func(m map[int64]map[PID]struct{}) { - executorPlayer, kickedPlayer = slf.GetRoomPlayer(roomId, executor), slf.GetRoomPlayer(roomId, kicked) - if generic.IsHasNil(executorPlayer, kickedPlayer) { - err = ErrRoomOrPlayerNotExist - return - } - room = slf.rooms.Get(roomId).room - if generic.IsNil(room) { - err = ErrRoomNotExist - return - } - }) - if err == nil { - return err - } - slf.OnPlayerKickedOutEvent(room, executorPlayer, kickedPlayer, reason) - slf.Leave(roomId, slf.players.Get(kicked)) - return nil -} - -// GetSeatInfo 获取座位信息 -func (slf *Manager[PID, P, R]) GetSeatInfo(roomId int64) *Seat[PID, P, R] { - var result *Seat[PID, P, R] - slf.rooms.Atom(func(m map[int64]*Info[PID, P, R]) { - room, exist := m[roomId] - if !exist { - return - } - result = room.seat - }) - return result -} diff --git a/game/room/manager_test.go b/game/room/manager_test.go deleted file mode 100644 index e47b6e9..0000000 --- a/game/room/manager_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package room_test - -import ( - "fmt" - "github.com/kercylan98/minotaur/game/room" - "testing" -) - -func TestNewManager(t *testing.T) { - m := room.NewManager[string, *Player, *Room]() - r := &Room{} - m.CreateRoom(r) - helper := m.GetHelper(r) - - helper.Join(&Player{ID: "player_01"}) - helper.Join(&Player{ID: "player_02"}) - helper.Join(&Player{ID: "player_03"}) - helper.Leave(helper.GetPlayer("player_02")) - helper.Join(&Player{ID: "player_02"}) - - helper.BroadcastExcept(func(player *Player) { - fmt.Println(player.GetID()) - }, func(player *Player) bool { - return false - }) -} diff --git a/game/room/room.go b/game/room/room.go deleted file mode 100644 index 7a55191..0000000 --- a/game/room/room.go +++ /dev/null @@ -1,7 +0,0 @@ -package room - -// Room 游戏房间接口 -type Room interface { - // GetGuid 获取房间的唯一标识符 - GetGuid() int64 -} diff --git a/game/room/room_options.go b/game/room/room_options.go deleted file mode 100644 index d5f2e35..0000000 --- a/game/room/room_options.go +++ /dev/null @@ -1,19 +0,0 @@ -package room - -import "github.com/kercylan98/minotaur/game" - -type Option[PID comparable, P game.Player[PID], R Room] func(info *Info[PID, P, R]) - -// WithPlayerLimit 设置房间人数上限 -func WithPlayerLimit[PID comparable, P game.Player[PID], R Room](limit int) Option[PID, P, R] { - return func(info *Info[PID, P, R]) { - info.playerLimit = limit - } -} - -// WithNotAutoJoinSeat 设置不自动加入座位 -func WithNotAutoJoinSeat[PID comparable, P game.Player[PID], R Room]() Option[PID, P, R] { - return func(info *Info[PID, P, R]) { - info.seat.autoSitDown = false - } -} diff --git a/game/room/seat.go b/game/room/seat.go deleted file mode 100644 index 8c722c1..0000000 --- a/game/room/seat.go +++ /dev/null @@ -1,289 +0,0 @@ -package room - -import ( - "github.com/kercylan98/minotaur/game" - "github.com/kercylan98/minotaur/utils/concurrent" - "github.com/kercylan98/minotaur/utils/generic" - "github.com/kercylan98/minotaur/utils/hash" - "sync" -) - -const ( - NoSeat = -1 // 无座位 -) - -func newSeat[PlayerID comparable, P game.Player[PlayerID], R Room](manager *Manager[PlayerID, P, R], room R, event *event[PlayerID, P, R]) *Seat[PlayerID, P, R] { - roomSeat := &Seat[PlayerID, P, R]{ - manager: manager, - room: room, - event: event, - seatPS: concurrent.NewBalanceMap[PlayerID, int](), - autoSitDown: true, - } - return roomSeat -} - -// Seat 房间座位信息 -type Seat[PlayerID comparable, P game.Player[PlayerID], R Room] struct { - manager *Manager[PlayerID, P, R] - room R - event *event[PlayerID, P, R] - mutex sync.RWMutex - vacancy []int - seatPS *concurrent.BalanceMap[PlayerID, int] - seatSP []*PlayerID - duplicateLock bool - autoSitDown bool -} - -// GetSeatPlayerCount 获取座位上的玩家数量 -// - 该数量不包括空缺的座位 -func (slf *Seat[PlayerID, P, R]) GetSeatPlayerCount() int { - return slf.seatPS.Size() -} - -// AddSeat 为特定玩家添加座位 -// - 当座位存在空缺的时候,玩家将会优先在空缺位置坐下,否则将会在末位追加 -func (slf *Seat[PlayerID, P, R]) AddSeat(id PlayerID) { - if slf.seatPS.Exist(id) { - return - } - var seat int - slf.mutex.Lock() - if len(slf.vacancy) > 0 { - seat = slf.vacancy[0] - slf.vacancy = slf.vacancy[1:] - slf.seatPS.Set(id, seat) - slf.seatSP[seat] = &id - } else { - seat = len(slf.seatSP) - slf.seatPS.Set(id, seat) - slf.seatSP = append(slf.seatSP, &id) - } - slf.mutex.Unlock() - slf.event.OnPlayerSeatSetEvent(slf.room, slf.manager.GetPlayer(id), seat) -} - -// RemoveSeat 删除玩家座位 -func (slf *Seat[PlayerID, P, R]) RemoveSeat(id PlayerID) { - if !slf.seatPS.Exist(id) { - return - } - slf.event.OnPlayerSeatCancelEvent(slf.room, slf.manager.GetPlayer(id), slf.seatPS.Get(id)) - slf.mutex.Lock() - defer slf.mutex.Unlock() - seat := slf.seatPS.DeleteGet(id) - slf.vacancy = append(slf.vacancy, seat) - slf.seatSP[seat] = nil -} - -// HasSeat 判断玩家是否有座位 -func (slf *Seat[PlayerID, P, R]) HasSeat(id PlayerID) bool { - return slf.seatPS.Exist(id) -} - -// SetSeat 设置玩家的座位号 -// - 如果位置已经有玩家,将会与其进行更换 -func (slf *Seat[PlayerID, P, R]) SetSeat(id PlayerID, seat int) int { - slf.mutex.Lock() - slf.duplicateLock = true - defer func() { - slf.mutex.Unlock() - slf.duplicateLock = false - }() - oldSeat := slf.GetSeat(id) - player := slf.GetPlayerWithSeat(seat) - if generic.IsNil(player) { - if oldSeat == NoSeat { - maxSeat := len(slf.seatSP) - 1 - if seat > maxSeat { - count := seat - maxSeat - slf.seatSP = append(slf.seatSP, make([]*PlayerID, count)...) - } - slf.seatSP[seat] = &id - slf.seatPS.Set(id, seat) - } else { - ov := slf.seatSP[oldSeat] - slf.seatSP[oldSeat] = slf.seatSP[seat] - slf.seatSP[seat] = ov - slf.seatPS.Set(id, seat) - slf.seatPS.Set(player.GetID(), oldSeat) - } - } else { - maxSeat := len(slf.seatSP) - 1 - if seat > maxSeat { - count := seat - maxSeat - slf.seatSP = append(slf.seatSP, make([]*PlayerID, count)...) - } - slf.seatSP[seat] = slf.seatSP[oldSeat] - slf.seatSP[oldSeat] = nil - slf.vacancy = append(slf.vacancy, oldSeat) - slf.seatPS.Set(id, seat) - } - slf.event.OnPlayerSeatChangeEvent(slf.room, slf.manager.GetPlayer(id), oldSeat, seat) - return oldSeat -} - -// IsNoSeat 判断玩家是否没有座位 -func (slf *Seat[PlayerID, P, R]) IsNoSeat(id PlayerID) bool { - return slf.GetSeat(id) == NoSeat -} - -// GetSeat 获取玩家座位号 -// - 如果玩家没有座位,将会返回 NoSeat -func (slf *Seat[PlayerID, P, R]) GetSeat(id PlayerID) int { - seat, exist := slf.seatPS.GetExist(id) - if !exist { - return NoSeat - } - return seat -} - -// GetPlayerIDWithSeat 获取特定座位号的玩家ID -func (slf *Seat[PlayerID, P, R]) GetPlayerIDWithSeat(seat int) (id PlayerID) { - if !slf.duplicateLock { - slf.mutex.RLock() - defer slf.mutex.RUnlock() - } - if seat >= len(slf.seatSP) || seat < 0 { - return id - } - playerId := slf.seatSP[seat] - if playerId == nil { - return id - } - return *playerId -} - -// GetPlayerWithSeat 获取特定座位号的玩家 -func (slf *Seat[PlayerID, P, R]) GetPlayerWithSeat(seat int) (player P) { - if !slf.duplicateLock { - slf.mutex.RLock() - defer slf.mutex.RUnlock() - } - if seat >= len(slf.seatSP) || seat < 0 { - return player - } - id := slf.seatSP[seat] - if id == nil { - return player - } - return slf.manager.GetRoomPlayer(slf.room.GetGuid(), *id) -} - -// GetSeatInfo 获取所有座位号 -// - 在非补位模式(WithRoomSeatFillIn)下由于座位号可能存在缺席的情况,所以需要根据是否为空指针进行判断 -func (slf *Seat[PlayerID, P, R]) GetSeatInfo() []*PlayerID { - slf.mutex.RLock() - defer slf.mutex.RUnlock() - return slf.seatSP -} - -// GetSeatInfoMap 获取座位号及其对应的玩家信息 -// - 缺席情况将被忽略 -func (slf *Seat[PlayerID, P, R]) GetSeatInfoMap() map[int]PlayerID { - var seatInfo = make(map[int]PlayerID) - slf.mutex.RLock() - defer slf.mutex.RUnlock() - for seat, playerId := range slf.seatSP { - if playerId == nil { - continue - } - seatInfo[seat] = *playerId - } - return seatInfo -} - -// GetSeatInfoMapVacancy 获取座位号及其对应的玩家信息 -// - 缺席情况将不会被忽略 -func (slf *Seat[PlayerID, P, R]) GetSeatInfoMapVacancy() map[int]*PlayerID { - slf.mutex.RLock() - defer slf.mutex.RUnlock() - return hash.ToMap(slf.seatSP) -} - -// GetSeatInfoWithPlayerIDMap 获取玩家及其座位号信息 -func (slf *Seat[PlayerID, P, R]) GetSeatInfoWithPlayerIDMap() map[PlayerID]int { - return slf.seatPS.Map() -} - -// GetFirstSeat 获取第一个未缺席的座位号 -// - 如果没有,将会返回 NoSeat -func (slf *Seat[PlayerID, P, R]) GetFirstSeat() int { - for seat, playerId := range slf.seatSP { - if playerId != nil { - return seat - } - } - return NoSeat -} - -// GetNextSeat 获取特定座位号下一个未缺席的座位号 -func (slf *Seat[PlayerID, P, R]) GetNextSeat(seat int) int { - l := len(slf.seatSP) - if l == 0 || seat >= l || seat < 0 { - return NoSeat - } - var target = seat - for { - target++ - if target >= l { - target = 0 - } - if target == seat { - return seat - } - if slf.seatSP[target] != nil { - return target - } - } -} - -// GetNextSeatVacancy 获取特定座位号下一个座位号 -// - 缺席将不会被忽略 -func (slf *Seat[PlayerID, P, R]) GetNextSeatVacancy(seat int) int { - l := len(slf.seatSP) - if l == 0 || seat >= l || seat < 0 { - return NoSeat - } - seat++ - if seat >= l { - seat = 0 - } - return seat -} - -// GetPrevSeat 获取特定座位号上一个未缺席的座位号 -func (slf *Seat[PlayerID, P, R]) GetPrevSeat(seat int) int { - l := len(slf.seatSP) - if l == 0 || seat >= l || seat < 0 { - return NoSeat - } - var target = seat - for { - target-- - if target < 0 { - target = l - 1 - } - if target == seat { - return seat - } - if slf.seatSP[target] != nil { - return target - } - } -} - -// GetPrevSeatVacancy 获取特定座位号上一个座位号 -// - 缺席将不会被忽略 -func (slf *Seat[PlayerID, P, R]) GetPrevSeatVacancy(seat int) int { - l := len(slf.seatSP) - if l == 0 || seat >= l || seat < 0 { - return NoSeat - } - seat-- - if seat < 0 { - seat = l - 1 - } - return seat -} diff --git a/game/room/seat_test.go b/game/room/seat_test.go deleted file mode 100644 index 58ec3cc..0000000 --- a/game/room/seat_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package room_test - -import ( - "fmt" - "github.com/kercylan98/minotaur/game/room" - "github.com/kercylan98/minotaur/server" - "testing" -) - -type Player struct { - ID string -} - -func (slf *Player) GetID() string { - return slf.ID -} - -func (slf *Player) GetConn() *server.Conn { - return nil -} - -func (slf *Player) UseConn(conn *server.Conn) { - -} - -func (slf *Player) Close(err ...error) { - -} - -type Room struct { -} - -func (slf *Room) GetGuid() int64 { - return 0 -} - -func TestSeat_SetSeat(t *testing.T) { - rm := room.NewManager[string, *Player, *Room]() - - r := &Room{} - rm.CreateRoom(r) - helper := rm.GetHelper(r) - helper.AddSeat("a") - helper.AddSeat("b") - helper.RemoveSeat("a") - helper.AddSeat("c") - - for i, s := range helper.GetSeatInfo() { - if s == nil { - fmt.Println(i, "nil") - } else { - fmt.Println(i, *s) - } - } -}