package entertainment import ( "crypto/rand" "fmt" "go_dreamfactory/pb" "math/big" ) const ( Width = 7 Height = 7 Total = Width * Height FiveType = 3 // 5消类型 FourUType = 1 // 4消上下类型 FourLType = 2 // 4消左右类型 ) // type Girde struct { // X int32 // x // Y int32 // ID int32 // Itype int32 // } type Girde struct { oid int32 // 唯一ID color int32 // 颜色 cid int32 // 配置表id score int32 // 分数 special int32 // 消除特效 } //地图数据 type MapData struct { Plat []*pb.GirdeData // 地图 oid int32 // 唯一id module *Entertainment } // 1~6随机一个数 func GetRandType() int32 { n, _ := rand.Int(rand.Reader, big.NewInt(6)) return int32(n.Int64() + 1) } func (this *MapData) CreateGride(index int32) *pb.GirdeData { t := GetRandType() fmt.Printf("create=====index: %d, color:%d \n", index, t) this.oid++ return &pb.GirdeData{ Oid: this.oid, Color: t, Cid: GetRandType(), Score: 1, Special: 0, } } // 初始化地图数据 func (this *MapData) InitMap(module *Entertainment) { this.module = module this.oid = 1000 // 方便观察 从1000开始 this.Plat = make([]*pb.GirdeData, Width*Height) for i := 0; i < Width*Height; i++ { this.Plat[i] = this.CreateGride(int32(i)) } this.SetMap() // 方便测试固定地图 } // 交换2个元素(参数 oid ) func (this *MapData) SwapGirde(oldId, newId int32) bool { var ( bSwap bool // 能否交换 ) // x = int32(i/Width), y = int32(i%Height) if (oldId%Height != Total-1 && oldId+1 == newId) || (oldId%Height > 0 && oldId-1 == newId) || (oldId+Width < Total && oldId+Width == newId) || (oldId-Width > 0 && oldId-Width == newId) { bSwap = true tmp := new(pb.GirdeData) *tmp = *this.Plat[newId] this.Plat[newId] = this.Plat[oldId] this.Plat[oldId] = tmp } return bSwap } func (this *MapData) SetMap() { sz2 := []int32{ 5, 1, 2, 5, 1, 5, 2, 3, 1, 5, 4, 2, 4, 4, 4, 4, 2, 1, 6, 4, 1, 6, 3, 1, 4, 3, 6, 3, 6, 3, 3, 1, 1, 6, 1, 5, 6, 5, 5, 1, 3, 1, 6, 5, 5, 1, 2, 1, 4, } var pos int for index := Width - 1; index >= 0; index-- { for j := 0; j < Height; j++ { this.Plat[index+j*Height].Color = sz2[pos] pos++ } } } func (this *MapData) Debugf() { fmt.Printf("================\n") for index := Width - 1; index >= 0; index-- { for j := 0; j < Height; j++ { fmt.Printf("%d:%d ", this.Plat[index+j*Height].Oid, this.Plat[index+j*Height].Color) } fmt.Printf("\n") } } // 检查5消 func (this *MapData) Check5X() (bEliminate bool, score int32) { var xiaochu []int // 即将消除的key for k, v := range this.Plat { if v.Color == 0 { continue } x := int32(k % Height) // x if x+4 < Height { k1 := this.Plat[k].Color k2 := this.Plat[k+1].Color k3 := this.Plat[k+2].Color k4 := this.Plat[k+3].Color k5 := this.Plat[k+4].Color if k1 == k2 && k3 == k4 && k5 == k1 && k2 == k3 { this.oid++ // 生成一个新的类型元素 conf, _ := this.module.configure.GetGameBlock(k1, FiveType) this.Plat[k+2] = &pb.GirdeData{ Oid: this.oid, Color: k1, Cid: conf.Key, Score: conf.Score, Special: conf.Type, } xiaochu = append(xiaochu, []int{k, k + 1, k + 3, k + 4}...) bEliminate = true } } if k+4*Width < Total { k1 := this.Plat[k].Color k2 := this.Plat[k+Width].Color k3 := this.Plat[k+2*Width].Color k4 := this.Plat[k+3*Width].Color k5 := this.Plat[k+4*Width].Color if k1 == k2 && k3 == k4 && k5 == k1 && k2 == k3 { this.oid++ // 生成一个新的类型元素 conf, _ := this.module.configure.GetGameBlock(k1, FiveType) this.Plat[k+2*Width] = &pb.GirdeData{ Oid: this.oid, Color: k1, Cid: conf.Key, Score: conf.Score, Special: conf.Type, } xiaochu = append(xiaochu, []int{k, k + Width, k + 3*Width, k + 4*Width}...) bEliminate = true } } } var next []int for _, id := range xiaochu { if s := this.Plat[id].Special; s != 0 { if s == FourUType { // 4消上下类型 for i := 0; i < Total; i++ { if id/Height == i/Height { next = append(next, i) } } next = append(next, 1) } else if s == FourLType { // 左右类型 for i := 0; i < Total; i++ { if id%Height == i%Height { next = append(next, i) } } } else if s == FiveType { // 随机消除 } else { // 普通类型 直接消除 score += this.Plat[id].Score this.Plat[id] = &pb.GirdeData{} } } } for _, v := range next { score += this.Plat[v].Score this.Plat[v] = &pb.GirdeData{} } return } func (this *MapData) Check4X() (bEliminate bool, score int32) { var xiaochu []int // 即将消除的key for k, v := range this.Plat { if v.Color == 0 { continue } x := int32(k % Height) // x if x+3 < Height { k1 := this.Plat[k].Color k2 := this.Plat[k+1].Color k3 := this.Plat[k+2].Color k4 := this.Plat[k+3].Color if k1 == k2 && k3 == k4 && k2 == k3 { this.oid++ // 生成一个新的类型元素 conf, _ := this.module.configure.GetGameBlock(k1, FourUType) // 上下类型 this.Plat[k+1] = &pb.GirdeData{ Oid: this.oid, Color: k1, Cid: conf.Key, Score: conf.Score, Special: conf.Type, } xiaochu = append(xiaochu, []int{k, k + 2, k + 3}...) bEliminate = true } } if k+3*Width < Total { k1 := this.Plat[k].Color k2 := this.Plat[k+Width].Color k3 := this.Plat[k+2*Width].Color k4 := this.Plat[k+3*Width].Color if k1 == k2 && k3 == k4 && k2 == k3 { this.oid++ // 生成一个新的类型元素 conf, _ := this.module.configure.GetGameBlock(k1, FourLType) // 左右类型 this.Plat[k+1*Width] = &pb.GirdeData{ Oid: this.oid, Color: k1, Cid: conf.Key, Score: conf.Score, Special: conf.Type, } xiaochu = append(xiaochu, []int{k, k + 2*Width, k + 3*Width}...) bEliminate = true } } } var next []int for _, id := range xiaochu { if s := this.Plat[id].Special; s != 0 { if s == FourUType { // 4消上下类型 for i := 0; i < Total; i++ { if id/Height == i/Height { next = append(next, i) } } next = append(next, 1) } else if s == FourLType { // 左右类型 for i := 0; i < Total; i++ { if id%Height == i%Height { next = append(next, i) } } } else if s == FiveType { // 随机消除 } else { // 普通类型 直接消除 score += this.Plat[id].Score this.Plat[id] = &pb.GirdeData{} } } } for _, v := range next { score += this.Plat[v].Score this.Plat[v] = &pb.GirdeData{} } return } func (this *MapData) Check3X() (bEliminate bool, score int32) { var xiaochu []int // 即将消除的key for k, v := range this.Plat { if v.Color == 0 { continue } x := int32(k % Height) // x if x+2 < Height { k1 := this.Plat[k].Color k2 := this.Plat[k+1].Color k3 := this.Plat[k+2].Color if k1 == k2 && k2 == k3 { xiaochu = append(xiaochu, []int{k, k + 1, k + 2}...) bEliminate = true } } if k+2*Width < Total { k1 := this.Plat[k].Color k2 := this.Plat[k+Width].Color k3 := this.Plat[k+2*Width].Color if k1 == k2 && k2 == k3 { xiaochu = append(xiaochu, []int{k, k + 1, k + 2}...) bEliminate = true } } } var next []int for _, id := range xiaochu { if s := this.Plat[id].Special; s != 0 { if s == FourUType { // 4消上下类型 for i := 0; i < Total; i++ { if id/Height == i/Height { next = append(next, i) } } next = append(next, 1) } else if s == FourLType { // 左右类型 for i := 0; i < Total; i++ { if id%Height == i%Height { next = append(next, i) } } } else if s == FiveType { // 随机消除 } else { // 普通类型 直接消除 score += this.Plat[id].Score this.Plat[id] = &pb.GirdeData{} } } } for _, v := range next { score += this.Plat[v].Score this.Plat[v] = &pb.GirdeData{} } return } // 校验地图可消除的 判断各组上面2个和右边两个是否三个相等 func (this *MapData) CheckMap() (score int32, szMap []*pb.MapData) { for { var curScore int32 if bRet, s := this.Check5X(); !bRet { fmt.Printf("=====检测消除5x===========\n") curScore += s } if bRet, s := this.Check4X(); !bRet { fmt.Printf("=====检测消除4x===========\n") curScore += s } if bRet, s := this.Check3X(); !bRet { fmt.Printf("=====检测消除3x===========\n") curScore += s } score += curScore // 总分 if curScore == 0 { break } this.DropGirde() szMap = append(szMap, &pb.MapData{ Data: this.Plat, CurSocre: curScore, }) } return } // 下落 生成新的格子 (返回掉落所获得的分数) func (this *MapData) DropGirde() { for i := 0; i < Width; i++ { for j := 0; j < Height; j++ { index := i*Width + j if this.Plat[index].Color == 0 { // 说明这列有空 var add int for m := j + 1; m < Height; m++ { k1 := i*Width + m if this.Plat[k1].Color != 0 { this.Plat[index] = this.Plat[k1] index++ add++ } } for m := j + add; m < Height; m++ { k1 := i*Width + m this.Plat[k1] = this.CreateGride(int32(k1)) } break } } } this.Debugf() return } // ai操作 func (this *MapData) AiSwapGirde() bool { var ( bSwap bool // 能否交换 ) for pos := 0; pos < Total; pos++ { y := pos % Height if y < Height-1 { if this.SwapGirde(int32(pos), int32(pos+1)) { bSwap = true break } } if pos/Width+1 < Width { if this.SwapGirde(int32(pos), int32(pos+Width)) { bSwap = true break } } } return bSwap }