0

I am writing a program to play the Game of Fifteen.

So, I am writing the code that moves the tiles within the board. I'll copy it herein and explain it afterwards, step by step.

bool move(int tile)
{
    for (int i=0; i<d; i++)
    {
        for (int j=0; j<d; j++)
        {
            if (tile == board[i][j])
            {
              if (board[i-1][j] == 0)
              {
                  int temporary = board[i][j];
                  board[i][j] = board[i-1][j];
                  board[i-1][j] = temporary;
                  return true;
              }
              
              else if (board[i][j-1] == 0)
              {
                  int temporary = board[i][j];
                  board[i][j] = board[i][j-1];
                  board[i][j-1] = temporary;
                  return true;
              }
              
              else if (board[i+1][j] == 0)
              {
                  int temporary = board[i][j];
                  board[i][j] = board[i+1][j];
                  board[i+1][j] = temporary;
                  return true;
              }
              
              else if (board[i][j+1] == 0)
              {
                  int temporary = board[i][j];
                  board[i][j] = board[i][j+1];
                  board[i][j+1] = temporary;
                  return true;
              }
              return false;
            }
            
        }
    }
    return false;
}

What is the purpose of the code?

  1. It receives as an input -via int tile = get_int();- the tile that the user wants to move.
  2. It finds the int within the 2D array that has the inputted value tile.
  3. Then, it checks if, surrounding that tile, there is a blank space (the only blank space that there can be in the game).
  4. If there is a blank space, it switches the tiles positions. Et voilà.

What goes wrong?

What appears to be not working is the identification of that blank space.

See below the initialized and drawn board.

 8| 7| 6
 5| 4| 3
 2| 1| _
Tile to move: 

If I input 3, this is what happens and what should always happen: It finds the tile "3", checks if there is a blank space surrounding it (up, down, left, right), and switches positions with that blank space:

8| 7| 6
5| 4| _
2| 1| 3
Tile to move: 

Not a problem right? Well, it does not work as well as it might seem.

See below, how it works with a number not surrounded by the blank space: I have inputted 8, and although not being surrounded by the blank space, it has converted it into a new blank space.

 _| 7| 6
 5| 4| _
 2| 1| 3
Tile to move:

...I'll do it now with the 6; oh, surprise!:

 _| 7| _
 5| 4| _
 2| 1| 3
Tile to move:

Why it should not happen?

I have included this code, which in my opinion is well written and should avoid all these problems (comments inside):

for (int i=0; i<d; i++)             //For every row and every column in the board,...
{
    for (int j=0; j<d; j++)        //check if the inputted tile is within the boards' values.
    {
        if (tile == board[i][j])   //If it is, check "up/down/left/right" for a 0 (blnk spc)
        {
          if (board[i-1][j] == 0)  //If there is, switch the values of those tiles.
          {
              int temporary = board[i][j];
              board[i][j] = board[i-1][j];
              board[i-1][j] = temporary;
              return true;
          }

This code is just a piece of the one at the beginning of the post. In the one in here, it can be seen how it only checks the i-1'th position (above) for a blank space (or 0); the full code at the beginning has not only the i-1'th but also the i+1'th (below), j-1'th (left), and j+1'th (right) positions.

So, when I input 8, the code should go to the position [0][0] and see that there is a tile with that value (which it correctly does).

But after that, it should check if there is a 0 in the positions "[-1][0]", "[0][-1]", [1][0], or [0][1] (which it incorrectly does not).

At this point is where I try a hundred different combinations of code, none of which works, and finally decide to ask in Stackoverflow.

Any help would be much appreciated! Go ahead with any requests for clarifications -I have been working on this for a long time and take for granted many things, but they might not be completely clearly explained (sorry about that if that's the case)-!

The whole code is much longer, and I just didn't want to scare anybody. If you still want to see it, here you have it: https://pastebin.com/FZPq1F7b Thanks again!

5
  • You clearly have a logic problem which is not surprising because your code has no structure. You give your code some structure. Sometimes in your code you access elements that are out of bounds, so your code is likely behaving in a way that's impossible to find the cause of the strange and unexpected behavior. Commented Aug 28, 2017 at 18:24
  • Hint: if you understand pointers you can write a nicer algorithm for this. Commented Aug 28, 2017 at 18:28
  • @IharobAlAsimi hi and thanks for your quick reply. About pointers, I did feel like they would be so useful here, but I have read about them online, in SO, and I still cannot understand them. I have been coding for a month, so I'm still getting settled. When you say "you access elements that are out of bounds", do you talk about checking positions [-1][0] in an array, for example? Because I feel like that is wrong too, but with the nested if's the checking should continue to "real" positions without major problems, right? Thank you!! Commented Aug 28, 2017 at 18:34
  • Wrong, it would be in a undefined state after checking position -1 and you can't predict what will happen next. Read my answer please. Commented Aug 28, 2017 at 18:37
  • (While I was replying to your comment you posted the answer and it wasn't until I refreshed the page that I saw it). I haven't writen it down in my code but I can feel your expertise so I am sure it will work perfectly! I obviously wasn't aware of this "undefined state" a program can find itself in, I will be much more cautious from now on. And, really, thank you very much again. It might have taken you only 2 seconds to see it, but I spend a lot of time with that! Thank you very very much!! Commented Aug 28, 2017 at 18:44

1 Answer 1

1

You need to check that the index lies within the array or something unexpected like what happens, will happen.

For example,

if (board[i-1][j] == 0)

would be:

if ((i > 0) && (board[i - 1][j] == 0))

likewise

else if (board[i+1][j] == 0)

would be

else if ((i < d - 1) && (board[i + 1][j] == 0))

And please, do not use d as a variable name. Use something with a meaning like board_size and since it's apparently a constant BOARD_SIZE would be much better. It might seem like an unimportant detail, but trust me, it's very important.

Oh, and about this comment

At this point is where I try a hundred different combinations of code, none of which works, and finally decide to ask in Stackoverflow.

Coding is not a guessing game, you should not try hundreds of combinations of code. If your code does not do what you think it does there are 2 things to do

  1. Execute it in your head, you would have noticed that board[-1] was a problem immediately.
  2. Use a debugger, you would have seen board[-1] immediately too.
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, it worked! Thank you again, both for the solution and the lesson!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.