02. SNAP! でオブジェクト指向(1/4)

出席をWebclassに登録。

先回の Viscuit 作品紹介

2018年度作品のピックアップ:

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=167&smoothMotion=true&dynamicFile=false 継承時に時間ルールが追加されている。上位のルールを継承しつつ機能修正が可能な例。私も今まで気が付かず。Java等のプログラム言語でいえば、サブクラスでオーバライドしたメソッドからスーパークラスのメソッドを呼び出し、さらに他の処理を追加することに相当。☆

子どもがビスケットの仕様を作っている話

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=114&smoothMotion=true&dynamicFile=false ゲーム。意外に難しい。時間差をつけた継承を活用している。☆

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=130&smoothMotion=true&dynamicFile=false ゲーム。耐久力2を表現している。

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=135&smoothMotion=true&dynamicFile=false アニメーション。勝敗のルールが面白い。

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=160&smoothMotion=true&dynamicFile=false シンプル&アニメーションが面白い

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=134&smoothMotion=true&dynamicFile=false 継承を利用したアニメーションが面白い

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=152&smoothMotion=true&dynamicFile=false 生態系。クラゲを増殖させるパズルとして面白い。

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=151&smoothMotion=true&dynamicFile=false 足し算が織り込まれたルールが俊逸。2桁の計算結果が1桁に還元されるのも面白い。

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=148&smoothMotion=true&dynamicFile=false 複雑なルールが継承によりまとめられていて良い例。ゲームのルールも面白い。☆

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=145&smoothMotion=true&dynamicFile=false シンプルだがアニメーションと異なるオブジェクトが共通のルールを持つようになる過程が面白い。☆

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=144&smoothMotion=true&dynamicFile=false ランダム演奏の中に時折パターンが表れて面白い。

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=139&smoothMotion=true&dynamicFile=false VISCUITの継承機能がシンプルなアニメーションにまとまっている好例。☆

http://develop.viscuit.com/3.1/Land.html?path=2518958&name=116&smoothMotion=true&dynamicFile=false タイムラインを利用したシンプルなアニメーション。

復習課題:

Viscuit で説明したオブジェクト指向プログラミング(OOP)の「継承」に関する概念について、以下の点を回答する。

確認

OOPで、クラスの継承を用いるメリットはなにか?

クラスとインスタンスの関係は? (2018年度 説明し忘れ。補足する。)

インスタンスの持つプロパティ(または変数)は、Viscuitでは、何が相当するか?

親クラスに設定されたルールと 子クラスに設定されたルール が競合する場合( 親 右に動け 、 子 左に動け)

Viscuit ではどのように処理されているか?

他のOOP言語で(例 Java)、親子間でルールの競合がある場合は、どのように処理されるのか、調べる。

WebClassの第2回課題に回答(次回まで)

第1回目のVISCUITでオブジェクト指向のコンセプトを理解するために必要な事項はほとんど体験済み。

オブジェクト指向とお風呂場のハサミ トップクラスのコンピュータ将棋開発者 山本一成氏の記事。

VISCUITの仕様から雪だるまルールをなくした場合、複数のオブジェクト(道具)から必要とされる共通ルールが、個々の道具にバラバラに仕舞われてしまう。

すると、すべての道具の個々のルールを管理する必要が出てくる。

その状況では、全体的なルール変更や追加を行う際に、雪だるまルールが無いVISCUITでは大変な作業となることがイメージできますか?

今回導入する概念・用語:

オブジェクトの状態と振舞い インスタンス変数 メッセージ 引数

Scratch2.0とオブジェクト指向

http://scratch.mit.edu/

Scratchのオブジェクト指向 と Javaのオブジェクト指向

http://prezi.com/o1jlsf_celo1/scratchjava/ Scratchに組み込まれたオブジェクト指向的概念をJavaの文法で表現した資料。

※Scratchはオブジェクト指向のメッセージパッシング(メッセージを送信することで他のスプライトのメソッド(プログラム)を起動させる)機能をサポートしている。

※2018年現在のScratchには、特定のスプライトを指名したメッセージパッシング機能は採用されていない。全スプライトへのメッセージ送信として扱われる。

(補足)オブジェクト指向の概念の発明者は誰ですか?(改訂版)

大きく2系統に分かれる。

・アラン・ケイ(初期のオブジェクト指向言語 Smalltalk の開発者)の メッセージングのオブジェクト指向

・ビアルネ・ストラウストラップ(初期のオブジェクト指向言語 C++ の開発者)の 抽象データ型のオブジェクト指向※

※さらに、クラスベースのオブジェクト指向(C++やJava)と プロトタイプベースのオブジェクト指向(JavaScript)がある。

※現在、クラスベースのオブジェクト指向が開発の主流

