ミニオセロ(AI対戦)の作り方①

ミニオセロ(AI対戦)の作り方①
ok-scratch

スクラッチに挑戦している皆さん、どうも!スクラッチコーチです。

旗クリックで盤面クローンが並び、置けるマスが光るミニリバーシの作り方。8方向スキャンで石をひっくり返す判定と、角を優先するCPU思考ロジックまで一気に解説するよ。

さぁ、スクラッチでナニ作る!?

チュートリアルの元になった作品

オセロ入門

オセロ入門

by ok-scratch
プレイしておこう プレイしておこう
今回のスクラッチを作る参考作品です。8方向をオフセット配列でまとめてループ回すだけで、挟める石を全部拾ってくる設計がキレッキレ。CPUも同じロジックで反転数を評価して、角マスなら+100点で爆アゲするから、たった4×4の盤面でも駆け引きがガチで生まれる。条件分岐を並べずに数値評価だけで戦略を組み立ててるのがイカす。どうやって作ってるか、見ていこう。

今回の目標

審判・マス・スタートボタンの3つのスプライトを作り、クローンで4×4盤面を表示。石を置いて挟んだ石をひっくり返す基本ルールと、角を優先するCPU対戦相手を実装する。

スターター作品をリミックスしよう

このチュートリアルにはスターター作品があります。使わなくても大丈夫だけど、最低限の素材などが用意されてるので便利です。
スターター作品をダウンロード

#1審判: 審判のスタート準備

ok-scratch ok-scratch
まずはゲーム全体を仕切る「審判」から作っていくよ。ミニリバーシの進行も勝ち負けの判定も、ぜんぶこの子が管理する司令塔なんだ。

準備

スプライト「審判」を開く

審判審判
スプライトについて
ゲーム全体の進行、盤面の管理、勝敗判定を行う司令塔スプライト
どんな役割か
ミニリバーシのルールを管理する審判役を作るよ。ゲームの状態や手番を管理して、プレイヤーとCPUの対戦を進めていくんだ。

実装

step-0

イベントgreenflag が押されたときで旗が押されたらスタート。背景を黒板に切り替えて、画面の右上あたりに小さめサイズで配置するよ。

最後に見た目表示するで姿を出す。ここはまだ見た目を整えてるだけで、ゲームのルールはこのあと足していくやつ。

確認プレビューしておこう 確認プレビューしておこう
旗を押すと審判のネコが画面の右あたりに出てきて、黒板の背景に切り替わる。まずは主役の登場ってとこ、位置とサイズもここで整えてる感じ。

#2マス: マスの初期化

ok-scratch ok-scratch
審判の土台ができたから、次は盤面の「マス」を作っていくよ。このマスを増やして盤を並べる作戦。

準備

スプライト「マス」を開く

マスマス
スプライトについて
盤面の1マスを表し、石の色やヒント表示を切り替えるスプライト
どんな役割か
盤面のマスを16個クローンして並べるよ。石が置かれたら色を変えて、置けるマスは光らせてヒントを出すんだ。

変数「マスID」を追加

このクローンに割り当てられたマスの番号

変数「マスID」を追加

実装

step-1

旗が押されたら見た目隠すで本体はいったん隠す。「マスID」を0にして、グラフィックの効果もリセットしておくよ。

本体は分身のもとになるだけだから、画面には出さない。実際に盤に並ぶのは、このあと作るクローンのほうなんだ。

確認プレビューしておこう 確認プレビューしておこう
マスの本体は旗で隠して初期化しておいて、スタートボタンを右下にスタンバイさせるとこ。プレイヤーが押す前の下ごしらえが整った感じ。

#3スタートボタン: ボタンの配置

ok-scratch ok-scratch
マスの準備ができたら、今度はゲームを始める「スタートボタン」。押したら対戦がスタートするやつを作るよ。

準備

スプライト「スタートボタン」を開く

