- 1. スクラッチで4×4ミニリバーシ(オセロ)の作り方|CPU対戦とヒント表示 (いまここ)
- 2. スクラッチで4×4ミニリバーシ(オセロ)の作り方|CPU対戦とヒント表示
さぁ、スクラッチでナニ作る!?
チュートリアルの元になった作品
今回の目標
スターター作品をリミックスしよう
このチュートリアルにはスターター作品があります。使わなくても大丈夫だけど、最低限の素材などが用意されてるので便利です。
スターター作品をダウンロード
#1審判: 審判のスタート準備
準備
スプライト「審判」を開く
| スプライトについて |
|---|
| ゲーム全体の進行、盤面の管理、勝敗判定を行う司令塔スプライト |
| どんな役割か |
| ミニリバーシのルールを管理する審判役を作るよ。ゲームの状態や手番を管理して、プレイヤーとCPUの対戦を進めていくんだ。 |
実装
が押されたときで旗が押されたらスタート。背景を黒板に切り替えて、画面の右上あたりに小さめサイズで配置するよ。
最後に表示するで姿を出す。ここはまだ見た目を整えてるだけで、ゲームのルールはこのあと足していくやつ。
#2マス: マスの初期化
準備
スプライト「マス」を開く
| スプライトについて |
|---|
| 盤面の1マスを表し、石の色やヒント表示を切り替えるスプライト |
| どんな役割か |
| 盤面のマスを16個クローンして並べるよ。石が置かれたら色を変えて、置けるマスは光らせてヒントを出すんだ。 |
変数「マスID」を追加
このクローンに割り当てられたマスの番号
実装
旗が押されたら隠すで本体はいったん隠す。「マスID」を0にして、グラフィックの効果もリセットしておくよ。
本体は分身のもとになるだけだから、画面には出さない。実際に盤に並ぶのは、このあと作るクローンのほうなんだ。
#3スタートボタン: ボタンの配置
準備
スプライト「スタートボタン」を開く
| スプライトについて |
|---|
| ゲームの開始を操作するボタンスプライト |
| どんな役割か |
| 押すとゲームが始まるスタートボタンを作るよ。ゲーム中は隠れて、終わったらまた表示されるんだ。 |
実装
が押されたときで旗スタート。ボタンのコスチュームにして、審判の下あたりに置くよ。
#4スタートボタン: ボタンを表示
効果をリセットしてから表示するで表示。これでスタートボタンが押せる状態になるよ。
#5審判: ゲーム状態の初期化
準備
スプライト「審判」を開く
変数「★ゲームの状態」を追加
ゲームの進行状態を管理する変数(0=タイトル、1=対戦中、2=終了)
変数「★手番」を追加
今どちらの番か(1=青のプレイヤー、2=ピンクのCPU)を管理する変数
変数「★着手完了」を追加
プレイヤーの着手が完了したかを表す変数
変数「★パス回数」を追加
連続でパスした回数を数える変数
変数「★クリックしたマス」を追加
クリックされたマスの番号を保持する変数
実装
( ) を ( ) にするで「★ゲームの状態」を0(タイトル画面)にセット。手番は1で青のプレイヤーから、みたいな初期値を並べていくよ。
「★着手完了」「★パス回数」「★クリックしたマス」も0に。ゲームの流れを数字で管理して、あちこちのスプライトがこの数字を見て動く仕組みなんだ。
#6審判: 方向リストを準備
準備
カスタム定義「_リストを準備する」を追加
方向一覧と角マス一覧を初期化する
リスト「■方向一覧」の追加
盤面上で8方向を調べるための移動量の一覧
実装
定義 ( )で「_リストを準備する」っていう自分専用ブロックを作る。「■方向一覧」をいったん空にして、-7、-6、-5を追加。
この数字、盤の上での「1マス動く量」を表してるんだ。盤を1本のリストで持ってるから、方向も数字1個で表せるってわけ。くわしくは盤面を作るとき分かるよ。
#7審判: 8方向をそろえる
これで合計8個。上下・左右・ナナメ、ぜんぶの向きが数字1個ずつでそろったことになるよ。
たとえば1は右へ1マス、6は下へ1マス、7は右下へナナメ、みたいな対応。方向をリストにまとめとくと、あとで8回ループするだけで全方向を調べられるんだ。
#8審判: 角マスを登録
準備
リスト「■角マス一覧」の追加
盤面の角にあたるマス番号の一覧
実装
リバーシだと角はめちゃくちゃ強いマス。あとでコンピューターが「角を優先して狙う」判断に、この一覧を使うんだ。
#9審判: 盤面の器を作る
準備
カスタム定義「_盤面を作る」を追加
盤面と初期配置を作る
リスト「★盤面」の追加
盤面36マス分の状態を保持する一覧
リスト「■マス番号一覧」の追加
盤面のプレイ可能な16マスの番号一覧
実装
ここからは盤面そのものを作る「_盤面を作る」ブロック。まず「★盤面」を空にして、( ) 回繰り返すで36回、9っていう数字を追加していくよ。
遊ぶ盤は4×4なのに、なんで36マス(6×6)なの?って感じだよね。じつは外側を「壁」で1周ぐるっと囲むため。この9が壁の印なんだ。
外周を壁で埋めておくと、石を調べる線が盤の外へ出た瞬間に自然と止まる。毎回「はみ出してないか」をチェックしなくて済む、番兵っていう賢いテク。「■マス番号一覧」もここで空にしておくよ。
#10審判: 行と列でループ
準備
変数「行カウンター」を追加
盤面を作るときに使う行のカウンター
変数「列カウンター」を追加
盤面を作るときに使う列のカウンター
実装
( ) 回繰り返すで縦4行ぶんループして、その中で「列カウンター」を1に戻す。行と列の二重ループで、4×4のマスを順番に処理していくよ。
#11審判: マス番号を計算
内側のループで、各マスの「番号」を計算していくよ。( ) 回繰り返すで横4列ぶん回す。
番号は「行×6+列+1」で出す。これを「■マス番号一覧」に追加して、その場所の「★盤面」を0(空っぽ)に書き換えるよ。
1本のリストでも、かけ算と足し算を組み合わせれば2次元の座標が表せるんだ。計算が終わったら「列カウンター」を1増やして隣のマスへ。
#12審判: 次の行へ
この繰り返しで16マスぜんぶに番号と空っぽ状態がセットされる。二重ループの外側が1周進んだ感じ。
#13審判: 最初の石を置く
この2つと次のステップの2つで、中央にナナメ模様の初期配置ができあがる。ゲーム開始時の定番のかたちになるよ。
#14審判: 初期配置の仕上げ
準備
リスト「★ひっくり返す石一覧」の追加
石を置いたときにひっくり返すマスの一覧
リスト「★置けるマス一覧」の追加
今置けるマスの番号を集めた一覧
実装
これで青とピンクが斜め向かいに2個ずつ、リバーシらしいスタート形ができあがるよ。
最後に「★ひっくり返す石一覧」と「★置けるマス一覧」を空にしてリセット。次のゲームに前の状態を持ち越さないための片付けなんだ。
#15審判: 石を数える準備
準備
カスタム定義「_石を数える」を追加
青とピンクの石の数を数える
変数「★青の数」を追加
盤面にある青の石の数
変数「★ピンクの数」を追加
盤面にあるピンクの石の数
変数「数える番号」を追加
石を数えるループのインデックス
実装
「★青の数」と「★ピンクの数」をいったん0にリセット。数える位置を表す「数える番号」も1からスタート。
#16審判: 青の石を数える
準備
変数「数えるマス」を追加
石の数を数えている対象のマス番号
実装
( ) 回繰り返すで16マスぶんループして、1マスずつ中身をチェックするよ。
「■マス番号一覧」から今見るマスの番号を取り出して、その「★盤面」が1(青)なら( ) を ( ) ずつ変えるで「★青の数」を1増やす。
#17審判: ピンクの石を数える
調べ終わったら「数える番号」を1進めて次のマスへ。16マスぜんぶ回れば、両方の石の数が出そろう。
#18審判: 初期化をまとめる
作ってきた準備ブロックを、まとめて呼び出すよ。( )で「_リストを準備する」→「_盤面を作る」→「_石を数える」を順番に実行。
この順番が地味に大事。方向や盤を用意してからじゃないと、石も数えられないからね。
最後に「★青の数」と「★ピンクの数」を画面に表示。対戦中ずっとスコアが見える状態にしておく。
#19審判: 開始の合図を送る
準備
メッセージ「マスの初期化」を追加
マスの初期化を指示するメッセージ
メッセージ「ボタンを表示」を追加
スタートボタンを表示させるメッセージ
実装
( ) を送るで「マスの初期化」と「ボタンを表示」を送信。マスを並べたりボタンを出したりは、受け取った側が担当するよ。
最後に( ) と言うでルール説明のあいさつ。「青がきみ、ピンクがぼく」って感じで対戦相手を紹介するんだ。
#20マス: マスの生成開始
準備
スプライト「マス」を開く
変数「配置行」を追加
クローンを並べるときの行の位置
実装
( ) を受け取ったときで「マスの初期化」を受け取ったら動きだす。ただし「マスID」が0より大きいときは で止めるんだ。
これはクローンが二重に合図を受け取って増殖しちゃうのを防ぐストッパー。本体だけが並べる作業をやる、っていう仕切り。
#21マス: 並べる行ループ
準備
変数「配置列」を追加
クローンを並べるときの列の位置
実装
( ) 回繰り返すで縦4行ぶん回して、その中で「配置列」を毎回1に戻す。盤づくりのときと同じ二重ループの形になるよ。
#22マス: マスをクローン
内側のループで、実際にマスの分身を作っていくよ。横4列ぶん( ) 回繰り返すで回す。
「マスID」を1増やしてから( ) のクローンを作るで自分のクローンを作成。1個ずつ通し番号がついた分身が生まれるよ。
作ったら「配置列」を1進めて隣へ。これを繰り返すと1行に4個ずつマスが並ぶことになるんだ。
#23マス: 次の行のマスへ
外側のループが4周すれば、4×4で合計16個のマスがそろう計算。
#24マス: 本体の番号を戻す
こうしておくと本体は「ID0=並べ役」のまま。実際に盤で光るのは1〜16番のクローンたち、っていう役割分担がキープされる。
#25マス: クローンの起動
準備
変数「自分のマス番号」を追加
このクローンに対応する盤面上のマス番号
実装
ここからは生まれたクローン1個ずつの動きを作っていくよ。クローンされたときで分身として目覚めた瞬間からスタート。
まず自分の「マスID」を使って「■マス番号一覧」から担当マスを取り出し、「自分のマス番号」に記録。クローンごとに違う番号を持つから、それぞれ別のマスを受け持てるんだ。
#26マス: マスを配置して表示
準備
変数「前回の状態」を追加
直前に確認したこのマスの状態
実装
自分の担当が決まったら、画面のその位置へ移動するよ。「配置列」と「配置行」から座標を計算してx座標を ( ) 、y座標を ( ) にするでピタッと配置。
サイズを110にそろえて、「前回の状態」は-1にしておくよ。これは「まだ一度も見てない」印。準備できたら表示するで表示するよ。
#27マス: 盤面を見張る
準備
変数「今の状態」を追加
今確認しているこのマスの状態
実装
ここが各マスの心臓部。ずっとでずーっと自分の担当マスを見張り続けるんだ。
毎回「★盤面」から自分のマスの中身を読んで「今の状態」に入れる。石が置かれたか、空きか、それをリアルタイムで受け取るよ。
審判が盤面リストを書き換えるだけで、各マスが勝手に見た目を合わせにいく。命令を1個ずつ送らなくていい、賢い作りなんだ。
#28マス: 石が変わったら拡大
マスの状態が前回と変わった瞬間だけ、演出を入れるよ。もし ( ) ならで「今の状態」と「前回の状態」がちがうかチェック。
ちがってたら記録を更新して、サイズを150にドンと拡大。石が置かれた瞬間にプワッと大きくなるよ。
そのあとサイズが110より大きければ、少しずつ-6して縮めていく。拡大→じわじわ縮小で、アニメっぽい動きが作れるってわけなんだ。
#29マス: 青の石を表示
見張った結果で見た目を切り替えるよ。「今の状態」が1(青)ならコスチュームを ( ) にするで青の石のコスチュームにチェンジ。
透明度を0にしてハッキリ表示。これで青が置かれたマスは、ちゃんと青い石に見えるよ。
#30マス: ピンクの石を表示
こっちも透明度0でくっきり。青と同じ作りだから、色ちがいの分身って感じ。
#31マス: 置けるマスを光らせる
空きマス(状態0)のときは、ちょっと工夫するよ。もし ( ) ならで「★置けるマス一覧」に自分がいるか確認。
入ってたら「今ここ置けるよ」の合図。ヒント用のコスチュームにして、幽霊の効果を20にうっすら光らせるよ。
#32マス: 空きマスを薄く
かなり透けるから盤の背景になじむ。置けるマスだけが目立って、どこに打てるか一目で分かるんだ。
#33スタートボタン: ボタンを再表示
準備
スプライト「スタートボタン」を開く
実装
( ) を受け取ったときで「ボタンを表示」を受け取ったら、サイズを100に整えて表示するで表示。ゲーム開始前やリセット後に、また押せるようになるよ。
#34スタートボタン: ボタンを押したとき
ボタンが押されたときの反応を作るよ。このスプライトが押されたときでクリックを受け取る。
ただしもし ( ) ならで「★ゲームの状態」が1(対戦中)じゃないときだけ反応。対戦中に誤爆で押されても始まらないようにするガードなんだ。
OKなら「Coin」の音を鳴らして、サイズを130にプクッと拡大。押した手ごたえを出す演出だよ。
#35スタートボタン: ゲーム開始を送信
準備
メッセージ「ゲーム開始」を追加
ゲームの開始を審判に知らせるメッセージ
実装
そのあと隠すでボタンを隠して、( ) を送るで「ゲーム開始」を送信。あとは受け取った審判が対戦をセットしてくれるんだ。
#36審判: 対戦をセットアップ
準備
スプライト「審判」を開く
メッセージ「ボタンを隠す」を追加
スタートボタンを隠すメッセージ
実装
ボタンの処理ができたから、次は審判に戻るよ。合図が届いたら審判が対戦の準備をととのえる。( ) を受け取ったときで「ゲーム開始」を受け取ってスタートするよ。
「_盤面を作る」で盤をまっさらに戻して、手番を1(青)、パス回数と着手完了を0にリセット。そして「★ゲームの状態」を1にして対戦モードに切り替えるよ。
石を数え直して、( ) を送るで「ボタンを隠す」を送信。これで何度でもリスタートできる作りになってるんだ。
#37スタートボタン: ボタンを隠す
準備
スプライト「スタートボタン」を開く
実装
審判の準備ができたから、次はボタン側に戻るよ。「隠して」の合図が来たら、ボタンはサッと引っ込むよ。( ) を受け取ったときで「ボタンを隠す」を受信。
隠すで非表示にするだけのシンプルな役目。対戦中はジャマにならないように消えてる、っていう気配りなんだ。
#38審判: ひっくり返す石を探す
準備
スプライト「審判」を開く
カスタム定義「_ひっくり返せる石を調べる」を追加
指定したマスに石を置いたときにひっくり返せる石を調べてFLIP_LISTに入れる
変数「相手の色」を追加
ひっくり返す石を調べるときに使う相手の色
変数「方向番号」を追加
8方向をチェックするループのインデックス
実装
「マス番号」と「置く色」を受け取って動く。まず「★ひっくり返す石一覧」を空にして、もし ( ) ならでそのマスが空っぽ(0)のときだけ調べるんだ。
「相手の色」は「3ー置く色」で出す。青が1、ピンクが2だから、3から引くともう片方になる小ワザ。方向をたどる番号も1にセットするよ。
#39審判: 8方向をチェック
準備
変数「移動量」を追加
調べている方向1回分の移動量
変数「走査位置」を追加
石をひっくり返せるか調べているときの走査位置
リスト「調査中の石一覧」の追加
ひっくり返せるか調べている途中の石を一時的にためる一覧
実装
ここが方向リストの本領発揮。( ) 回繰り返すで8回ループして、8つの向きを順番に調べていくよ。
「方向番号」を使って「■方向一覧」から今回の移動量を取り出し、置いたマスから1歩進んだ場所を「走査位置」にセット。調査中の石をためる「調査中の石一覧」も空にしておく。
#40審判: 相手の石を数える
選んだ方向に、相手の石が続くかぎりまっすぐ進むよ。( ) まで繰り返すで「走査位置」が相手の色じゃなくなるまで繰り返す。
相手の石を見つけるたびに、その場所を「調査中の石一覧」にメモして、また同じ方向へ1歩。ここで盤の外に出ても、外周が壁(9)だから相手の色と一致せず自然に止まるんだ。
#41審判: はさめたら確定
相手の石をたどった先が自分の色だったら、はさみ成立。もし ( ) ならで「走査位置」が「置く色」と同じかチェックするよ。
成立してたら、さっきメモした石を全部「★ひっくり返す石一覧」に移す。これでこの方向でひっくり返る石が確定だね。
相手をはさんで自分の色で閉じたときだけ裏返せるのが、リバーシのルールそのもの。最後に方向番号を1進めて次の向きへ。8方向ぶん終わればこのブロックは完成なんだ。
#42審判: 置けるマスを調べる
準備
カスタム定義「_置けるマスを更新する」を追加
今置けるマスを調べてHINT_LISTを更新する
変数「ヒント調査番号」を追加
置けるマスを調べるループのインデックス
変数「調べるマス」を追加
置けるか調べている候補のマス番号
実装
「★置けるマス一覧」を空にして、( ) 回繰り返すで16マスぶんループ。1マスずつ「_ひっくり返せる石を調べる」を呼んで、今の手番で試すよ。
結果の「★ひっくり返す石一覧」が1個でもあれば、そこは置けるマス。もし ( ) ならで確認して「★置けるマス一覧」に追加するよ。さっきマスを光らせてたヒントは、この一覧を見てたってわけ。
#43マス: マスのクリック受付
準備
スプライト「マス」を開く
実装
このスプライトが押されたときでクリックをキャッチするよ。ただし「マスID」が0の本体は で無視する。反応するのは盤に並んだクローンだけなんだ。
#44マス: 押せる条件をチェック
クリックされても、いつでも置けるわけじゃないよ。もし ( ) ならで条件をしぼる。
「★ゲームの状態」が1(対戦中)で、かつ「★手番」が1(青のプレイヤー)のときだけ受け付けるよ。( ) かつ ( )で2つの条件を同時に満たすかを判定。コンピューターの番に横取りされないためのガードなんだ。
#45マス: クリックを審判へ
準備
メッセージ「マスがクリックされた」を追加
マスがクリックされたことを審判に知らせるメッセージ
実装
そのあと( ) を送るで「マスがクリックされた」を送信。あとは審判がこの番号を見て、石を置く処理を進めてくれるんだ。押したのはマス、判断するのは審判、っていう連携だよ。
まとめ
1次元リストで盤面を表現して、方向オフセット配列で8方向を一気に処理する書き方が体に馴染んだはず。番兵を使えば境界チェックがいらなくなるのも地味に効くテクニック。CPUの評価値ロジックは他のボードゲームにも応用できるから、いろんな作品で試してみてほしい。