■SNAP! とオブジェクト指向

SNAP!はScratchに、ブロック作成機能と関数オブジェクトを加えたプログラム学習環境。

http://byob.berkeley.edu/ ← こちらのページの Run SNAP! Now から利用できる。

SNAP!のページ ← 直接利用するには、こちらから。

SNAP!マニュアル

特徴:

関数スタイルのコード作成が可能。

独自の制御ブロックを作成することができる。

再帰呼び出しのプログラムも可能。

※ Chrome ブラウザからの利用を推奨

■演習内容

http://byob.berkeley.edu/ から run SNAP! now で、SNAP!のプログラムを作成し、以下の内容を確認。

言語は英語環境になっているので 歯車アイコン から Language を 日本語 に切り替えておくとよい。

SNAP!マニュアル P12~15

クラスとインスタンス

確認内容:

・スプライト固有の変数

・スプライトのクローン

クローンの位置・向き・サイズ・画像

SNAP!は、プロトタイプベースのオプジェクト指向プログラミング

変数を新しく作る から 変数を作成

global_a を全てのスプライト用で作成

class_a をこのスプライトに用で作成

※注 クローンは オリジナルと同じ位置に、重なって作成されます。クローン作成後、マウスで移動してください。

※注 SNAP!のスプライトの クローン は、クローンした時点のオリジナルのスプライトのコードを引き継ぎます。

※クローンを削除するブロックはクローンのコードで利用する。クローンを実行中に自分自身を破壊するブロック。オリジナルのスプライトは削除されない。

※プログラムの停止ボタン(赤丸)を押すと、クローンは消える。

作業例)

グローバル変数(全スプライト共用) と クラス変数(あるスプライト専用)

2つ目以降のスプライトはコスチュームを編集して見た目で区別がつくようにしておく。

クラス変数 と インスタンス変数(クローンのプロパティ。座標や向きなど)

クローンを新規作成した場合、XY座標や向きなどは元のスプライト同じ値に初期化される。

マウスやプログラムで、各クローンに個別のプロパティ(座標や向きなど)を操作できる。

※「言う」ブロックの吹き出し内に表示が収まらない場合、演算ブロックの 丸める で、端数を切り捨てるとよい。

例)

その他の変数:

SNAP! で利用できる変数は、以下の8種類ある。

永続化可能※1

・スプライトのプロパティ(座標・向き・サイズ・コスチュームなどの要素。x座標などの名前が予め決められている。値の代入書き換えは、移動ブロックなど専用のブロックで行う。)

・スプライト全体で共用の変数(グローバル変数)

・個別のスプライト固有でそのスプライト専用の変数(クラス変数)

※1 transient 指定すればプログラムを保存しても変数の値は保存されない。次回実行時には初期値に戻る。

一時的変数※2

・スクリプト変数(スクリプト変数ブロックで一時的に作成した変数。ブロックの実行終了時に変数は消滅する)※3

・カスタムブロックの引数(自作ブロックを作成した際に、パラメータとして渡す変数。カスタムブロックの実行開始時に生成され、終了時に消滅する)※3

・関数オブジェクト・関数ブロックの引数※3

このページの下のほう、ブロックのデータ化(リング化)で説明。

・クローンのプロパティ(スプライト同様。プログラムが停止すると消える。)

・継続

継続とは、あるブロックの次に実行するブロックの位置とプログラムの実行環境をデータ化したもの。変数に保存したり引数に渡すことができる。(次回説明)

※2ブロックやプログラムの実行中にだけ存在する

※3関数の再起呼び出し、ブロックの再起呼び出しの際に、引数は毎回新たに生成される。再起呼び出しは次回説明。

変数の説明用の画像

プロパティ

関数オブジェクト

マニュアルP23~P26

関数ブロック と 関数オブジェクト の比較

例)

ブロック・エディターを開いてカスタムブロックの関数ブロックを作成

数式ブロックをリング化して関数オブジェクトを作成

両者を変数に代入して、その挙動を比較

・ set x test 1 の場合:

関数ブロックそのものを変数にセットすることはできない。関数ブロックを変数にセットしようとしても関数ブロックの実行結果の値が変数にセットされる。

上の例では x は値 4 になる。

・ set y 関数オブジェクトの場合:

関数オブジェクトそのものを変数にセットすることができる。

上の例では y の値は関数オブジェクトになっている。

変数にセットされた関数オブジェクトを、別のプログラムから実行(call)することができる。

SNAP!マニュアル P43~50

・計算式ブロック

・関数オブジェクト (関数化(リング化))

・パラメータ適用 (関数呼び出し)

・関数オブジェクトの利用

関数オブジェクト と 関数適用