スタートボタンスタートボタン
スプライトについて
ゲームの開始を操作するボタンスプライト
どんな役割か
押すとゲームが始まるスタートボタンを作るよ。ゲーム中は隠れて、終わったらまた表示されるんだ。

実装

step-2

イベントgreenflag が押されたときで旗スタート。ボタンのコスチュームにして、審判の下あたりに置くよ。

確認プレビューしておこう 確認プレビューしておこう
さっき用意したスタートボタンが画面にちゃんと出てくるとこ。画像効果をリセットして表示、これで押せる状態になった的な。

#4スタートボタン: ボタンを表示

ok-scratch ok-scratch
さっきのボタン、まだ位置を決めただけ。ここで実際に画面へ出すとこまでやるよ。
step-3

効果をリセットしてから見た目表示するで表示。これでスタートボタンが押せる状態になるよ。

確認プレビューしておこう 確認プレビューしておこう
旗を押した時点で方向リストや盤面データを準備して、石を数えて青とピンクの数を画面に表示するとこ。中身の下ごしらえが一気に動く感じ。

#5審判: ゲーム状態の初期化

ok-scratch ok-scratch
見た目チームができたから、審判に戻ってゲームの「状態」を整えるよ。ここからがルールづくりの本番。

準備

スプライト「審判」を開く

審判
審判

変数「★ゲームの状態」を追加

ゲームの進行状態を管理する変数(0=タイトル、1=対戦中、2=終了)

変数「★ゲームの状態」を追加

変数「★手番」を追加

今どちらの番か(1=青のプレイヤー、2=ピンクのCPU)を管理する変数

変数「★手番」を追加

変数「★着手完了」を追加

プレイヤーの着手が完了したかを表す変数

変数「★着手完了」を追加

変数「★パス回数」を追加

連続でパスした回数を数える変数

変数「★パス回数」を追加

変数「★クリックしたマス」を追加

クリックされたマスの番号を保持する変数

変数「★クリックしたマス」を追加

実装

step-4

変数( ) を ( ) にするで「★ゲームの状態」を0(タイトル画面)にセット。手番は1で青のプレイヤーから、みたいな初期値を並べていくよ。

「★着手完了」「★パス回数」「★クリックしたマス」も0に。ゲームの流れを数字で管理して、あちこちのスプライトがこの数字を見て動く仕組みなんだ。

確認プレビューしておこう 確認プレビューしておこう
旗の最後に、マスを作る合図とボタン表示の合図を送って、審判が『青がきみ、ピンクがぼく』ってルールをしゃべるとこ。

#6審判: 方向リストを準備

ok-scratch ok-scratch
ここでちょっと面白い準備。石をひっくり返すときに使う「方向」を、数字のリストで用意していくよ。

準備

カスタム定義「_リストを準備する」を追加

方向一覧と角マス一覧を初期化する

カスタム定義「_リストを準備する」を追加

リスト「■方向一覧」の追加

盤面上で8方向を調べるための移動量の一覧

リスト「■方向一覧」の追加

実装

step-5

ブロック定義定義 ( )で「_リストを準備する」っていう自分専用ブロックを作る。「■方向一覧」をいったん空にして、-7、-6、-5を追加。

この数字、盤の上での「1マス動く量」を表してるんだ。盤を1本のリストで持ってるから、方向も数字1個で表せるってわけ。くわしくは盤面を作るとき分かるよ。

確認プレビューしておこう 確認プレビューしておこう
マスを作る合図を受けて、4×4のループでクローンを16個生成するとこ。工場役の本体は自分を増やさないガードもちゃんと入ってる。

#7審判: 8方向をそろえる

ok-scratch ok-scratch
さっきの続きで、残りの方向も足していくよ。-1、1、5、6、7を「■方向一覧」に追加。
step-6

これで合計8個。上下・左右・ナナメ、ぜんぶの向きが数字1個ずつでそろったことになるよ。

