【世界初】micro:bitの拡張機能でステートマシン・コーディングをマスターしよう

# 世界初のステートマシン・コーディング

micro:bitのユーザー定義の拡張機能である[Mstate拡張機能](https://github.com/jp-rad/pxt-mstate)を使って、ステートマシン・コーディングをマスターできます。
![g403.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/c9b1dc7b-78d0-da90-4660-8fee89732de7.png)

https://github.com/jp-rad/pxt-mstate

:::note info
**世界初[^worldsfirst]の試み**
micro:bitでステートマシンを使ったブロック・コーディングは、 **世界初の試み**です。
[^worldsfirst]:自分調べ：2023年9月3日現在**
:::

## コーディングを元に設計の検証をする
さて、このブロック・コーディングを読んで、これがどのような振る舞いをするのか、わかりますか？
これをわかりやすくするのが、**ステート図**です。一般的には、UMLなどでステート図を描いてから、ソースコードを自動生成したりしますが、Mstate拡張機能には、コーディングから[ステート図(PluntUML)](https://plantuml.com/ja-dark/state-diagram)の記述を生成する機能が備わっています。
`最初だけ` ブロック内に、 `UML` ブロックを追加します。すると、 `Show data シミュレーター` 画面で、コンソール・ログとして [PluntUML によるステート図](https://plantuml.com/ja-dark/state-diagram)の記述が出力されます。これを http://www.plantuml.com/plantuml/ などの描画サービスに入力し、ステート図に変換します。
**UMLの追加**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/edb906e4-579f-57f5-a2f3-e212981481df.png)
**コンソール・ログ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/f2d2a7a0-9f79-48f6-f821-0c489f540bef.png)
**ステート図**
```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] --> 準備
state 計測
計測 --> 停止 : StartPause
計測 --> 結果 : Stop
state 準備
準備 --> 計測 : StartPause
state 停止
停止 --> 計測 : StartPause
停止 --> 結果 : Stop
state 結果
結果 --> 準備 : Reset
}
@enduml
```

## ステート図の説明
**四角形と矢印**
四角形で表現しているのが、`ステート`（状態）です。矢印で表現しているのが`トランジション`（状態遷移）で、その矢印に記述してあるのが、`トリガー`です。`トリガー`のことを`イベント`とも呼びますが、micro:bitにおける`イベント`と区別するために、`トリガー`と呼ぶようにします。
尚、外側の四角形は、 **１つのステートマシン** を表現しています。Mstate拡張機能では、複数のステートマシンを定義できます。

**ステートマシンの開始**
黒丸は、開始状態です。 `start` ブロックを実行すると、指定された `デフォルト・ステート`としての `準備` ステートへ状態遷移し、ステートマシンが開始されます。

**トリガーと状態遷移**
`準備` ステートからは、 `StartPause` トリガーにより、 `計測` ステートへと状態遷移します。 `StartPause` トリガーは、 `ボタンAが押されたとき` イベントで、 `fire` ブロックによって発生させています。尚、 `準備` ステートでは、 `StartPasue` トリガー以外では、状態遷移が起こりません。
`計測` ステートでは、 `StartPause` トリガー、または、`Stop` トリガーによって状態遷移します。 `StartPause` トリガーは、計測を開始したり、停止したり、再開したりと、複数の状態遷移を引き起こします。つまり、**Aボタンだけ**で、開始・停止・再開を操作できるということです。

**ステート図から読み取る動作**
ブロック・コーディングよりもステート図のほうが、どのような振る舞いをするのかわかりやすいと思います。
`StartPause` トリガー（ボタンA）によって、計測を開始・停止・再開でき、 `Stop` トリガー（ボタンB）によって、結果になり、 `Reset` トリガー（ボタンA+B）によって、準備に戻るという振る舞いを読み取ることができます。

※ QiitaのMarkdown記法において、PluntUMLに対応していますので、本記事でもMarkdownでステート図を記述しています。[→ ダイアグラム-PlantUMLを使う](https://qiita.com/Qiita/items/c686397e4a0f4f11683d#plantuml%E3%82%92%E4%BD%BF%E3%81%86)

https://qiita.com/Qiita/items/c686397e4a0f4f11683d#plantuml%E3%82%92%E4%BD%BF%E3%81%86

# ステートマシンの振る舞い

ステート図から振る舞いを読み取ることができましたが、もう少し詳しくブロックのコードを読んでみましょう。
例えば、`計測` ステートは、 `on entry` ブロック、 `on do` ブロック、 `on exit` ブロック、および、`transition` ブロックの組み合わせで定義されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/bb1dd7e2-072d-8785-cd99-a47e490dad83.png)

## ステートでの entry-do-exit

ある `ステート`（状態）において、次の２つのアクションと１つのアクテビティが実行されます。
- entryアクション
- doアクティビティ
- exitアクション

**entryアクション** は、その状態に**状態遷移した直後**に１度だけ実行されます。その後、その状態で **doアクテビティ** が**繰り返し**実行されます。状態遷移が起こる場合、**状態遷移する直前**に **exitアクション** が１度だけ実行されます。
尚、状態遷移には、他の状態への状態遷移だけでなく、自身の状態への状態遷移もあります。いずれの状態遷移であっても、**exitアクション**と**entryアクション**とが実行されます。

<table>
<tr><th>実行順序</th><th>状態遷移</th></tr>
<tr>
<td>

```plantuml
start
:(状態遷移:突入);
:entryアクション;
repeat
:doアクティビティ;
repeat while (状態遷移なし？)
:exitアクション;
:(状態遷移：退出);
end
```

</td>
<td>

```plantuml

[*] --> prev : start
prev --> __this__
__this__ --> next : next
__this__ -r-> __this__ : re-entry
next --> [*]

__this__: entry/ (entryアクション)\n - 状態遷移した直後に実行\n
__this__: do/ (doアクティビティ)\n - 繰り返し実行\n
__this__: exit/ (exitアクション)\n - 状態遷移する直前に実行\n

```

</td>
</tr></table>

## アクションとアクティビティの宣言

お察しいただいている通り、Mstate拡張機能では、**entryアクション**、**doアクティビティ**、**exitアクション**をそれぞれ、 `on entry` ブロック、 `on do` ブロック、 `on exit` ブロックで宣言します。
`on do` ブロックは、繰り返し呼び出され、その呼び出し間隔を指定できます(ミリ秒)。ただし、その精度は低いので注意してください(デフォルトでは100ms以上の精度)。
尚、宣言する順序は、任意です。また、同一のアクションやアクティビティを複数宣言した場合、その実行順序は不定です。通常、entry-do-exitの順に配置し、アクションやアクティビティは、ゼロまたは１個で宣言するというコーディング・ルールを決めておくと良いと思います。

**entryアクション**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/c0038d87-28e4-6ce8-522d-839afd791b3e.png)

