带有座位号的房间实现
This commit is contained in:
parent
47f2267918
commit
dfa5f7a063
|
@ -0,0 +1,89 @@
|
|||
package builtin
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/game"
|
||||
"github.com/kercylan98/minotaur/utils/synchronization"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func NewRoomSeat[PlayerID comparable, Player game.Player[PlayerID]](room game.Room[PlayerID, Player]) *RoomSeat[PlayerID, Player] {
|
||||
roomSeat := &RoomSeat[PlayerID, Player]{
|
||||
Room: room,
|
||||
seatPS: synchronization.NewMap[PlayerID, int](),
|
||||
}
|
||||
room.RegPlayerJoinRoomEvent(roomSeat.onJoinRoom)
|
||||
room.RegPlayerLeaveRoomEvent(roomSeat.onLeaveRoom)
|
||||
return roomSeat
|
||||
}
|
||||
|
||||
type RoomSeat[PlayerID comparable, Player game.Player[PlayerID]] struct {
|
||||
game.Room[PlayerID, Player]
|
||||
mutex sync.Mutex
|
||||
vacancy []int
|
||||
seatPS *synchronization.Map[PlayerID, int]
|
||||
seatSP []*PlayerID
|
||||
}
|
||||
|
||||
func (slf *RoomSeat[PlayerID, Player]) SetSeat(id PlayerID, seat int) error {
|
||||
oldSeat, err := slf.GetSeat(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
player, err := slf.GetPlayerWithSeat(seat)
|
||||
if err != nil {
|
||||
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.seatPS.Set(id, seat)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (slf *RoomSeat[PlayerID, Player]) GetSeat(id PlayerID) (int, error) {
|
||||
seat, exist := slf.seatPS.GetExist(id)
|
||||
if !exist {
|
||||
return 0, ErrRoomNotHasPlayer
|
||||
}
|
||||
return seat, nil
|
||||
}
|
||||
|
||||
func (slf *RoomSeat[PlayerID, Player]) GetPlayerWithSeat(seat int) (player Player, err error) {
|
||||
if seat > len(slf.seatSP)-1 {
|
||||
return player, ErrRoomNotHasPlayer
|
||||
}
|
||||
id := slf.seatSP[seat]
|
||||
if id == nil {
|
||||
return player, ErrRoomNotHasPlayer
|
||||
}
|
||||
return slf.GetPlayer(*id), nil
|
||||
}
|
||||
|
||||
func (slf *RoomSeat[PlayerID, Player]) onJoinRoom(room game.Room[PlayerID, Player], player Player) {
|
||||
slf.mutex.Lock()
|
||||
defer slf.mutex.Unlock()
|
||||
playerId := player.GetID()
|
||||
if len(slf.vacancy) > 0 {
|
||||
seat := slf.vacancy[0]
|
||||
slf.vacancy = slf.vacancy[1:]
|
||||
slf.seatPS.Set(player.GetID(), seat)
|
||||
slf.seatSP[seat] = &playerId
|
||||
} else {
|
||||
slf.seatPS.Set(player.GetID(), len(slf.seatSP))
|
||||
slf.seatSP = append(slf.seatSP, &playerId)
|
||||
}
|
||||
}
|
||||
|
||||
func (slf *RoomSeat[PlayerID, Player]) onLeaveRoom(room game.Room[PlayerID, Player], player Player) {
|
||||
seat := slf.seatPS.DeleteGet(player.GetID())
|
||||
slf.seatSP[seat] = nil
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package builtin
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrRoomNotHasPlayer = errors.New("player not exist")
|
||||
)
|
|
@ -0,0 +1,12 @@
|
|||
package game
|
||||
|
||||
// RoomSeat 带有座位号的房间实现
|
||||
type RoomSeat[PlayerID comparable, P Player[PlayerID]] interface {
|
||||
Room[PlayerID, P]
|
||||
// SetSeat 设置玩家座位号
|
||||
SetSeat(id PlayerID, seat int) error
|
||||
// GetSeat 获取玩家座位号
|
||||
GetSeat(id PlayerID) (int, error)
|
||||
// GetPlayerWithSeat 根据座位号获取玩家
|
||||
GetPlayerWithSeat(seat int) (P, error)
|
||||
}
|
Loading…
Reference in New Issue