エブリサイトでゲームを作ってみた 実装編

公開日:

注意

本記事は情報提供を目的としており、本記事の内容は無保証、サポートの対象外です。
サポート窓口、問合せ窓口にご質問をいただいても対応いたしかねますのでご了承ください。

はじめに

サポートの沖です。

前回の記事はどうだったでしょうか? 見ていない方のために前回のブログを紹介しておきます。

画面を決めるために色々と試した結果、画面レイアウトを決めるところまでで終わっていました。今回は実際の操作などを作成していきます。

まだ、エブリサイトを使ってないよ、という方はこちらのページを確認いただいてお申し込みをお願いします。

諸々のルールを決めていこう

処理を簡単にするために、ユーザーが先手番でCOMが後手番ということにしておきましょう。COMが先手番には出来ないということにして、文字の表示は先手が⚪︎で後手が×ということにしておきます。こうすることで処理をシンプルにできるはず。

操作するのは2つだけ

プルダウンで位置を決めてボタンを押すという操作なので、操作できないような場合はボタンを無効にする方向にしてみました。プルダウンの項目を可変にしたりとかは無し。画面にには常に

という配置にしておいて、選択できない位置を選んだ場合は以下のようにエラー表示してボタンを無効にする感じ

対COM戦はどう実現する?

kintoneにレコード追加して、「kintoneアプリのWebhook」を呼び出して、「OpenAI を呼び出してテキストを生成する」で考えて貰う・・、という仕組みだと誤回答時の処理が面倒なので、単純にレコードで解答手を用意するような方法にしてみます。

現状の盤面でレコード検索して、レコードがあれば解答手をセットして、レコードがなければ解答手をユーザーに入力させるという機械学習とかじゃなく人力学習。。人工無能のような懐かしい感じ。。。

とは言え真面目に打ち手を考えると大体が引き分けになって面白く無いので、わざと負ける手も登録してもらう必要がある感じかな。そうしておくと特定の手順で負けるとかも出来るし、逆に勝つ事もできる。なお、誰かが入力するとその結果を使うので、先に入力したもの勝ちにしてます。同一パターン時に複数登録できてランダムに選択も考えたのですが、面倒そうなので今回はパスです。。

マーク済み判定

置く場所の入力は既に置かれている場所は選択出来ないようにする必要があるので、選択した位置が空欄かどうかの判定が必要です。とはいえ判定するアクションを9つ用意するのも面倒。。なので、こんな式で判定してみました。

= findif([“p1″,”p2″,”p3″,”p4″,”p5″,”p6″,”p7″,”p8″,”p9”], “=”, 位置, [p1,p2,p3,p4,p5,p6,p7,p8,p9])

設定部分はこちら。

式の仕組みとしては、「位置」を選択するとアクションの結果は”p1″などの値になるので、「findif 関数」を使って選択した位置の「文字列入力(1行)」の値を取得します。その値が空欄でないならばエラー表示という仕組みです。第一引数はアイテムIDの文字列の配列で、第四引数はアイテムの値の配列という違いがあります。