たとえば1は右へ1マス、6は下へ1マス、7は右下へナナメ、みたいな対応。方向をリストにまとめとくと、あとで8回ループするだけで全方向を調べられるんだ。

確認プレビューしておこう 確認プレビューしておこう
クローンが起動して、自分がどのマス担当かをマスの位置リストから読んで覚えるとこ。各マスが自分の場所を知る第一歩みたいな。

#8審判: 角マスを登録

ok-scratch ok-scratch
次は盤の「角」の場所を覚えておくよ。「■角マス一覧」を空にして、8、11、26、29を追加。

準備

リスト「■角マス一覧」の追加

盤面の角にあたるマス番号の一覧

リスト「■角マス一覧」の追加

実装

step-7

リバーシだと角はめちゃくちゃ強いマス。あとでコンピューターが「角を優先して狙う」判断に、この一覧を使うんだ。

確認プレビューしておこう 確認プレビューしておこう
クローンが盤面のマス位置に並んで表示されるとこ。担当マスの状態が変わると一瞬150に拡大して、じわっと110へ戻す弾む演出も入ってる。

#9審判: 盤面の器を作る

準備

カスタム定義「_盤面を作る」を追加

盤面と初期配置を作る

カスタム定義「_盤面を作る」を追加

リスト「★盤面」の追加

盤面36マス分の状態を保持する一覧

リスト「★盤面」の追加

リスト「■マス番号一覧」の追加

盤面のプレイ可能な16マスの番号一覧

リスト「■マス番号一覧」の追加

実装

step-8

ここからは盤面そのものを作る「_盤面を作る」ブロック。まず「★盤面」を空にして、制御( ) 回繰り返すで36回、9っていう数字を追加していくよ。

遊ぶ盤は4×4なのに、なんで36マス(6×6)なの?って感じだよね。じつは外側を「壁」で1周ぐるっと囲むため。この9が壁の印なんだ。

外周を壁で埋めておくと、石を調べる線が盤の外へ出た瞬間に自然と止まる。毎回「はみ出してないか」をチェックしなくて済む、番兵っていう賢いテク。「■マス番号一覧」もここで空にしておくよ。

確認プレビューしておこう 確認プレビューしておこう
マスの状態が1なら青の石、2ならピンクの石にコスチュームを切り替えて、ghostを0にしてくっきり表示。石の色が見た目に反映されるとこ。

#10審判: 行と列でループ

ok-scratch ok-scratch
空っぽの盤に、遊べる16マスの場所を書き込んでいくよ。「行カウンター」を1にしてスタート。

準備

変数「行カウンター」を追加

盤面を作るときに使う行のカウンター

変数「行カウンター」を追加

変数「列カウンター」を追加

盤面を作るときに使う列のカウンター

変数「列カウンター」を追加

実装

step-9

制御( ) 回繰り返すで縦4行ぶんループして、その中で「列カウンター」を1に戻す。行と列の二重ループで、4×4のマスを順番に処理していくよ。

確認プレビューしておこう 確認プレビューしておこう
空きマスのうち、今置けるマスだけをヒント一覧と照らして半透明で光らせるとこ。どこに置けるか光でわかる、ヒント表示の核心みたいな。

#11審判: マス番号を計算

step-10

内側のループで、各マスの「番号」を計算していくよ。制御( ) 回繰り返すで横4列ぶん回す。

番号は「行×6+列+1」で出す。これを「■マス番号一覧」に追加して、その場所の「★盤面」を0(空っぽ)に書き換えるよ。

1本のリストでも、かけ算と足し算を組み合わせれば2次元の座標が表せるんだ。計算が終わったら「列カウンター」を1増やして隣のマスへ。

確認プレビューしておこう 確認プレビューしておこう
置けない空きマスはうっすら表示にして区別するとこ。あとボタン側に表示の合図を受け取る仕組みを足して、必要なときに出せるようにした。