**doアクティビティ（500ms間隔）**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/96c8de4c-387b-5bca-b118-a4f02fbbfdfb.png)

**exitアクション**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/5649f800-0a34-76da-a5f7-7f149b48026f.png)


## ステートの振る舞いを説明する（UML表記）

その`ステート`（状態）での振る舞いは、ブロック・コーディングを読めばわかりますが、その説明をUMLに加えることができます。
`define` ブロックで、状態名称を定義していますが、`":"`(コロン)で区切って、アクションやアクティビティの説明を記述します。

|ブロック|状態名称のみ|状態名称と説明|
|-------|------------|--------------|
|define|"<状態名称>"|"<状態名称>" + ":" + "<説明>"|

例えば、各状態の状態名称を次のように編集し、UMLで出力してみます。

|#|状態名称|状態名称と説明|備考|
|--|:--:|----|--|
|1|準備|準備:経過時間の初期化|
|2|計測|計測:entry/\n - 開始時間を保持\ndo/ (500ms)\n - LED点滅\nexit/\n - 経過時間を加算|**\n**は改行|
|3|停止|停止|何もしない|
|4|結果|結果:経過時間を表示|

**ブロックの例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/2f804339-a4b8-931d-ee98-9c0e14a33899.png)

**ステート図（説明つき）**
```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] --> 準備
state 準備 : 経過時間の初期化
準備 --> 計測 : StartPause
state 結果 : 経過時間を表示
結果 --> 準備 : Reset
state 停止
停止 --> 計測 : StartPause
停止 --> 結果 : Stop
state 計測 : entry/\n - 開始時間を保持\ndo/ (500ms)\n - LED点滅\nexit/\n - 経過時間を加算
計測 --> 停止 : StartPause
計測 --> 結果 : Stop
}
@enduml
```

