package entertainment import ( "crypto/rand" "fmt" "go_dreamfactory/comm" "go_dreamfactory/pb" cfg "go_dreamfactory/sys/configure/structs" "go_dreamfactory/utils" "math/big" ) const ( Width = 7 Height = 7 Total = Width * Height FiveType = 3 // 5消类型 FourUType = 1 // 4消上下类型 FourLType = 2 // 4消左右类型 BoomType = 4 // 炸弹类型 FireUp = 5 //上烟火 FireDown = 6 //下烟火 FireLeft = 7 //左烟火 FireRight = 8 //右烟火 ) 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 operElem []int32 // 当前移动的元素 iType int32 // 玩法类型 } // 1~6随机一个数 func (this *MapData) GetRandType() int32 { return this.module.configure.GetGameNormalElem() // 权重随机 } // 玩法带入 func (this *MapData) CreateGride(count int) (girdes []*pb.GirdeData) { var ( id int32 conf *cfg.GameBlockData err error ) // 权重带入 for i := 0; i < count; i++ { this.oid++ girde := &pb.GirdeData{ // 默认值 Oid: this.oid, Color: 1, Cid: 1, Score: 1, Special: 0, } id = this.GetRandType() if conf, err = this.module.configure.GetGameBlockByKey(id); err == nil { girde.Color = conf.Color girde.Cid = conf.Key girde.Special = conf.Type girde.Score = conf.Score girdes = append(girdes, girde) } } return } // 生成自定义地图 func (this *MapData) SetMap() { sz2 := []int32{ 3, 1, 2, 2, 1, 3, 1, 5, 1, 2, 3, 1, 2, 2, 2, 4, 3, 4, 3, 1, 6, 1, 3, 3, 4, 2, 3, 6, 1, 5, 2, 5, 6, 1, 4, 6, 6, 3, 26, 3, 1, 3, 3, 3, 1, 3, 3, 2, 5, } var pos int for index := Width - 1; index >= 0; index-- { for j := 0; j < Height; j++ { Color := sz2[pos] Cid := sz2[pos] if sz2[pos] > 6 { // 特殊元素 conf, err := this.module.configure.GetGameBlockByKey(sz2[pos]) if err == nil { Color = conf.Color Cid = conf.Key this.Plat[index+j*Height].Special = conf.Type } } this.Plat[index+j*Height].Color = Color this.Plat[index+j*Height].Cid = Cid pos++ } } this.CheckAndRefreshPlat() // this.SetIndelibilityPlat() } // 初始化地图数据 func (this *MapData) InitMap(module *Entertainment, iType int32) { this.module = module this.iType = iType this.oid = 1000 // 方便观察 从1000开始 this.Plat = make([]*pb.GirdeData, Width*Height) for i, v := range this.CreateGride(Total) { this.Plat[i] = v } if iType > 1 { var sp int32 var mp map[int32]struct{} mp = make(map[int32]struct{}, 0) for { n1, _ := rand.Int(rand.Reader, big.NewInt(Total)) mp[int32(n1.Int64())] = struct{}{} if len(mp) >= 2 { break } } for key := range mp { if iType == 3 { sp = 4 } else if iType == 4 { n1, _ := rand.Int(rand.Reader, big.NewInt(4)) // 随机一个消除类型 sp = int32(n1.Int64()) + 5 } if conf, err := this.module.configure.GetGameBlock(this.Plat[key].Color, sp); err == nil { this.Plat[key].Cid = conf.Key this.Plat[key].Special = conf.Type this.Plat[key].Score = conf.Score } } } this.SetIndelibilityPlat() this.Plat = this.GetPalatData() } // 交换之前先判断是不是特殊元素的交换 func (this *MapData) CheckSpecialElemChange(oldId, newId int32, color int32) (bSwap bool, szMap []*pb.MapData) { this.operElem = []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 x := make(map[int]struct{}) if this.Plat[newId].Special != 0 && this.Plat[oldId].Special != 0 { // 都不为0 tmp := new(pb.GirdeData) *tmp = *this.Plat[newId] this.Plat[newId] = this.Plat[oldId] this.Plat[oldId] = tmp this.operElem = append(this.operElem, newId) this.operElem = append(this.operElem, oldId) x = this.SpecialElem(int(oldId), this.Plat[oldId].Special) xc := this.SpecialElem(int(newId), this.Plat[newId].Special) for k := range xc { x[k] = struct{}{} } var energy int32 var curScore int32 for id := range x { if this.Plat[id].Color == color { energy++ } curScore += this.Plat[id].Score this.Plat[id] = &pb.GirdeData{} this.operElem = append(this.operElem, int32(id)) } for id := range x { if this.Plat[id].Color == color { energy++ } curScore += this.Plat[id].Score this.Plat[id] = &pb.GirdeData{} this.operElem = append(this.operElem, int32(id)) } if this.DropGirde() { szMap = append(szMap, &pb.MapData{ Data: this.GetPalatData(), CurSocre: curScore, CurEnergy: energy, }) } } else { bSwap = false } } return } // 交换2个元素(参数 oid ) func (this *MapData) SwapGirde(oldId, newId int32) (bSwap bool) { this.operElem = []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.operElem = append(this.operElem, newId) this.operElem = append(this.operElem, oldId) } //this.Debugf() return } func (this *MapData) Debugf() { fmt.Printf("================\n") var v int for index := Width - 1; index >= 0; index-- { for j := 0; j < Height; j++ { v = index + j*7 fmt.Printf("%d:%d ", v, this.Plat[index+j*Height].Cid) } fmt.Printf("\n") } } // 检查5消 (s 是生成新的一个新的元素 key 下标 value 消除后效果类型) func (this *MapData) Check5X() (bEliminate bool, xiaochu []int, s map[int]int) { //var xiaochu []int // 即将消除的key s = make(map[int]int) for k, v := range this.Plat { if v.Cid == 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 { s[k+2] = FiveType xiaochu = append(xiaochu, []int{k, k + 1, k + 2, k + 3, k + 4}...) this.Plat[k].Cid = 0 this.Plat[k+1].Cid = 0 this.Plat[k+2].Cid = 0 this.Plat[k+3].Cid = 0 this.Plat[k+4].Cid = 0 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 { s[k+2*Width] = FiveType xiaochu = append(xiaochu, []int{k, k + Width, k + 2*Width, k + 3*Width, k + 4*Width}...) this.Plat[k].Cid = 0 this.Plat[k+Width].Cid = 0 this.Plat[k+2*Width].Cid = 0 this.Plat[k+3*Width].Cid = 0 this.Plat[k+4*Width].Cid = 0 bEliminate = true } } } return } func (this *MapData) Check4X() (bEliminate bool, xiaochu []int, s map[int]int) { var ( newElem int // 生成的一个新的元素CID ) s = make(map[int]int) for k, v := range this.Plat { if v.Cid == 0 { continue } x := int32(k % Height) // x newElem = 0 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 { for _, v1 := range this.operElem { for i := 0; i <= 3; i++ { if int(v1) == k+i { newElem = int(v1) break } } if newElem != 0 { break } } if newElem == 0 { newElem = k + 2 // 给个默认值 } // 如果当前生成的也是一个特殊的元素 直接消除 if this.Plat[newElem].Special == 0 { s[newElem] = FourUType } xiaochu = append(xiaochu, []int{k, k + 1, k + 2, k + 3}...) for _, v := range xiaochu { this.Plat[v].Cid = 0 } 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 { for _, v1 := range this.operElem { for i := 0; i <= 3; i++ { if int(v1) == k+i*Width { newElem = int(v1) // 创建一个特殊的元素 break } } if newElem != 0 { break } } if newElem == 0 { newElem = k + 2*Width // 给个默认值 } // 如果当前生成的也是一个特殊的元素 直接消除 if this.Plat[newElem].Special == 0 { s[newElem] = FourLType } xiaochu = append(xiaochu, k+Width) xiaochu = append(xiaochu, []int{k, k + Width, k + 2*Width, k + 3*Width}...) for _, v := range xiaochu { this.Plat[v].Cid = 0 } bEliminate = true } } } return } func (this *MapData) Check3X() (bEliminate bool, xiaochu []int) { //var xiaochu []int // 即将消除的key for k, v := range this.Plat { b := false for _, e := range this.operElem { if e == int32(k) { b = true break } } if v.Cid == 0 && !b { 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}...) this.Plat[k].Cid = 0 this.Plat[k+1].Cid = 0 this.Plat[k+2].Cid = 0 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}...) this.Plat[k].Cid = 0 this.Plat[k+Width].Cid = 0 this.Plat[k+2*Width].Cid = 0 bEliminate = true } } } return } // 校验地图可消除的 判断各组上面2个和右边两个是否三个相等 // xc 判断用来是否加体力 func (this *MapData) CheckMap(color int32, bSkill bool) (szMap []*pb.MapData, xc bool) { var ( //tXiaochu []int tXiaochu map[int]struct{} curScore int32 energy int32 new map[int]int x map[int]struct{} ) for { new = make(map[int]int) x = make(map[int]struct{}) tXiaochu = make(map[int]struct{}) curScore = 0 energy = 0 if bEliminate, xiaochu, s := this.Check5X(); bEliminate { for _, v := range xiaochu { tXiaochu[v] = struct{}{} } for k, v := range s { new[k] = v } xc = true // 只要有 4x 5x 就标记ture } if bEliminate, xiaochu, s := this.Check4X(); bEliminate { for _, v := range xiaochu { tXiaochu[v] = struct{}{} } for k, v := range s { new[k] = v } xc = true // 只要有 4x 5x 就标记ture } if bEliminate, xiaochu := this.Check3X(); bEliminate { for _, v := range xiaochu { tXiaochu[v] = struct{}{} } } for id := range tXiaochu { if _, ok := new[id]; ok { if this.Plat[id].Color == color { energy++ } curScore += this.Plat[id].Score this.oid++ // 生成一个新的类型元素 if this.module == nil { // 稍后删掉 方便测试 this.Plat[id] = &pb.GirdeData{ Oid: this.oid, Color: this.Plat[id].Color, Cid: 2*(this.Plat[id].Color-1) + 6 + int32(new[id]), Score: 1, Special: int32(new[id]), } } else { if conf, err := this.module.configure.GetGameBlock(this.Plat[id].Color, int32(new[id])); err == nil { this.Plat[id] = &pb.GirdeData{ Oid: this.oid, Color: this.Plat[id].Color, Cid: conf.Key, Score: conf.Score, Special: conf.Type, } } } continue } if s := this.Plat[id].Special; s != 0 { for key := range this.SpecialElem(id, s) { x[key] = struct{}{} } } x[id] = struct{}{} } for id := range x { if this.Plat[id].Color == color { energy++ } curScore += this.Plat[id].Score this.Plat[id] = &pb.GirdeData{} this.operElem = append(this.operElem, int32(id)) } if this.DropGirde() { if !bSkill { energy = 0 } szMap = append(szMap, &pb.MapData{ Data: this.GetPalatData(), CurSocre: curScore, CurEnergy: energy, }) } // 检查掉落 this.operElem = []int32{} // 初始化操作元素 if curScore == 0 { break } } return } // 下落 生成新的格子 (返回掉落所获得的分数) func (this *MapData) DropGirde() bool { // 需要填充的格子 var fill []int bDrop := false for i := 0; i < Width; i++ { for j := 0; j < Height; j++ { index := i*Width + j if this.Plat[index].Cid == 0 { // 说明这列有空 bDrop = true var add int for m := j + 1; m < Height; m++ { k1 := i*Width + m if this.Plat[k1].Cid != 0 { this.Plat[index] = this.Plat[k1] index++ add++ } } for m := j + add; m < Height; m++ { k1 := i*Width + m fill = append(fill, k1) } break } } } if len(fill) == 0 { return bDrop } sz := this.CreateGride(len(fill)) for pos, id := range fill { this.Plat[id] = sz[pos] } if this.iType > 1 { var sp int32 var mp map[int]struct{} mp = make(map[int]struct{}, 0) var count int32 for pos, v := range this.Plat { if this.iType == 4 { if v.Special == 5 || v.Special == 6 || v.Special == 7 || v.Special == 8 { mp[pos] = struct{}{} count++ if count >= 2 { break } } } else if this.iType == 3 { if v.Special == 4 { mp[pos] = struct{}{} count++ if count >= 2 { break } } } } if len(mp) < 2 { ilen := 2 - len(mp) mp = make(map[int]struct{}, ilen) for i := 0; i < ilen; i++ { n1, _ := rand.Int(rand.Reader, big.NewInt(int64(len(fill)))) mp[fill[n1.Int64()]] = struct{}{} } for key := range mp { if this.iType == 3 { sp = 4 } else if this.iType == 4 { n1, _ := rand.Int(rand.Reader, big.NewInt(4)) // 随机一个消除类型 sp = int32(n1.Int64()) + 5 } if conf, err := this.module.configure.GetGameBlock(this.Plat[key].Color, sp); err == nil { this.Plat[key].Cid = conf.Key this.Plat[key].Special = conf.Type this.Plat[key].Score = conf.Score } else { // 错误打印 this.module.Errorf("cond conf err :%v,color:%d", err, this.Plat[key].Color) } } } } return bDrop } // 深拷贝 func (this *MapData) GetPalatData() (data []*pb.GirdeData) { for _, v := range this.Plat { data = append(data, &pb.GirdeData{ Oid: v.Oid, Color: v.Color, Cid: v.Cid, Score: v.Score, Special: v.Special, }) } return data } // ai操作 func (this *MapData) AiSwapGirde() (szMap []*pb.MapData, oid1 int32, oid2 int32, bAddPs bool) { for pos := 0; pos < Total; pos++ { y := pos % Height if y < Height-1 { if b := this.SwapGirde(int32(pos), int32(pos+1)); b { oid1 = this.Plat[pos+1].Oid oid2 = this.Plat[pos].Oid if m, b := this.CheckMap(2, true); len(m) == 0 { this.SwapGirde(int32(pos+1), int32(pos)) this.operElem = []int32{} oid1 = 0 oid2 = 0 } else { szMap = append(szMap, m...) bAddPs = b break } } } if pos/Width+1 < Width { if b := this.SwapGirde(int32(pos), int32(pos+Width)); b { oid1 = this.Plat[pos+Width].Oid oid2 = this.Plat[pos].Oid if m, b := this.CheckMap(2, true); len(m) == 0 { this.SwapGirde(int32(pos+Width), int32(pos)) this.operElem = []int32{} oid1 = 0 oid2 = 0 } else { szMap = append(szMap, m...) bAddPs = b break } } } } return } // 释放技能 技能id 和参数 func (this *MapData) SkillUp(pos int32, color int32, skillid int32, value int32, bDrop bool) (x map[int]struct{}, szMap []*pb.MapData) { var ( skillScore int32 // 技能获得的分数 skillEnergy int32 // 技能获得的能量 ids []int ) x = make(map[int]struct{}) if skillid == 1 { // 随机消除盘面上X个方块 ids = utils.RandomNumbers(0, Total-1, int(value)) } else if skillid == 4 { // 找到pos 位置的所有方块 x := int(pos / Width) y := int(pos % Height) for i := 1; i < 7; i++ { if x-i >= 0 && y+i < Height { // 左上 ids = append(ids, (x-i)*Width+(y+i)) } if x-i >= 0 && y-i >= 0 { // 左下 ids = append(ids, (x-i)*Width+(y-i)) } if x+i < Width && y+i < Height { // 右上 ids = append(ids, (x+i)*Width+(y+i)) } if x+i < Width && y-i >= 0 { // 右下 ids = append(ids, (x+i)*Width+(y-i)) } } } else if skillid == 5 { //选中一个方块,消除周围一圈 ids = append(ids, int(pos)) // 包含自己 x := int(pos / Width) y := int(pos % Height) if x-1 >= 0 { // 左 ids = append(ids, (x-1)*Width+(y)) } if y-1 >= 0 { // 下 ids = append(ids, (x)*Width+(y-1)) } if y+1 < Height { // 上 ids = append(ids, (x)*Width+(y+1)) } if x+1 < Width { // 右 ids = append(ids, (x+1)*Width+(y)) } if x-1 >= 0 && y+1 < Height { // 左上 ids = append(ids, (x-1)*Width+(y+1)) } if x-1 >= 0 && y-1 >= 0 { // 左下 ids = append(ids, (x-1)*Width+(y-1)) } if x+1 < Width && y+1 < Height { // 右上 ids = append(ids, (x+1)*Width+(y+1)) } if x+1 < Width && y-1 >= 0 { // 右下 ids = append(ids, (x+1)*Width+(y-1)) } } else if skillid == 2 { // 消除中间的一列宝石 for i := 0; i < Height; i++ { ids = append(ids, 3*Width+i) } } else if skillid == 3 { // 四周蔓延 第一次100% 第二次 60% 第三次 30% 第四次 10% 最多4次 for k := range this.Skill3(pos, 0) { ids = append(ids, k) // 转换成最终消除的坐标 } ids = append(ids, int(pos)) // 包含自己 } for _, id := range ids { if s := this.Plat[id].Special; s != 0 { for k := range this.SpecialElem(id, s) { x[k] = struct{}{} } } x[id] = struct{}{} } if bDrop { for key := range x { if this.Plat[key].Color == color { skillEnergy += 1 } skillScore += this.Plat[key].Score this.Plat[key] = &pb.GirdeData{} } if this.DropGirde() { szMap = append(szMap, &pb.MapData{ Data: this.GetPalatData(), CurSocre: skillScore, CurEnergy: skillEnergy, }) if list, _ := this.CheckMap(color, false); len(list) > 0 { szMap = append(szMap, list...) } } } return } // 校验当前地图 有没有能消除的 func (this *MapData) CheckAndRefreshPlat() (bEliminate bool) { bEliminate = false for k, v := range this.Plat { if v.Color == 0 { continue } x := int32(k % Height) y := int32(k / Height) if x+2 < Height { // 上 k1 := this.Plat[k].Color k2 := this.Plat[k+1].Color if k1 == k2 { // 校验k3 左边和右边 if true { pos := k + 2 if pos/Width-1 >= 0 { // 左 p := this.Plat[pos-Width].Color if p == k1 { bEliminate = true return } } if pos/Width+1 < Width { // 右 p := this.Plat[pos+Width].Color if p == k1 { bEliminate = true return } } if pos%Height+1 < Height { // 上 p := this.Plat[pos+1].Color if p == k1 { bEliminate = true return } } } // xia pos := k - 1 if x > 0 { if pos%Height >= 0 { // 左右 if pos/Width-1 >= 0 { //左 p := this.Plat[pos-Width].Color if p == k1 { bEliminate = true return } } if pos/Width+1 < Width { // 右 p := this.Plat[pos+Width].Color if p == k1 { bEliminate = true return } } } } if x > 1 { p := this.Plat[pos-1].Color if p == k1 { bEliminate = true return } } } } if y+2 < Height { // 左 k1 := this.Plat[k].Color k2 := this.Plat[k+Width].Color if k1 == k2 { // 校验k3 左边和右边 if true { pos := k + 2*Width if pos/Width+1 < Width { // 右 p := this.Plat[pos+Width].Color if p == k1 { bEliminate = true return } } if pos%Height+1 < Width { // 上 p := this.Plat[pos+1].Color if p == k1 { bEliminate = true return } } if pos%Height-1 >= 0 { p := this.Plat[pos-1].Color if p == k1 { bEliminate = true return } } } if true { pos := k - Width if pos >= 0 { if pos%Height+1 < Width { // 上 p := this.Plat[pos+1].Color if p == k1 { bEliminate = true return } } if pos%Height-1 >= 0 { // 下 p := this.Plat[pos-1].Color if p == k1 { bEliminate = true return } } } if pos/Height-1 >= 0 { p := this.Plat[pos-Height].Color if p == k1 { bEliminate = true return } } } } } } for k, v := range this.Plat { if v.Color == 0 { continue } // x := int32(k % Height) // x y := int32(k / Height) // y if y+2 < Width { k1 := this.Plat[k].Color k2 := this.Plat[k+2*Width].Color pos := k + Width if k1 == k2 { // 上 if pos%Height+1 < Height { p := this.Plat[pos+1].Color if p == k1 { bEliminate = true return } } if pos%Height-1 >= 0 { p := this.Plat[pos-1].Color if p == k1 { bEliminate = true return } } } } } // 上下检测中间元素左右互换 for k, v := range this.Plat { if v.Color == 0 { continue } if k%Height+2 < Height { k1 := this.Plat[k].Color k2 := this.Plat[k+2].Color pos := k + 1 if k1 == k2 { if pos/Height+1 < Width { // 右 p := this.Plat[pos+Width].Color if p == k1 { bEliminate = true return } } if pos/Height-1 >= 0 { // 右 p := this.Plat[pos-Width].Color if p == k1 { bEliminate = true return } } } } } if !bEliminate { fmt.Printf("=====地图数据不能交换===========\n") this.Debugf() } return } // 生成一个不能消除的地图 func (this *MapData) SetIndelibilityPlat() { 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 { if this.Plat[k+2].Special == 0 { newId := k + 2 oldId := Total - 1 for i := 0; i < Total; i++ { if this.Plat[oldId].Color == k3 { // 找到颜色不一样的 if oldId > 0 { oldId -= 1 } } else { break } } tmp := new(pb.GirdeData) *tmp = *this.Plat[newId] this.Plat[newId] = this.Plat[oldId] this.Plat[oldId] = tmp } } } 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 { if this.Plat[k+2*Width].Special == 0 { // 找最后一个交换 newId := k + 2*Width oldId := Total - 1 for i := 0; i < Total; i++ { if this.Plat[oldId].Color == k3 { // 找到颜色不一样的 oldId -= 1 } else { break } } tmp := new(pb.GirdeData) *tmp = *this.Plat[newId] this.Plat[newId] = this.Plat[oldId] this.Plat[oldId] = tmp } } } } if b, _ := this.Check3X(); b { fmt.Printf("plat init\n") this.CheckMap(0, false) } } // 重新洗牌 func (this *MapData) RedsetPlatData() { for i := 0; i < Total-1; i++ { targetId := comm.GetRandNum(0, Total-1) if i == int(targetId) { continue } tmp := new(pb.GirdeData) *tmp = *this.Plat[i] this.Plat[i] = this.Plat[targetId] this.Plat[targetId] = tmp } this.SetIndelibilityPlat() } //四周蔓延 第一次100% 第二次 60% 第三次 30% 第四次 10% 最多4次 func (this *MapData) Skill3(pos int32, count int32) (m map[int]struct{}) { m = make(map[int]struct{}, 0) var sz []int var percent int32 var cur []int // 先找出可以蔓延的方向 x := int(pos / Width) y := int(pos % Height) if x-1 >= 0 { // 左 sz = append(sz, (x-1)*Width+(y)) } if y-1 >= 0 { // 下 sz = append(sz, (x)*Width+(y-1)) } if y+1 < Height { // 上 sz = append(sz, (x)*Width+(y+1)) } if x+1 < Width { // 右 sz = append(sz, (x+1)*Width+(y)) } if count == 0 { // 蔓延技能概率调整支持配置 percent = 100 } else if count == 1 { percent = 60 } else if count == 2 || count == 3 { percent = 30 } else { return } szid := utils.RandomNumbers(0, len(sz), 2) for _, v := range szid { if percent >= comm.GetRandNum(0, 100) { m[sz[v]] = struct{}{} cur = append(cur, sz[v]) } } count++ // for _, v := range cur { // fmt.Printf("=======蔓延的id:%d====,count=%d====\n", v, count) // } // fmt.Printf("=======count=%d====\n", count) for _, k := range cur { for k1 := range this.Skill3(int32(k), count) { // 递归蔓延 m[k1] = struct{}{} } } return } // 获取BoomType 类型周围的所有元素(pos 四周+ 四周的上下左右) func (this *MapData) GetBoomElem(pos int) (elem []int) { x := int(pos / Width) y := int(pos % Height) if x-1 >= 0 { // 左 elem = append(elem, (x-1)*Width+(y)) } if y-1 >= 0 { // 下 elem = append(elem, (x)*Width+(y-1)) } if y+1 < Height { // 上 elem = append(elem, (x)*Width+(y+1)) } if x+1 < Width { // 右 elem = append(elem, (x+1)*Width+(y)) } if x-1 >= 0 && y+1 < Height { // 左上 elem = append(elem, (x-1)*Width+(y+1)) } if x-1 >= 0 && y-1 >= 0 { // 左下 elem = append(elem, (x-1)*Width+(y-1)) } if x+1 < Width && y+1 < Height { // 右上 elem = append(elem, (x+1)*Width+(y+1)) } if x+1 < Width && y-1 >= 0 { // 右下 elem = append(elem, (x+1)*Width+(y-1)) } /// if x-2 >= 0 { // 左左 elem = append(elem, (x-2)*Width+(y)) } if y-2 >= 0 { // 下下 elem = append(elem, (x)*Width+(y-2)) } if y+2 < Height { // 上上 elem = append(elem, (x)*Width+(y+2)) } if x+2 < Width { // 右右 elem = append(elem, (x+2)*Width+(y)) } return } func (this *MapData) GetFireBoom(pos int, itype int32) (elem []int) { x := int(pos / Width) y := int(pos % Height) if itype == FireUp || itype == FireDown || itype == FireLeft || itype == FireRight { elem = append(elem, pos) } switch itype { case FireUp: //上烟火 for i := 0; i < Height; i++ { if y+1 < Height { // 上上 elem = append(elem, (x)*Width+(y+1)) y += 1 } } case FireDown: //下烟火 for i := 0; i < Height; i++ { if y-1 >= 0 { // 下下 elem = append(elem, (x)*Width+(y-1)) y -= 1 } } case FireLeft: //左烟火 for i := 0; i < Height; i++ { if x-1 >= 0 { // 左左 elem = append(elem, (x-1)*Width+(y)) x -= 1 } } case FireRight: //右烟火 for i := 0; i < Height; i++ { if x+1 < Width { // 右右 elem = append(elem, (x+1)*Width+(y)) x += 1 } } } return } // 特殊类型元素 统一处理 func (this *MapData) SpecialElem(id int, s int32) (x map[int]struct{}) { if s <= 0 { return } x = make(map[int]struct{}) if s == FourUType { // 4消上下类型 for i := 0; i < Height; i++ { // id 的一条线位置 x[(id/Width)*Height+i] = struct{}{} } } else if s == FourLType { // 左右类型 for i := 0; i < Width; i++ { // id 的一条线位置 x[id%Height+i*Width] = struct{}{} } } else if s == FiveType { // 随机消除 // 获取配置 if c, _ := this.module.configure.GetGameBlock(this.Plat[id].Color, FiveType); c != nil { ids := utils.RandomNumbers(0, Total-1, int(c.Value)) for _, v := range ids { x[v] = struct{}{} } } } else if s == BoomType { // 炸弹类型 带走周围一圈+ 上下左右 for _, key := range this.GetBoomElem(id) { x[key] = struct{}{} } } else if s == FireUp || s == FireDown || s == FireLeft || s == FireRight { // 烟花技能 for _, key := range this.GetFireBoom(id, s) { x[key] = struct{}{} } } this.Plat[id].Special = 0 x[id] = struct{}{} for k := range x { if k == id { continue } if this.Plat[k].Special != 0 { ids := this.SpecialElem(k, this.Plat[k].Special) // 递归调用 for key := range ids { x[key] = struct{}{} } } } return }