findif 関数」は便利なので、この後の設定でも大活躍します(笑

勝敗判定

縦・横・斜めに同じ文字が並んでいると勝ちなので、極論すれば全パターンを判定すれば良いことにはなる。例えば、3×3のマスを左上から右に向かってp1〜p9だとして、上の列が同じ文字の判定だと、if(and(p1 = “⚪︎”, p2 = “⚪︎”, p3 = “⚪︎”), “勝ち”, “”) という感じ。ただこれだと8パターン作成する必要があるのと、右上に置くと一番上と一番左が同時に揃うような場合を考えると複数一致の場合の処理がダブるかも? それに、出来れば1アクションにしたいし。。

ということで、以下のような式にして、「数値が条件を満たすならば」で0より大きければ勝ちということにしました。

= if(textjoin(“”, “no”, [p1,p2,p3]) = “⚪︎⚪︎⚪︎”, 1, 0) + if(textjoin(“”, “no”, [p1,p5,p9]) = “⚪︎⚪︎⚪︎”, 1, 0) + if(textjoin(“”, “no”, [p1,p4,p7]) = “⚪︎⚪︎⚪︎”, 1, 0)+ if(textjoin(“”, “no”, [p2,p5,p8]) = “⚪︎⚪︎⚪︎”, 1, 0)+ if(textjoin(“”, “no”, [p3,p6,p9]) = “⚪︎⚪︎⚪︎”, 1, 0)+ if(textjoin(“”, “no”, [p4,p5,p6]) = “⚪︎⚪︎⚪︎”, 1, 0)+ if(textjoin(“”, “no”, [p7,p8,p9]) = “⚪︎⚪︎⚪︎”, 1, 0)+ if(textjoin(“”, “no”, [p3,p5,p7]) = “⚪︎⚪︎⚪︎”, 1, 0)

これならば、3列同時に並んでも判定としては1つになるのでシンプル! なお、負けの方は、⚪︎が×に変わるだけで、式としては同じです。

設定していこう!

基本的な考えは大体決まったと思うので、実際に設定していきましょう。

まずは、接続設定。

接続先アプリには定石が保存されます。パターンとその場合にどこに置くのかという情報がレコード単位で保存されています。

ページ作成時処理は特になし

このように、特に設定はしていません。設定しようとしたんですが、よく考えると不要でした。。

続いては、ページ内処理を設定!

動作としてはページ内処理で全て設定します。色々な動きがあるので順に設定していきましょう。

位置を選択と重複チェック

位置のプルダウンを変更したらエラー表示のクリア後に既に置いているかをチェックします。既に置いている場所を選んでいたらボタンを無効にして先に進めないようにするという仕組みです。セット先が空の場合はボタンは有効になります。

選択した場所にセット

位置選択後のボタンを押すと「入力アイテムの値をまとめてセットする」でセットします。

このセットは9つの入力アイテムにまとめてセットすることで1アクションにしています。p1 を例にとると、値にセットしている式はこんな感じになります。

= findif([“p1″,”p2″,”p3″,”p4″,”p5″,”p6″,”p7″,”p8″,”p9”], “=”, 位置, [“⚪︎”,p1,p1,p1,p1,p1,p1,p1,p1])

findifの仕組みとしては、p1と位置が一致していれば”⚪︎”で、一致していなければ今の値という事になります。これにより、選択した場所だけ値をセットということが可能になります。

・・・え? if関数でも出来るって? 
= if(位置 = “p1”, “⚪︎”, p1)
あ、ほんとだ。

・・・あれですよ、ややこしい式書くのはロマンですw

終了判定(勝ち)

自分の場所に⚪︎を置いたら「終了判定(勝ち)」をチェックします。勝敗判定の式は紹介済みなので省略。最後にダイアログを表示して終了です。

終了判定(引き分け)

勝ちではなく、空いている場所がなくなると引き分けで終了です

= count(findif([p1,p2,p3,p4,p5,p6,p7,p8,p9], “=”, “”, [p1,p2,p3,p4,p5,p6,p7,p8,p9]))
という式で、入力アイテムの値が空欄の場所は0個の場合に引き分けにしています。

基本的に引き分けになるのは先手番なので、引き分け判定はこのタイミングのみになります。(そう考えると、3目並べは先手が超有利・・)

ゲーム継続

引き分けでも勝ちでもない場合は、ゲームを続けます。まずはセットするボタンを無効にして解答手の処理に進みます。

解答手を取得してセット

ユーザーの手番が終わったのでCOMの手番になります。まずは、今の盤面から解答手を取得してレコードがあればセットします。2番の設定はデバッグ用ですが複数レコード表示が可能なので、有効手を複数表示も可能ですね。

なお、解答手の取得処理はユーザー手番後とCOM手の投稿後の両方で実行なので、1番ではいずれかで2アクションと繋がっています。

終了判定(負け)

COMの手をセット後にユーザーの時と同じように判定をします。違いとしては引き分けはないので判定不要という点です。

解答手が見つからないので追加

先ほどの解答手の取得でレコードが0件の場合は人工無能モードに入ります。

ダイアログを表示して投稿すべき場所を選ぶように促しつつボタンなどの表示を切り替えます。item4はユーザー手をセット用で、投稿はCOM手を投稿するためのボタンです。ユーザー手を選択直後なので投稿ボタンは無効にしておきます。

実は、投稿のボタンは以下のように、ページ表示時には非表示にしてました。ボタン名が切り替わっているように見えて、実際は2つのボタンの表示・非表示を切り替えるという仕組みになっています。

COM手を投稿

投稿のボタンを押したときはkintoneアプリにレコードを追加します。パターンの値は「textjoin 関数」でアイテムの値をまとめて文字列にします。式はこんな感じ。

= textjoin(“,”,”no”,[p1,p2,p3,p4,p5,p6,p7,p8,p9])

それと解答手は位置のプルダウンなので同時にマッピングしておきます。

レコードの追加後は人工無能モードにから抜けるのでボタンなどを非表示にします。この後はCOM手の取得とセットになるのでセットのボタンは無効にしておきます。処理としては解答手の取得になり、今度は必ず1レコードあるのでセットされるという流れです。

その後は、位置のプルダウンで未セットの場所を選択することでセットのボタンが有効になり、以降は繰り返しです。

勝敗が決まったら操作できるものを全て非表示にして終了

勝ちと負けと引き分けのどれかで終わったら、それ以上は操作することがないので操作するアイテムを非表示にして終了です。再度プレイしたい場合はブラウザをリロードします。

まとめ

いやー、やってみて思ったんですが、ボタンなどのアイテムの表示を切り替えたりなどで、意外とゲームっぽいものも作れたりしますね。他にもクイズや多段項目のアンケートとか、アプリのレコードを使うことで動的なものも作れそうです。

なお。。。

今回のゲームは、2ヶ月くらい前にふと思いついて作ったので、今ではもっと良い方法があるかも。エブリサイトも毎週のように変わってますしねー。アップデート情報はこちらにありますが、変更項目がすごい多い。。

https://preview-portal.everysite.net/changelog.html

社外もチームだ!
エブリサイトで社外DXを!

gusuku Everysite(グスク エブリサイト)は、kintoneをはじめとした複数のサービスと連携し、そのデータを自由なレイアウト・挙動でWebサイトとして入出力できるフロントエンド開発サービスです。

また、何か作ったらブログにしてみます。

投稿者プロフィール

アバター画像
"サイボウズ公認kintoneエバンジェリスト
カスタマインやデプロイットでも色々とやってます"