How can I figure out which tiles move and merge in my implementation of 2048?
I am building a little 2048 WinForms game just for fun.
Note that this is not about a 2048 AI. I am just trying to make a 2048 game that can be played by humans.
I first decided to use 0-17 to represent the tiles. 0 represents an empty tile. 1 represents a 2 tile. 2 represents a 4 tile. 3 represents a 8 tile, and so on.
Then I was thinking about how to calculate the resulting board, given the direction of movement and the board before the move. Here's what I thought about:
So I just need to figure out how to calculate the resulting board when the player moves left, then I can just figure out the rest of the directions by rotating the board, move left, and rotating back. I then came p with this quite bizarre algorithm for moving left.
char
. Now a back tick (`) represents an empty tile, a
represents a 2 tile, b
represents a 4 tile, and so on, al the way to p
. An example board might look like this:
aa``
````
```b
``cb
For each string,
([ap])1
and get the first match of the string. So this is how I evaluate each row:
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());
}
However, there is a really big problem with my current algorithm. This algorithm only tells me the final result of a move, but I don't know which picture box (I'm using picture boxes to show the tiles) I need to move, how many spaces should each picture box move, and which picture boxes need to show a new image. I really want to not use another solution and I want to just make some changes to my current solution.
Here are the things I need to get from each row (string):
List<(int x, int spaces)>
. Each element represents which tile needs to move (the x coordinate), and how many spaces it should move ( spaces
). List<int>
. Each element represents the x coordinates of the tiles which is merged into. How can I get these information from a row string? Example:
The row string:
`a`a
will produce a list like [(1, 1), (3, 3)]
and another list like [1]
.
I don't think the transformation to characters is really adding anything useful. If you stick with the number representation (0 = empty), then you can employ the following logic to find both the target configuration and which block went where. This is pseudo code ( row
is given):
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++;
}
}
}
Now the fromTo
array will indicate for each index, where the block at that original position went to. The result
will have the final values. From those two pieces of information you can also know which blocks were merged. A block at original position i is merged when result[fromTo[i]] != row[i]
. You also know the distance a block will travel: i - fromTo[i]
. In short, you have all information to set up an animation for each block.
Examples
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/40216.html
上一篇: 胜出的Hang子手优化算法