はじめに
Teams版のPower Virtual AgetnsとPower Automateを利用して、作成した神経衰弱ゲームの解説その2になります。
「その1(初期処理)はこちら」
「その2(ループトピック)はこちら」
Power Platform 2022 release wave1 で Power Automate と Power Virtual Agetns がより便利で面白くなりそうで嬉しい!
— Miyake Mito (@MiTo60448639) January 26, 2022
嬉しさ余って、娘にも遊んで欲しくて神経衰弱を可愛くしてみました。#PowerApps #PowerAutomate #PowerVirtualAgents pic.twitter.com/a80RnwfaCa
フロー「神経衰弱処理」
今回は神経衰弱のメイン処理となる、神経衰弱処理フローについて説明します。
全体図
このフローは、神経衰弱の1ターンである1手目と2手目のそれぞれで、共通で呼び出されるフローとなります。
よって、2手目の処理では、最後にめくったカードが1手目と同じか判断を行います。
1.フローのパラメータ
② 初期処理にて生成されたランダムな数字配列
③ 場のカード。1手目と2手目で異なります。
④ 1手目でめくったカードの値。1手目処理のときは"null"を設定します。その後、当フローでアウトプットされた値を、2手目でインプットとします。
⑤ 1手目をめくる前の場のカード。当フローを呼び出すトピックA、およびトピックBのインプットである場のカードの値です。ハズレだった場合にめくったカードを戻すためにインプットとします。
2.場のカードの機種依存文字を通常文字に変換
チャットボットでの見栄えをよくするために、チャットボットでの表示には機種依存文字を多用します。
機種依存文字は、Power Automate にて substring() で文字長が2となる場合があります。(サロゲートペアは2と予想しています)
以後の文字位置の算出処理等を複雑化しないために、フローの先頭で文字長が1の文字に置換し、フローの後半で戻します。
当初はトランプをイメージして作成していたため、1~13 の文字を A,②~⑩,J,Q,K の文字に置き換えています。
変換前
🔳🐭🐞🐯🐔🐻🐼🐟🐨🐶🐷🐸🐹🐛
変換後
■ A ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ J Q K
最後に、1行目(列番号を表示)もまるっと置換します。
replace(outputs('特殊文字を変換_14'), '🔲 ❶ ❷ ❸ ❹ ❺ ❻ ❼ ❽ ❾', '▯123456789')
3.ランダムな数字配列を、数字のarrayに変換
次にランダムな数字配列を、カンマ区切りの横並びの状態からJSON配列に変換します。

4.場のカードにおける、Inputの「めくったカード」の位置を特定
場のカードは文字列として扱います。
今回めくったカードは、行⇒列の番号で指定します。
(下図の黄色いセルは「3の6」)
指定された行列に対する、場のカードの位置を取得します。
(下図の黄色いセルは「43」)

行番号や改行を加味し、場のカードにおけるめくったカードの位置を求めます。
X+1+Y×12
5.ランダムな数字配列における、「めくったカード」に該当する数字を特定
ランダムな数字配列は、上記でJSON配列に変換しました。そのJSON配列の添え字と、めくったカードの関係は下図になります。
(めくったカードが「36」ならば、JSON配列の添え字は「24」)
上記のJSON配列の添え字は、
X+(Y-1)×9-1
この添え字を、JSON配列化したランダムな数字配列に指定すると、ランダムな数字配列における数字が取得できます。

ランダムな数字は1~54で構成されています。
13で除算した剰余が、トランプのA~Kに相当します。

剰余は10~12の2桁数字も含むため、そのまま場のカードに挿入してしまうと桁ズレが起きます。
一桁の数字
■■■■■ ⇒ ■■■8■
は問題ありませんが、二桁の数字
■■■■■ ⇒ ■■■12■
は桁ズレが発生します。
よって、ここでも A,②~⑩,J,Q,K への置換を行います。
文字の置換は、スイッチアクションで可能ですが、フローが横に広がり見難くなるため、
Hiroさんの「横長なSwitchアクション・条件分岐はJSON Dictionaryですっきり短く」を利用するとすっきりします。すごいテクニックです。
マッピング表をJSONで作成し、
(これもExcelとテキストエディタを駆使すれば簡単に作成可能です)