## トランジションの宣言

`トランジション`（状態遷移）は、 `transition` ブロックで宣言できますが、**Transition**グループにはいくつかのブロックがあります。ブロックの説明の前に、`トランジション`についてステート図で説明します。

**Transitionグループのブロック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/ef82699e-abff-5c3f-c6e9-868b84b36223.png)

## ステート図でのトランジション

ステート図において、`トランジション`（状態遷移）は、矢印で表現され、ある状態からある状態への状態遷移を示しています。
状態遷移は、`トリガー`によって起こります。また、 `ガード` によって、条件を指定することも可能です。`トリガー`が発生し、`ガード`の条件が満たされていれば、状態遷移が起こります。`トリガー`が発生しても、`ガード`の条件が満たされていなければ、状態遷移は起こりません。
状態遷移が起こる場合、 `エフェクト` が実行されます。
ある状態からある状態へ複数の矢印で表現することができますが、状態遷移できる矢印はその中の１つだけです。また、他の状態だけでなく、自分自身へ状態遷移することも可能です。

```plantuml
[*] -r-> this
this -r-> next : トリガー [ガード] / エフェクト
this --> other : other
other --> other : re-entry
other -u-> next : done
next -r-> [*]
```

|項目|表記|説明|補足|
|----|----|----|---|
|トランジション|矢印|状態から状態への状態遷移を示す。|複数矢印可。自分自身への状態遷移可。|
|トリガー|トリガー名|トリガーによってその矢印の状態遷移が引き起こされる。|省略時は即座に状態遷移(completion transition)。|
|ガード|[]内に表記|ガードの条件を満たしていなければ、トリガーが発生しても状態遷移しない。|省略可。|
|エフェクト|/に続けて表記|状態遷移が起こる場合に実行される。|省略可。|

## 元となるtaransitionブロック

**Transitionグループ**にはいくつかのブロックがありますが、`transition`ブロックである `declareSimpleTransition`と`declareTimeoutedTransition`は、`declareCustomTransition`を元に簡素化したブロックです。その為、元となる`declareCustomTransition`から説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/4d16dc51-3f34-a393-29d9-0b553a78461e.png)

## transitionブロック - declareCustomTransition

`declareCustomTransition` ブロックを説明するために、次のような疑似コードを定義し、ステート図に出力しました（疑似コードは、実際には動作しません）。

**ブロック・コード（疑似コード）**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/0b387e60-f279-8f91-db07-64d3f226e86b.png)

**ステート図（疑似コード）**
```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] --> a
state a : (疑似コード)
a --> a : e [ガード1] / エフェクト1
a --> b : e [ガード2] / エフェクト2
a --> c : e [ガード3] / エフェクト3
}
@enduml
```

`a` ステート、 `b` ステート、 `c` ステートがあり、 `e` トリガーによって、 `トランジション` が引き起こされます。ただし、それぞれの`トランジション`には、`ガード`があり、その条件を満たしていなければ、状態遷移しません。
`e` トリガーによって引き起こされる `トランジション` は、ブロック・コード図で示した `transition` ブロックで宣言できます。遷移先は、配列として定義します。
もし、 `e` トリガーが発生した場合、この `transition` ブロック内が実行されます。この中で、`ガード`の条件を満たしているかどうかを判断し、状態遷移を起こします。`ガード`の条件を満たしていれば、 `transit` ブロックで、遷移先の添え字（配列のインデックス）を設定することで、状態遷移が起こるのです。 `transit` ブロックで、有効な遷移先の添え字を設定しなければ、状態遷移は起こりません。
また、 `エフェクト` は、この中で実行するようにコーディングします。`transit` ブロックの前でも後でも順序はどちらでも構いません。この`transition` ブロック内のコードが実行された後に、（状態遷移があれば）**exitアクション**が呼び出されます（`transit` ブロックでは、まだ、状態遷移が起こりません）。

## トリガーによる単純なトランジション - declareSimpleTransition

`トランジション`の多くは、一つの遷移先へ遷移する為、 `declareSimpleTransition` ブロックを予め実装しています。