#12審判: 次の行へ

ok-scratch ok-scratch
横1行ぶんのマスを書き終えたら、「行カウンター」を1増やすよ。これで1つ下の行に移るんだ。
step-11

この繰り返しで16マスぜんぶに番号と空っぽ状態がセットされる。二重ループの外側が1周進んだ感じ。

確認プレビューしておこう 確認プレビューしておこう
スタートボタンを押したときの反応を作るとこ。ゲーム中じゃなければコイン音を鳴らして、ボタンをぐっと130に拡大。押した手応えを出す演出。

#13審判: 最初の石を置く

ok-scratch ok-scratch
盤ができたら、リバーシのお約束「真ん中の4つの石」を置くよ。「★盤面」の15番目を2(ピンク)、16番目を1(青)に書き換え。
step-12

この2つと次のステップの2つで、中央にナナメ模様の初期配置ができあがる。ゲーム開始時の定番のかたちになるよ。

確認プレビューしておこう 確認プレビューしておこう
拡大したボタンを元のサイズに戻して隠して、ゲーム開始の合図を送るとこ。押す、縮む、スタート、って流れが一本につながった感じ。

#14審判: 初期配置の仕上げ

ok-scratch ok-scratch
残りの中央2マスも置いていくよ。21番目を1(青)、22番目を2(ピンク)に書き換え。

準備

リスト「★ひっくり返す石一覧」の追加

石を置いたときにひっくり返すマスの一覧

リスト「★ひっくり返す石一覧」の追加

リスト「★置けるマス一覧」の追加

今置けるマスの番号を集めた一覧

リスト「★置けるマス一覧」の追加

実装

step-13

これで青とピンクが斜め向かいに2個ずつ、リバーシらしいスタート形ができあがるよ。

最後に「★ひっくり返す石一覧」と「★置けるマス一覧」を空にしてリセット。次のゲームに前の状態を持ち越さないための片付けなんだ。

確認プレビューしておこう 確認プレビューしておこう
ゲーム開始の合図で盤面を組み直して手番や状態をリセット、対戦モードに突入。ボタン側は隠す合図を受けて画面から消えるとこ。

#15審判: 石を数える準備

ok-scratch ok-scratch
盤の石を数える「_石を数える」ブロックを作るよ。今どっちが何個置いてるか、これで分かるよ。

準備

カスタム定義「_石を数える」を追加

青とピンクの石の数を数える

カスタム定義「_石を数える」を追加

変数「★青の数」を追加

盤面にある青の石の数

変数「★青の数」を追加

変数「★ピンクの数」を追加

盤面にあるピンクの石の数

変数「★ピンクの数」を追加

変数「数える番号」を追加

石を数えるループのインデックス

変数「数える番号」を追加

実装

step-14

「★青の数」と「★ピンクの数」をいったん0にリセット。数える位置を表す「数える番号」も1からスタート。

#16審判: 青の石を数える

準備

変数「数えるマス」を追加

石の数を数えている対象のマス番号

変数「数えるマス」を追加

実装

step-15

制御( ) 回繰り返すで16マスぶんループして、1マスずつ中身をチェックするよ。

「■マス番号一覧」から今見るマスの番号を取り出して、その「★盤面」が1(青)なら変数( ) を ( ) ずつ変えるで「★青の数」を1増やす。

#17審判: ピンクの石を数える

ok-scratch ok-scratch
同じマスをピンクについてもチェック。「★盤面」が2ならピンクの数を1増やすよ。
step-16

調べ終わったら「数える番号」を1進めて次のマスへ。16マスぜんぶ回れば、両方の石の数が出そろう。

#18審判: 初期化をまとめる

step-17

作ってきた準備ブロックを、まとめて呼び出すよ。ブロック定義( )で「_リストを準備する」→「_盤面を作る」→「_石を数える」を順番に実行。

この順番が地味に大事。方向や盤を用意してからじゃないと、石も数えられないからね。

