猿问

2048 游戏的正确瓷砖移动

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


我目前的结构是该板是一个二维数组(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”一个值水平将是 -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

                }

            }

        } 


皈依舞
浏览 235回答 1
1回答

扬帆大鱼

首先你的合并问题目前你总是从上到下和从左到右扫描你的瓷砖,与玩家的移动无关。然而,对于 2048,最好在玩家移动的相反方向上扫描,因为瓷砖只会在那个方向合并。例如,让我们考虑以下场景:0&nbsp; &nbsp;0&nbsp; &nbsp;2&nbsp; &nbsp;0&nbsp; &nbsp;|0&nbsp; &nbsp;0&nbsp; &nbsp;2&nbsp; &nbsp;2&nbsp; &nbsp;| Player move0&nbsp; &nbsp;2&nbsp; &nbsp;4&nbsp; &nbsp;8&nbsp; &nbsp;v2&nbsp; &nbsp;32&nbsp; 4&nbsp; &nbsp;2让我们假设玩家的移动方向是朝向底部,所以我们开始从底部向上扫描。在第三列中,我们需要先合并 4+4,然后再合并 2+2,即自下而上。朝那个方向前进,您可以合并 4+4,然后将列的最底部字段标记为已合并,从而不允许进一步合并(由数字周围的括号表示):0&nbsp; &nbsp;0&nbsp; &nbsp;0&nbsp; &nbsp;0&nbsp; &nbsp;|0&nbsp; &nbsp;0&nbsp; &nbsp;2&nbsp; &nbsp;2&nbsp; &nbsp;| Player move0&nbsp; &nbsp;2&nbsp; &nbsp;2&nbsp; &nbsp;8&nbsp; &nbsp;v2&nbsp; &nbsp;32&nbsp; (8) 2合并最底部的单元格(如果可能)后,我们继续处理上面的单元格,依此类推……0&nbsp; &nbsp;0&nbsp; &nbsp;0&nbsp; &nbsp;0&nbsp; &nbsp;|0&nbsp; &nbsp;0&nbsp; &nbsp;0&nbsp; &nbsp;2&nbsp; &nbsp;| Player move0&nbsp; &nbsp;2&nbsp; &nbsp;(4) 8&nbsp; &nbsp;v2&nbsp; &nbsp;32&nbsp; (8) 2[...]0&nbsp; &nbsp;0&nbsp; &nbsp;(0) 0&nbsp; &nbsp;|0&nbsp; &nbsp;0&nbsp; &nbsp;(0) 2&nbsp; &nbsp;| Player move0&nbsp; &nbsp;2&nbsp; &nbsp;(4) 8&nbsp; &nbsp;v2&nbsp; &nbsp;32&nbsp; (8) 2当不再有可能合并时,移动结束,所有“合并”标记都被删除,我们等待下一轮。这种方法解决了您的多重合并问题。扫描方向的另一个示例(数字现在表示循环将如何通过字段):Player move&nbsp; &nbsp; ---->4&nbsp; &nbsp;3&nbsp; &nbsp;2&nbsp; &nbsp;18&nbsp; &nbsp;7&nbsp; &nbsp;6&nbsp; &nbsp;512&nbsp; 11&nbsp; 10&nbsp; 916&nbsp; 15&nbsp; 14&nbsp; 13关于你的代码查看代码,您会注意到关于您的循环有很多代码重复。对于每个case你做一个单独的嵌套for循环,这不是真正的最佳。相反,您可以执行以下操作:for i := 1; i < height; i++ {&nbsp; &nbsp; for j := 0; j < width; j++ {&nbsp; &nbsp; &nbsp; &nbsp; if board[i][j] == 0 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; switch input {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "d":&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; updateBoardDown(board, i, j)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "u":&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; updateBoardUp(board, i, j)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [...]&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答