game_sync/robot/chess/scchesstitians.go

482 lines
17 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()
}