[PowerApps]オセロゲームでAIBuilderを使ってみた（碁石をひっくり返す）

# 背景
PowerAppsのキャンバスアプリでオセロゲームの碁石がひっくり返すロジックを開発してみたところ、**コード量が多かったため、AIさんなんとかやってくれないか**と考えました。

# ゴール
PowerAppsで連携しやすい**AIBuilder**を活用して、作成したプロンプトに**打つ前の盤面の状態、打った碁石の盤面を渡し、碁石を打った後の盤面を応答してもらおう**と考えております。

# プロンプトを作成する画面
[PowerApps](https://www.bing.com/ck/a?!&&p=9a6575feaf1c93b093eaf6cde685ec15cecf6b53a31faa1d9a985d6b21e3360dJmltdHM9MTczNzg0OTYwMA&ptn=3&ver=2&hsh=4&fclid=0fcb9892-36af-692c-1856-8def37186851&psq=PowerApps&u=a1aHR0cHM6Ly9tYWtlLnBvd2VyYXBwcy5jb20v&ntb=1)にログインし、以下メニューボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/da788eee-86af-7e41-29bc-102f47ace13b.png)

# プロンプト設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/eb8c8a76-c0fb-436e-49f6-d6a59d48d652.png)

# 作成したプロンプト
```text:プロンプト
# 前提条件
あなたは、オセロ（リバーシとも呼ばれる）のプロゲーマーです。
# ゴールの定義
打つ前の盤面、打った盤面から打った後の盤面を応答してください。
# 盤面のデータ定義
縦8行、横8列の盤面とする。
rowは1を始まりとする縦行数です。
colは1を始まりとする横列数です。
statusは0が空の碁石、1が黒の碁石、2が白の碁石です。
# 盤面のデータ例
縦1行、横1列目の空の碁石
{"row":1,"col":1,"status":0}
縦2行、横1列目の黒の碁石
{"row":2,"col":1,"status":1}
縦2行、横2列目の白の碁石
{"row":2,"col":2,"status":2}
# 打つ前の盤面の定義
$beforeBoard$
# 打った盤面の定義
$placeBoard$
# 応答の定義
打った後の盤面の配列を返してください。
```
## 入力設定
### beforeBoard
```text:サンプルデータ
[
    {"row":1,"col":1,"status":0},
    {"row":1,"col":2,"status":0},
    {"row":1,"col":3,"status":0},
    {"row":1,"col":4,"status":0},
    {"row":1,"col":5,"status":0},
    {"row":1,"col":6,"status":0},
    {"row":1,"col":7,"status":0},
    {"row":1,"col":8,"status":0},
    {"row":2,"col":1,"status":0},
    {"row":2,"col":2,"status":0},
    {"row":2,"col":3,"status":0},
    {"row":2,"col":4,"status":0},
    {"row":2,"col":5,"status":0},
    {"row":2,"col":6,"status":0},
    {"row":2,"col":7,"status":0},
    {"row":2,"col":8,"status":0},
    {"row":3,"col":1,"status":0},
    {"row":3,"col":2,"status":0},
    {"row":3,"col":3,"status":0},
    {"row":3,"col":4,"status":0},
    {"row":3,"col":5,"status":0},
    {"row":3,"col":6,"status":0},
    {"row":3,"col":7,"status":0},
    {"row":3,"col":8,"status":0},
    {"row":4,"col":1,"status":0},
    {"row":4,"col":2,"status":0},
    {"row":4,"col":3,"status":0},
    {"row":4,"col":4,"status":2},
    {"row":4,"col":5,"status":1},
    {"row":4,"col":6,"status":0},
    {"row":4,"col":7,"status":0},
    {"row":4,"col":8,"status":0},
    {"row":5,"col":1,"status":0},
    {"row":5,"col":2,"status":0},
    {"row":5,"col":3,"status":0},
    {"row":5,"col":4,"status":1},
    {"row":5,"col":5,"status":2},
    {"row":5,"col":6,"status":0},
    {"row":5,"col":7,"status":0},
    {"row":5,"col":8,"status":0},
    {"row":6,"col":1,"status":0},
    {"row":6,"col":2,"status":0},
    {"row":6,"col":3,"status":0},
    {"row":6,"col":4,"status":0},
    {"row":6,"col":5,"status":0},
    {"row":6,"col":6,"status":0},
    {"row":6,"col":7,"status":0},
    {"row":6,"col":8,"status":0},
    {"row":7,"col":1,"status":0},
    {"row":7,"col":2,"status":0},
    {"row":7,"col":3,"status":0},
    {"row":7,"col":4,"status":0},
    {"row":7,"col":5,"status":0},
    {"row":7,"col":6,"status":0},
    {"row":7,"col":7,"status":0},
    {"row":7,"col":8,"status":0},
    {"row":8,"col":1,"status":0},
    {"row":8,"col":2,"status":0},
    {"row":8,"col":3,"status":0},
    {"row":8,"col":4,"status":0},
    {"row":8,"col":5,"status":0},
    {"row":8,"col":6,"status":0},
    {"row":8,"col":7,"status":0},
    {"row":8,"col":8,"status":0}
]
```

### placeBoard
```text:サンプルデータ
{"row":3,"col":4,"status":1}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/2db468e6-ed75-af85-f86d-ec9700cc3b6c.png)

## 出力設定
```text:サンプルデータ
[
  {
    "row": 1,
    "col": 1,
    "status": 0
  },
  {
    "row": 1,
    "col": 2,
    "status": 0
  },
  {
    "row": 1,
    "col": 3,
    "status": 0
  },
  {
    "row": 1,
    "col": 4,
    "status": 0
  },
  {
    "row": 1,
    "col": 5,
    "status": 0
  },
  {
    "row": 1,
    "col": 6,
    "status": 0
  },
  {
    "row": 1,
    "col": 7,
    "status": 0
  },
  {
    "row": 1,
    "col": 8,
    "status": 0
  },
  {
    "row": 2,
    "col": 1,
    "status": 0
  },
  {
    "row": 2,
    "col": 2,
    "status": 0
  },
  {
    "row": 2,
    "col": 3,
    "status": 0
  },
  {
    "row": 2,
    "col": 4,
    "status": 0
  },
  {
    "row": 2,
    "col": 5,
    "status": 0
  },
  {
    "row": 2,
    "col": 6,
    "status": 0
  },
  {
    "row": 2,
    "col": 7,
    "status": 0
  },
  {
    "row": 2,
    "col": 8,
    "status": 0
  },
  {
    "row": 3,
    "col": 1,
    "status": 0
  },
  {
    "row": 3,
    "col": 2,
    "status": 0
  },
  {
    "row": 3,
    "col": 3,
    "status": 0
  },
  {
    "row": 3,
    "col": 4,
    "status": 1
  },
  {
    "row": 3,
    "col": 5,
    "status": 0
  },
  {
    "row": 3,
    "col": 6,
    "status": 0
  },
  {
    "row": 3,
    "col": 7,
    "status": 0
  },
  {
    "row": 3,
    "col": 8,
    "status": 0
  },
  {
    "row": 4,
    "col": 1,
    "status": 0
  },
  {
    "row": 4,
    "col": 2,
    "status": 0
  },
  {
    "row": 4,
    "col": 3,
    "status": 0
  },
  {
    "row": 4,
    "col": 4,
    "status": 1
  },
  {
    "row": 4,
    "col": 5,
    "status": 1
  },
  {
    "row": 4,
    "col": 6,
    "status": 0
  },
  {
    "row": 4,
    "col": 7,
    "status": 0
  },
  {
    "row": 4,
    "col": 8,
    "status": 0
  },
  {
    "row": 5,
    "col": 1,
    "status": 0
  },
  {
    "row": 5,
    "col": 2,
    "status": 0
  },
  {
    "row": 5,
    "col": 3,
    "status": 0
  },
  {
    "row": 5,
    "col": 4,
    "status": 1
  },
  {
    "row": 5,
    "col": 5,
    "status": 2
  },
  {
    "row": 5,
    "col": 6,
    "status": 0
  },
  {
    "row": 5,
    "col": 7,
    "status": 0
  },
  {
    "row": 5,
    "col": 8,
    "status": 0
  },
  {
    "row": 6,
    "col": 1,
    "status": 0
  },
  {
    "row": 6,
    "col": 2,
    "status": 0
  },
  {
    "row": 6,
    "col": 3,
    "status": 0
  },
  {
    "row": 6,
    "col": 4,
    "status": 0
  },
  {
    "row": 6,
    "col": 5,
    "status": 0
  },
  {
    "row": 6,
    "col": 6,
    "status": 0
  },
  {
    "row": 6,
    "col": 7,
    "status": 0
  },
  {
    "row": 6,
    "col": 8,
    "status": 0
  },
  {
    "row": 7,
    "col": 1,
    "status": 0
  },
  {
    "row": 7,
    "col": 2,
    "status": 0
  },
  {
    "row": 7,
    "col": 3,
    "status": 0
  },
  {
    "row": 7,
    "col": 4,
    "status": 0
  },
  {
    "row": 7,
    "col": 5,
    "status": 0
  },
  {
    "row": 7,
    "col": 6,
    "status": 0
  },
  {
    "row": 7,
    "col": 7,
    "status": 0
  },
  {
    "row": 7,
    "col": 8,
    "status": 0
  },
  {
    "row": 8,
    "col": 1,
    "status": 0
  },
  {
    "row": 8,
    "col": 2,
    "status": 0
  },
  {
    "row": 8,
    "col": 3,
    "status": 0
  },
  {
    "row": 8,
    "col": 4,
    "status": 0
  },
  {
    "row": 8,
    "col": 5,
    "status": 0
  },
  {
    "row": 8,
    "col": 6,
    "status": 0
  },
  {
    "row": 8,
    "col": 7,
    "status": 0
  },
  {
    "row": 8,
    "col": 8,
    "status": 0
  }
]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/5c564962-7a8d-147c-6da8-e0275d0fb380.png)

