package chess import ( "math/rand" "time" "mongo.games.com/goserver/core/basic" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/core/task" "mongo.games.com/goserver/core/timer" rule "mongo.games.com/game/gamerule/chess" "mongo.games.com/game/proto" proto_chesstitians "mongo.games.com/game/protocol/chesstitians" "mongo.games.com/game/robot/base" ) type SCChesstitiansRoomInfoPacketFactory struct { } type SCChesstitiansRoomInfoHandler struct { } func (this *SCChesstitiansRoomInfoPacketFactory) CreatePacket() interface{} { pack := &proto_chesstitians.SCChesstitiansRoomInfo{} return pack } func (this *SCChesstitiansRoomInfoHandler) Process(s *netlib.Session, packid int, pack interface{}) error { logger.Logger.Tracef("(this *SCChesstitiansRoomInfoHandler) Process [%v].", s.GetSessionConfig().Id) if msg, ok := pack.(*proto_chesstitians.SCChesstitiansRoomInfo); ok { scene := base.SceneMgrSingleton.GetScene(msg.GetRoomId()) if scene == nil { scene = NewChesstitiansScene(msg) base.SceneMgrSingleton.AddScene(scene) } if scene != nil { for _, pd := range msg.GetPlayers() { if scene.GetPlayerBySnid(pd.GetSnId()) == nil { p := NewChesstitiansPlayer(pd) if p != nil { scene.AddPlayer(p) } } } //logger.Logger.Infof("(this *SCChesstitiansRoomInfoHandler) SetAttribute(base.SessionAttributeSceneId) %v %v", scene.GetRoomId(), msg) operateTask(s, 3) } } else { logger.Logger.Error("SCChesstitiansRoomInfo package data error.") } return nil } type SCChesstitiansPlayerOpPacketFactory struct { } type SCChesstitiansPlayerOpHandler struct { } func (this *SCChesstitiansPlayerOpPacketFactory) CreatePacket() interface{} { pack := &proto_chesstitians.SCChesstitiansPlayerOp{} return pack } func (this *SCChesstitiansPlayerOpHandler) Process(s *netlib.Session, packid int, pack interface{}) error { logger.Logger.Tracef("(this *SCChesstitiansPlayerOpHandler) Process [%v].", s.GetSessionConfig().Id) if scChesstitiansOp, ok := pack.(*proto_chesstitians.SCChesstitiansPlayerOp); ok { if scene, ok := base.GetScene(s).(*ChesstitiansScene); ok { player := scene.GetMe(s) if player == base.NilPlayer { //logger.Logger.Errorf("(this *SCChesstitiansPlayerOpHandler) nilPlayer") return nil } me, ok2 := player.(*ChesstitiansPlayer) //logger.Logger.Infof("(this *SCChesstitiansPlayerOpHandler) player ok:%v me:%v", ok2, me) if ok2 && me != ChesstitiansNilPlayer { //logger.Logger.Tracef("SCChesstitiansPlayerOpHandler msg:%v", scChesstitiansOp) isMeOp := me.GetSnId() == scChesstitiansOp.GetSnId() if isMeOp { if int(scChesstitiansOp.GetOpRetCode()) == 0 { switch scChesstitiansOp.GetOpCode() { case rule.PlayerOpPlay: } } else { //操作失败 logger.Logger.Infof("TODO: 如果操作失败,应改为操作") switch scChesstitiansOp.GetOpCode() { case rule.PlayerOpPlay: // ai请求失败,随便走一步 AiRandom(s) } } } if scChesstitiansOp.GetOpCode() == rule.PlayerOpPlay && scChesstitiansOp.GetOpRetCode() == 0 { param := scChesstitiansOp.GetOpParam() //scene.chess.PlayOp(int(param[0]), int(param[1])) //scene.chess.NextAct() scene.PlayOp(int(param[0]), int(param[1])) } if !isMeOp { //todo 对方求和,机器人暂时都同意求和 // 机器人模拟真人,求和,认输,悔棋等操作 switch scChesstitiansOp.GetOpCode() { case rule.PlayerOpDraw: pack := &proto_chesstitians.SCChesstitiansPlayerOp{ OpCode: proto.Int32(rule.PlayerOpPlay), } if rand.Int31n(100) < 80 { pack.OpParam = []int64{rule.RefuseDraw} } else { pack.OpParam = []int64{rule.AgreeDraw} } base.DelaySendSecond(s, int(proto_chesstitians.ChesstitiansPacketID_PACKET_CSChesstitiansPlayerOp), pack, []int{2, 5}...) } operateTask(s, 3) } } else { logger.Logger.Errorf("(this *SCChesstitiansPlayerOpHandler) nilPlayer") } } else { logger.Logger.Error("SCChesstitiansPlayerOp base.GetScene(s).(*ChesstitiansScene) error") } } else { logger.Logger.Error("SCChesstitiansPlayerOp package data error.") } return nil } type SCChesstitiansRoomStatePacketFactory struct { } type SCChesstitiansRoomStateHandler struct { } func (this *SCChesstitiansRoomStatePacketFactory) CreatePacket() interface{} { pack := &proto_chesstitians.SCChesstitiansRoomState{} return pack } func (this *SCChesstitiansRoomStateHandler) Process(s *netlib.Session, packid int, pack interface{}) error { logger.Logger.Infof("(this *SCChesstitiansRoomStateHandler) Process [%v].", s.GetSessionConfig().Id) if scChesstitiansRoomState, ok := pack.(*proto_chesstitians.SCChesstitiansRoomState); ok { //logger.Logger.Infof("(this *SCChesstitiansRoomStateHandler) base.GetScene(s).(*ChesstitiansScene)") if scene, ok := base.GetScene(s).(*ChesstitiansScene); ok { scene.State = scChesstitiansRoomState.State p := scene.GetMe(s) me, ok := p.(*ChesstitiansPlayer) //logger.Logger.Infof("(this *SCChesstitiansRoomStateHandler) get player snId:%v ok:%v me:%v", p.GetSnId(), ok, me) if ok && me != ChesstitiansNilPlayer { //logger.Logger.Infof("(this *SCChesstitiansRoomStateHandler) to roomState state:%v", scChesstitiansRoomState.GetState()) switch scChesstitiansRoomState.GetState() { case int32(rule.SceneStateWaitPlayer): scene.Clear() case int32(rule.SceneStateWaitStart): //等待开始 scene.Clear() if me.GetSnId() == scene.GetMasterSnid() { packOp := &proto_chesstitians.CSChesstitiansPlayerOp{ OpCode: proto.Int32(3), } proto.SetDefaults(packOp) //if scene.GetIsAllAi() { // base.DelayAISend(s, int(proto_chesstitians.ChesstitiansPacketID_PACKET_CSChesstitiansPlayerOp), packOp) //} else { // base.DelaySendSecond(s, int(proto_chesstitians.ChesstitiansPacketID_PACKET_CSChesstitiansPlayerOp), packOp, []int{3, 7}...) //} base.DelaySendSecond(s, int(proto_chesstitians.ChesstitiansPacketID_PACKET_CSChesstitiansPlayerOp), packOp, []int{2, 5}...) } case int32(rule.SceneStatePlayerOp): logger.Logger.Infof("检查是否机器人先开始 %d", scene.CurOpIdx) operateTask(s, 3) case int32(rule.SceneStateBilled): scene.Clear() me.Clear() } } else { logger.Logger.Errorf("(this *SCChesstitiansRoomStateHandler) get player snId:%v", me.GetSnId()) } } else { logger.Logger.Errorf("(this *SCChesstitiansRoomStateHandler) base.GetScene(s).(*ChesstitiansScene)") } } else { logger.Logger.Error("SCChesstitiansRoomState package data error.") } return nil } func operateTask(s *netlib.Session, times int) { logger.Logger.Info("@@CallableWrapper") var array []int64 var code int if s == nil { return } scene, ok := base.GetScene(s).(*ChesstitiansScene) if !ok { return } p := scene.GetMe(s) me, ok := p.(*ChesstitiansPlayer) if !ok || me == ChesstitiansNilPlayer || me == nil { return } if scene.State != int32(rule.SceneStatePlayerOp) { return } if me.IsBlack == 1 && scene.GetAct() == "b" || me.IsBlack != 1 && scene.GetAct() == "w" { // 轮到当前行棋方 chess := scene.chess fen := chess.GenFen() logger.Logger.Infof("fen: %s", fen) skillLevel := 20 switch scene.SceneType { case 1: skillLevel = -6 case 2: skillLevel = -3 case 3: skillLevel = 0 case 4: skillLevel = 3 case 5: skillLevel = 6 } var resp StockfishResp task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { if scene.GetVariant() == int32(rule.ChessVarChess) { resp = UCIPost(fen, 500) } else if scene.GetVariant() == int32(rule.ChessVarMakruk) { resp = MakrukPost(fen, 500) } else if scene.GetVariant() == int32(rule.ChessVarCambodian) { resp = CambodianPost(fen, 500, skillLevel) } return nil }), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) { if resp.Error == 0 && len(resp.Bestmove) >= 4 { array = chess.UciTwoPosToIdxList(resp.Bestmove) logger.Logger.Infof("fen: %v, Bestmove: %v, Ponder: %v", fen, resp.Bestmove, resp.Ponder) packOp := &proto_chesstitians.SCChesstitiansPlayerOp{ OpCode: proto.Int32(rule.PlayerOpPlay), OpParam: array, } base.DelaySendSecond(s, int(proto_chesstitians.ChesstitiansPacketID_PACKET_CSChesstitiansPlayerOp), packOp, []int{1, 2}...) //logger.Logger.Infof("CSChesstitiansPlayerOp %v", packOp.String()) } else { logger.Logger.Errorf("AI错误 %v", code) if times > 0 { timer.StartTimer(timer.TimerActionWrapper(func(h timer.TimerHandle, ud interface{}) bool { operateTask(s, times-1) return true }), nil, time.Second*5, 1) } else { // ai请求失败,随便走一步 AiRandom(s) } } }), "UCI_Action").Start() } } type SCChesstitiansGameBilledPacketFactory struct { } type SCChesstitiansGameBilledHandler struct { } func (this *SCChesstitiansGameBilledPacketFactory) CreatePacket() interface{} { pack := &proto_chesstitians.SCChesstitiansGameBilled{} return pack } func (this *SCChesstitiansGameBilledHandler) Process(s *netlib.Session, packid int, pack interface{}) error { logger.Logger.Tracef("(this *SCChesstitiansGameBilledHandler) Process [%v].", s.GetSessionConfig().Id) if scChesstitiansBilled, ok := pack.(*proto_chesstitians.SCChesstitiansGameBilled); ok { if scene, ok := base.GetScene(s).(*ChesstitiansScene); ok { //logger.Logger.Trace(scChesstitiansBilled) billData := scChesstitiansBilled.GetDatas() for _, data := range billData { p := scene.GetMe(s) if p == base.NilPlayer { continue } if me, ok2 := p.(*ChesstitiansPlayer); ok2 && me != ChesstitiansNilPlayer { if data.GetSnId() == me.GetSnId() { //自己的数据 me.Coin = proto.Int64(data.GetGameCoin()) me.IsWin = data.GetIsWin() me.ChessGrade = int64(data.Score) me.WinTimes = data.WinTimes me.WinScore = data.WinScore me.OtherScore = data.OtherScore me.NextRank = data.NextRank me.WinCoin = data.WinCoin } } } } } else { logger.Logger.Error("SCChesstitiansGameBilled package data error.") } return nil } type SCChesstitiansCardPacketFactory struct { } type SCChesstitiansCardHandler struct { } func (this *SCChesstitiansCardPacketFactory) CreatePacket() interface{} { pack := &proto_chesstitians.SCChesstitiansCard{} return pack } func (this *SCChesstitiansCardHandler) Process(s *netlib.Session, packid int, pack interface{}) error { logger.Logger.Tracef("(this *SCChesstitiansCardHandler) Process [%v].", s.GetSessionConfig().Id) if scChesstitiansCard, ok := pack.(*proto_chesstitians.SCChesstitiansCard); ok { if scene, ok := base.GetScene(s).(*ChesstitiansScene); ok { scene.Chess = scChesstitiansCard.GetChess() scene.Act = scChesstitiansCard.GetAct() scene.Castling = scChesstitiansCard.GetCastling() scene.Enpassant = scChesstitiansCard.GetEnpassant() scene.ChessRound = scChesstitiansCard.GetChessRound() cards := scChesstitiansCard.GetCards() p := scene.GetMe(s) if me, ok2 := p.(*ChesstitiansPlayer); ok2 && me != ChesstitiansNilPlayer { if scene.GetState() == int32(rule.SceneStateChessInit) { op := scene.GetOp(s).(*ChesstitiansPlayer) // TODO: if cards[0] == 1 { me.IsBlack = 1 op.IsBlack = 0 } else { me.IsBlack = 0 op.IsBlack = 1 } scene.makeChessStruct(scene.chess) } } } } else { logger.Logger.Error("SCChesstitiansCardHandler package SCChesstitiansCard error.") } return nil } type SCChesstitiansUpdateMasterSnidPacketFactory struct { } type SCChesstitiansUpdateMasterSnidHandler struct { } func (this *SCChesstitiansUpdateMasterSnidPacketFactory) CreatePacket() interface{} { pack := &proto_chesstitians.SCChesstitiansUpdateMasterSnid{} return pack } func (this *SCChesstitiansUpdateMasterSnidHandler) Process(s *netlib.Session, packid int, pack interface{}) error { logger.Logger.Tracef("(this *SCChesstitiansUpdateMasterSnidHandler) Process [%v].", s.GetSessionConfig().Id) if scChesstitiansUpdateMasterSnid, ok := pack.(*proto_chesstitians.SCChesstitiansUpdateMasterSnid); ok { if scene, ok := base.GetScene(s).(*ChesstitiansScene); ok { masterSnid := scChesstitiansUpdateMasterSnid.GetMasterSnid() scene.MasterSnid = masterSnid //更新房主 } } else { logger.Logger.Error("SCChesstitiansUpdateMasterSnidHandler package SCChesstitiansUpdateMasterSnid error.") } return nil } // 玩家进入 type SCChesstitiansPlayerEnterFactory struct { } func (this *SCChesstitiansPlayerEnterFactory) CreatePacket() interface{} { pack := &proto_chesstitians.SCChesstitiansPlayerEnter{} return pack } type SCChesstitiansPlayerEnterHandler struct { } func (this *SCChesstitiansPlayerEnterHandler) Process(s *netlib.Session, packid int, pack interface{}) error { msg, ok := pack.(*proto_chesstitians.SCChesstitiansPlayerEnter) if !ok { logger.Logger.Error("SCChesstitiansPlayerEnterHandler error") return nil } logger.Logger.Trace("Recover SCChesstitiansPlayerEnterHandler ", msg.String()) scene, ok := base.GetScene(s).(*ChesstitiansScene) if !ok { return nil } if scene == nil { return nil } if player := NewChesstitiansPlayer(msg.GetData()); player != nil { scene.AddPlayer(player) } return nil } // 玩家离开 type SCChesstitiansPlayerLeaveFactory struct { } func (this *SCChesstitiansPlayerLeaveFactory) CreatePacket() interface{} { pack := &proto_chesstitians.SCChesstitiansPlayerLeave{} return pack } type SCChesstitiansPlayerLeaveHandler struct { } func (this *SCChesstitiansPlayerLeaveHandler) Process(s *netlib.Session, packid int, pack interface{}) error { msg, ok := pack.(*proto_chesstitians.SCChesstitiansPlayerLeave) if !ok { logger.Logger.Error("SCChesstitiansPlayerLeaveHandler error") return nil } logger.Logger.Trace("Recover SCChesstitiansPlayerLeaveHandler ", msg.String()) scene, ok := base.GetScene(s).(*ChesstitiansScene) if !ok { return nil } if scene == nil { return nil } if player, ok := scene.GetPlayerByPos(msg.GetPos()).(*ChesstitiansPlayer); ok && player != nil { scene.DelPlayer(player.GetSnId()) } return nil } func init() { //SCChesstitiansRoomInfo netlib.RegisterHandler(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomInfo), &SCChesstitiansRoomInfoHandler{}) netlib.RegisterFactory(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomInfo), &SCChesstitiansRoomInfoPacketFactory{}) //SCChesstitiansPlayerOp netlib.RegisterHandler(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansPlayerOp), &SCChesstitiansPlayerOpHandler{}) netlib.RegisterFactory(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansPlayerOp), &SCChesstitiansPlayerOpPacketFactory{}) //SCChesstitiansRoomState netlib.RegisterHandler(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomState), &SCChesstitiansRoomStateHandler{}) netlib.RegisterFactory(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomState), &SCChesstitiansRoomStatePacketFactory{}) //SCChesstitiansFinalBilled netlib.RegisterHandler(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansGameBilled), &SCChesstitiansGameBilledHandler{}) netlib.RegisterFactory(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansGameBilled), &SCChesstitiansGameBilledPacketFactory{}) //SCChesstitiansCard netlib.RegisterHandler(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansCard), &SCChesstitiansCardHandler{}) netlib.RegisterFactory(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansCard), &SCChesstitiansCardPacketFactory{}) //SCChesstitiansUpdateMasterSnid netlib.RegisterHandler(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansUpdateMasterSnid), &SCChesstitiansUpdateMasterSnidHandler{}) netlib.RegisterFactory(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansUpdateMasterSnid), &SCChesstitiansUpdateMasterSnidPacketFactory{}) //ChesstitiansPacketID_PACKET_SCChesstitiansPlayerEnter netlib.RegisterHandler(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansPlayerEnter), &SCChesstitiansPlayerEnterHandler{}) netlib.RegisterFactory(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansPlayerEnter), &SCChesstitiansPlayerEnterFactory{}) //ChesstitiansPacketID_PACKET_SCChesstitiansPlayerLeave netlib.RegisterHandler(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansPlayerLeave), &SCChesstitiansPlayerLeaveHandler{}) netlib.RegisterFactory(int(proto_chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansPlayerLeave), &SCChesstitiansPlayerLeaveFactory{}) ////Testjson() //task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { // logger.Logger.Info("@@CallableWrapper") // stockfishResp := UCIPost("fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", 500) // logger.Logger.Infof("stockfishResp %v", stockfishResp) // return nil //}), nil, "UCIPost_Action").Start() }