Skip to main content

第3回 そのタイル動く?

タイルを探して動かせるか調べよう

まずはSearchTile()でタイルの位置を探してみよう! 位置が分かったら、CanMoveTile()で空白の隣にあるか調べます。


1.指定したタイルの位置を探そう

例えば、次の盤面を考えます。

  1   2   3   4
  5   6   7   8
  9  10      12
 13  14  11  15

このとき、

空白 → x = 2, y = 2
11   → x = 2, y = 3

です。

見つけた位置はPositionで返そう! 関数の形はこうなります。

Position SearchTile(Board* board, int number)

numberには探したいタイル番号が入ります。盤面を左上から順番に調べて、同じ番号を見つけたら、その位置を返そう!

最初のresultを{-1, -1}にしておけば、見つからなかったときは「盤面の外の位置」を返せます。

穴埋め

Position SearchTile(Board* board, int number)
{
    Position result = { -1, -1 };

    for (int y = 0; y < BOARD_HEIGHT; y++)
    {
        for (int x = 0; x < BOARD_WIDTH; x++)
        {
            int index = ______________________________;

            if (______________________________________)
            {
                result.x = ______;
                result.y = ______;

                return result;
            }
        }
    }

    return result;
}

模範解答

模範解答を見る
Position SearchTile(Board* board, int number)
{
    Position result = { -1, -1 };

    for (int y = 0; y < BOARD_HEIGHT; y++)
    {
        for (int x = 0; x < BOARD_WIDTH; x++)
        {
            int index = y * BOARD_WIDTH + x;

            if (board->tile[index] == number)
            {
                result.x = x;
                result.y = y;
                return result;
            }
        }
    }

    return result;
}

2.そのタイルは動かせる?

スライドパズルでは、空白の上下左右にあるタイルだけを動かせます。

まず、空白と指定タイルの位置を調べます。

ここでは、今作ったSearchTile()をそのまま使います。

Position blank = SearchTile(board, BLANK_TILE);
Position tile = SearchTile(board, number);

位置が分かったら、2つの位置の差を求めてみよう!

int dx = blank.x - tile.x;
int dy = blank.y - tile.y;

上下左右に隣り合っているとき、dxとdyは、

( 1,  0)
(-1,  0)
( 0,  1)
( 0, -1)

のどれかになります。

そこで、

dx × dx + dy × dy

を計算すると、どの場合でも1になります。

穴埋め

int CanMoveTile(Board* board, int number)
{
    Position blank = SearchTile(board, BLANK_TILE);
    Position tile = SearchTile(board, number);

    int dx = blank.x - tile.x;
    int dy = blank.y - tile.y;

    if (________________________________)
    {
        return 1;
    }

    return 0;
}

模範解答

模範解答を見る
int CanMoveTile(Board* board, int number)
{
    Position blank = SearchTile(board, BLANK_TILE);
    Position tile = SearchTile(board, number);

    int dx = blank.x - tile.x;
    int dy = blank.y - tile.y;

    if (dx * dx + dy * dy == 1)
    {
        return 1;
    }

    return 0;
}

3.関数を組み合わせている

CanMoveTile()の中では、SearchTile()を2回使っています。

つまり、

タイルを探す処理

をもう一度書いたわけではありません。

SearchTile()に探索を任せることで、CanMoveTile()では位置関係の判定に集中できます。

SearchTile()とCanMoveTile()を使えば、実際にタイルを移動する処理を作れます。