第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()を使えば、実際にタイルを移動する処理を作れます。