# プロンプトの応答
**1手目の碁石をひっくり返すところは、正常な応答**を返してくれました。
```text:応答
[
  {
    "row": 1,
    "col": 1,
    "status": 0
  },
  {
    "row": 1,
    "col": 2,
    "status": 0
  },
  {
    "row": 1,
    "col": 3,
    "status": 0
  },
  {
    "row": 1,
    "col": 4,
    "status": 0
  },
  {
    "row": 1,
    "col": 5,
    "status": 0
  },
  {
    "row": 1,
    "col": 6,
    "status": 0
  },
  {
    "row": 1,
    "col": 7,
    "status": 0
  },
  {
    "row": 1,
    "col": 8,
    "status": 0
  },
  {
    "row": 2,
    "col": 1,
    "status": 0
  },
  {
    "row": 2,
    "col": 2,
    "status": 0
  },
  {
    "row": 2,
    "col": 3,
    "status": 0
  },
  {
    "row": 2,
    "col": 4,
    "status": 0
  },
  {
    "row": 2,
    "col": 5,
    "status": 0
  },
  {
    "row": 2,
    "col": 6,
    "status": 0
  },
  {
    "row": 2,
    "col": 7,
    "status": 0
  },
  {
    "row": 2,
    "col": 8,
    "status": 0
  },
  {
    "row": 3,
    "col": 1,
    "status": 0
  },
  {
    "row": 3,
    "col": 2,
    "status": 0
  },
  {
    "row": 3,
    "col": 3,
    "status": 0
  },
  {
    "row": 3,
    "col": 4,
    "status": 1
  },
  {
    "row": 3,
    "col": 5,
    "status": 0
  },
  {
    "row": 3,
    "col": 6,
    "status": 0
  },
  {
    "row": 3,
    "col": 7,
    "status": 0
  },
  {
    "row": 3,
    "col": 8,
    "status": 0
  },
  {
    "row": 4,
    "col": 1,
    "status": 0
  },
  {
    "row": 4,
    "col": 2,
    "status": 0
  },
  {
    "row": 4,
    "col": 3,
    "status": 0
  },
  {
    "row": 4,
    "col": 4,
    "status": 1
  },
  {
    "row": 4,
    "col": 5,
    "status": 1
  },
  {
    "row": 4,
    "col": 6,
    "status": 0
  },
  {
    "row": 4,
    "col": 7,
    "status": 0
  },
  {
    "row": 4,
    "col": 8,
    "status": 0
  },
  {
    "row": 5,
    "col": 1,
    "status": 0
  },
  {
    "row": 5,
    "col": 2,
    "status": 0
  },
  {
    "row": 5,
    "col": 3,
    "status": 0
  },
  {
    "row": 5,
    "col": 4,
    "status": 1
  },
  {
    "row": 5,
    "col": 5,
    "status": 2
  },
  {
    "row": 5,
    "col": 6,
    "status": 0
  },
  {
    "row": 5,
    "col": 7,
    "status": 0
  },
  {
    "row": 5,
    "col": 8,
    "status": 0
  },
  {
    "row": 6,
    "col": 1,
    "status": 0
  },
  {
    "row": 6,
    "col": 2,
    "status": 0
  },
  {
    "row": 6,
    "col": 3,
    "status": 0
  },
  {
    "row": 6,
    "col": 4,
    "status": 0
  },
  {
    "row": 6,
    "col": 5,
    "status": 0
  },
  {
    "row": 6,
    "col": 6,
    "status": 0
  },
  {
    "row": 6,
    "col": 7,
    "status": 0
  },
  {
    "row": 6,
    "col": 8,
    "status": 0
  },
  {
    "row": 7,
    "col": 1,
    "status": 0
  },
  {
    "row": 7,
    "col": 2,
    "status": 0
  },
  {
    "row": 7,
    "col": 3,
    "status": 0
  },
  {
    "row": 7,
    "col": 4,
    "status": 0
  },
  {
    "row": 7,
    "col": 5,
    "status": 0
  },
  {
    "row": 7,
    "col": 6,
    "status": 0
  },
  {
    "row": 7,
    "col": 7,
    "status": 0
  },
  {
    "row": 7,
    "col": 8,
    "status": 0
  },
  {
    "row": 8,
    "col": 1,
    "status": 0
  },
  {
    "row": 8,
    "col": 2,
    "status": 0
  },
  {
    "row": 8,
    "col": 3,
    "status": 0
  },
  {
    "row": 8,
    "col": 4,
    "status": 0
  },
  {
    "row": 8,
    "col": 5,
    "status": 0
  },
  {
    "row": 8,
    "col": 6,
    "status": 0
  },
  {
    "row": 8,
    "col": 7,
    "status": 0
  },
  {
    "row": 8,
    "col": 8,
    "status": 0
  }
]
```

# まとめ
**1手目は正常な応答**が返してくれましたが、**2手目の応答の盤面データが正しくありませんでした。**
これは**プロンプトの定型文**の問題なのか。または、**AIモデルの精度**の問題なのか。それとも**プロンプトの設定**の問題なのか切り分けが難しいと感じました。
いろいろ試行錯誤してみようと考えております。
この記事が皆さんの役に立てば幸いです！
また、解決策があるという方おられましたら、コメントいただけると幸いです。
記事をご覧いただきありがとうございます。