277 lines
7.2 KiB
Go
277 lines
7.2 KiB
Go
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)
|
|
}
|