百人场
This commit is contained in:
parent
0ad0125109
commit
99d726dc2a
@ -13,12 +13,21 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type PlayerType int
|
||||
|
||||
const (
|
||||
PT_User PlayerType = 0
|
||||
PT_Robot PlayerType = 1
|
||||
PT_All PlayerType = 2
|
||||
)
|
||||
|
||||
// 房间基类,不要直接用于业务
|
||||
type BaseRoom[Seat ISeat] struct {
|
||||
id int
|
||||
roomType int // 房间配置id 初级,中级,高级
|
||||
playType int // 玩法配置id color玩法id
|
||||
gameNo string
|
||||
Seats []Seat
|
||||
seats []Seat
|
||||
processor *processor.Processor
|
||||
timeProcessor *processor.TimerProcessor
|
||||
|
||||
@ -26,12 +35,13 @@ type BaseRoom[Seat ISeat] struct {
|
||||
srv service.IService
|
||||
}
|
||||
|
||||
func NewBaseRoom[Seat ISeat](id, roomType, playType int, srv service.IService) (*BaseRoom[Seat], pb.ErrCode) {
|
||||
func NewBaseRoom[Seat ISeat](id, roomType, playType, seatNum int, srv service.IService) (*BaseRoom[Seat], pb.ErrCode) {
|
||||
room := &BaseRoom[Seat]{
|
||||
id: id,
|
||||
roomType: roomType,
|
||||
playType: playType,
|
||||
gameNo: "",
|
||||
seats: make([]Seat, seatNum),
|
||||
timeTypes: make(map[timer.ITimeType]uint32),
|
||||
srv: srv,
|
||||
processor: processor.NewProcessor(),
|
||||
@ -53,93 +63,86 @@ func (r *BaseRoom[Seat]) PlayType() int {
|
||||
return r.playType
|
||||
}
|
||||
|
||||
// 入座玩家数量(包含机器人)
|
||||
func (r *BaseRoom[Seat]) SeatPlayerNum() int {
|
||||
// 入座玩家数量
|
||||
func (r *BaseRoom[Seat]) SeatPlayerNum(playerType PlayerType) int {
|
||||
num := 0
|
||||
for _, seat := range r.Seats {
|
||||
for _, seat := range r.seats {
|
||||
if !seat.Empty() {
|
||||
num++
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// 真实玩家数量
|
||||
func (r *BaseRoom[Seat]) RealPlayerNum() int {
|
||||
num := 0
|
||||
for _, seat := range r.Seats {
|
||||
if !seat.Empty() && seat.Player().Robot() == nil {
|
||||
num++
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// 机器人数量
|
||||
func (r *BaseRoom[Seat]) RobotPlayerNum() int {
|
||||
num := 0
|
||||
for _, seat := range r.Seats {
|
||||
if !seat.Empty() && seat.Player().Robot() != nil {
|
||||
num++
|
||||
switch playerType {
|
||||
case PT_All:
|
||||
num++
|
||||
case PT_User:
|
||||
if !seat.Player().IsRobot() {
|
||||
num++
|
||||
}
|
||||
case PT_Robot:
|
||||
if seat.Player().IsRobot() {
|
||||
num++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// 返回是否有空座位及空座位编号
|
||||
func (r *BaseRoom[Seat]) HasEmptySeat() (bool, int) {
|
||||
for _, seat := range r.Seats {
|
||||
func (r *BaseRoom[Seat]) FindEmptySeat() (bool, Seat) {
|
||||
for _, seat := range r.seats {
|
||||
if seat.Empty() {
|
||||
return true, seat.No()
|
||||
return true, seat
|
||||
}
|
||||
}
|
||||
return false, -1
|
||||
return false, utils.TValue[Seat]{}.V
|
||||
}
|
||||
|
||||
// 查找玩家及玩家所在的座位
|
||||
func (r *BaseRoom[Seat]) FindPlayer(uid int64) (IPlayer, Seat) {
|
||||
for _, seat := range r.Seats {
|
||||
// 查找玩家所在的座位
|
||||
func (r *BaseRoom[Seat]) FindSeat(uid int64) (bool, Seat) {
|
||||
for _, seat := range r.seats {
|
||||
if !seat.Empty() && seat.Player().Id() == uid {
|
||||
return seat.Player(), seat
|
||||
return true, seat
|
||||
}
|
||||
}
|
||||
return nil, utils.TValue[Seat]{}.V
|
||||
return false, utils.TValue[Seat]{}.V
|
||||
}
|
||||
|
||||
func (r *BaseRoom[Seat]) AddPlayer(player IPlayer, seat int) {
|
||||
if seat < 0 || seat >= len(r.Seats) {
|
||||
log.Error(r.SeatLog(r.Seats[seat], "out of range"))
|
||||
return
|
||||
// 查找玩家所在的座位
|
||||
func (r *BaseRoom[Seat]) GetSeat(seatNo int) (bool, Seat) {
|
||||
if seatNo < 0 || seatNo >= len(r.seats) {
|
||||
return false, utils.TValue[Seat]{}.V
|
||||
}
|
||||
r.Seats[seat].SetPlayer(player)
|
||||
return
|
||||
return true, r.seats[seatNo]
|
||||
}
|
||||
|
||||
func (r *BaseRoom[Seat]) RemovePlayer(player IPlayer) {
|
||||
for _, seat := range r.Seats {
|
||||
if !seat.Empty() && seat.Player().Id() == player.Id() {
|
||||
seat.SetPlayer(nil)
|
||||
break
|
||||
}
|
||||
// 站起时player为nil,坐下时player非nil
|
||||
func (r *BaseRoom[Seat]) SitDownOrStandup(player IPlayer, seat int) bool {
|
||||
if seat < 0 || seat >= len(r.seats) {
|
||||
log.Error(r.SeatLog(r.seats[seat], "out of range"))
|
||||
return false
|
||||
}
|
||||
if player != nil && r.seats[seat].Player() != nil {
|
||||
log.Error(r.SeatLog(r.seats[seat], "is already here"))
|
||||
return false
|
||||
}
|
||||
r.seats[seat].SetPlayer(player)
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *BaseRoom[Seat]) RangePlayer(proc func(IPlayer) bool) {
|
||||
for _, seat := range r.Seats {
|
||||
if !seat.Empty() && !proc(seat.Player()) {
|
||||
func (r *BaseRoom[Seat]) RangeSeat(proc func(Seat) bool) {
|
||||
for _, seat := range r.seats {
|
||||
if !seat.Empty() && !proc(seat) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *BaseRoom[Seat]) FilterPlayer(proc func(IPlayer) bool) []IPlayer {
|
||||
players := make([]IPlayer, 0)
|
||||
for _, seat := range r.Seats {
|
||||
if !seat.Empty() && proc(seat.Player()) {
|
||||
players = append(players, seat.Player())
|
||||
func (r *BaseRoom[Seat]) FilterSeat(proc func(Seat) bool) []Seat {
|
||||
seats := make([]Seat, 0)
|
||||
for _, seat := range r.seats {
|
||||
if !seat.Empty() && proc(seat) {
|
||||
seats = append(seats, seat)
|
||||
}
|
||||
}
|
||||
return players
|
||||
return seats
|
||||
}
|
||||
|
||||
func (r *BaseRoom[Seat]) DebugSendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message) {
|
||||
@ -151,19 +154,13 @@ func (r *BaseRoom[Seat]) SendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message
|
||||
if user.Robot() != nil {
|
||||
user.Robot().OnMessage(msgId, msg)
|
||||
} else {
|
||||
for _, seat := range r.Seats {
|
||||
if !seat.Empty() && seat.Player().Id() == user.Id() {
|
||||
iMsg := ipb.MakeMsgEx(r.srv.Name(), 0, user.Id(), int32(msgId), msg)
|
||||
_ = r.srv.Send(user.GateTopicName(), iMsg)
|
||||
break
|
||||
}
|
||||
}
|
||||
iMsg := ipb.MakeMsgEx(r.srv.Name(), 0, user.Id(), int32(msgId), msg)
|
||||
_ = r.srv.Send(user.GateTopicName(), iMsg)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *BaseRoom[Seat]) Broadcast(msgId pb.MsgId, msg proto.Message, exclude ...IPlayer) {
|
||||
for _, seat := range r.Seats {
|
||||
for _, seat := range r.seats {
|
||||
if !seat.Empty() {
|
||||
exist := false
|
||||
for _, excludePlayer := range exclude {
|
||||
@ -231,7 +228,7 @@ func (r *BaseRoom[Seat]) SeatLog(seat Seat, format string, a ...any) string {
|
||||
func (r *BaseRoom[Seat]) UserLog(uid int64, format string, a ...any) string {
|
||||
var seat Seat
|
||||
exist := false
|
||||
for _, st := range r.Seats {
|
||||
for _, st := range r.seats {
|
||||
if !st.Empty() && st.Player().Id() == uid {
|
||||
seat = st
|
||||
exist = true
|
||||
|
180
common/baseroom/hundredRoom.go
Normal file
180
common/baseroom/hundredRoom.go
Normal file
@ -0,0 +1,180 @@
|
||||
package baseroom
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"game/common/proto/pb"
|
||||
"github.com/fox/fox/ipb"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/fox/fox/processor"
|
||||
"github.com/fox/fox/service"
|
||||
"github.com/fox/fox/timer"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 百人场
|
||||
type HundredRoom struct {
|
||||
room *BaseRoom[*BaseSeat]
|
||||
users map[int64]IPlayer // 所有玩家
|
||||
}
|
||||
|
||||
func NewHundredRoom(id, roomType, playType int, srv service.IService) (*HundredRoom, pb.ErrCode) {
|
||||
baseRoom, code := NewBaseRoom[*BaseSeat](id, roomType, playType, 0, srv)
|
||||
if code != pb.ErrCode_OK {
|
||||
return nil, code
|
||||
}
|
||||
room := &HundredRoom{
|
||||
room: baseRoom,
|
||||
}
|
||||
return room, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
func (r *HundredRoom) Id() int {
|
||||
return r.room.Id()
|
||||
}
|
||||
|
||||
func (r *HundredRoom) RoomType() int {
|
||||
return r.room.RoomType()
|
||||
}
|
||||
|
||||
func (r *HundredRoom) PlayType() int {
|
||||
return r.room.PlayType()
|
||||
}
|
||||
|
||||
// 房间玩家数量
|
||||
func (r *HundredRoom) GetPlayerNum(playerType PlayerType) int {
|
||||
if playerType == PT_All {
|
||||
return len(r.users)
|
||||
}
|
||||
num := 0
|
||||
for _, user := range r.users {
|
||||
switch playerType {
|
||||
case PT_User:
|
||||
if !user.IsRobot() {
|
||||
num++
|
||||
}
|
||||
case PT_Robot:
|
||||
if user.IsRobot() {
|
||||
num++
|
||||
}
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// 查找玩家所在的座位
|
||||
func (r *HundredRoom) FindPlayer(uid int64) (IPlayer, bool) {
|
||||
u, ok := r.users[uid]
|
||||
return u, ok
|
||||
}
|
||||
|
||||
// 站起时player为nil,坐下时player非nil
|
||||
func (r *HundredRoom) AddPayer(user IPlayer) bool {
|
||||
if _, ok := r.users[user.Id()]; ok {
|
||||
return false
|
||||
}
|
||||
r.users[user.Id()] = user
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *HundredRoom) DelPlayer(uid int64) {
|
||||
delete(r.users, uid)
|
||||
}
|
||||
|
||||
func (r *HundredRoom) RangePlayer(proc func(IPlayer) bool) {
|
||||
for _, seat := range r.users {
|
||||
if !proc(seat) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *HundredRoom) FilterPlayer(proc func(IPlayer) bool) []IPlayer {
|
||||
users := make([]IPlayer, 0)
|
||||
for _, user := range r.users {
|
||||
if proc(user) {
|
||||
users = append(users, user)
|
||||
}
|
||||
}
|
||||
return users
|
||||
}
|
||||
|
||||
func (r *HundredRoom) DebugSendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message) {
|
||||
log.Debug(r.UserLog(user.Id(), "send msg:%v %v", msgId, msg.String()))
|
||||
}
|
||||
|
||||
func (r *HundredRoom) SendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message) {
|
||||
r.DebugSendMsg(user, msgId, msg)
|
||||
if user.Robot() != nil {
|
||||
user.Robot().OnMessage(msgId, msg)
|
||||
} else {
|
||||
iMsg := ipb.MakeMsgEx(r.room.srv.Name(), 0, user.Id(), int32(msgId), msg)
|
||||
_ = r.room.srv.Send(user.GateTopicName(), iMsg)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *HundredRoom) Broadcast(msgId pb.MsgId, msg proto.Message, exclude ...IPlayer) {
|
||||
for _, user := range r.users {
|
||||
exist := false
|
||||
for _, excludePlayer := range exclude {
|
||||
if excludePlayer.Id() == user.Id() {
|
||||
exist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exist {
|
||||
r.SendMsg(user, msgId, msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *HundredRoom) NewTimer(timerType timer.ITimeType, duration time.Duration, args ...any) {
|
||||
r.room.NewTimer(timerType, duration, args...)
|
||||
}
|
||||
|
||||
func (r *HundredRoom) CancelTimer(timerType timer.ITimeType) {
|
||||
r.room.CancelTimer(timerType)
|
||||
}
|
||||
|
||||
func (r *HundredRoom) CancelAllTimer() {
|
||||
r.room.CancelAllTimer()
|
||||
}
|
||||
|
||||
func (r *HundredRoom) Log(format string, a ...any) string {
|
||||
return r.room.Log(format, a...)
|
||||
}
|
||||
|
||||
func (r *HundredRoom) UserLog(uid int64, format string, a ...any) string {
|
||||
head := ""
|
||||
user := r.users[uid]
|
||||
if user != nil {
|
||||
head = fmt.Sprintf("room:%v type:%v user:%v robot:%v ", r.Id(), r.RoomType(), uid, user.IsRobot())
|
||||
} else {
|
||||
head = fmt.Sprintf("room:%v type:%v ", r.Id(), r.RoomType())
|
||||
}
|
||||
|
||||
return head + fmt.Sprintf(format, a...)
|
||||
}
|
||||
|
||||
func (r *HundredRoom) Unmarshal(cmd int32, data []byte) (any, error) {
|
||||
return r.room.Unmarshal(cmd, data)
|
||||
}
|
||||
|
||||
func (r *HundredRoom) Dispatch(user IPlayer, cmd int32, params ...any) error {
|
||||
return r.room.Dispatch(user, cmd, params...)
|
||||
}
|
||||
|
||||
func (r *HundredRoom) RegisterMessages(metas processor.RegisterMetas) {
|
||||
r.room.RegisterMessages(metas)
|
||||
}
|
||||
|
||||
// 注册时间事件及处理
|
||||
func (r *HundredRoom) RegisterTimerMessages(metas processor.RegisterTimerMetas) {
|
||||
r.room.RegisterTimerMessages(metas)
|
||||
}
|
||||
|
||||
// 初始化房间
|
||||
func (r *HundredRoom) OnInit() {
|
||||
|
||||
}
|
@ -11,7 +11,7 @@ type IRoom interface {
|
||||
PlayType() int
|
||||
OnInit()
|
||||
// SeatPlayerNum() int
|
||||
// HasEmptySeat() bool
|
||||
// FindEmptySeat() bool
|
||||
// FindPlayer(uid int64) bool
|
||||
Unmarshal(cmd int32, data []byte) (any, error)
|
||||
Dispatch(user IPlayer, cmd int32, params ...any) error
|
||||
@ -30,6 +30,7 @@ type ISeat interface {
|
||||
type IPlayer interface {
|
||||
Id() int64
|
||||
Robot() IRobot
|
||||
IsRobot() bool
|
||||
GateTopicName() string
|
||||
RoomId() int
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package room
|
||||
|
||||
import (
|
||||
"game/common/baseroom"
|
||||
"game/common/proto/pb"
|
||||
"github.com/fox/fox/ipb"
|
||||
)
|
||||
@ -25,17 +24,7 @@ func (rm *ColorRoom) onMatchRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *
|
||||
}
|
||||
|
||||
func (rm *ColorRoom) enterRoom(user *ColorPlayer) {
|
||||
// 第一次进房间分配座位
|
||||
if u, _ := rm.FindPlayer(user.ID); u == nil {
|
||||
var seat *baseroom.BaseSeat
|
||||
if exist, no := rm.HasEmptySeat(); exist {
|
||||
seat = rm.Seats[no]
|
||||
} else {
|
||||
rm.Seats = append(rm.Seats, baseroom.NewBaseSeat(len(rm.Seats)))
|
||||
seat = rm.Seats[len(rm.Seats)-1]
|
||||
}
|
||||
seat.SetPlayer(user)
|
||||
}
|
||||
_ = rm.AddPayer(user)
|
||||
rm.notifyColorRoomInfo(user)
|
||||
}
|
||||
|
||||
@ -62,8 +51,7 @@ func (rm *ColorRoom) checkLeaveRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, re
|
||||
}
|
||||
|
||||
func (rm *ColorRoom) leaveRoom(user *ColorPlayer) {
|
||||
_, st := rm.FindPlayer(user.Id())
|
||||
st.SetPlayer(nil)
|
||||
rm.DelPlayer(user.Id())
|
||||
rm.userMgr.Del(user.ID)
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,10 @@ func (p *ColorPlayer) Robot() baseroom.IRobot {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ColorPlayer) IsRobot() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *ColorPlayer) GateTopicName() string {
|
||||
return p.gateTopicName
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
type ColorRoom struct {
|
||||
*baseroom.BaseRoom[*baseroom.BaseSeat]
|
||||
*baseroom.HundredRoom
|
||||
userMgr *baseroom.PlayerMgr
|
||||
|
||||
roomCfg *game.ColorRoomConfig
|
||||
@ -35,7 +35,7 @@ type ColorRoom struct {
|
||||
func newColorRoom(id, roomType int, srv service.IService, userMgr *baseroom.PlayerMgr) (baseroom.IRoom, pb.ErrCode) {
|
||||
playType := int(pb.ServiceTypeId_STI_ColorGame)
|
||||
rm := &ColorRoom{
|
||||
BaseRoom: nil,
|
||||
HundredRoom: nil,
|
||||
userMgr: userMgr,
|
||||
roomCfg: &game.ColorRoomConfig{},
|
||||
timingCfg: &game.ColorGameTiming{},
|
||||
@ -50,7 +50,7 @@ func newColorRoom(id, roomType int, srv service.IService, userMgr *baseroom.Play
|
||||
rm.resetGameData()
|
||||
|
||||
code := pb.ErrCode_OK
|
||||
rm.BaseRoom, code = baseroom.NewBaseRoom[*baseroom.BaseSeat](id, roomType, playType, srv)
|
||||
rm.HundredRoom, code = baseroom.NewHundredRoom(id, roomType, playType, srv)
|
||||
if code != pb.ErrCode_OK {
|
||||
log.ErrorF("new color room err code:%v", code)
|
||||
return nil, code
|
||||
@ -99,11 +99,10 @@ func (rm *ColorRoom) resetGameData() {
|
||||
rm.initPrizeAreaRange()
|
||||
|
||||
// 清理玩家身上数据
|
||||
for _, st := range rm.Seats {
|
||||
if st.Player() != nil {
|
||||
GetPlayer(st.Player()).resetData()
|
||||
}
|
||||
}
|
||||
rm.RangePlayer(func(u baseroom.IPlayer) bool {
|
||||
GetPlayer(u).resetData()
|
||||
return true
|
||||
})
|
||||
|
||||
// 游戏开始前清理不下注玩家
|
||||
rm.kickoutUsers()
|
||||
|
Loading…
x
Reference in New Issue
Block a user