go_dreamfactory/modules/entertainment/room.go
2023-10-23 19:49:13 +08:00

292 lines
7.7 KiB
Go

package entertainment
import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/sys/timewheel"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
"google.golang.org/protobuf/proto"
)
const (
MaxPs = 2 // 最大体力
MaxRound = 7 // 最大回合数
MaxTime = 1800 // 游戏操作时间
// AITime = 4 // AI延迟操作时间操作时间 随机+-3
)
//游戏房间
type Room struct {
modules.ModuleBase
Id string // 房间id
szSession []comm.IUserSession
player1 *pb.PlayerData // 玩家1
player2 *pb.PlayerData // 玩家2
chessboard *MapData
module *Entertainment
round int32 // 轮数
operatetimer *timewheel.Task //操作倒计时定时器
//aiTimer *timewheel.Task //AI操作随机做个延时
curPower string // 当前操作的玩家
NexPower string // 下一个操作的玩家
}
func (this *Room) operateTimeOut(task *timewheel.Task, args ...interface{}) {
if this.player1.Uid == this.curPower { // 给玩家2
this.player1.Ps--
if this.player1.Ps <= 0 { // 体力消耗完权限给下一个人
this.NexPower = this.player2.Uid
this.player2.Ps = MaxPs // 恢复体力
}
} else { // 权限给1号玩家
this.player2.Ps--
if this.player2.Ps <= 0 {
this.curPower = this.player1.Uid
this.player1.Ps = MaxPs // 恢复体力
}
}
if this.curPower != this.NexPower { // 变更权限的适合
this.round++
if this.operatetimer != nil {
timewheel.Remove(this.operatetimer)
} // 回合+1
this.operatetimer = timewheel.Add(time.Second*MaxTime, this.operateTimeOut) // 开启新的定时器
}
var szMap []*pb.MapData
szMap = append(szMap, &pb.MapData{
Data: this.chessboard.Plat,
})
if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "operatorrst", &pb.EntertainOperatorRstPush{
Mpadata: szMap,
Power: this.NexPower,
Curpower: this.curPower,
Score: 0,
Round: this.round,
User1: this.player1,
User2: this.player2,
Itype: 0,
Curid: 0,
Targetid: 0,
}, this.szSession...); err != nil {
this.Errorln(err)
}
// 变更权限
this.curPower = this.NexPower
if this.round > MaxRound { // 游戏结束
this.GameOver()
return
}
}
func (this *Room) InitRoom(module *Entertainment, s1 comm.IUserSession, s2 comm.IUserSession, p1 *pb.PlayerData, p2 *pb.PlayerData) *Room {
this.chessboard = new(MapData)
this.chessboard.InitMap(module) // 初始化棋盘
this.szSession = append(this.szSession, s1.Clone())
if p2.Uid != "999" { // 是否是机器人
this.szSession = append(this.szSession, s2.Clone())
}
return &Room{
ModuleBase: modules.ModuleBase{},
Id: primitive.NewObjectID().Hex(),
player1: p1,
player2: p2,
chessboard: this.chessboard,
module: module,
curPower: s1.GetUserId(),
round: 1,
szSession: this.szSession,
}
}
// AI 操作了
func (this *Room) AiOperator() {
var (
curScore int32
szMap []*pb.MapData
oid1 int32
oid2 int32
)
this.module.Debugf("AI 操作\n")
this.player2.Ps--
if this.player2.Ps <= 0 { // 权限给下一个人
this.NexPower = this.player1.Uid
}
this.player1.Ps = MaxPs
// 交换元素
_, szMap, oid1, oid2 = this.chessboard.AiSwapGirde()
if this.NexPower != this.curPower {
this.round++
}
this.player2.Score += curScore
// 广播消息
if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "operatorrst", &pb.EntertainOperatorRstPush{
Mpadata: szMap,
Power: this.NexPower,
Curpower: this.curPower,
Score: curScore,
Round: this.round,
User1: this.player1,
User2: this.player2,
Itype: 0,
Curid: oid1,
Targetid: oid2,
}, this.szSession...); err != nil {
this.Errorln(err)
}
if this.round > MaxRound { // 游戏结束
this.GameOver()
return
}
this.curPower = this.NexPower
if len(this.szSession) == 1 && this.curPower == this.player2.Uid {
this.AiOperator()
}
}
func (this *Room) ReceiveMessage(session comm.IUserSession, stype string, msg proto.Message) (errdata *pb.ErrorData) {
switch stype {
case "operator": // 操作消息
var (
curScore int32
AIOperator bool
oid1 int32 // 唯一id
oid2 int32
)
var szMap []*pb.MapData
req := msg.(*pb.EntertainOperatorReq)
if session.GetUserId() != this.curPower { // 校验是不是你的权限
errdata = &pb.ErrorData{
Code: pb.ErrorCode_EntertainNoPower,
Title: pb.ErrorCode_EntertainNoPower.ToString(),
}
return
}
oid1 = this.chessboard.Plat[req.Curid].Oid
oid2 = this.chessboard.Plat[req.Targetid].Oid
// 交换元素
if b := this.chessboard.SwapGirde(req.Curid, req.Targetid); !b { // 交换格子
errdata = &pb.ErrorData{
Code: pb.ErrorCode_EntertainCantSwap, // 不能交换 直接返回
Title: pb.ErrorCode_EntertainCantSwap.ToString(),
}
return
}
if score, m, _ := this.chessboard.CheckMap(1); score > 0 {
curScore += score
szMap = append(szMap, m...)
} else { // 不能消除
this.chessboard.SwapGirde(req.Targetid, req.Curid) // 换到原来的位置
errdata = &pb.ErrorData{
Code: pb.ErrorCode_EntertainCantSwap, // 不能交换 直接返回
Title: pb.ErrorCode_EntertainCantSwap.ToString(),
}
return
}
if this.curPower == this.player1.Uid { //权限校验
this.player1.Score += curScore
this.player1.Ps--
if this.player1.Ps <= 0 { // 权限给下一个人
this.NexPower = this.player2.Uid
if len(this.szSession) == 1 { // 校验2号玩家是不是AI
AIOperator = true
}
}
this.player2.Ps = MaxPs
} else if this.curPower == this.player2.Uid {
this.player2.Score += curScore
this.player2.Ps--
if this.player2.Ps <= 0 { // 权限给下一个人
this.NexPower = this.player1.Uid
}
this.player1.Ps = MaxPs
} else { // err 未知权限
return
}
if this.NexPower != this.curPower {
this.round++
if this.operatetimer != nil {
timewheel.Remove(this.operatetimer)
this.operatetimer = timewheel.Add(time.Second*MaxTime, this.operateTimeOut) // 开启新的定时器
}
}
// 广播消息
if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "operatorrst", &pb.EntertainOperatorRstPush{
Mpadata: szMap,
Power: this.NexPower,
Curpower: this.curPower,
Score: curScore,
Round: this.round,
User1: this.player1,
User2: this.player2,
Itype: req.Itype,
Curid: oid1,
Targetid: oid2,
}, this.szSession...); err != nil {
this.Errorln(err)
}
if this.round > MaxRound { // 游戏结束
this.GameOver()
return
}
// 变更权限
this.curPower = this.NexPower
if AIOperator { // AI操作
this.AiOperator()
}
case "ready":
if len(this.szSession) == 1 { // AI对战的话直接开始游戏
this.NexPower = this.player1.Uid
this.curPower = this.player1.Uid
this.player1.Ps = MaxPs
this.player2.Ps = MaxPs
if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "startgame", &pb.EntertainStartGamePush{
User1: this.player1,
User2: this.player2,
Mpadata: &pb.MapData{Data: this.chessboard.Plat},
Power: this.NexPower,
Round: this.round,
Roomid: "",
}, this.szSession...); err != nil {
this.Errorln(err)
}
this.operatetimer = timewheel.Add(time.Second*MaxTime, this.operateTimeOut)
}
}
return
}
// 游戏结束
func (this *Room) GameOver() (errdata *pb.ErrorData) {
if this.operatetimer != nil {
timewheel.Remove(this.operatetimer)
}
this.module.SendMsgSyncToSession(string(this.module.GetType()), "gameover", &pb.EntertainGameOverPush{
User1: this.player1,
User2: this.player2,
Mpadata: &pb.MapData{
Data: this.chessboard.Plat,
},
Power: "", // 清理权限
Round: this.round,
}, this.szSession...)
return
}