diff --git a/utils/g2d/dropper.go b/utils/g2d/dropper.go deleted file mode 100644 index 752b90c..0000000 --- a/utils/g2d/dropper.go +++ /dev/null @@ -1,33 +0,0 @@ -package g2d - -func NewDropper[T any](matrix [][]T, setPosition func(x, y, newX, newY int), allowDrop, allowCross, isObstacle func(data T) bool) *Dropper[T] { - return &Dropper[T]{ - matrix: matrix, - width: len(matrix) + 1, - height: len(matrix[0]), - setPosition: setPosition, - allowDrop: allowDrop, - allowCross: allowCross, - isObstacle: isObstacle, - } -} - -// Dropper 掉落器 -type Dropper[T any] struct { - matrix [][]T - width, height int - setPosition func(x, y, newX, newY int) - allowDrop, allowCross, isObstacle func(data T) bool -} - -func (slf *Dropper[T]) Drop() { - - for x := 0; x < slf.width; x++ { - for y := slf.height - 1; y >= 0; y-- { - data := slf.matrix[x][y] - if slf.allowDrop(data) { - - } - } - } -} diff --git a/utils/g2d/physics.go b/utils/g2d/physics.go new file mode 100644 index 0000000..ab81172 --- /dev/null +++ b/utils/g2d/physics.go @@ -0,0 +1,126 @@ +package g2d + +// SlideDropXY 侧滑掉落特定位置成员 +func SlideDropXY[T any](matrix [][]T, x, y int, isStop func(x, y int, data T) bool) (dropX, dropY int) { + width, height := len(matrix), len(matrix[0]) + var offsetX, offsetY = -1, 1 + for { + targetX, targetY := x+offsetX, y+offsetY + if targetX < 0 || targetY == height || isStop(targetX, targetY, matrix[targetX][targetY]) { + dropX, dropY = targetX+1, targetY-1 + break + } + offsetX-- + offsetY++ + } + offsetX, offsetY = 1, 1 + for dropX != x && dropY != y { + targetX, targetY := x+offsetX, y+offsetY + if targetX == width || targetY == height || isStop(targetX, targetY, matrix[targetX][targetY]) { + dropX, dropY = targetX-1, targetY-1 + break + } + offsetX++ + offsetY++ + } + return +} + +// SlideDropX 侧滑掉落一整列 +// - 返回每一个成员的y轴新坐标 +func SlideDropX[T any](matrix [][]T, x int, isStop func(x, y int, data T) bool) (result []int, change bool) { + result = make([]int, len(matrix[x])) + for y := len(matrix[x]) - 1; y >= 0; y-- { + _, dropY := SlideDropXY(matrix, x, y, isStop) + result[y] = dropY + if y != dropY { + change = true + } + } + return +} + +// SlideDropY 侧滑掉落一整行 +// - 返回每一个成员的x轴新坐标 +func SlideDropY[T any](matrix [][]T, y int, isStop func(x, y int, data T) bool) (result []int, change bool) { + result = make([]int, len(matrix)) + for x := 0; x < len(matrix); x++ { + dropX, _ := SlideDropXY(matrix, x, y, isStop) + result[x] = dropX + if x != dropX { + change = true + } + } + return +} + +// SlideDrop 侧滑掉落整个矩阵 +func SlideDrop[T any](matrix [][]T, isStop func(x, y int, data T) bool) (result [][][2]int, change bool) { + result = make([][][2]int, len(matrix)) + for x := 0; x < len(matrix); x++ { + ys := make([][2]int, len(matrix[x])) + var dropYs []int + dropYs, change = SlideDropX(matrix, x, isStop) + for y, positionY := range dropYs { + ys[y] = PositionToArray(x, positionY) + } + result[x] = ys + } + return +} + +// VerticalDropXY 垂直掉落特定位置成员 +func VerticalDropXY[T any](matrix [][]T, x, y int, isStop func(x, y int, data T) bool) (dropX, dropY int) { + height := len(matrix[0]) + var offsetY = 1 + for { + testY := y + offsetY + if testY == height || isStop(x, testY, matrix[x][testY]) { + return x, testY - 1 + } + offsetY++ + } +} + +// VerticalDropX 垂直掉落一整列 +// - 返回每一个成员的y轴新坐标 +func VerticalDropX[T any](matrix [][]T, x int, isStop func(x, y int, data T) bool) (result []int, change bool) { + result = make([]int, len(matrix[x])) + for y := len(matrix[x]) - 1; y >= 0; y-- { + _, dropY := VerticalDropXY(matrix, x, y, isStop) + result[y] = dropY + if y != dropY { + change = true + } + } + return +} + +// VerticalDropY 垂直掉落一整行 +// - 返回每一个成员的x轴新坐标 +func VerticalDropY[T any](matrix [][]T, y int, isStop func(x, y int, data T) bool) (result []int, change bool) { + result = make([]int, len(matrix)) + for x := 0; x < len(matrix); x++ { + dropX, _ := VerticalDropXY(matrix, x, y, isStop) + result[x] = dropX + if x != dropX { + change = true + } + } + return +} + +// VerticalDrop 垂直掉落整个矩阵 +func VerticalDrop[T any](matrix [][]T, isStop func(x, y int, data T) bool) (result [][][2]int, change bool) { + result = make([][][2]int, len(matrix)) + for x := 0; x < len(matrix); x++ { + ys := make([][2]int, len(matrix[x])) + var dropYs []int + dropYs, change = VerticalDropX(matrix, x, isStop) + for y, positionY := range dropYs { + ys[y] = PositionToArray(x, positionY) + } + result[x] = ys + } + return +}