457 lines
11 KiB
Go
457 lines
11 KiB
Go
package catchbugs
|
|
|
|
import (
|
|
"fmt"
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/lego/sys/log"
|
|
"go_dreamfactory/pb"
|
|
"go_dreamfactory/sys/configure"
|
|
cfg "go_dreamfactory/sys/configure/structs"
|
|
"time"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
type Room struct {
|
|
module *CatchBugs
|
|
data *pb.DBCatchBugsRoom
|
|
conf *cfg.GameCatchbugSkillData
|
|
sessions []comm.IUserSession
|
|
starttime time.Time
|
|
round int32
|
|
isReplenish bool
|
|
handleplayer string
|
|
handleplayers int32
|
|
aihandlecards []int32
|
|
aihandlenumber int32
|
|
}
|
|
|
|
func (this *Room) GameStart() (err error) {
|
|
this.starttime = configure.Now()
|
|
if this.conf, err = this.module.configure.getGameCatchbugSkillData(this.data.Rules.Skill); err != nil {
|
|
this.module.Errorln(err)
|
|
return
|
|
}
|
|
this.SendAllSessions("gameready", &pb.CatchbugsGameReadyPush{
|
|
ServicePath: fmt.Sprintf("%s/%s", this.module.service.GetType(), this.module.service.GetId()),
|
|
Room: this.data,
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
func (this *Room) PlayerReadyEnd(uid string) (err error) {
|
|
if uid == this.data.Red.Info.Uid {
|
|
this.data.Red.Ready = true
|
|
} else {
|
|
this.data.Blue.Ready = true
|
|
}
|
|
|
|
if this.handleplayer == "" {
|
|
if this.data.Rules.Headstart == 0 {
|
|
this.handleplayer = this.data.Red.Info.Uid
|
|
} else {
|
|
this.handleplayer = this.data.Blue.Info.Uid
|
|
}
|
|
}
|
|
|
|
if this.data.Red.Ready && this.data.Blue.Ready { //两个人都准备了
|
|
this.data.Red.Ready = false
|
|
this.data.Blue.Ready = false
|
|
this.SendAllSessions("roundstart", &pb.CatchbugsRoundStartPush{
|
|
Round: this.round,
|
|
Handleplayer: this.handleplayer,
|
|
})
|
|
this.data.Red.Lastopencard = -1
|
|
this.data.Blue.Lastopencard = -1
|
|
}
|
|
return
|
|
}
|
|
|
|
//玩家操作
|
|
func (this *Room) PlayerHandle(uid string, handle *pb.CatchbugsHandleReq) (err error) {
|
|
if uid != this.handleplayer {
|
|
err = fmt.Errorf("It's not your operation!")
|
|
return
|
|
}
|
|
|
|
if this.data.Card[handle.Index].Isopen {
|
|
err = fmt.Errorf("card is opened")
|
|
return
|
|
}
|
|
var (
|
|
issucc bool
|
|
number int32
|
|
)
|
|
if this.data.Red.Info.Uid == uid {
|
|
if this.data.Red.Lastopencard == -1 {
|
|
this.data.Red.Lastopencard = handle.Index
|
|
number = 0
|
|
} else {
|
|
if this.data.Card[this.data.Red.Lastopencard].Cid == this.data.Card[handle.Index].Cid {
|
|
issucc = true
|
|
this.data.Card[this.data.Red.Lastopencard].Isopen = true
|
|
this.data.Card[handle.Index].Isopen = true
|
|
this.data.Red.Cards = append(this.data.Red.Cards, this.data.Card[this.data.Red.Lastopencard].Cid)
|
|
|
|
}
|
|
number = 1
|
|
this.data.Red.Lastopencard = -1
|
|
}
|
|
} else {
|
|
if this.data.Blue.Lastopencard == -1 {
|
|
this.data.Blue.Lastopencard = handle.Index
|
|
number = 0
|
|
} else {
|
|
if this.data.Card[this.data.Blue.Lastopencard].Cid == this.data.Card[handle.Index].Cid {
|
|
issucc = true
|
|
this.data.Card[this.data.Red.Lastopencard].Isopen = true
|
|
this.data.Card[handle.Index].Isopen = true
|
|
this.data.Blue.Cards = append(this.data.Red.Cards, this.data.Card[this.data.Blue.Lastopencard].Cid)
|
|
}
|
|
number = 1
|
|
this.data.Blue.Lastopencard = -1
|
|
}
|
|
|
|
}
|
|
this.SendAllSessions("opencard", &pb.CatchbugsOpenCardPush{
|
|
Roomid: this.data.Rid,
|
|
Handleplayer: uid,
|
|
Index: handle.Index,
|
|
Number: number,
|
|
Issucc: issucc,
|
|
})
|
|
return
|
|
}
|
|
|
|
//玩家操作
|
|
func (this *Room) PlayerHandleEnd(uid string, handle *pb.CatchbugsHandleEndReq) (err error) {
|
|
if uid != this.handleplayer {
|
|
err = fmt.Errorf("It's not your operation!")
|
|
return
|
|
}
|
|
|
|
var (
|
|
card []*pb.DBCatchBugsCard
|
|
)
|
|
this.handleplayers++
|
|
if uid == this.data.Red.Info.Uid {
|
|
this.handleplayer = this.data.Blue.Info.Uid
|
|
} else {
|
|
this.handleplayer = this.data.Red.Info.Uid
|
|
}
|
|
|
|
state := this.checkGameOver()
|
|
if state == 3 {
|
|
this.gameover()
|
|
} else {
|
|
if state == 2 { //需要补拍
|
|
this.ReplenishCard()
|
|
card = this.data.Card
|
|
this.SendAllSessions("tableschange", &pb.CatchbugsTablesChangePush{
|
|
Changetype: 1,
|
|
Card: card,
|
|
})
|
|
this.SendAllSessions("roundend", &pb.CatchbugsRoundEndPush{})
|
|
}
|
|
if this.handleplayers == 2 {
|
|
this.round++
|
|
this.handleplayers = 0
|
|
if this.round <= 6 {
|
|
if this.round%this.conf.Round == 0 { //触发技能
|
|
switch this.data.Rules.Skill {
|
|
case 1:
|
|
this.data.Card = Skill1Effect(this.data.Card)
|
|
card = this.data.Card
|
|
this.SendAllSessions("tableschange", &pb.CatchbugsTablesChangePush{
|
|
Changetype: 0,
|
|
Card: card,
|
|
})
|
|
break
|
|
case 2:
|
|
this.data.Card = Skill2Effect(this.data.Card)
|
|
card = this.data.Card
|
|
this.SendAllSessions("tableschange", &pb.CatchbugsTablesChangePush{
|
|
Changetype: 0,
|
|
Card: card,
|
|
})
|
|
break
|
|
case 4:
|
|
this.data.Card = Skill4Effect(this.data.Card)
|
|
card = this.data.Card
|
|
this.SendAllSessions("tableschange", &pb.CatchbugsTablesChangePush{
|
|
Changetype: 0,
|
|
Card: card,
|
|
})
|
|
break
|
|
}
|
|
}
|
|
} else {
|
|
this.gameover()
|
|
return
|
|
}
|
|
}
|
|
this.SendAllSessions("roundend", &pb.CatchbugsRoundEndPush{})
|
|
}
|
|
return
|
|
}
|
|
|
|
//检测游戏是否结束 1 正常 2 补拍 3结束
|
|
func (this *Room) checkGameOver() (state int32) {
|
|
if this.round >= 6 {
|
|
state = 3
|
|
return
|
|
}
|
|
for _, v := range this.data.Card {
|
|
if !v.Isopen {
|
|
state = 1
|
|
return
|
|
}
|
|
}
|
|
if (this.round < 3 && !this.isReplenish) || this.round == 3 { //需要补拍
|
|
state = 2
|
|
} else {
|
|
state = 3
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
//补牌操作
|
|
func (this *Room) ReplenishCard() {
|
|
var index = 0
|
|
this.round = 4
|
|
for _, v := range this.data.Card {
|
|
if v.Isopen {
|
|
v.Cid = this.data.Backup[index].Cid
|
|
v.Id = this.data.Backup[index].Id
|
|
index++
|
|
}
|
|
}
|
|
this.isReplenish = true
|
|
if this.data.Rules.Headstart == 0 {
|
|
this.handleplayer = this.data.Blue.Info.Uid
|
|
} else {
|
|
this.handleplayer = this.data.Red.Info.Uid
|
|
}
|
|
}
|
|
|
|
func (this *Room) AiHanle(stype string) {
|
|
switch stype {
|
|
case "gameready", "roundend":
|
|
this.PlayerReadyEnd(this.data.Blue.Info.Uid)
|
|
break
|
|
case "roundstart":
|
|
if this.handleplayer != this.data.Blue.Info.Uid {
|
|
return
|
|
}
|
|
randoms := []int32{2, 3, 4, 5, 6}
|
|
random := randoms[comm.GetRandW(randoms)]
|
|
cardsSlice := []int32{}
|
|
for _, v := range this.data.Card {
|
|
if !v.Isopen {
|
|
cardsSlice = append(cardsSlice, v.Index)
|
|
}
|
|
}
|
|
if random > int32(len(cardsSlice)) {
|
|
random = int32(len(cardsSlice))
|
|
}
|
|
indexs := comm.RandShuffle(len(cardsSlice))
|
|
this.aihandlecards = make([]int32, 0)
|
|
this.aihandlenumber = 0
|
|
for _, v := range indexs[0:random] {
|
|
this.aihandlecards = append(this.aihandlecards, cardsSlice[v])
|
|
}
|
|
this.AiHandleByOpenCard()
|
|
break
|
|
case "opencard":
|
|
if this.aihandlenumber < int32(len(this.aihandlecards)) {
|
|
this.AiHandleByOpenCard()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *Room) SendAllSessions(stype string, msg proto.Message) (err error) {
|
|
if err = this.module.SendMsgSyncToSession(string(this.module.GetType()), stype, msg, this.sessions...); err != nil {
|
|
this.module.Errorln(err)
|
|
return
|
|
}
|
|
if this.data.Blue.Isai {
|
|
go this.AiHanle(stype)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (this *Room) AiHandleByOpenCard() {
|
|
this.PlayerHandle(this.data.Blue.Info.Uid, &pb.CatchbugsHandleReq{
|
|
Roomid: this.data.Rid,
|
|
Index: this.aihandlecards[this.aihandlenumber],
|
|
Number: int32(this.aihandlenumber % 2),
|
|
})
|
|
this.aihandlenumber++
|
|
if this.aihandlenumber >= int32(len(this.aihandlecards)) {
|
|
this.PlayerHandleEnd(this.data.Blue.Info.Uid, &pb.CatchbugsHandleEndReq{
|
|
Roomid: this.data.Rid,
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func (this *Room) gameover() {
|
|
winuid := ""
|
|
if len(this.data.Red.Cards) > len(this.data.Blue.Cards) {
|
|
winuid = this.data.Red.Info.Uid
|
|
this.data.Red.Score = int32(len(this.data.Red.Cards) * 4)
|
|
this.data.Blue.Score = int32(len(this.data.Blue.Cards))
|
|
|
|
} else if len(this.data.Red.Cards) < len(this.data.Blue.Cards) {
|
|
winuid = this.data.Blue.Info.Uid
|
|
this.data.Blue.Score = int32(len(this.data.Blue.Cards) * 4)
|
|
this.data.Red.Score = int32(len(this.data.Red.Cards))
|
|
} else {
|
|
this.data.Red.Score = int32(len(this.data.Red.Cards) * 2)
|
|
this.data.Blue.Score = int32(len(this.data.Blue.Cards) * 2)
|
|
}
|
|
this.data.Red.Integral += this.data.Red.Score
|
|
this.data.Blue.Integral += this.data.Blue.Score
|
|
this.module.model.Change(this.data.Red.Info.Uid, map[string]interface{}{
|
|
"integral": this.data.Red.Integral,
|
|
})
|
|
if !this.data.Blue.Isai {
|
|
this.module.model.Change(this.data.Blue.Info.Uid, map[string]interface{}{
|
|
"integral": this.data.Blue.Integral,
|
|
})
|
|
}
|
|
this.SendAllSessions("gameover", &pb.CatchbugsGameOverPush{
|
|
Winuid: winuid,
|
|
Redintegral: this.data.Red.Integral,
|
|
Blueintegral: this.data.Blue.Integral,
|
|
})
|
|
}
|
|
|
|
//技能效果1 随机2x2的区域 旋转
|
|
func Skill1Effect(cards []*pb.DBCatchBugsCard) (cardsTemp []*pb.DBCatchBugsCard) {
|
|
var (
|
|
cardsSlice []int32
|
|
ramdon int32 //随机点
|
|
x int32
|
|
y int32
|
|
offsetX, offsetY int32
|
|
ramdonCard []*pb.DBCatchBugsCard
|
|
)
|
|
for _, v := range cards {
|
|
if !v.Isopen {
|
|
cardsSlice = append(cardsSlice, v.Index)
|
|
}
|
|
}
|
|
ramdon = cardsSlice[comm.RandShuffle(len(cardsSlice))[0]]
|
|
x = ramdon % 6
|
|
y = ramdon / 6
|
|
offsetX = 1
|
|
if x == 3 {
|
|
offsetX = -1
|
|
}
|
|
offsetY = 1
|
|
if y == 6 {
|
|
offsetY = -1
|
|
}
|
|
ramdonCard = append(ramdonCard, cards[y*4+x])
|
|
ramdonCard = append(ramdonCard, cards[y*4+x+offsetX])
|
|
ramdonCard = append(ramdonCard, cards[(y+offsetY)*4+x+offsetX])
|
|
ramdonCard = append(ramdonCard, cards[(y+offsetY)*4+x])
|
|
log.Debugf("技能1 前的数据:", ramdonCard)
|
|
index0 := ramdonCard[0].Index
|
|
for i, v := range ramdonCard {
|
|
if i < len(ramdonCard)-1 {
|
|
v.Index = ramdonCard[i+1].Index
|
|
} else {
|
|
v.Index = index0
|
|
}
|
|
}
|
|
log.Debugf("技能1 后的数据:", ramdonCard)
|
|
cardsTemp = cards
|
|
cardsTemp = make([]*pb.DBCatchBugsCard, len(cards))
|
|
for _, v := range cards {
|
|
cardsTemp[v.Index] = v
|
|
}
|
|
return cardsTemp
|
|
}
|
|
|
|
//技能效果1 随机2x2的区域 旋转
|
|
func Skill2Effect(cards []*pb.DBCatchBugsCard) (cardsTemp []*pb.DBCatchBugsCard) {
|
|
|
|
cardsTemp = make([]*pb.DBCatchBugsCard, len(cards))
|
|
|
|
cardsTemp[0] = cards[12]
|
|
cardsTemp[1] = cards[13]
|
|
cardsTemp[2] = cards[14]
|
|
cardsTemp[6] = cards[18]
|
|
cardsTemp[7] = cards[19]
|
|
cardsTemp[8] = cards[20]
|
|
|
|
cardsTemp[3] = cards[0]
|
|
cardsTemp[4] = cards[1]
|
|
cardsTemp[5] = cards[2]
|
|
cardsTemp[9] = cards[6]
|
|
cardsTemp[10] = cards[7]
|
|
cardsTemp[11] = cards[8]
|
|
|
|
cardsTemp[15] = cards[3]
|
|
cardsTemp[16] = cards[4]
|
|
cardsTemp[17] = cards[5]
|
|
cardsTemp[21] = cards[9]
|
|
cardsTemp[22] = cards[10]
|
|
cardsTemp[23] = cards[11]
|
|
|
|
cardsTemp[12] = cards[15]
|
|
cardsTemp[13] = cards[16]
|
|
cardsTemp[14] = cards[17]
|
|
cardsTemp[18] = cards[21]
|
|
cardsTemp[19] = cards[22]
|
|
cardsTemp[20] = cards[23]
|
|
|
|
for i, v := range cardsTemp {
|
|
v.Index = int32(i)
|
|
}
|
|
return
|
|
}
|
|
|
|
//技能效果1 随机2x2的区域 旋转
|
|
func Skill4Effect(cards []*pb.DBCatchBugsCard) (cardsTemp []*pb.DBCatchBugsCard) {
|
|
var (
|
|
ramdonSclie []int32 = make([]int32, 0)
|
|
number int32
|
|
cardsSlice []int32
|
|
ramdoncards []*pb.DBCatchBugsCard
|
|
)
|
|
ramdonSclie = append(ramdonSclie, 2)
|
|
if len(cards) > 6 {
|
|
ramdonSclie = append(ramdonSclie, 4, 6)
|
|
} else if len(cards) > 4 {
|
|
ramdonSclie = append(ramdonSclie, 4)
|
|
}
|
|
|
|
number = ramdonSclie[comm.RandShuffle(len(ramdonSclie))[0]]
|
|
for _, v := range cards {
|
|
if !v.Isopen {
|
|
cardsSlice = append(cardsSlice, v.Index)
|
|
}
|
|
}
|
|
for _, v := range comm.RandShuffle(len(cardsSlice))[0:number] {
|
|
ramdoncards = append(ramdoncards, cards[cardsSlice[v]])
|
|
}
|
|
index0 := ramdoncards[0].Index
|
|
for i, v := range ramdoncards {
|
|
if i < len(ramdoncards)-1 {
|
|
v.Index = ramdoncards[i+1].Index
|
|
} else {
|
|
v.Index = index0
|
|
}
|
|
}
|
|
cardsTemp = make([]*pb.DBCatchBugsCard, len(cards))
|
|
for _, v := range cards {
|
|
cardsTemp[v.Index] = v
|
|
}
|
|
return
|
|
}
|