次の２つのコーディングは同じ振る舞いをします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/2a8b3898-8d70-a89b-7b6a-a75a148085fb.png)

`e` トリガーが、発生したら、常に `b` ステートへ状態遷移するように `transit` ブロックで、添え字 `0` を設定しています。

## タイムアウトによるトランジション - declareTimeoutedTransition

タイムアウトによる`トランジション`である、`declareTimeoutedTransition` ブロックも予め実装しています。
タイムアウトというのは、 `ガード` のみで判断しており、`トリガー`はありません（**空の文字列**）。

次の２つのコーディングは同じ振る舞いをします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/298d6263-2d77-2a3c-d791-5ea1974d9247.png)

`timeouted` ブロックは、その状態に遷移してからの経過時間（ミリ秒）で判断されます。

## transitionブロックでの名称の省略（空の文字列）

`transtion` ブロックの `トリガー` と `ステート` において、その名称を省略することがあります（空の文字列）が、これらには、特別な意味があります。

`トリガー` の名称を空の文字列で省略すると、`completion transition` であり、即座に状態遷移することを示しています。つまり、**entryアクション**、**doアクティビティ**が一度だけ実行され、**exitアクション**の後に状態遷移します。

また、遷移先の `ステート` の名称を空の文字列で省略すると、それは、**終了状態**を意味します。

**ブロック・コードの例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/bf26ae2b-34a2-f307-07a3-00cbe0227d88.png)

**ステート図**
```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] -r-> a
state b
b -r-> [*] : e
state a
a -r-> b
}
@enduml
```

## トランジションの振る舞いを説明する（UML表記）

既にお気づきかと思いますが、 `トランジション` の `ガード`、`エフェクト` の説明をブロック・コード内に記述することができます。

`transition` ブロックで、遷移先の状態名称を定義していますが、`":"`(コロン)で区切って、`ガード`や`エフェクト`を記述することができます。

|ブロック|状態名称のみ|状態名称とガード、エフェクト|
|-------|-----------|-------------------------|
|transition|"<状態名称>"|"<状態名称>" + ":" + "<ガード>" + "/" + "<エフェクト>"|

尚、`"<ガード>"`の記述を省略することも可能です。その際は、`"<状態名称>" + ":" + "/" + "<エフェクト>"` と記述します。

## タイムアウトの追加とトランジションの表記形式

ここで、プロジェクトを改造してみます。`結果` ステートにタイムアウトによる`トランジション` を追加し、10秒経過したら、`準備` ステートへ状態遷移するようにします。もちろん、 `Reset` トリガーでも状態遷移します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/e7cf9fe7-1b2a-2b99-16b6-4b3e025d3a39.png)

さらにステート図でひと工夫します。タイムアウトのような`トランジション`は多くの状態から矢印が引かれることになり、ステート図が矢印だらけになって、正常系の状態遷移がわかりにくくなってしまいます。そこで、状態遷移先の`":"`の記述の後にもう一つ`":"`を追加してください（つまり、`"::"`）。すると、矢印が消え、`ステート`の中に説明として表記されます。

<table>
<tr><th>矢印として表記</th><th>説明として表記</th></tr>
<tr>
<td>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/e1fd6d40-c8c2-a40d-833c-4e3fb33d6b89.png)

</td>
<td>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/b2a9aa0a-ab02-32cb-6cc6-a6cdd4a35288.png)

</td>
</tr>

<tr>
<td>

```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] --> 準備
state 準備 : 経過時間の初期化
準備 --> 計測 : StartPause
state 結果 : 経過時間を表示
結果 --> 準備 : Reset
結果 --> 準備 : [>10s]
state 停止
停止 --> 計測 : StartPause
停止 --> 結果 : Stop
state 計測 : entry/\n - 開始時間を保持\ndo/ (500ms)\n - LED点滅\nexit/\n - 経過時間を加算
計測 --> 停止 : StartPause
計測 --> 結果 : Stop
}
@enduml
```

</td>
<td>

```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] --> 準備
state 準備 : 経過時間の初期化
準備 --> 計測 : StartPause
state 結果 : 経過時間を表示
state 結果: --> 準備 : Reset
state 結果: --> 準備 : [>10s]
state 停止
停止 --> 計測 : StartPause
停止 --> 結果 : Stop
state 計測 : entry/\n - 開始時間を保持\ndo/ (500ms)\n - LED点滅\nexit/\n - 経過時間を加算
計測 --> 停止 : StartPause
計測 --> 結果 : Stop
}
@enduml
```