・ 1 + 3 の計算処理と X + 3の計算処理の例

・計算式を関数化する例 関数オブジェクトを作成し 変数に格納する。 変数に値を適用(代入ではなく、関数オブジェクトの引数として処理される)して関数オブジェクトの処理を呼び出す。

数値を2乗する関数と、関数オブジェクトの利用例)

2018年度 第3回はここからスタート

SNAP!マニュアル P48~50

ブロックのデータ化 を扱う。

前述の関数オブジェクトは数式をデータ化したもの。

ここではブロックをオブジェクト化して扱う例を示す。

ブロックをオブジェクト化してデータとして扱えば、ブロックを組み立てたり修正したりするプログラムの作成、つまりプログラムをプロブラムすることが出来るようになる。

■ブロックオブジェクトを2回実行するカスタムブロックの例)

SNAP!には、ブロックを指定して回数で繰り返し実行するブロックが既に制御ブロックとして用意されている。

ここでは、ブロックを制御するブロックを作成する例として、引数として渡したブロックオブジェクトを2回実行する例を示す。

※カスタムブロックの編集画面で、引数が a λ (ギリシャ文字 λ はラムダと読む)の部分は、

引数の型指定を行い、このカスタムブロックの引数をブロックオブジェクトだけに制限した目印。

引数の型指定の方法:

ブロックの引数をクリックして、設定パネルを表示する。▼をクリックしてパネルの型指定パネルに切り替える。

型指定パネル: コマンド(インライン)を選択する。

カスタムブロック twice の引数が、リング付きのブロックに限定される。

■応用 twice に twice を渡してスプライトを移動させるコードを試せ。

■ 観覧車の骨組みとカゴを描く例)

観覧車の骨組みを描くプログラムの内部で、変数Aにセットされたカゴ(○)を描くプログラムを利用する。

・変数 a に丸を描くブロックオブジェクトをセットして実行した例)

変数Aに別の籠(△)を描くプログラムをセットすると、観覧車の骨組みを描くプログラムを修正せずに、全体の動作を変更することができる。

※プログラムの合成が可能になる。コードをシンプルかつ柔軟に記述できる。

・変数 a に三角を描くブロックオブジェクトをセットして実行した例)

上の例をブロックオブジェクトによる挙動の変更の代わりに、通常の条件分岐でプログラムした例)

この変数 a の値によってカゴの形を切り替えるコードでは、その後、カゴの種類が増える度に もし・なら ブロックによる条件判定と図形を描くコードの追記が必要となる。

しかも、放射状に12本のアームを描くプロブラムは、カゴのプログラムと強固に結びついているので、カゴのプログラム専用のプログラムとなり、他で再利用するには、コード全体をコピーして書き換える他ない。

最初に紹介した、ブロックオブジェクトを利用する例では、放射状に12本のアームを描くプロブラムは 変数 a と結びついているが a を変更してもコードの修正やコピーと書き換えの必要もない。独立したプログラムとして再利用性が高い。

さらに、変数 a との結び付きも解消するには、以下のようにカスタムブロックを作成し、ブロックの引数としてブロックオブジェクトを渡すようにすればよい。

任意の図形を描くプログラムを、12本のアームの先にぶら下げて秒化するコマンド arm12 の出来上がり。

※ブロックオブジェクトは、このような図形を合成するコードで利用するだけでなく、

「 次の2つのブロックを交互に3回実行 【プログラムブロックA】【プログラムブロックB】」 →ABABABの順に実行

のような、ブロックの実行順序や回数を制御するブロック、つまりカスタムの制御構造を用意する際にも利用する。

■プログラムの保存と提出など

SNAP!で作成したコードは、IDを取得すればクラウド上に保存できる。

クラウドに保存の他、ブラウザの保存領域(File API利用?)に保存することも可能。

提出方法:

2018年度は プログラムエディターを開いて、作成したブロックの内容を表示し、

実行結果をスクリーンに描画し、スクリーンショットの画像で課題提出に変更。

保存されたファイルをWebClassにアップロードする。

Q&A

Q:リストにコマンドを格納して実行したいがうまく行かない

A:コマンドをリング化して格納する

例1)

スプライトを回転するコマンドをモニターとして作成。

上の実行例では、モニターをリストに格納しているように見えるが、実際はモニターの実行結果が格納されているため、期待通りに動かない。

した実行例では、モニターをリング化して格納している。リング化ブロックは実行するブロックで実行したときに初めて動くので、期待通り動く。

例2)

コマンドをモニターとして作成せずに、動きブロックとして作成してリストに格納して実行する。

下の例では、R2コマンドをモニターとして作成して、リング化した状態で値を返している。こうすれば、コマンドをリストに格納する際にいちいちリング化しなくて済む。