最後に「★青の数」と「★ピンクの数」を画面に表示。対戦中ずっとスコアが見える状態にしておく。

#19審判: 開始の合図を送る

ok-scratch ok-scratch
審判の初期化の締めくくりだよ。ほかのスプライトへ「準備して」の合図を飛ばすよ。

準備

メッセージ「マスの初期化」を追加

マスの初期化を指示するメッセージ

メッセージ「マスの初期化」を追加

メッセージ「ボタンを表示」を追加

スタートボタンを表示させるメッセージ

メッセージ「ボタンを表示」を追加

実装

step-18

イベント( ) を送るで「マスの初期化」と「ボタンを表示」を送信。マスを並べたりボタンを出したりは、受け取った側が担当するよ。

最後に見た目( ) と言うでルール説明のあいさつ。「青がきみ、ピンクがぼく」って感じで対戦相手を紹介するんだ。

#20マス: マスの生成開始

ok-scratch ok-scratch
審判の初期化が終わったから、次はマス側の出番。ここから盤面の16マスをクローンで並べていくよ。

準備

スプライト「マス」を開く

マス
マス

変数「配置行」を追加

クローンを並べるときの行の位置

変数「配置行」を追加

実装

step-19

イベント( ) を受け取ったときで「マスの初期化」を受け取ったら動きだす。ただし「マスID」が0より大きいときは制御 で止めるんだ。

これはクローンが二重に合図を受け取って増殖しちゃうのを防ぐストッパー。本体だけが並べる作業をやる、っていう仕切り。

#21マス: 並べる行ループ

ok-scratch ok-scratch
マスを格子状に並べるために、行と列の二重ループを組むよ。「配置行」を1にしてスタート。

準備

変数「配置列」を追加

クローンを並べるときの列の位置

変数「配置列」を追加

実装

step-20

制御( ) 回繰り返すで縦4行ぶん回して、その中で「配置列」を毎回1に戻す。盤づくりのときと同じ二重ループの形になるよ。

#22マス: マスをクローン

step-21

内側のループで、実際にマスの分身を作っていくよ。横4列ぶん制御( ) 回繰り返すで回す。

「マスID」を1増やしてから制御( ) のクローンを作るで自分のクローンを作成。1個ずつ通し番号がついた分身が生まれるよ。

作ったら「配置列」を1進めて隣へ。これを繰り返すと1行に4個ずつマスが並ぶことになるんだ。

#23マス: 次の行のマスへ

ok-scratch ok-scratch
1行ぶんのマスを作り終えたら、「配置行」を1増やすよ。これで1段下の行の生成に移る。
step-22

外側のループが4周すれば、4×4で合計16個のマスがそろう計算。

#24マス: 本体の番号を戻す

ok-scratch ok-scratch
クローンを全部作り終えたら、本体の「マスID」を0に戻すよ。
step-23

こうしておくと本体は「ID0=並べ役」のまま。実際に盤で光るのは1〜16番のクローンたち、っていう役割分担がキープされる。

#25マス: クローンの起動

準備

変数「自分のマス番号」を追加

このクローンに対応する盤面上のマス番号

変数「自分のマス番号」を追加

実装

step-24

ここからは生まれたクローン1個ずつの動きを作っていくよ。制御クローンされたときで分身として目覚めた瞬間からスタート。

まず自分の「マスID」を使って「■マス番号一覧」から担当マスを取り出し、「自分のマス番号」に記録。クローンごとに違う番号を持つから、それぞれ別のマスを受け持てるんだ。

#26マス: マスを配置して表示

準備

変数「前回の状態」を追加

直前に確認したこのマスの状態

変数「前回の状態」を追加

実装

step-25

自分の担当が決まったら、画面のその位置へ移動するよ。「配置列」と「配置行」から座標を計算して動きx座標を ( ) 、y座標を ( ) にするでピタッと配置。