</td>
</tr>
</table>

# トリガー発生時の引数

トリガー発生時の何らかの値（数値）を配列で渡すことができます。
次のブロック・コーディング例では、 `fire` ブロックで、それぞれ異なる値を渡し、 `transition` ブロックの引数で( `args` )で、その値を参照しています(0番目の値)。　

**ブロック・コーディング例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/b85074cc-a897-b6a4-da47-8c1c1d05db1d.png)

## 活用例

どのような場合にこの引数が必要になりそうでしょうか。
例えば、無線のシリアル番号を使って通信相手を区別したいときに役立ちます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/e05bad08-8000-6015-3653-73e3567b2f3c.png)

```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] -r-> listen
state listen
listen --> answer : request
state answer : 重い処理
answer --> listen
}
@enduml
```

重い処理を行っている最中に別のmicro:bitから無線で受信した場合でも、 `現在の相手` を維持することができます。
もし、無線で受信したときに、 `現在の相手` を設定してしまうと 別のmicro:bitのシリアル番号で上書きしてしまうことになるでしょう。

## 本プロジェクトでの適用例

実は、本プロジェクトでは、その表示で遅延が発生しないように工夫していますが、アイコンや文字列等の表示において処理が中断しています。その為、`ボタンAが押されたとき` イベントが発生してから、**entryアクション**や**exitアクション**で、`稼働時間（ミリ秒）`を取得するまでに少しばかり時間が経過してしまう可能性があります。
そこで、`ボタンAが押されたとき` イベントが発生したタイミングで、`稼働時間（ミリ秒）`を取得し、`トリガー`の引数で取得した値を渡すようにすると、より精度が高くなると考えられます。
しかし、実際にコーディングしてみると、**ステート図**の**エフェクト版**のようになり、コーディング量が増え、不具合の危険性が高まります（**entry/exitアクション**の利点が失われる）。
そこで、これらを合わせた**ミックス版**のようにするのが良いのかもしれません。

**ステート図**

<table>
<tr><th>アクション版</th><th>エフェクト版</th><th>ミックス版</th></tr>
<tr>
<td>

```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] --> 準備
state 準備 : 経過時間の初期化
準備 --> 計測 : StartPause
state 結果 : 経過時間を表示
state 結果: --> 準備 : Reset
state 結果: --> 準備 : [>10s]
state 停止
停止 --> 計測 : StartPause
停止 --> 結果 : Stop
state 計測 : entry/\n - 開始時間を保持\ndo/ (500ms)\n - LED点滅\nexit/\n - 経過時間を加算
計測 --> 停止 : StartPause
計測 --> 結果 : Stop
}
@enduml
```

</td>
<td>

```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] --> 準備
state 準備 : 経過時間の初期化
準備 --> 計測 : StartPause / 開始時間を保持
state 結果 : 経過時間を表示
state 結果: --> 準備 : Reset
state 結果: --> 準備 : [>10s]
state 停止
停止 --> 計測 : StartPause / 開始時間を保持
停止 --> 結果 : Stop
state 計測 : do/ (500ms)\n - LED点滅
計測 --> 停止 : StartPause / 経過時間を加算
計測 --> 結果 : Stop / 経過時間を加算
}
@enduml
```

</td>
<td>

```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] --> 準備
state 準備 : 経過時間の初期化
準備 --> 計測 : StartPause / 稼働時間（ミリ秒）を保持
state 結果 : 経過時間を表示
state 結果: --> 準備 : Reset
state 結果: --> 準備 : [>10s]
state 停止
停止 --> 計測 : StartPause / 稼働時間（ミリ秒）を保持
停止 --> 結果 : Stop
state 計測 : entry/\n - 開始時間を保持（※1）\ndo/ (500ms)\n - LED点滅\nexit/\n - 経過時間を加算（※2）
計測 --> 停止 : StartPause / 稼働時間（ミリ秒）を保持
計測 --> 結果 : Stop / 稼働時間（ミリ秒）を保持

note right of 計測
※1 保持している稼働時間を
　　開始時間とする

※2 保持している稼働時間と開始時間から
　　経過時間を加算
end note

}
@enduml
```