上記マッピングのキーに、取得したランダムな数字配列における数字が一致したら値を返す if() を記載します。
(今回は一致しないことはあり得ないので、if() のtrue条件は null とかでも問題ありません)

6.場のカードにめくったカードを情報を付与
「2.場のカードの機種依存文字を通常文字に変換」の結果に対し、1文字ずつのJSON配列を作成します。
その際、indexとして文字位置を付与していきます。
[データ操作]-[選択]アクションで、開始には、2.場のカードの機種依存文字を通常文字に変換の結果をセット。

マップには、
index : item()
value : substring(outputs('Card'), item(), 1)
上記[選択]の出力に対し、上記の「4.場のカードにおける、Inputの「めくったカード」の位置を特定」で取得した位置に、「5.ランダムな数字配列における、「めくったカード」に該当する数字を特定」で変換したカードを差し込みます。
マップには以下を設定してください。
if(equals(outputs('Firsthandint_onCard'), item()?['index']), variables('turnCard'), item()?['value'])
最後に、JSON配列を文字列に変換します。
[データ操作]-[結合]アクションを利用し、結合文字はnullです。
7.場のカードの通常文字を機種依存文字に変換
「2.場のカードの機種依存文字を通常文字に変換」で変換した通常文字を機種依存文字に戻します。
変換前
■ A ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ J Q K
変換後
🔳🐭🐞🐯🐔🐻🐼🐟🐨🐶🐷🐸🐹🐛
8.めくったカードが2枚目の場合、当たり/ハズレの判定をする
上記の「1.フローのパラメータ」の1手目でめくったカードの値がnullでない場合、2枚目をめくったとき独自の処理を行います。

2枚目の場合は、1枚目でめくったカードと一致するか判定します。
「1.フローのパラメータ」の1手目でめくったカードの値と、「5.ランダムな数字配列における、「めくったカード」に該当する数字を特定」の値を比較します。

一致する場合は当たりの画像と、「7.場のカードの通常文字を機種依存文字に変換」で作成した場のカード情報をフローのアウトプットに設定します。
一致しない場合はハズレの画像と、「1.フローのパラメータ」の1枚目をめくる前の場のカードをアウトプットに設定します。
当たりとハズレの画像は、いらすとやさんから頂きました。
チャットボットの応答に画像を表示する方法は、
「Power Virtual Agents でチャットボットに画像を表示する【改定版】」
を参照ください。
また、当たりはずれを加味した場のカードとして
・当たりの場合は「6.場のカードにめくったカードを情報を付与」にかかわらずめくった後の場のカード
・ハズレの場合は1枚目と2枚目のカードを元に戻すため「1.フローのパラメータ」で受け取った1手目をめくる前の場のカード
を設定します。

9.フローのアウトプット
① 「7.場のカードの通常文字を機種依存文字に変換」で変換した場のカード(当たり/ハズレ結果は反映していないもの)
② 「8.めくったカードが2枚目の場合、当たり/ハズレの判定をする」の当たり/ハズレの画像
③ 「8.めくったカードが2枚目の場合、当たり/ハズレの判定をする」の当たりはずれを加味した場のカード
⑤ 1手目をめくる前の場のカードは、当フローを呼び出すトピックA、およびトピックBのインプットである場のカードの値です。ハズレだった場合にめくったカードを戻す際に利用します。

まとめ
全3回でPower Virtual Agetns と Power Automate を利用した神経衰弱ゲームの説明をしました。
文字列の処理では繰り返し処理を多用するルーチンですが、Power Automate のApply to each を利用すると処理時間が激増し、
チャットボットでのゲームとしては成立しません。
よって、Apply to each を一切使わないロジックを構築しました。


















