#51 9スライド
● 問題
シャッフルされた1~8までの数字をスライドさせて,9マスに揃えましょう。
■完成図
$$
\begin{array}{ccc}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 &
\end{array}
$$
プログラムを実行すると数字がシャッフルされます。
空いたところに数字を動かします。この場合,動かせるのは,1か7です。
$$
\begin{array}{ccc}
& 7 & 8 \\
1 & 2 & 4 \\
5 & 3 & 6
\end{array}
$$
1を入力すると,空いたところに1が動きます。
$$
\begin{array}{ccc}
1 & 7 & 8 \\
& 2 & 4 \\
5 & 3 & 6
\end{array}
$$
このようにして,空いたところに数字を移動(スライド)させて,完成図になるようにします。
進めていくと,エラーになることがあります。
import random
piece = [['1','2','3'],['4','5','6'],['7','8',' ']]
goal = [['1','2','3'],['4','5','6'],['7','8',' ']]
space_i = 2
space_j = 2
complete = False
def piece_move():
global space_i
global space_j
if move == 1:
next_i = space_i-1
if next_i >= 0:
piece[space_i][space_j] = piece[next_i][space_j]
piece[next_i][space_j] = ' '
space_i = next_i
if move == 2:
next_j = space_j-1
if next_j >= 0:
piece[space_i][space_j] = piece[space_i][next_j]
piece[space_i][next_j] = ' '
space_j = next_j
if move == 3:
next_i = space_i+1
if next_i <= 2:
piece[space_i][space_j] = piece[next_i][space_j]
piece[next_i][space_j] = ' '
space_i = next_i
if move == 4:
next_j = space_j+1
if next_j <= 2:
piece[space_i][space_j] = piece[space_i][next_j]
piece[space_i][next_j] = ' '
space_j = next_j
def piece_print():
print(' ')
for i in range(3):
print(' '.join(piece[i]))
for i in range(1000):
move = random.randint(1,4)
piece_move()
piece_print()
while complete != True:
result = input('移動する数字は?')
if piece[space_i-1][space_j] == result:
move = 1
if piece[space_i][space_j-1] == result:
move = 2
if piece[space_i+1][space_j] == result:
move = 3
if piece[space_i][space_j+1] == result:
move = 4
piece_move()
piece_print()
if piece == goal:
complete = True
print('完成!')
● 解答
IndexErrorになります。
空いた位置を変数space_i,space_jで記憶し,入力された上下左右の位置に空いた位置がないかを確認しています。
配列は3×3の二次元なので,Indexの範囲は0~2でなければなりません。
問題のコードでは,常に上下左右,つまり,現在のIndex±1を調べているので範囲をこえてしまうことがあるのです。
範囲をこえないように条件を追加しました。
数字を適当にシャッフルすると,どうやっても完成図にならない場合がでてきます。
例えば,以下の場合は,どうやっても完成図にすることができません。
$$
\begin{array}{ccc}
1 & 2 & 3 \\
4 & 5 & 6 \\
8 & 7 &
\end{array}
$$
そこで,このプログラムでは,完成図の段階からはじめて,ランダムに数字をスライドさせて,スタートの段階を作成しています。
それが以下の部分です。1000回動かしています。
for i in range(1000):
move = random.randint(1,4)
piece_move()
コードには,move=0を追加しています。
これは,シャッフルの段階で変数moveに1から4までの値が入りますが,その最後の値が残ったままになると,動かせない数字を動かせる場合が出てしまうためです。試しに,move=0を # move=0 として実行してみるとよいでしょう。
import random
piece = [['1','2','3'],['4','5','6'],['7','8',' ']]
goal = [['1','2','3'],['4','5','6'],['7','8',' ']]
space_i = 2
space_j = 2
complete = False
def piece_move():
global space_i
global space_j
if move == 1:
next_i = space_i-1
if next_i >= 0:
piece[space_i][space_j] = piece[next_i][space_j]
piece[next_i][space_j] = ' '
space_i = next_i
if move == 2:
next_j = space_j-1
if next_j >= 0:
piece[space_i][space_j] = piece[space_i][next_j]
piece[space_i][next_j] = ' '
space_j = next_j
if move == 3:
next_i = space_i+1
if next_i <= 2:
piece[space_i][space_j] = piece[next_i][space_j]
piece[next_i][space_j] = ' '
space_i = next_i
if move == 4:
next_j = space_j+1
if next_j <= 2:
piece[space_i][space_j] = piece[space_i][next_j]
piece[space_i][next_j] = ' '
space_j = next_j
def piece_print():
print(' ')
for i in range(3):
print(' '.join(piece[i]))
for i in range(1000):
move = random.randint(1,4)
piece_move()
piece_print()
while complete != True:
result = input('移動する数字は?')
move = 0 # 追加
if space_i-1 >= 0 and piece[space_i-1][space_j] == result: # 修正
move = 1
if space_j-1 >= 0 and piece[space_i][space_j-1] == result: # 修正
move = 2
if space_i+1 <= 2 and piece[space_i+1][space_j] == result: # 修正
move = 3
if space_j+1 <= 2 and piece[space_i][space_j+1] == result: # 修正
move = 4
piece_move()
piece_print()
if piece == goal:
complete = True
print('完成!')
#Python #プログラミング
この記事が気に入ったらサポートをしてみませんか?