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 { 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, color int32) (bSwap bool, xCount int32) { if (oldId%Height-1 < Total && 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 } //this.CheckMap(color) return } 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, 1, 3, 5, 1, 6, 1, 5, 6, 5, 5, 1, 3, 1, 6, 1, 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] this.Plat[index+j*Height].Cid = 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(color int32) (bEliminate bool, score int32, count 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++ // 生成一个新的类型元素 if conf, err := this.module.configure.GetGameBlock(k1, FiveType); err != nil { this.Plat[k+2] = &pb.GirdeData{ Oid: this.oid, Color: k1, Cid: conf.Key, Score: conf.Score, Special: conf.Type, } } else { xiaochu = append(xiaochu, k+2) } 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++ // 生成一个新的类型元素 if conf, err := this.module.configure.GetGameBlock(k1, FiveType); err != nil { this.Plat[k+2*Width] = &pb.GirdeData{ Oid: this.oid, Color: k1, Cid: conf.Key, Score: conf.Score, Special: conf.Type, } } else { xiaochu = append(xiaochu, k+2*Width) } 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 { // 普通类型 直接消除 if this.Plat[id].Color == color { count++ } score += this.Plat[id].Score this.Plat[id] = &pb.GirdeData{} } } for _, v := range next { if this.Plat[v].Color == color { count++ } score += this.Plat[v].Score this.Plat[v] = &pb.GirdeData{} } return } func (this *MapData) Check4X(color int32) (bEliminate bool, score int32, count 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++ // 生成一个新的类型元素 if this.module != nil { if conf, err := this.module.configure.GetGameBlock(k1, FourUType); err != nil { // 上下类型 this.Plat[k+1] = &pb.GirdeData{ Oid: this.oid, Color: k1, Cid: conf.Key, Score: conf.Score, Special: conf.Type, } } else { xiaochu = append(xiaochu, k+1) } } xiaochu = append(xiaochu, k+1) 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++ if this.module != nil { // 生成一个新的类型元素 if conf, err := this.module.configure.GetGameBlock(k1, FourLType); err != nil { // 左右类型 this.Plat[k+Width] = &pb.GirdeData{ Oid: this.oid, Color: k1, Cid: conf.Key, Score: conf.Score, Special: conf.Type, } if k1 == color { count++ } } else { xiaochu = append(xiaochu, k+Width) } } xiaochu = append(xiaochu, k+Width) 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 { // 普通类型 直接消除 if this.Plat[id].Color == color { count++ } score += this.Plat[id].Score this.Plat[id] = &pb.GirdeData{} } } for _, v := range next { if this.Plat[v].Color == color { count++ } score += this.Plat[v].Score this.Plat[v] = &pb.GirdeData{} } return } func (this *MapData) Check3X(color int32) (bEliminate bool, score int32, count 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 + Width, k + 2*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 { // 普通类型 直接消除 if this.Plat[id].Color == color { count++ } score += this.Plat[id].Score this.Plat[id] = &pb.GirdeData{} } } for _, v := range next { if this.Plat[v].Color == color { count++ } score += this.Plat[v].Score this.Plat[v] = &pb.GirdeData{} } return } // 校验地图可消除的 判断各组上面2个和右边两个是否三个相等 func (this *MapData) CheckMap(color int32) (score int32, szMap []*pb.MapData, count int32) { var curScore int32 for { curScore = 0 this.DropGirde() // 先掉落 if bRet, s, c := this.Check5X(color); bRet { fmt.Printf("=====检测消除5x===========\n") curScore += s count += c } if bRet, s, c := this.Check4X(color); bRet { fmt.Printf("=====检测消除4x===========\n") curScore += s count += c } if bRet, s, c := this.Check3X(color); bRet { fmt.Printf("=====检测消除3x===========\n") curScore += s count += c } score += curScore // 总分 szMap = append(szMap, &pb.MapData{ Data: this.Plat, CurSocre: curScore, }) if curScore == 0 { break } } //this.Debugf() 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 b, _ := this.SwapGirde(int32(pos), int32(pos+1), 2); b { if s, _, _ := this.CheckMap(2); s == 0 { this.SwapGirde(int32(pos+1), int32(pos), 2) } else { bSwap = true break } } } if pos/Width+1 < Width { if b, _ := this.SwapGirde(int32(pos), int32(pos+Width), 2); b { if s, _, _ := this.CheckMap(2); s == 0 { this.SwapGirde(int32(pos+Width), int32(pos), 2) } else { bSwap = true break } } } } return bSwap }