新增辐射图,移除不合理Match3内容
This commit is contained in:
parent
b9d6575c4f
commit
8bbaf03ed8
|
@ -1,224 +0,0 @@
|
|||
package matrix
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/g2d"
|
||||
"github.com/kercylan98/minotaur/utils/synchronization"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func NewMatch3[ItemType comparable, Item Match3Item[ItemType]](width, height int, options ...Match3Option[ItemType, Item]) *Match3[ItemType, Item] {
|
||||
match3 := &Match3[ItemType, Item]{
|
||||
matrix: NewMatrix[Item](width, height),
|
||||
generators: map[ItemType]func() Item{},
|
||||
links: synchronization.NewMap[int64, map[int64]bool](),
|
||||
positions: map[int64][2]int{},
|
||||
notNil: map[int]map[int]bool{},
|
||||
matchStrategy: map[int]func(matrix [][]Item) [][]Item{},
|
||||
generateNotMatchRetryCount: 3,
|
||||
}
|
||||
for x := 0; x < width; x++ {
|
||||
match3.notNil[x] = map[int]bool{}
|
||||
}
|
||||
for _, option := range options {
|
||||
option(match3)
|
||||
}
|
||||
if len(match3.generators) == 0 {
|
||||
panic("please use WithMatch3Generator set at least one generation strategy")
|
||||
}
|
||||
if len(match3.matchStrategy) == 0 {
|
||||
panic("please use WithMatch3Strategy set at least one match strategy")
|
||||
}
|
||||
return match3
|
||||
}
|
||||
|
||||
// Match3 基于三消类游戏的二维矩阵
|
||||
// - 提供了适合三消类游戏的功能
|
||||
type Match3[ItemType comparable, Item Match3Item[ItemType]] struct {
|
||||
matrix *Matrix[Item]
|
||||
|
||||
guid int64 // 成员guid
|
||||
links *synchronization.Map[int64, map[int64]bool] // 成员类型相同且相连的链接
|
||||
positions map[int64][2]int // 根据成员guid记录的成员位置
|
||||
notNil map[int]map[int]bool // 特定位置是否不为空
|
||||
|
||||
generators map[ItemType]func() Item // 成员生成器
|
||||
matchStrategy map[int]func(matrix [][]Item) [][]Item // 匹配策略
|
||||
generateNotMatchRetryCount int // 生成不匹配类型重试次数
|
||||
}
|
||||
|
||||
// GetHeight 获取高度
|
||||
func (slf *Match3[ItemType, Item]) GetHeight() int {
|
||||
return slf.matrix.h
|
||||
}
|
||||
|
||||
// GetWidth 获取宽度
|
||||
func (slf *Match3[ItemType, Item]) GetWidth() int {
|
||||
return slf.matrix.w
|
||||
}
|
||||
|
||||
// GenerateItem 在特定位置生成特定类型的成员
|
||||
func (slf *Match3[ItemType, Item]) GenerateItem(x, y int, itemType ItemType) Item {
|
||||
item := slf.generators[itemType]()
|
||||
item.SetGuid(slf.getNextGuid())
|
||||
slf.set(x, y, item)
|
||||
return item
|
||||
}
|
||||
|
||||
// Predict 预言
|
||||
func (slf *Match3[ItemType, Item]) Predict() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// GenerateItemsByNotMatch 生成一批在特定位置不会触发任何匹配规则的成员类型
|
||||
// - 这一批成员不会被加入到矩阵中,索引与位置索引相对应
|
||||
// - 无解的策略下会导致死循环
|
||||
func (slf *Match3[ItemType, Item]) GenerateItemsByNotMatch(xys ...[2]int) (result []ItemType) {
|
||||
result = make([]ItemType, 0, len(xys))
|
||||
lastIndex := len(xys) - 1
|
||||
retry := 0
|
||||
backup := NewBackup(slf)
|
||||
start:
|
||||
{
|
||||
for i, xy := range xys {
|
||||
x, y := g2d.PositionArrayToXY(xy)
|
||||
var match bool
|
||||
for _, f := range slf.generators {
|
||||
slf.set(x, y, f())
|
||||
for i := 1; i <= len(slf.matchStrategy); i++ {
|
||||
if len(slf.matchStrategy[i](slf.matrix.m)) > 0 {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
break
|
||||
}
|
||||
}
|
||||
if match {
|
||||
if i == lastIndex {
|
||||
if retry < slf.generateNotMatchRetryCount {
|
||||
retry++
|
||||
result = result[:0]
|
||||
backup.Restore()
|
||||
goto start
|
||||
} else {
|
||||
panic("no solution, the matrix rule is wrong or there are matching members.")
|
||||
}
|
||||
} else {
|
||||
result = result[:0]
|
||||
backup.Restore()
|
||||
goto start
|
||||
}
|
||||
}
|
||||
result = append(result, slf.matrix.m[x][y].GetType())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetMatch 获取二维矩阵
|
||||
// - 该矩阵为克隆的,意味着任何修改都不会影响原有内容
|
||||
func (slf *Match3[ItemType, Item]) GetMatch() [][]Item {
|
||||
var (
|
||||
width = slf.GetWidth()
|
||||
height = slf.GetHeight()
|
||||
clone = make([][]Item[ItemType], width)
|
||||
)
|
||||
for x := 0; x < width; x++ {
|
||||
ys := make([]Item, height)
|
||||
for y := 0; y < height; y++ {
|
||||
ys[y] = slf.matrix.m[x][y].Clone().(Item)
|
||||
}
|
||||
clone[x] = ys
|
||||
}
|
||||
return clone
|
||||
}
|
||||
|
||||
// 设置特定位置的成员
|
||||
func (slf *Match3[ItemType, Item]) set(x, y int, item Item) {
|
||||
if old := slf.matrix.m[x][y]; slf.notNil[x][y] {
|
||||
oldGuid := old.GetGuid()
|
||||
for linkGuid := range slf.links.Get(oldGuid) {
|
||||
xy := slf.positions[linkGuid]
|
||||
slf.searchNeighbour(xy[0], xy[1], synchronization.NewMap[int64, bool](), synchronization.NewMap[int64, bool]())
|
||||
}
|
||||
slf.links.Delete(oldGuid)
|
||||
}
|
||||
|
||||
slf.notNil[x][y] = true
|
||||
slf.matrix.Set(x, y, item)
|
||||
slf.positions[item.GetGuid()] = [2]int{x, y}
|
||||
slf.searchNeighbour(x, y, synchronization.NewMap[int64, bool](), synchronization.NewMap[int64, bool]())
|
||||
}
|
||||
|
||||
func (slf *Match3[ItemType, Item]) searchNeighbour(x, y int, filter *synchronization.Map[int64, bool], childrenLinks *synchronization.Map[int64, bool]) {
|
||||
var (
|
||||
item = slf.matrix.m[x][y]
|
||||
neighboursLock sync.Mutex
|
||||
neighbours = map[int64]bool{}
|
||||
itemType = item.GetType()
|
||||
wait sync.WaitGroup
|
||||
itemGuid = item.GetGuid()
|
||||
handle = func(x, y int) bool {
|
||||
neighbour := slf.matrix.m[x][y]
|
||||
if !slf.notNil[x][y] || neighbour.GetType() != itemType {
|
||||
return false
|
||||
}
|
||||
neighbourGuid := neighbour.GetGuid()
|
||||
neighboursLock.Lock()
|
||||
neighbours[neighbourGuid] = true
|
||||
neighboursLock.Unlock()
|
||||
childrenLinks.Set(neighbourGuid, true)
|
||||
slf.searchNeighbour(x, y, filter, childrenLinks)
|
||||
return true
|
||||
}
|
||||
)
|
||||
if filter.Get(itemGuid) {
|
||||
return
|
||||
}
|
||||
filter.Set(itemGuid, true)
|
||||
wait.Add(4)
|
||||
go func() {
|
||||
for sy := y - 1; sy >= 0; sy-- {
|
||||
if !handle(x, sy) {
|
||||
break
|
||||
}
|
||||
}
|
||||
wait.Done()
|
||||
}()
|
||||
go func() {
|
||||
for sy := y + 1; sy < slf.matrix.h; sy++ {
|
||||
if !handle(x, sy) {
|
||||
break
|
||||
}
|
||||
}
|
||||
wait.Done()
|
||||
}()
|
||||
go func() {
|
||||
for sx := x - 1; sx >= 0; sx-- {
|
||||
if !handle(sx, y) {
|
||||
break
|
||||
}
|
||||
}
|
||||
wait.Done()
|
||||
}()
|
||||
go func() {
|
||||
for sx := x + 1; sx < slf.matrix.w; sx++ {
|
||||
if !handle(sx, y) {
|
||||
break
|
||||
}
|
||||
}
|
||||
wait.Done()
|
||||
}()
|
||||
wait.Wait()
|
||||
childrenLinks.Range(func(key int64, value bool) {
|
||||
neighbours[key] = value
|
||||
})
|
||||
slf.links.Set(itemGuid, neighbours)
|
||||
}
|
||||
|
||||
// 获取下一个guid
|
||||
func (slf *Match3[ItemType, Item]) getNextGuid() int64 {
|
||||
slf.guid++
|
||||
return slf.guid
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package matrix
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/g2d"
|
||||
"github.com/kercylan98/minotaur/utils/hash"
|
||||
"github.com/kercylan98/minotaur/utils/synchronization"
|
||||
)
|
||||
|
||||
func NewBackup[ItemType comparable, Item Match3Item[ItemType]](match3 *Match3[ItemType, Item]) *Match3Backup[ItemType, Item] {
|
||||
backup := &Match3Backup[ItemType, Item]{match3: match3}
|
||||
|
||||
backup.guid = match3.guid
|
||||
backup.links = synchronization.NewMap[int64, map[int64]bool]()
|
||||
match3.links.Range(func(key int64, value map[int64]bool) {
|
||||
backup.links.Set(key, hash.Copy(value))
|
||||
})
|
||||
backup.positions = map[int64][2]int{}
|
||||
for key, value := range match3.positions {
|
||||
backup.positions[key] = g2d.PositionClone(value)
|
||||
}
|
||||
backup.notNil = map[int]map[int]bool{}
|
||||
for key, values := range match3.notNil {
|
||||
var notNil = map[int]bool{}
|
||||
for key, value := range values {
|
||||
notNil[key] = value
|
||||
}
|
||||
backup.notNil[key] = notNil
|
||||
}
|
||||
return backup
|
||||
}
|
||||
|
||||
type Match3Backup[ItemType comparable, Item Match3Item[ItemType]] struct {
|
||||
match3 *Match3[ItemType, Item]
|
||||
|
||||
guid int64 // 成员guid
|
||||
links *synchronization.Map[int64, map[int64]bool] // 成员类型相同且相连的链接
|
||||
positions map[int64][2]int // 根据成员guid记录的成员位置
|
||||
notNil map[int]map[int]bool // 特定位置是否不为空
|
||||
}
|
||||
|
||||
// Restore 还原备份
|
||||
func (slf *Match3Backup[ItemType, Item]) Restore() {
|
||||
slf.match3.guid = slf.guid
|
||||
slf.match3.links = synchronization.NewMap[int64, map[int64]bool]()
|
||||
slf.links.Range(func(key int64, value map[int64]bool) {
|
||||
slf.match3.links.Set(key, hash.Copy(value))
|
||||
})
|
||||
slf.match3.positions = map[int64][2]int{}
|
||||
for key, value := range slf.positions {
|
||||
slf.match3.positions[key] = g2d.PositionClone(value)
|
||||
}
|
||||
slf.match3.notNil = map[int]map[int]bool{}
|
||||
for key, values := range slf.notNil {
|
||||
var notNil = map[int]bool{}
|
||||
for key, value := range values {
|
||||
notNil[key] = value
|
||||
}
|
||||
slf.match3.notNil[key] = notNil
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package matrix
|
||||
|
||||
// Match3Item 三消成员接口定义
|
||||
type Match3Item[Type comparable] interface {
|
||||
// SetGuid 设置guid
|
||||
SetGuid(guid int64)
|
||||
// GetGuid 获取guid
|
||||
GetGuid() int64
|
||||
// GetType 获取成员类型
|
||||
GetType() Type
|
||||
// Clone 克隆
|
||||
Clone() Match3Item[Type]
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package matrix
|
||||
|
||||
type Match3Option[ItemType comparable, Item Match3Item[ItemType]] func(match3 *Match3[ItemType, Item])
|
||||
|
||||
func WithMatch3Generator[ItemType comparable, Item Match3Item[ItemType]](itemType ItemType, generator func() Item) Match3Option[ItemType, Item] {
|
||||
return func(match3 *Match3[ItemType, Item]) {
|
||||
match3.generators[itemType] = generator
|
||||
}
|
||||
}
|
||||
|
||||
// WithMatch3Tactics 设置匹配策略
|
||||
// - 匹配策略用于匹配出对应成员
|
||||
func WithMatch3Tactics[ItemType comparable, Item Match3Item[ItemType]](tactics func(matrix [][]Item) [][]Item) Match3Option[ItemType, Item] {
|
||||
return func(match3 *Match3[ItemType, Item]) {
|
||||
match3.matchStrategy[len(match3.matchStrategy)+1] = tactics
|
||||
}
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
package matrix
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kercylan98/minotaur/utils/g2d"
|
||||
"github.com/kercylan98/minotaur/utils/random"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Item[Type comparable] struct {
|
||||
guid int64
|
||||
t Type
|
||||
}
|
||||
|
||||
func (slf *Item[Type]) SetGuid(guid int64) {
|
||||
slf.guid = guid
|
||||
}
|
||||
|
||||
func (slf *Item[Type]) GetGuid() int64 {
|
||||
return slf.guid
|
||||
}
|
||||
|
||||
func (slf *Item[Type]) GetType() Type {
|
||||
return slf.t
|
||||
}
|
||||
|
||||
func (slf *Item[Type]) Clone() Match3Item[Type] {
|
||||
return &Item[Type]{
|
||||
guid: slf.guid,
|
||||
t: slf.t,
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatch3(t *testing.T) {
|
||||
var options []Match3Option[int, *Item[int]]
|
||||
for i := 0; i < 7; i++ {
|
||||
t := i + 1
|
||||
options = append(options, WithMatch3Generator[int, *Item[int]](t, func() *Item[int] {
|
||||
return &Item[int]{t: t}
|
||||
}))
|
||||
}
|
||||
var match3 = NewMatch3[int, *Item[int]](3, 3,
|
||||
options...,
|
||||
)
|
||||
|
||||
for x := 0; x < match3.GetWidth(); x++ {
|
||||
for y := 0; y < match3.GetHeight(); y++ {
|
||||
match3.GenerateItem(x, y, random.Int(1, 2))
|
||||
}
|
||||
}
|
||||
|
||||
for y := 0; y < match3.GetHeight(); y++ {
|
||||
for x := 0; x < match3.GetWidth(); x++ {
|
||||
fmt.Print(match3.matrix.m[x][y].t, " ")
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Println()
|
||||
links := match3.links.Get(4)
|
||||
linkItem := match3.matrix.m[match3.positions[4][0]][match3.positions[4][1]]
|
||||
fmt.Println("LINK", linkItem.t, match3.positions[4])
|
||||
|
||||
for y := 0; y < match3.GetHeight(); y++ {
|
||||
for x := 0; x < match3.GetWidth(); x++ {
|
||||
item := match3.matrix.m[x][y]
|
||||
if links[item.guid] {
|
||||
fmt.Print("*", " ")
|
||||
} else {
|
||||
fmt.Print(match3.matrix.m[x][y].t, " ")
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
var now = time.Now()
|
||||
var xys [][2]int
|
||||
for guid := range links {
|
||||
xys = append(xys, match3.positions[guid])
|
||||
}
|
||||
|
||||
for _, rect := range g2d.SearchNotRepeatFullRectangle(2, 2, xys...) {
|
||||
fmt.Println(fmt.Sprintf("找到矩形: TopLeft: (%d, %d), BottomRight: (%d, %d)", rect[0][0], rect[0][1], rect[1][0], rect[1][1]))
|
||||
}
|
||||
fmt.Println("耗时", time.Since(now))
|
||||
|
||||
now = time.Now()
|
||||
for _, rect := range g2d.SearchNotRepeatCross(xys...) {
|
||||
fmt.Print("找到十字:")
|
||||
for _, points := range rect {
|
||||
fmt.Print(fmt.Sprintf("{%d, %d}", points[0], points[1]))
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Println("耗时", time.Since(now))
|
||||
|
||||
now = time.Now()
|
||||
for _, rect := range g2d.SearchNotRepeatRightAngle(4, xys...) {
|
||||
fmt.Print("找到L形:")
|
||||
for _, points := range rect {
|
||||
fmt.Print(fmt.Sprintf("{%d, %d}", points[0], points[1]))
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Println("耗时", time.Since(now))
|
||||
|
||||
now = time.Now()
|
||||
for _, rect := range g2d.SearchNotRepeatT(4, xys...) {
|
||||
fmt.Print("找到T形:")
|
||||
for _, points := range rect {
|
||||
fmt.Print(fmt.Sprintf("{%d, %d}", points[0], points[1]))
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Println("耗时", time.Since(now))
|
||||
|
||||
now = time.Now()
|
||||
for _, rect := range g2d.SearchNotRepeatStraightLine(3, xys...) {
|
||||
fmt.Print("找到直线:")
|
||||
for _, points := range rect {
|
||||
fmt.Print(fmt.Sprintf("{%d, %d}", points[0], points[1]))
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Println("耗时", time.Since(now))
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package g2d
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/hash"
|
||||
"github.com/kercylan98/minotaur/utils/synchronization"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func NewRadiationPattern[ItemType comparable, Item RadiationPatternItem[ItemType]](matrix [][]Item) *RadiationPattern[ItemType, Item] {
|
||||
var clone = make([][]Item, len(matrix))
|
||||
for x := 0; x < len(matrix); x++ {
|
||||
ys := make([]Item, len(matrix[0]))
|
||||
for y := 0; y < len(matrix[0]); y++ {
|
||||
ys[y] = matrix[x][y]
|
||||
}
|
||||
clone[x] = ys
|
||||
}
|
||||
rp := &RadiationPattern[ItemType, Item]{
|
||||
matrix: clone,
|
||||
links: synchronization.NewMap[int64, map[int64]bool](),
|
||||
positions: map[int64][2]int{},
|
||||
}
|
||||
for x := 0; x < len(matrix); x++ {
|
||||
for y := 0; y < len(matrix[0]); y++ {
|
||||
item := matrix[x][y]
|
||||
rp.positions[item.GetGuid()] = PositionToArray(x, y)
|
||||
rp.searchNeighbour(x, y, synchronization.NewMap[int64, bool](), synchronization.NewMap[int64, bool]())
|
||||
}
|
||||
}
|
||||
return rp
|
||||
}
|
||||
|
||||
// RadiationPattern 辐射图数据结构
|
||||
// - 辐射图用于将一个二维数组里相邻的所有类型相同的成员进行标注
|
||||
type RadiationPattern[ItemType comparable, Item RadiationPatternItem[ItemType]] struct {
|
||||
matrix [][]Item
|
||||
links *synchronization.Map[int64, map[int64]bool] // 成员类型相同且相连的链接
|
||||
positions map[int64][2]int // 根据成员guid记录的成员位置
|
||||
}
|
||||
|
||||
// GetLinks 获取特定成员能够辐射到的所有成员
|
||||
func (slf *RadiationPattern[ItemType, Item]) GetLinks(guid int64) []int64 {
|
||||
return hash.KeyToSlice(slf.links.Get(guid))
|
||||
}
|
||||
|
||||
// Refresh 刷新特定位置成员并且更新其辐射信息
|
||||
func (slf *RadiationPattern[ItemType, Item]) Refresh(x, y int, item Item) {
|
||||
old := slf.matrix[x][y]
|
||||
oldGuid := old.GetGuid()
|
||||
for linkGuid := range slf.links.Get(oldGuid) {
|
||||
xy := slf.positions[linkGuid]
|
||||
slf.searchNeighbour(xy[0], xy[1], synchronization.NewMap[int64, bool](), synchronization.NewMap[int64, bool]())
|
||||
}
|
||||
slf.links.Delete(oldGuid)
|
||||
delete(slf.positions, oldGuid)
|
||||
|
||||
slf.positions[item.GetGuid()] = PositionToArray(x, y)
|
||||
slf.searchNeighbour(x, y, synchronization.NewMap[int64, bool](), synchronization.NewMap[int64, bool]())
|
||||
}
|
||||
|
||||
func (slf *RadiationPattern[ItemType, Item]) searchNeighbour(x, y int, filter *synchronization.Map[int64, bool], childrenLinks *synchronization.Map[int64, bool]) {
|
||||
var (
|
||||
item = slf.matrix[x][y]
|
||||
neighboursLock sync.Mutex
|
||||
neighbours = map[int64]bool{}
|
||||
itemType = item.GetType()
|
||||
wait sync.WaitGroup
|
||||
itemGuid = item.GetGuid()
|
||||
handle = func(x, y int) bool {
|
||||
neighbour := slf.matrix[x][y]
|
||||
if neighbour.GetType() != itemType {
|
||||
return false
|
||||
}
|
||||
neighbourGuid := neighbour.GetGuid()
|
||||
neighboursLock.Lock()
|
||||
neighbours[neighbourGuid] = true
|
||||
neighboursLock.Unlock()
|
||||
childrenLinks.Set(neighbourGuid, true)
|
||||
slf.searchNeighbour(x, y, filter, childrenLinks)
|
||||
return true
|
||||
}
|
||||
)
|
||||
if filter.Get(itemGuid) {
|
||||
return
|
||||
}
|
||||
filter.Set(itemGuid, true)
|
||||
wait.Add(4)
|
||||
go func() {
|
||||
for sy := y - 1; sy >= 0; sy-- {
|
||||
if !handle(x, sy) {
|
||||
break
|
||||
}
|
||||
}
|
||||
wait.Done()
|
||||
}()
|
||||
go func() {
|
||||
for sy := y + 1; sy < len(slf.matrix[0]); sy++ {
|
||||
if !handle(x, sy) {
|
||||
break
|
||||
}
|
||||
}
|
||||
wait.Done()
|
||||
}()
|
||||
go func() {
|
||||
for sx := x - 1; sx >= 0; sx-- {
|
||||
if !handle(sx, y) {
|
||||
break
|
||||
}
|
||||
}
|
||||
wait.Done()
|
||||
}()
|
||||
go func() {
|
||||
for sx := x + 1; sx < len(slf.matrix); sx++ {
|
||||
if !handle(sx, y) {
|
||||
break
|
||||
}
|
||||
}
|
||||
wait.Done()
|
||||
}()
|
||||
wait.Wait()
|
||||
childrenLinks.Range(func(key int64, value bool) {
|
||||
neighbours[key] = value
|
||||
})
|
||||
slf.links.Set(itemGuid, neighbours)
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package g2d
|
||||
|
||||
type RadiationPatternItem[Type comparable] interface {
|
||||
GetGuid() int64
|
||||
GetType() Type
|
||||
}
|
|
@ -15,6 +15,19 @@ func Copy[V any](slice []V) []V {
|
|||
return s
|
||||
}
|
||||
|
||||
// CopyMatrix 复制二维数组
|
||||
func CopyMatrix[V any](slice [][]V) [][]V {
|
||||
var s = make([][]V, len(slice), len(slice))
|
||||
for i := 0; i < len(slice); i++ {
|
||||
is := make([]V, len(slice[0]))
|
||||
for j := 0; j < len(slice[0]); j++ {
|
||||
is[j] = slice[i][j]
|
||||
}
|
||||
s[i] = is
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Insert 在特定索引插入元素
|
||||
func Insert[V any](slice *[]V, index int, value V) {
|
||||
s := *slice
|
||||
|
|
Loading…
Reference in New Issue