サイズを110にそろえて、「前回の状態」は-1にしておくよ。これは「まだ一度も見てない」印。準備できたら見た目表示するで表示するよ。

#27マス: 盤面を見張る

準備

変数「今の状態」を追加

今確認しているこのマスの状態

変数「今の状態」を追加

実装

step-26

ここが各マスの心臓部。制御ずっとでずーっと自分の担当マスを見張り続けるんだ。

毎回「★盤面」から自分のマスの中身を読んで「今の状態」に入れる。石が置かれたか、空きか、それをリアルタイムで受け取るよ。

審判が盤面リストを書き換えるだけで、各マスが勝手に見た目を合わせにいく。命令を1個ずつ送らなくていい、賢い作りなんだ。

#28マス: 石が変わったら拡大

step-27

マスの状態が前回と変わった瞬間だけ、演出を入れるよ。制御もし ( ) ならで「今の状態」と「前回の状態」がちがうかチェック。

ちがってたら記録を更新して、サイズを150にドンと拡大。石が置かれた瞬間にプワッと大きくなるよ。

そのあとサイズが110より大きければ、少しずつ-6して縮めていく。拡大→じわじわ縮小で、アニメっぽい動きが作れるってわけなんだ。

#29マス: 青の石を表示

step-28

見張った結果で見た目を切り替えるよ。「今の状態」が1(青)なら見た目コスチュームを ( ) にするで青の石のコスチュームにチェンジ。

透明度を0にしてハッキリ表示。これで青が置かれたマスは、ちゃんと青い石に見えるよ。

#30マス: ピンクの石を表示

ok-scratch ok-scratch
同じノリでピンクも。「今の状態」が2ならピンクの石のコスチュームに切り替えるよ。
step-29

こっちも透明度0でくっきり。青と同じ作りだから、色ちがいの分身って感じ。

#31マス: 置けるマスを光らせる

step-30

空きマス(状態0)のときは、ちょっと工夫するよ。制御もし ( ) ならで「★置けるマス一覧」に自分がいるか確認。

入ってたら「今ここ置けるよ」の合図。ヒント用のコスチュームにして、幽霊の効果を20にうっすら光らせるよ。

#32マス: 空きマスを薄く

ok-scratch ok-scratch
逆に、置けない空きマスはひかえめに見せるよ。空きマスのコスチュームにして、幽霊の効果を65までかける。
step-31

かなり透けるから盤の背景になじむ。置けるマスだけが目立って、どこに打てるか一目で分かるんだ。

#33スタートボタン: ボタンを再表示

ok-scratch ok-scratch
マスの表示ができたから、スタートボタンに戻るよ。審判からの合図でボタンを出す仕組みを作る。

準備

スプライト「スタートボタン」を開く

スタートボタン
スタートボタン

実装

step-32

イベント( ) を受け取ったときで「ボタンを表示」を受け取ったら、サイズを100に整えて見た目表示するで表示。ゲーム開始前やリセット後に、また押せるようになるよ。

#34スタートボタン: ボタンを押したとき

step-33

ボタンが押されたときの反応を作るよ。イベントこのスプライトが押されたときでクリックを受け取る。

ただし制御もし ( ) ならで「★ゲームの状態」が1(対戦中)じゃないときだけ反応。対戦中に誤爆で押されても始まらないようにするガードなんだ。

OKなら「Coin」の音を鳴らして、サイズを130にプクッと拡大。押した手ごたえを出す演出だよ。

#35スタートボタン: ゲーム開始を送信

ok-scratch ok-scratch
ボタンを押した演出の続きだよ。0.08秒だけ待ってサイズを100に戻す。この一瞬でボタンがへこんだみたいに見えるよ。

準備

メッセージ「ゲーム開始」を追加

ゲームの開始を審判に知らせるメッセージ

メッセージ「ゲーム開始」を追加

実装

step-34

