このスライド学習では、Google Colabを使用します。
Google Colabへは、次のリンクをクリックして移動しましょう。
前回作成した、「IP02-13」を開き、改変を加えることでもこの回は完了できますが、新しいノートブックを作成することをおすすめします。
新しいノートブックを作成する場合は、「IP02-14」という名前をつけてください。
情報活用編プラス
第3章「コンピュータとプログラミング」
IP02-14
ゲームを作ってみよう②
学習の目的
1.前回の「15パズル」を確認する
2.今回の追加機能
まずは、前回作成した「15パズル」について確認しましょう。
このスライド学習では、Google Colabを使用します。
Google Colabへは、次のリンクをクリックして移動しましょう。
前回作成した、「IP02-13」を開き、改変を加えることでもこの回は完了できますが、新しいノートブックを作成することをおすすめします。
新しいノートブックを作成する場合は、「IP02-14」という名前をつけてください。
まずは、前回の「15パズル」のプログラムを再現しながら、内容を確認しましょう。
プログラムを一つずつ、セルに入力して実行していってください。
盤面モデルとして、「15パズル」の4×4のマスを、二次元配列で表現します。
クリアの状態の盤面モデルを作成する関数です。
# プログラム1
def init():
global tiles
tiles = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,0]
]
呼び出すことで、空きマスの位置を戻り値として返す関数です。
# プログラム2
def find_blank():
for i in range(4):
for j in range(4):
if tiles[i][j] == 0:
return i, j
引数で指定した位置が、移動できるか(空きマスが隣接しているか)を確認する関数です。
# プログラム3
def can_move(i, j):
bi, bj = find_blank()
# 同じ行で横に1マス差 or 同じ列で縦に1マス差
return (
(i == bi and (j == bj + 1 or j == bj - 1)) or
(j == bj and (i == bi + 1 or i == bi - 1))
)
指定したマスと空きマスの内容を交換します。
# プログラム4
def move_tile(i, j):
bi, bj = find_blank()
temp = tiles[i][j]
tiles[i][j] = tiles[bi][bj]
tiles[bi][bj] = temp
現在、クリアの状態かを確認する関数です。
クリアの状態なら、"true"を戻り値として返します。
# プログラム5
# ゴール状態か確認
def is_goal():
last_tiles = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,0]]
return tiles == last_tiles
盤面モデルをシャッフルします。
空きマスへランダムに移動をおこないます。
# プログラム6
import random
# 盤面モデルをシャッフル
def shuffle(num = 500):
for _ in range(num):
bi, bj = find_blank()
options = []
#空きマスの上が盤面モデルの中
if bi - 1 >= 0:
options.append([bi-1, bj])
#空きマスの下が盤面モデルの中
if bi + 1 < 4:
options.append([bi+1, bj])
#空きマスの左が盤面モデルの中
if bj - 1 >= 0:
options.append([bi, bj-1])
#空きマスの右が盤面モデルの中
if bj + 1 < 4:
options.append([bi, bj+1])
ni, nj = random.choice(options)
move_tile(ni, nj)
画面のボタンの配置などを設定します。
# プログラム7
import ipywidgets as widgets
from IPython.display import display, clear_output
import random
# 表示を更新
def update_display():
clear_output(wait=True)
grid = []
for i in range(4):
row = []
for j in range(4):
num = tiles[i][j]
label = str(num) if num != 0 else ""
btn = widgets.Button(description=label, layout=widgets.Layout(width='50px', height='50px'))
def on_click(b, i=i, j=j):
if can_move(i, j):
move_tile(i, j)
update_display()
btn.on_click(on_click)
row.append(btn)
grid.append(row)
# ステータス表示
if is_goal():
status = widgets.HTML(value="You Win!")
else:
status = widgets.HTML(value="")
# リセットボタン
reset_btn = widgets.Button(description="Reset", layout=widgets.Layout(width='100px'))
def on_reset(b):
shuffle()
update_display()
reset_btn.on_click(on_reset)
#「」、数字ボタンの表示
display(widgets.VBox([
widgets.GridBox(sum(grid, []), layout=widgets.Layout(grid_template_columns="repeat(4, 50px)")),
status,
reset_btn
]))
盤面モデルをシャッフルし、実行します。
# プログラム8
# 初期シャッフル&表示
init()
shuffle()
update_display()
セルが8個つくられていることを確認しましょう。
プログラム1~8をすべて実行して、エラーがなければ前回の完成形と同じになります。
反応が遅れることがあるので、一度クリックしたら、反応がなくても少し待ってみましょう。
今回行うことは、「15パズル」の機能追加です。
以下の機能を追加していきます。
①移動回数のカウント
②クリアまでの時間計測
③ランキングの表示
今回は、上記の三つの機能を「15パズル」に実装させていきます。
完成したら、以下のようになりますよ。
それでは、張り切っていきましょう!!