samba/server/truco/room/trucoRobotAplomb.go

277 lines
7.2 KiB
Go
Raw Permalink Normal View History

2025-06-04 09:51:39 +08:00
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)
}