そのあと見た目隠すでボタンを隠して、イベント( ) を送るで「ゲーム開始」を送信。あとは受け取った審判が対戦をセットしてくれるんだ。

#36審判: 対戦をセットアップ

準備

スプライト「審判」を開く

審判
審判

メッセージ「ボタンを隠す」を追加

スタートボタンを隠すメッセージ

メッセージ「ボタンを隠す」を追加

実装

step-35

ボタンの処理ができたから、次は審判に戻るよ。合図が届いたら審判が対戦の準備をととのえる。イベント( ) を受け取ったときで「ゲーム開始」を受け取ってスタートするよ。

「_盤面を作る」で盤をまっさらに戻して、手番を1(青)、パス回数と着手完了を0にリセット。そして「★ゲームの状態」を1にして対戦モードに切り替えるよ。

石を数え直して、イベント( ) を送るで「ボタンを隠す」を送信。これで何度でもリスタートできる作りになってるんだ。

#37スタートボタン: ボタンを隠す

準備

スプライト「スタートボタン」を開く

スタートボタン
スタートボタン

実装

step-36

審判の準備ができたから、次はボタン側に戻るよ。「隠して」の合図が来たら、ボタンはサッと引っ込むよ。イベント( ) を受け取ったときで「ボタンを隠す」を受信。

見た目隠すで非表示にするだけのシンプルな役目。対戦中はジャマにならないように消えてる、っていう気配りなんだ。

#38審判: ひっくり返す石を探す

ok-scratch ok-scratch
ボタン周りができたから、審判に戻るよ。いよいよリバーシの核心、「はさんだ石をひっくり返す」判定を作っていくよ。「_ひっくり返せる石を調べる」ブロックの中身。

準備

スプライト「審判」を開く

審判
審判

カスタム定義「_ひっくり返せる石を調べる」を追加

指定したマスに石を置いたときにひっくり返せる石を調べてFLIP_LISTに入れる

カスタム定義「_ひっくり返せる石を調べる」を追加

変数「相手の色」を追加

ひっくり返す石を調べるときに使う相手の色

変数「相手の色」を追加

変数「方向番号」を追加

8方向をチェックするループのインデックス

変数「方向番号」を追加

実装

step-37

「マス番号」と「置く色」を受け取って動く。まず「★ひっくり返す石一覧」を空にして、制御もし ( ) ならでそのマスが空っぽ(0)のときだけ調べるんだ。

「相手の色」は「3ー置く色」で出す。青が1、ピンクが2だから、3から引くともう片方になる小ワザ。方向をたどる番号も1にセットするよ。

#39審判: 8方向をチェック

準備

変数「移動量」を追加

調べている方向1回分の移動量

変数「移動量」を追加

変数「走査位置」を追加

石をひっくり返せるか調べているときの走査位置

変数「走査位置」を追加

リスト「調査中の石一覧」の追加

ひっくり返せるか調べている途中の石を一時的にためる一覧

リスト「調査中の石一覧」の追加

実装

step-38

ここが方向リストの本領発揮。制御( ) 回繰り返すで8回ループして、8つの向きを順番に調べていくよ。

「方向番号」を使って「■方向一覧」から今回の移動量を取り出し、置いたマスから1歩進んだ場所を「走査位置」にセット。調査中の石をためる「調査中の石一覧」も空にしておく。

ok-scratch ok-scratch
この「方向を数字のリストにして8回ループ」ってやり方、めちゃくちゃ賢いんだ。普通に書くと上・下・左・右・ナナメ4つで、8個の条件をコピペする羽目になる。でもこの作品は盤を1本のリストで持ってるから、『右下へ1マス』が『+7』みたいに数字1個で表せる。その8個の数字を並べたリストをループで回すだけで、全方向を同じ処理でチェックできちゃう。方向をデータにまとめて処理を1つにする、プロも使う考え方だよ。

#40審判: 相手の石を数える

step-39

