package entertainment import ( "fmt" "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 // 游戏操作时间 ) //游戏房间 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 //操作倒计时定时器 curPower string // 当前操作的玩家 NexPower string // 下一个操作的玩家 MaxRound int32 rd1 bool rd2 bool } 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 > this.MaxRound { // 游戏结束 this.GameOver() return } } func (this *Room) InitRoom(module *Entertainment, p1 *pb.PlayerData, p2 *pb.PlayerData) *Room { var room *Room this.module = module this.chessboard = new(MapData) this.chessboard.InitMap(module) // 初始化棋盘 if s1, ok := this.module.GetUserSession(p1.Uid); !ok { this.module.PutUserSession(s1) } else { this.szSession = append(this.szSession, s1.Clone()) } if p2.Uid != "999" { // 是否是机器人 if s2, ok := this.module.GetUserSession(p2.Uid); !ok { this.module.PutUserSession(s2) } else { this.szSession = append(this.szSession, s2.Clone()) } } this.MaxRound = module.ModuleTools.GetGlobalConf().ConsumeRounds room = &Room{ ModuleBase: modules.ModuleBase{}, Id: primitive.NewObjectID().Hex(), szSession: this.szSession, player1: p1, player2: p2, chessboard: this.chessboard, module: module, round: 1, MaxRound: this.MaxRound, } if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "enterroom", &pb.EntertainEnterRoomPush{ Rooid: room.Id, Servepath: fmt.Sprintf("%s/%s", this.module.service.GetType(), this.module.service.GetId()), User1: room.player1, User2: room.player2, }, this.szSession...); err != nil { this.Errorln(err) } return room } // AI 操作了 func (this *Room) AiOperator() { var ( curScore int32 szMap []*pb.MapData bAddPs bool oid1 int32 oid2 int32 ) this.player2.Ps-- if this.player2.Ps <= 0 { // 权限给下一个人 this.NexPower = this.player1.Uid } this.player1.Ps = MaxPs // 交换元素 szMap, oid1, oid2, bAddPs = this.chessboard.AiSwapGirde() if this.NexPower != this.curPower { this.round++ } for _, v := range szMap { // //if v.CurEnergy > 0 { this.player2.Energy += v.CurEnergy v.CurEnergy = this.player2.Energy //} curScore += v.CurSocre this.player2.Score += v.CurSocre v.CurSocre = this.player2.Score } if bAddPs { this.player2.Ps++ if this.player2.Ps > MaxPs { this.player2.Ps = MaxPs } } 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 > this.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 color int32 // 校验消除的颜色 bAddPs bool ) 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 } if this.curPower == this.player1.Uid { color = 1 } else { color = 2 } if req.Itype == 1 { //释放技能 // 能量校验 if color == 1 { // 玩家1 放技能 conf, err := this.module.configure.GetGameConsumeHero(this.player1.Cardid) if err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoHeroSkill, Title: pb.ErrorCode_EntertainNoHeroSkill.ToString(), } return } if this.player1.Energy >= conf.Skillload { this.player1.Energy = 0 // 清零 if m := this.chessboard.SkillUp(conf.Skilleffect, conf.Skillvalue); len(m) > 0 { szMap = append(szMap, m...) } else { szMap = append(szMap, &pb.MapData{ Data: this.chessboard.GetPalatData(), }) } for _, v := range szMap { curScore += v.CurSocre this.player1.Score += v.CurSocre v.CurSocre = this.player1.Score } } else { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoEnergy, Title: pb.ErrorCode_EntertainNoEnergy.ToString(), } return } this.NexPower = this.curPower } else { conf, err := this.module.configure.GetGameConsumeHero(this.player2.Cardid) if err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoHeroSkill, Title: pb.ErrorCode_EntertainNoHeroSkill.ToString(), } return } if this.player2.Energy >= conf.Skillload { this.player2.Energy = 0 // 清零 if m := this.chessboard.SkillUp(conf.Skilleffect, conf.Skillvalue); len(m) > 0 { szMap = append(szMap, m...) } else { szMap = append(szMap, &pb.MapData{ Data: this.chessboard.GetPalatData(), }) } for _, v := range szMap { curScore += v.CurSocre this.player2.Score += v.CurSocre v.CurSocre = this.player2.Score } } else { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoEnergy, Title: pb.ErrorCode_EntertainNoEnergy.ToString(), } return } this.NexPower = this.curPower } 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) } 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 m, b := this.chessboard.CheckMap(color, true); len(m) > 0 { // curScore += score szMap = append(szMap, m...) bAddPs = b } 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 bAddPs { this.player1.Ps++ if this.player1.Ps > MaxPs { this.player1.Ps = MaxPs } } this.player2.Ps = MaxPs } else { // this.curPower == this.player2.Uid this.player2.Score += curScore this.player2.Ps-- if bAddPs { this.player2.Ps++ if this.player2.Ps > MaxPs { this.player2.Ps = MaxPs } } this.player1.Ps = MaxPs } for _, v := range szMap { // curScore += v.CurSocre if color == 1 { this.player1.Score += v.CurSocre v.CurSocre = this.player1.Score //if v.CurEnergy > 0 { this.player1.Energy += v.CurEnergy v.CurEnergy = this.player1.Energy //} } else { this.player2.Score += v.CurSocre v.CurSocre = this.player2.Score //if v.CurEnergy > 0 { this.player2.Energy += v.CurEnergy v.CurEnergy = this.player2.Energy //} } } if this.player1.Ps <= 0 { // 权限给下一个人 this.NexPower = this.player2.Uid if len(this.szSession) == 1 { // 校验2号玩家是不是AI AIOperator = true } } if this.player2.Ps <= 0 { // 权限给下一个人 this.NexPower = this.player1.Uid } 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 > this.MaxRound && this.NexPower == this.player1.Uid { // 游戏结束 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.Id, // 房间ID }, this.szSession...); err != nil { this.Errorln(err) } this.operatetimer = timewheel.Add(time.Second*MaxTime, this.operateTimeOut) } else { if this.player1.Uid == session.GetUserId() { this.rd1 = true } else if this.player2.Uid == session.GetUserId() { this.rd2 = true } if this.rd1 && this.rd2 { // 两个玩家都准备好了 那么就开始游戏 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.Id, }, 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 }