正确的瓷砖移动为2048游戏

mno*_*ber 4 logic go tiles-game

我决定制作一个2048命令行版,但我无法获得合适的瓷砖移动......

我目前的结构是电路板是一个二维阵列(4x4)的整数.当收到一个输入时,它会尝试在该方向上推动每个图块(忽略值为0的图块),如果注意到它将重新开始更改(因为底行上的图块必须一直向上,不只是一步).但是,这样的副作用是以下问题:
[2] [2] [4]使用命令 - >应该给[0] [4] [4]但是由于它重新开始,程序将能够合并4和4得到[0] [0] [8] intead ...
另一个难题是[4] [4] [8] [8]应该给[0] [0] [8] [16] ]所以我不能在合并后停止.

下面的代码是我的processCommand函数.它需要一个板和一个输入(即"d","你","l"或"r".如果游戏注意到游戏,它将把"gameover"作为输入).它不是很漂亮,我试图为移动的瓷砖做一个单独的循环(如果你写"l",一个值horiz将是-1,如果你写"r"它将是1然后我移动瓷砖横向水平,但我无法做到这一点).

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

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
Run Code Online (Sandbox Code Playgroud)

}

fre*_*oma 5

首先是你的合并问题

目前,您始终从上到下和从左到右扫描您的瓷砖,与玩家的移动无关.然而,对于2048年,最好以与玩家移动相反的方向扫描,因为瓷砖只会在该方向上合并.例如,让我们采取以下场景:

0   0   2   0   |
0   0   2   2   | Player move
0   2   4   8   v
2   32  4   2
Run Code Online (Sandbox Code Playgroud)

让我们假设玩家的移动方向朝向底部,因此我们开始从底部向顶部扫描.在第三列中,我们需要首先合并4 + 4然后合并2 + 2,即从下到上.沿着该方向前进允许您合并4 + 4,然后将列的最底部字段标记为合并,从而不允许进一步合并(由数字周围的括号表示):

0   0   0   0   |
0   0   2   2   | Player move
0   2   2   8   v
2   32  (8) 2
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

当不再有可能合并时,移动结束并且所有"合并"标记被移除,我们等待下一轮.此方法可修复多重合并问题.

扫描方向的另一个示例(数字现在表示循环将如何通过字段):

Player move
    ---->
4   3   2   1
8   7   6   5
12  11  10  9
16  15  14  13
Run Code Online (Sandbox Code Playgroud)

关于你的代码

查看代码,注意到有关循环的代码重复很多.对于每个case你做一个单独的嵌套for-loop,这不是真正的最佳.相反,你可能会做这样的事情:

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)

            [...]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 堆栈溢出的成员永远不会因为他们的奉献精神给我留下深刻的印象,非常感谢你!非常感谢! (2认同)