</td>
</tr>
</table>

# 複数のステートマシンを同時実行する

Mstate拡張機能では、合成状態やフォークを実現することができません。代わりに複数のステートマシンを定義・宣言し、同時に実行することで同様の振る舞いを実現します。

<table>
<tr><th>メイン</th><th>サブ</th></tr>
<tr><td>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/f7162917-18ec-7b90-f167-4df26a77923a.png)

</td><td>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/9323aeb5-da28-15ca-4f52-e0f014e44f4c.png)

</td></tr>
<tr><td>

```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M0__ {
[*] --> オフ
state オン : entry/\n - M1を大で開始
オン --> オフ : パワー
state オフ : entry/\n - M1をオフ\n - □表示
オフ --> オン : パワー
}
@enduml
```

</td><td>

```plantuml
@startuml
' http://www.plantuml.com/plantuml/
state __M1__ {
[*] --> 大
state 小
小 --> 大 : モード
小 --> [*] : オフ
state 大
大 --> 小 : モード
大 --> [*] : オフ
}
@enduml
```

</td></tr></table>

# おわりに

ブロック・コーデイングやステート図を示しながら、Mstate拡張機能について学びました。

1. micro:bitでステートマシンを使ったブロック・コーディングは、世界初[^worldsfirst]の試みであることを謳いました
1. PluntUMLによるステート図の記述を出力できる為、コーディングを元に設計の検証をすることができます
1. ステートにおけるentryアクション、doアクティビティ、exitアクションの振る舞いとコーディングをマスターしました
1. トランジションの振る舞いとコーディングをマスターしました
1. トリガー発生時にその引数でトランジションへ値（配列）を渡せることをマスターしました
1. 最終成果物であるプロジェクトとステート図へのリンクをここに示します

**プロジェクト（共有）**

https://makecode.microbit.org/_7wgaXiT56Lg5

**ステート図（Webサービス）**

http://www.plantuml.com/plantuml/uml/SoWkIImgAStDuL9No2WfAR3IroylBzSho4dC0udg9UVdwiCu-bn0nIMf2l7nlWRnyGhLND5QiGgwkdOAptPDUzeq4o8BvIXOAJpVslEoiU_PpAQNqoO_Rbptj6Fkipdpd_PCuuAe0EjyiQBZsOurGCN186S499OMfqAC0UgUy6pU77HZcYQzMBZY-P9TA8giG4OXx0rABKujmQSWsixGe3WMgk9fuvndQnTnGIYSRa98Guq4I-SNG0n1Q4dDAocgr8_9Kz1LU3cj--doRhYxd-oV-wodCIOl9LzVGSFKm22tM1EipCVLvNdJpcUxMsFoKYioIy1wqVtyj6l1ytNJkI2sW1m1TJMA6s7Ic6wivN98pKi1HY00

## 追記：ビジュアル・プログラミングにおけるステートマシン

ビジュアル・プログラミング(Blocklyやmicro:bit)におけるステートマシンライブラリの実装や、ステートマシンに関する教材等についての資料・文献をメモしておきます（参考文献ではありません）。

[**Mstate拡張機能**](https://github.com/jp-rad/pxt-mstate)が、日本における中学校段階でのプログラミング教育に役に立つのかもしれません。

1. [Blocky and State Machines](https://groups.google.com/g/blockly/c/9KSzAqu7TVo)  
→ 提案のみ
1. [AI-Planning/blockly-pddl](https://github.com/AI-Planning/blockly-pddl)
→ blocklyでの実装
1. [micro:bitを用いた状態遷移システムの教材開発およびプログラムの実装](https://www.jstage.jst.go.jp/article/jaeis/15/1/15_37/_article/-char/ja)  
→ 会員のみ閲覧可能
1. [計測制御システムの状態遷移を可視化する教材開発と情報教育への応用に関する研究](https://oecu.repo.nii.ac.jp/index.php?action=pages_view_main&active_action=repository_action_common_download&item_id=283&item_no=1&attribute_id=20&file_no=1&page_id=13&block_id=17)  
→ Rtoysでの実装、中学校段階のプログラミング教育