在2048年的实现中,如何确定哪些图块移动和合并?

我正在构建一个小小的2048 WinForms游戏,只是为了好玩。

请注意,这不是关于2048 AI。 我只是想制作一个可以被人类玩的2048游戏。

我首先决定使用0-17来表示瓦片。 0代表一个空的瓦片。 1代表2瓦片。 2代表4个瓷砖。 3代表8瓦片,依此类推。

然后,我考虑如何计算最终的纸板,给出移动前的移动方向和纸板。 以下是我的想法:

  • 要向上移动,只需将电路板逆时针旋转90度,向左移动,然后旋转电路板
  • 要向右移动,只需将电路板顺时针旋转180度,向左移动,然后向后旋转
  • 向下移动时,只需将电路板顺时针旋转90度,向左移动,然后向后旋转。
  • 所以我只需要弄清楚当玩家向左移动时如何计算最终的棋盘,然后我可以通过旋转棋盘,向左移动和向后旋转来找出其余的方向。 然后我用这个相当离奇的算法向左移动。

  • 将每个初始板子的整数转换为字符,方法是添加96并将其转换为char 。 现在的后蜱(`)表示空瓦片, a代表一个2瓦, b代表一个4瓦,等等,人的方法来p
  • 连接字符以形成4个字符串,每个字符串表示一行棋盘。
  • 一个示例板可能如下所示:

    aa``
    ````
    ```b
    ``cb
    
  • 对于每个字符串,

  • 删除所有后面的勾号
  • 使用正则表达式(是的,我在2048年的游戏中使用正则表达式) ([ap])1并获得字符串的第一个匹配。
  • 用新瓷砖替换第一个匹配项
  • 匹配尚未匹配的字符串的其余部分,直到找不到更多匹配。
  • 如果字符串少于4个字符,请将字符串填充到右侧。
  • 通过减去96将每个字符串转回到整数数组
  • 所以这是我如何评估每一行:

        int[] EvaluateRow(int[] row) {
            // RowToString converts an int[] to a string like I said above
            StringBuilder rowString = new StringBuilder(RowToString(row));
            rowString.Replace("`", "");
            var regex = new Regex("([a-p])1");
            int lastIndex = -1;
            while (true) {
                var match = regex.Match(rowString.ToString(), lastIndex + 1);
                if (match.Success) {
                    // newChar is the new tile after the merge
                    char newChar = (char)(match.Value[0] + 1);
                    rowString.Remove(match.Index, match.Length);
                    rowString.Insert(match.Index, newChar);
                    lastIndex = match.Index;
    
                    Score += // some calculation for score, irrelevant
                } else {
                    break;
                }
            }
            // StringToRow converts a string to an int[]
            return StringToRow(rowString.ToString());
        }
    

    然而,我目前的算法存在一个很大的问题。 这个算法只告诉我移动的最终结果,但我不知道我需要移动哪个图片框(我使用图片框来显示图块),每个图片框移动多少个空间,以及哪个图片盒子需要显示一个新的图像。 我真的不想使用其他解决方案,我只想对当前的解决方案进行一些更改。

    这里是我需要从每一行(字符串)获得的东西:

  • List<(int x, int spaces)> 。 每个元素代表哪个瓷砖需要移动(x坐标),以及它应该移动多少个空间( spaces )。
  • 一个List<int> 。 每个元素表示合并到的图块的x坐标。
  • 我如何从行字符串中获取这些信息? 例:

    行字符串:

    `a`a
    

    会产生一个像[(1, 1), (3, 3)]和另一个像[1]这样的列表。


    我不认为向角色的转变确实增加了有用的东西。 如果您坚持使用数字表示(0 =空),那么您可以使用以下逻辑来查找目标配置和哪个块到达哪里。 这是伪代码(给出的row ):

    fromTo = [-1, -1, -1, -1];
    result = [0, 0, 0, 0];
    prevVal = 0;
    pos = 0;
    
    for (i = 0; i < 4; i++) {
        if (row[i]) { // Not empty
            if (row[i] == prevVal) {
                result[pos-1]++; // merged
                fromTo[i] = pos-1;
                prevVal = 0; // avoid triple merge
            } else {
                result[pos] = row[i];
                fromTo[i] = pos;
                prevVal = row[i];
                pos++;
            }
        }
    }
    

    现在, fromTo数组将为每个索引指示该原始位置处的块所处的位置。 result将会有最终值。 从这两条信息中,你也可以知道哪些块被合并。 当result[fromTo[i]] != row[i]时,原始位置i处的块被合并。 你也知道块的行程距离: i - fromTo[i] 。 总之,你有所有的信息为每个块设置一个动画。

    例子

    row         |   fromTo       |   result
    ------------+----------------+-----------
    [0,1,0,1]   |  [-1,0,-1,0]   |  [2,0,0,0]
    [0,1,1,1]   |  [-1,0,0,1]    |  [2,1,0,0]
    [1,1,1,1]   |  [0,0,1,1]     |  [2,2,0,0]
    [1,2,2,3]   |  [0,1,1,2]     |  [1,3,3,0]
    
    链接地址: http://www.djcxy.com/p/40215.html

    上一篇: How can I figure out which tiles move and merge in my implementation of 2048?

    下一篇: efficient general algorithm for merging tiles in game 2048