275 lines
7.2 KiB
Go
275 lines
7.2 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
|
|
power string // 谁的权限
|
|
round int32 // 轮数
|
|
operatetimer *timewheel.Task //操作倒计时定时器
|
|
aiTimer *timewheel.Task //AI操作随机做个延时
|
|
}
|
|
|
|
func (this *Room) operateTimeOut(task *timewheel.Task, args ...interface{}) {
|
|
if this.operatetimer != nil {
|
|
timewheel.Remove(this.operatetimer)
|
|
}
|
|
if this.player1.Uid == this.power { // 给玩家2
|
|
this.power = this.player2.Uid
|
|
this.player2.Ps = MaxPs // 恢复体力
|
|
} else { // 权限给1号玩家
|
|
this.power = this.player1.Uid
|
|
this.player1.Ps = MaxPs // 恢复体力
|
|
}
|
|
this.round++ // 回合+1
|
|
|
|
if this.round > MaxRound*2 { // 游戏结束
|
|
this.GameOver()
|
|
}
|
|
this.operatetimer = timewheel.Add(time.Second*MaxTime, this.operateTimeOut) // 开启新的定时器
|
|
var szMap []*pb.MapData
|
|
szMap = append(szMap, &pb.MapData{
|
|
Data: this.chessboard.Plat,
|
|
})
|
|
//this.module.Debugf("超时%d", configure.Now().Unix())
|
|
if err := this.module.SendMsgToSession(string(this.module.GetType()), "operatorrst", &pb.EntertainOperatorRstPush{
|
|
Mpadata: szMap,
|
|
Power: this.power,
|
|
Score: 0,
|
|
Round: this.round,
|
|
User1: this.player1,
|
|
User2: this.player2,
|
|
}, this.szSession...); err != nil {
|
|
this.Errorln(err)
|
|
}
|
|
}
|
|
|
|
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,
|
|
power: s1.GetUserId(),
|
|
round: 1,
|
|
szSession: this.szSession,
|
|
}
|
|
}
|
|
|
|
// AI 操作了
|
|
func (this *Room) AiTimeOut(task *timewheel.Task, args ...interface{}) {
|
|
var (
|
|
curScore int32
|
|
szMap []*pb.MapData
|
|
)
|
|
this.player2.Ps--
|
|
if this.player2.Ps <= 0 { // 权限给下一个人
|
|
this.power = this.player1.Uid
|
|
this.round++
|
|
}
|
|
this.player1.Ps = MaxPs
|
|
if this.aiTimer != nil {
|
|
timewheel.Remove(this.aiTimer)
|
|
}
|
|
|
|
// 交换元素
|
|
bSwap := this.chessboard.AiSwapGirde() // 交换格子
|
|
if !bSwap {
|
|
this.module.Errorf("AiSwapGirde fialed")
|
|
}
|
|
szMap = append(szMap, &pb.MapData{
|
|
Data: this.chessboard.Plat,
|
|
})
|
|
if score, m := this.chessboard.CheckMap(); score > 0 {
|
|
curScore += score
|
|
szMap = append(szMap, m...)
|
|
}
|
|
this.player2.Score += curScore
|
|
|
|
// 清理旧的计时器 开启一个新的
|
|
if this.operatetimer != nil {
|
|
timewheel.Remove(this.operatetimer)
|
|
}
|
|
this.operatetimer = timewheel.Add(time.Second*MaxTime, this.operateTimeOut) // 开启新的定时器
|
|
// 广播消息
|
|
if err := this.module.SendMsgToSession(string(this.module.GetType()), "operatorrst", &pb.EntertainOperatorRstPush{
|
|
Mpadata: szMap,
|
|
Power: this.power,
|
|
Score: curScore,
|
|
Round: this.round,
|
|
User1: this.player1,
|
|
User2: this.player2,
|
|
}, this.szSession...); err != nil {
|
|
this.Errorln(err)
|
|
}
|
|
}
|
|
|
|
func (this *Room) ReceiveMessage(session comm.IUserSession, stype string, msg proto.Message) (errdata *pb.ErrorData) {
|
|
switch stype {
|
|
case "operator": // 操作消息
|
|
var (
|
|
curScore int32
|
|
)
|
|
var szMap []*pb.MapData
|
|
req := msg.(*pb.EntertainOperatorReq)
|
|
|
|
if session.GetUserId() != this.power { // 校验是不是你的权限
|
|
return
|
|
}
|
|
if this.operatetimer != nil {
|
|
timewheel.Remove(this.operatetimer)
|
|
}
|
|
// 交换元素
|
|
this.chessboard.SwapGirde(req.Curid, req.Targetid) // 交换格子
|
|
szMap = append(szMap, &pb.MapData{
|
|
Data: this.chessboard.Plat,
|
|
})
|
|
if score, m := this.chessboard.CheckMap(); score > 0 {
|
|
curScore += score
|
|
szMap = append(szMap, m...)
|
|
}
|
|
//this.player2.Score += curScore
|
|
// 开启新的定时器
|
|
if this.operatetimer != nil {
|
|
timewheel.Remove(this.operatetimer)
|
|
}
|
|
this.operatetimer = timewheel.Add(time.Second*MaxTime, this.operateTimeOut) // 开启新的定时器
|
|
|
|
if this.power == this.player1.Uid { //权限校验
|
|
this.player1.Score += curScore
|
|
this.player1.Ps--
|
|
if this.player1.Ps <= 0 { // 权限给下一个人
|
|
this.power = this.player2.Uid
|
|
|
|
if len(this.szSession) == 1 { // 校验2号玩家是不是AI
|
|
// 起一个定时器
|
|
if this.aiTimer != nil {
|
|
timewheel.Remove(this.aiTimer)
|
|
}
|
|
this.aiTimer = timewheel.Add(time.Second*AITime, this.AiTimeOut)
|
|
}
|
|
this.round++
|
|
}
|
|
this.player2.Ps = MaxPs
|
|
} else if this.power == this.player2.Uid {
|
|
this.player2.Score += curScore
|
|
this.player2.Ps--
|
|
if this.player2.Ps <= 0 { // 权限给下一个人
|
|
this.power = this.player1.Uid
|
|
this.round++
|
|
}
|
|
this.player1.Ps = MaxPs
|
|
} else { // err 未知权限
|
|
return
|
|
}
|
|
|
|
// 广播消息
|
|
if err := this.module.SendMsgToSession(string(this.module.GetType()), "operatorrst", &pb.EntertainOperatorRstPush{
|
|
Mpadata: szMap,
|
|
Power: this.power,
|
|
Score: curScore,
|
|
Round: this.round,
|
|
User1: this.player1,
|
|
User2: this.player2,
|
|
}, this.szSession...); err != nil {
|
|
this.Errorln(err)
|
|
}
|
|
case "ready":
|
|
if len(this.szSession) == 1 { // AI对战的话直接开始游戏
|
|
if err := this.module.SendMsgToSession(string(this.module.GetType()), "startgame", &pb.EntertainStartGamePush{
|
|
User1: this.player1,
|
|
User2: this.player2,
|
|
Mpadata: &pb.MapData{
|
|
Data: this.chessboard.Plat,
|
|
},
|
|
Power: this.power,
|
|
Round: this.round,
|
|
}, session); err != nil {
|
|
this.Errorln(err)
|
|
}
|
|
|
|
this.operatetimer = timewheel.Add(time.Second*MaxTime, this.operateTimeOut)
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 玩家操作
|
|
func (this *Room) Opertor(uid string, iType int32, old int32, new int32) (errdata *pb.ErrorData) {
|
|
if iType == 1 {
|
|
this.chessboard.SwapGirde(old, new) // 交换格子
|
|
}
|
|
return
|
|
}
|
|
|
|
func (this *Room) StartGame() (errdata *pb.ErrorData) {
|
|
|
|
if err := this.module.SendMsgToSession(string(this.module.GetType()), "startgame", &pb.EntertainStartGamePush{
|
|
User1: this.player1,
|
|
User2: this.player2,
|
|
Mpadata: &pb.MapData{
|
|
Data: this.chessboard.Plat,
|
|
},
|
|
Power: this.power,
|
|
Round: this.round,
|
|
}, this.szSession...); err != nil {
|
|
this.Errorln(err)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 游戏结束
|
|
func (this *Room) GameOver() (errdata *pb.ErrorData) {
|
|
if this.aiTimer != nil {
|
|
timewheel.Remove(this.aiTimer)
|
|
}
|
|
if this.operatetimer != nil {
|
|
timewheel.Remove(this.operatetimer)
|
|
}
|
|
this.module.SendMsgToSession(string(this.module.GetType()), "gameover", &pb.EntertainGameOverPush{
|
|
User1: this.player1,
|
|
User2: this.player2,
|
|
Mpadata: &pb.MapData{
|
|
Data: this.chessboard.Plat,
|
|
},
|
|
Power: "",
|
|
Round: this.round,
|
|
})
|
|
return
|
|
}
|