package room import ( "math/rand" "samba/pkg/log" "samba/proto" "samba/server/game/baseroom" "samba/server/truco/poker" "samba/stub" "samba/util/model" "samba/util/util" "time" ) // RobotAplomb 稳定型机器人 type RobotAplomb struct { *BaseRobot } func NewRobotAplomb(cnf stub.RobotTemper, userInfo *model.UserInfo, seat *TrucoSeat, room *TrucoRoom) *RobotAplomb { return &RobotAplomb{ BaseRobot: NewBaseRobot(cnf, userInfo, seat, room), } } func (r *RobotAplomb) OnMessage(msgId string, iMsg interface{}) { switch msgId { case proto.RspEnterRoomId: r.NewTimer(baseroom.TtEnterRoom, time.Second*time.Duration(RobotOnMsgTime), func() { r.sendReady(r.room) }) case proto.NtfDealPokersId: r.sortPokers() msg := iMsg.(*proto.NtfDealPokers) if util.RandHappened(50) { break } r.NewSecretEmoteTimer(time.Second*time.Duration(rand.Int()%2+RobotOnMsgTime+3), func() { r.sendSecretEmote(r.room, msg) }) case proto.NtfDecidingGameId: msg := iMsg.(*proto.NtfDecidingGame) if TeamColor(msg.TeamColor) == r.room.teamColor(r.seat.No()) { r.NewTimer(baseroom.TtDecidingGame, time.Second*time.Duration(rand.Int()%RobotOnMsgRandTime+RobotOnMsgTime), func() { r.onDecidingAct(r.room, msg) }) } case proto.NtfPlayerActId: msg := iMsg.(*proto.NtfPlayerAct) if msg.Seat == r.seat.No() { r.NewTimer(baseroom.TtPlayerAct, time.Second*time.Duration(rand.Int()%RobotOnMsgRandTime+RobotOnMsgTime), func() { r.onPlayerAct(r.room, msg) }) } case proto.NtfPlayerRspRaiseId: msg := iMsg.(*proto.NtfPlayerRspRaise) if TeamColor(msg.TeamColor) != r.room.teamColor(r.seat.No()) { return } r.NewTimer(baseroom.TtPlayerRspRaise, time.Second*time.Duration(rand.Int()%RobotOnMsgRandTime+RobotOnMsgTime), func() { r.onRspRaise(r.room, msg) }) case proto.NtfEmoteId: r.onEmote(iMsg.(*proto.NtfEmote)) case proto.NtfUserDisbandRoomId: msg := iMsg.(*proto.NtfUserDisbandRoom) if len(msg.Agree) == r.room.SeatPlayerNum() { r.GameClean() } case proto.NtfGameSettleId, proto.NtfMaintainId: r.GameClean() } } func (r *RobotAplomb) outPokerRound1(room *TrucoRoom, _ interface{}) { var outPoker *poker.Poker pos := r.positionInOutPoker(room) if pos == 0 { outPoker = r.outMaxPoker(room) } else if pos == 1 { if r.canBigger(room) { outPoker = r.outMaxPoker(room) } else { outPoker = r.outMinPoker(room) } } else if pos == 2 || pos == 4 { if bigger, big := r.teammateBigger(room); bigger { if big { outPoker = r.outMinPoker(room) } else { if r.canBigger(room) { outPoker = r.outMaxPoker(room) } else { outPoker = r.outMinPoker(room) } } } else { if r.canBigger(room) { outPoker = r.outMaxPoker(room) } else { outPoker = r.outMinPoker(room) } } } else { if bigger, _ := r.teammateBigger(room); bigger { outPoker = r.outMinPoker(room) } else { if r.canBigger(room) { outPoker = r.outBiggerPoker(room) } else { outPoker = r.outMinPoker(room) } } } if outPoker != nil { req := &proto.ReqPlayerOutPoker{Poker: outPoker.ToInt()} msg := util.MakeMessage(proto.ReqPlayerOutPokerId, req, r.UID, room.Id()) room.OnMessage(proto.ReqPlayerOutPokerId, msg) } else { log.Error(r.room.SeatLog(r.seat, "ai error")) } } func (r *RobotAplomb) outPokerRound2ByPos0(room *TrucoRoom, _ interface{}) *poker.Poker { if room.IsMVM() { if r.roundWinLose(room, 0) != poker.CppEqual { return r.outMinPoker(room) } else { if r.handlePokerBiggerThenTeammate(room) { return r.outMaxPoker(room) } else { return r.outMinPoker(room) } } } else { return r.outMinPoker(room) } } func (r *RobotAplomb) outPokerRound2ByPos1(room *TrucoRoom, _ interface{}) *poker.Poker { if room.IsMVM() { if r.roundWinLose(room, 0) != poker.CppEqual { return r.outMaxPoker(room) } else { if r.handlePokerBiggerThenTeammate(room) { return r.outMaxPoker(room) } else { return r.outMinPoker(room) } } } else { if r.canBigger(room) { return r.outBiggerPoker(room) } else { return r.outMinPoker(room) } } } func (r *RobotAplomb) outPokerRound2ByPos2(room *TrucoRoom, _ interface{}) *poker.Poker { if bigger, big := r.teammateBigger(room); bigger { if big { return r.outMinPoker(room) } else { if r.canBigger(room) { return r.outMaxPoker(room) } else { return r.outMinPoker(room) } } } else { if r.canBigger(room) { return r.outMaxPoker(room) } else { return r.outMinPoker(room) } } } func (r *RobotAplomb) outPokerRound2ByPos3(room *TrucoRoom, _ interface{}) *poker.Poker { if bigger, _ := r.teammateBigger(room); bigger { return r.outMinPoker(room) } else { if r.canBigger(room) { return r.outBiggerPoker(room) } else { return r.outMinPoker(room) } } } func (r *RobotAplomb) outPokerRound2(room *TrucoRoom, msg interface{}) { var outPoker *poker.Poker pos := r.positionInOutPoker(room) if pos == 0 { outPoker = r.outPokerRound2ByPos0(room, msg) } else if pos == 1 { outPoker = r.outPokerRound2ByPos1(room, msg) } else if pos == 2 || pos == 4 { outPoker = r.outPokerRound2ByPos2(room, msg) } else { outPoker = r.outPokerRound2ByPos3(room, msg) } if outPoker != nil { req := &proto.ReqPlayerOutPoker{Poker: outPoker.ToInt()} msg := util.MakeMessage(proto.ReqPlayerOutPokerId, req, r.UID, room.Id()) room.OnMessage(proto.ReqPlayerOutPokerId, msg) } else { log.Error(r.room.SeatLog(r.seat, "ai error")) } } func (r *RobotAplomb) outPokerRound3(room *TrucoRoom, _ interface{}) { if len(r.seat.Pokers) > 0 { req := &proto.ReqPlayerOutPoker{Poker: r.seat.Pokers[0].ToInt()} msg := util.MakeMessage(proto.ReqPlayerOutPokerId, req, r.UID, room.Id()) room.OnMessage(proto.ReqPlayerOutPokerId, msg) } else { log.Error(r.room.SeatLog(r.seat, "ai error")) } } func (r *RobotAplomb) outPoker(room *TrucoRoom, msg interface{}) { if r.getRound() == 0 { r.outPokerRound1(room, msg) } else if r.getRound() == 1 { r.outPokerRound2(room, msg) } else { r.outPokerRound3(room, msg) } } func (r *RobotAplomb) onDecidingAct(room *TrucoRoom, _ *proto.NtfDecidingGame) { colorNum := r.bigPokerNumForTeam(room, 4) if colorNum >= stub.GGlobalAI.TrucoAplombRaise1 { r.sendRaise(room, AtAgree, true) } else { r.sendRaise(room, AtGiveUp, true) } } func (r *RobotAplomb) onPlayerAct(room *TrucoRoom, msg *proto.NtfPlayerAct) { // 第二轮尝试叫分 if r.getRound() == 1 { if r.canRaise(msg) { colorNum := 0 if r.roundWinLose(room, 0) == poker.CppBig { colorNum = r.bigPokerNumForTeam(room, 4) } if colorNum >= stub.GGlobalAI.TrucoAplombRaise1 { r.sendRaise(room, IntToActType(msg.CanCall), true) return } } } r.outPoker(room, msg) } func (r *RobotAplomb) onRspRaise(room *TrucoRoom, _ *proto.NtfPlayerRspRaise) { actType := AtGiveUp color := room.teamColor(r.seat.No()) colorNum := r.bigPokerNumForTeam(room, 4) if r.getRound() == 0 { actType = util.Tie(colorNum >= stub.GGlobalAI.TrucoAplombRaise1, AtAgree, AtGiveUp) } else if r.getRound() == 1 { if int(room.light[0].Color()) == int(color) { actType = util.Tie(colorNum >= stub.GGlobalAI.TrucoAplombRaise2, AtAgree, AtGiveUp) } } else { actType = util.Tie(colorNum >= stub.GGlobalAI.TrucoAplombRaise3, AtAgree, AtGiveUp) } r.sendRaise(room, actType, false) }