Go 2048游戏的正确磁砖移动

Go 2048游戏的正确磁砖移动,go,logic,tiles-game,Go,Logic,Tiles Game,我决定制作一个2048命令行版本,但是我在获得正确的瓷砖移动方面遇到了困难 我目前的结构是该电路板是一个整数的2D阵列(4x4)。当接收到输入时,它将尝试按该方向推送每个磁贴(忽略值为0的磁贴),如果注意到更改,它将重新开始(因为底部一行的磁贴必须一直向上推,而不仅仅是向上一步)。然而,这样做的副作用是以下问题: [2] [2][4]使用命令->应给出[0][4][4],但由于它重新启动,程序将能够合并4和4并获得[0][0][8]整数… 另一个难题是[4][4][8][8],它应该给出[0][

我决定制作一个2048命令行版本,但是我在获得正确的瓷砖移动方面遇到了困难

我目前的结构是该电路板是一个整数的2D阵列(4x4)。当接收到输入时,它将尝试按该方向推送每个磁贴(忽略值为0的磁贴),如果注意到更改,它将重新开始(因为底部一行的磁贴必须一直向上推,而不仅仅是向上一步)。然而,这样做的副作用是以下问题:
[2] [2][4]使用命令->应给出[0][4][4],但由于它重新启动,程序将能够合并4和4并获得[0][0][8]整数…
另一个难题是[4][4][8][8],它应该给出[0][0][8][16],所以我不能在合并后就停下来

下面的代码是我的processCommand函数。它接受一块棋盘和一个输入(即“d”、“u”、“l”或“r”。如果游戏注意到gameover,它会将“gameover”作为输入)。这不是很漂亮,我试着做了一个用于移动瓷砖的单for循环(比如如果你写“l”,那么horiz的值将是-1,如果你写“r”,它将是1,然后我将瓷砖horiz点水平移动,但我无法做到这一点)

任何关于如何做到这一点的想法(以及对我的编程的评论)都将不胜感激

func processCommand(board [][]int, input string) {

board_new := board

switch input {
    case "d":
        for i := 0; i < height - 1; i++ {
            for j := 0; j < width; j++ {

                if board[i][j] == 0 {
                    continue
                }

                if board[i + 1][j] == 0 || board[i + 1][j] == board[i][j] {
                    board_new[i + 1][j] = board[i + 1][j] + board[i][j]
                    board_new[i][j] = 0
                    i = 0
                    j = 0
                    change = true
                }
            }
        }

    case "u":
        for i := 1; i < height; i++ {
            for j := 0; j < width; j++ {

                if board[i][j] == 0 {
                    continue
                }

                if board[i - 1][j] == 0 || board[i - 1][j] == board[i][j] {
                    board_new[i - 1][j] = board[i - 1][j] + board[i][j]
                    board_new[i][j] = 0
                    i = 1
                    j = 0
                    change = true
                }
            }
        } 

    case "l":
        for i := 0; i < height; i++ {
            for j := 1; j < width; j++ {

                if board[i][j] == 0 {
                    continue
                }

                if board[i][j - 1] == 0 || board[i][j - 1] == board[i][j] {
                    board_new[i][j - 1] = board[i][j - 1] + board[i][j]
                    board_new[i][j] = 0
                    i = 0
                    j = 1
                    change = true
                }
            }
        }

    case "r":
        for i := 0; i < height; i++ {
            for j := 0; j < width - 1; j++ {

                if board[i][j] == 0 {
                    continue
                }

                if board[i][j + 1] == 0 || board[i][j + 1] == board[i][j] {
                    board_new[i][j + 1] = board[i][j + 1] + board[i][j]
                    board_new[i][j] = 0
                    i = 0
                    j = 0
                    change = true
                }
            }
        }

    case "gameover":
        gameOver = true

    default:
        processCommand(board, input)
}

board = board_new
func processCommand(单板[][]int,输入字符串){
董事会新:=董事会
开关输入{
案例“d”:
对于i:=0;i<高度-1;i++{
对于j:=0;j
}

首先要解决合并问题 目前,你总是从上到下、从左到右扫描你的磁贴,与玩家的移动无关。然而,对于2048,最好在玩家移动的相反方向进行扫描,因为分片只会在该方向合并。例如,让我们以以下场景为例:

0   0   2   0   |
0   0   2   2   | Player move
0   2   4   8   v
2   32  4   2
让我们假设玩家的移动方向是底部,所以我们开始从底部向顶部扫描。在第三列中,我们需要先合并4+4,然后合并2+2,即从下到上。向该方向移动允许合并4+4,然后将列的最底部字段标记为已合并,因此不允许进一步合并(由数字周围的括号表示):

合并最底部的单元格后(如果可能的话),我们继续上面的单元格,依此类推

0   0   0   0   |
0   0   0   2   | Player move
0   2   (4) 8   v
2   32  (8) 2

[...]

0   0   (0) 0   |
0   0   (0) 2   | Player move
0   2   (4) 8   v
2   32  (8) 2
当没有更多的合并是可能的,移动结束,所有的“合并”标记被删除,我们等待下一轮。这种方法解决了多重合并问题

扫描方向的另一个示例(数字现在表示循环如何在字段中运行):

关于你的代码 查看代码时,您会注意到循环中存在大量代码重复。对于每种
情况
都要为
-循环执行一个单独的嵌套
,这并不是真正的最优。相反,您可能可以执行以下操作:

for i := 1; i < height; i++ {
    for j := 0; j < width; j++ {
        if board[i][j] == 0 {
            continue
        }

        switch input {
            case "d":
                updateBoardDown(board, i, j)
            case "u":
                updateBoardUp(board, i, j)

            [...]
        }
    }
}
i:=1的
;i<身高;i++{
对于j:=0;j
stack overflow的成员从未停止过他们的奉献精神给我留下深刻印象,非常感谢!非常感谢!
Player move
    ---->
4   3   2   1
8   7   6   5
12  11  10  9
16  15  14  13
for i := 1; i < height; i++ {
    for j := 0; j < width; j++ {
        if board[i][j] == 0 {
            continue
        }

        switch input {
            case "d":
                updateBoardDown(board, i, j)
            case "u":
                updateBoardUp(board, i, j)

            [...]
        }
    }
}