選んだ方向に、相手の石が続くかぎりまっすぐ進むよ。制御( ) まで繰り返すで「走査位置」が相手の色じゃなくなるまで繰り返す。

相手の石を見つけるたびに、その場所を「調査中の石一覧」にメモして、また同じ方向へ1歩。ここで盤の外に出ても、外周が壁(9)だから相手の色と一致せず自然に止まるんだ。

#41審判: はさめたら確定

step-40

相手の石をたどった先が自分の色だったら、はさみ成立。制御もし ( ) ならで「走査位置」が「置く色」と同じかチェックするよ。

成立してたら、さっきメモした石を全部「★ひっくり返す石一覧」に移す。これでこの方向でひっくり返る石が確定だね。

相手をはさんで自分の色で閉じたときだけ裏返せるのが、リバーシのルールそのもの。最後に方向番号を1進めて次の向きへ。8方向ぶん終わればこのブロックは完成なんだ。

#42審判: 置けるマスを調べる

ok-scratch ok-scratch
さっきの判定を使って、「今どこに置けるか」を全部洗い出すよ。「_置けるマスを更新する」ブロックの中身。

準備

カスタム定義「_置けるマスを更新する」を追加

今置けるマスを調べてHINT_LISTを更新する

カスタム定義「_置けるマスを更新する」を追加

変数「ヒント調査番号」を追加

置けるマスを調べるループのインデックス

変数「ヒント調査番号」を追加

変数「調べるマス」を追加

置けるか調べている候補のマス番号

変数「調べるマス」を追加

実装

step-41

「★置けるマス一覧」を空にして、制御( ) 回繰り返すで16マスぶんループ。1マスずつ「_ひっくり返せる石を調べる」を呼んで、今の手番で試すよ。

結果の「★ひっくり返す石一覧」が1個でもあれば、そこは置けるマス。制御もし ( ) ならで確認して「★置けるマス一覧」に追加するよ。さっきマスを光らせてたヒントは、この一覧を見てたってわけ。

#43マス: マスのクリック受付

ok-scratch ok-scratch
判定ロジックができたから、プレイヤーがマスを押せるようにするよ。マス側に戻ってクリックの受付を作る。

準備

スプライト「マス」を開く

マス
マス

実装

step-42

イベントこのスプライトが押されたときでクリックをキャッチするよ。ただし「マスID」が0の本体は制御 で無視する。反応するのは盤に並んだクローンだけなんだ。

#44マス: 押せる条件をチェック

step-43

クリックされても、いつでも置けるわけじゃないよ。制御もし ( ) ならで条件をしぼる。

「★ゲームの状態」が1(対戦中)で、かつ「★手番」が1(青のプレイヤー)のときだけ受け付けるよ。演算( ) かつ ( )で2つの条件を同時に満たすかを判定。コンピューターの番に横取りされないためのガードなんだ。

#45マス: クリックを審判へ

ok-scratch ok-scratch
条件をクリアしたら、押されたマスを審判に伝えるよ。「★クリックしたマス」に自分のマス番号を書き込む。

準備

メッセージ「マスがクリックされた」を追加

マスがクリックされたことを審判に知らせるメッセージ

メッセージ「マスがクリックされた」を追加

実装

step-44

そのあとイベント( ) を送るで「マスがクリックされた」を送信。あとは審判がこの番号を見て、石を置く処理を進めてくれるんだ。押したのはマス、判断するのは審判、っていう連携だよ。

まとめ

1次元リストで盤面を表現して、方向オフセット配列で8方向を一気に処理する書き方が体に馴染んだはず。番兵を使えば境界チェックがいらなくなるのも地味に効くテクニック。CPUの評価値ロジックは他のボードゲームにも応用できるから、いろんな作品で試してみてほしい。

ブクマよろしくお願いします! ブクマよろしくお願いします!
どんどん追記・更新していくので、ブックマークやシェアよろしくお願いします!