title: How can I figure out which tiles move and merge in my implementation of 2048?
body: <p>I am building a little 2048 WinForms game just for fun.</p>
  
  <p>Note that this is not about a <a href="https://stackoverflow.com/questions/22342854/what-is-the-optimal-algorithm-for-the-game-2048">2048 AI</a>. I am just trying to make a 2048 game that can be played by humans.</p>
  
  <p>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.</p>
  
  <p>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:</p>
  
  <ul>
  <li>To move up, it's just rotating the board counterclockwise by 90 degrees, move left, then rotate the board back</li>
  <li>To move right, it's just rotating the board clockwise by 180 degrees, move left, then rotate back</li>
  <li>To move down, it's just rotating the board clockwise by 90 degrees, move left, then rotate back.</li>
  </ul>
  
  <p>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.</p>
  
  <ul>
  <li>Convert each of the initial board's integers into characters by adding 96 and casting to <code>char</code>. Now a back tick (`) represents an empty tile, <code>a</code> represents a 2 tile, <code>b</code> represents a 4 tile, and so on, al the way to <code>p</code>.</li>
  <li>Concatenate the characters to form 4 strings, each representing a row of the board.</li>
  <li><p>An example board might look like this:</p>
  
  <pre><code>aa``
  ````
  ```b
  ``cb
  </code></pre></li>
  <li><p>For each string,</p>
  
  <ul>
  <li>Remove all the back ticks</li>
  <li>Use the regex (yes I'm using a regex in a 2048 game) <code>([a-p])\1</code> and get the first match of the string.</li>
  <li>replace the first match with the new tile</li>
  <li>match the rest of the string which hasn't been matched yet until no more matches is found.</li>
  </ul></li>
  <li>Pad the string to the right if it has fewer than 4 characters.</li>
  <li>Turn each string back to an array of integers by subtracting 96</li>
  </ul>
  
  <p>So this is how I evaluate each row:</p>
  
  <pre><code>    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());
      }
  </code></pre>
  
  <p>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.</p>
  
  <p>Here are the things I need to get from each row (string):</p>
  
  <ul>
  <li>A <code>List&lt;(int x, int spaces)&gt;</code>. Each element represents which tile needs to move (the x coordinate), and how many spaces it should move (<code>spaces</code>).</li>
  <li>A <code>List&lt;int&gt;</code>. Each element represents the x coordinates of the tiles which is merged into.</li>
  </ul>
  
  <p>How can I get these information from a row string? Example:</p>
  
  <p>The row string:</p>
  
  <pre><code>`a`a
  </code></pre>
  
  <p>will produce a list like <code>[(1, 1), (3, 3)]</code> and another list like <code>[1]</code>.</p>