2EI実験ガイダンスでコンピュータ将棋など…
電子情報工学科の2年の後期実験では、 私の担当はゲームのプログラミング。 といっても、シューティングなどではなく、オセロ・五目並べ・ポーカーの 勝敗判定や役判定などを行うプログラムを通して、 プログラミングの大変さを味わってもらう。
プログラミングは、論理的思考能力のたわものではあるが、 ある程度は「プログラムを自分で作って間違った経験の差」が、 プログラム能力になると思う。そこで、タイミングやアニメ表示の プログラミングではなく、ゲーム盤の勝敗判定のプログラミングを通して 経験を深めてもらうのが目的。
簡単なゲームプログラムの作成
実験の配布資料を上記に示す。 実験では、2人が交互にオセロの手を打ち、ルール判定や勝敗を行うプログラムを作成するのが目標。
プログラミング技量に応じたプログラム作成をしてもらうために、 2週の最初にどの機能までを実装するのか、実装する機能目標の表をチェックし、 1週目さいご、2週目さいごに進捗を自分で確認する。 2週の最後には、隣の人と本当に動くのかチェックをしてもらう。
コンピュータ.vs.人間による対戦
実験ガイダンスは簡単にしておいて、プログラミングの興味を持ってもらうために、 チェスなどのコンピュータ対戦の雑談。
- コンピュータ・オセロ
- コンピュータ・チェス
チェス:カスパロフ.vs.ディープ・ブルー ・DB.vs.Kasparov動画 - コンピュータ将棋
電王戦の記録
電王戦で衝撃的な結末!「角成らず」を認識できずに反則負け… ・角歩成らず動画 - コンピュータ囲碁
コンピュータは論理的思考の処理(左脳)が得意で、現状ではコンピュータの速度にはかなわない。 しかし、人間のイメージで捉える能力(右脳)ではまだまだ劣っている。 こういった領域でもコンピュータが活躍するための研究なども進められている。
プログラマーに見て欲しい映画
構造体の参照渡しとオブジェクト指向
一緒に、来週のプログラミング応用の資料書いちゃえ。
構造体の参照渡し
構造体のデータを関数の呼び出しで記述する場合には、参照渡しを利用する。
struct Person { char name[ 20 ] ; int age ; } ; void print( struct Person* p ) { printf( "%s %d¥n" , p->name , p->age ) ; } void main() { struct Person saitoh ; strcpy( saitoh.name , "t-saitoh" ) ; saitoh.age = 50 ; print( &saitoh ) ; }
このようなプログラムの書き方をすると、「データ saitoh に、print() せよ…」 といった処理を記述したようになる。 これを発展して、データ saitoh に、print という命令をするイメージにも見える。
この考え方を、そのままプログラムに反映させ、Personというデータは、 名前と年齢、データを表示するprintは…といったように、 データ構造と、そのデータ構造への処理をペアで記述すると分かりやすい。
オブジェクト指向の導入
オブジェクト指向では、データ構造とその命令を合わせたものをクラス(class)と呼ぶ。 また、データ(class)への命令は、メソッド(method)と呼ぶ。
class Person { private: char name[ 20 ] ; int age ; public: Person( char s[] , int a ) { strcpy( name , s ) ; age = a ; } int scan() { return scan( "%s %d" , name , &age ) ; } void print() { printf( "%s %d¥n" , name , age ) ; } } ; void main() { Person saitoh( "t-saitoh" , 50 ) ; saitoh.print() ; Person table[ 50 ] ; for( int i = 0 ; i < 50 ; i++ ) { if ( table[ i ].scan() != 2 ) break ; table[ i ].print() ; } }
構造体とオブジェクト指向
プログラミング応用の後期では、構造体とコンピュータグラフィックスの基礎を扱う予定。 CGの基礎でも、X座標,Y座標…をひと塊の構造体で表現という意味では、構造体の延長として授業を進める予定。
構造体
上記資料を元に説明。 最初に構造体が無かったら、名前・国語・算数・理科の1クラス分のデータをどう表現しますか?
// まずは基本の宣言 char name[ 50 ][ 20 ] ; int kokugo[ 50 ] ; int sansu[ 50 ] ; int rika[ 50 ] ; // もしクラスが最初20人だったら、20→50に変更する際に、 // 文字列長の20も書きなおしちゃうかも。 // 50とか20とかマジックナンバーは使わないほうがいい。 #define SIZE 50 #define LEN 20 char name[ SIZE ][ LEN ] ; int kokugo[ SIZE ] ; : // 2クラス分のデータ(例えばEI科とE科)を保存したかったら? // case-1(配列2倍にしちゃえ) char name[ 100 ][ 20 ] ; // どこからがEI科? int kokugo[ 100 ] ; : // case-2(2次元配列にしちゃえ) char name[ 2 ][ 50 ][ 20 ] ; // 0,1どっちがEI科? int kokugo[ 2 ][ 50 ] ; : // case-3(目的に応じた名前の変数を作っちゃえ) char ei_name[ 50 ][ 20 ] ; // EI科は一目瞭然 int ei_kokugo[ 50 ] ; // だけど変数名が違うから : // 処理を2度書き char ee_name[ 50 ][ 20 ] ; int ee_kokugo[ 50 ] ; :
このような問題に対応するために構造体を用いる。
struct Person { // Personが構造体名(タグ名) char name[ 20 ] ; int kokugo ; int sansu ; int rika ; } ; struct Person saitoh ; struct Person ei[ 50 ] , ee[ 40 ] ; strcpy( saitoh.name , "t-saitoh" ) ; saitoh.kokugo = 100 ; ei[ 0 ].sansu = 80 ; ee[ 1 ].rika = 75 ;
授業では、構造体の初期化、入れ子の話をする。詳細は配布資料参照。
途中で、C言語の歴史として、unix開発時に、BCPL→B言語→C言語(K&R)→ANSI-C→…C++→D言語 といった雑談も説明。
入れ子の話では、 for(…) { for(…) { } } のような、処理の入れ子(処理の構造化)と、 構造体の入れ子(データの構造化)の話から、構造化プログラミング(structured programming)といった話も紹介する。
データベース・ガイダンス
今日が後期の選択科目「データベース」の第一回目ということで、 シラバス配布&ガイダンスをしてからぁ〜のぉ〜、概要説明。
インターネットの情報量
インターネット上の情報量の話として、2010年度に281EB(エクサバイト) 参考:kMGTPEZYで、今日改めて探したら、2013年度で、1.2 ZB(ゼタバイト) という情報があった。ムーアの法則2年で2倍の概算にも、それなりに近い。 今年2015年であれば、約2年で、2 ZBにはなっているかな。
そして、これらの情報をGoogleなどで探す場合、すぐにそれなりに情報を みつけてくれる。これらは、どの様に実装されているのか?
Webシステムとデータベース
まず、指定したキーワードの情報を見つけてくれるものとして、 検索システムがあるが、このデータベースはどのようにできているのか?
Web創成期の頃であれば、Yahooがディレクトリ型の検索システムを構築 してくれている。(ページ作者がキーワードとURLを登録する方式) しかし、ディレクトリ型では、自分が考えたキーワードではページが 見つからないことが多い。
そこで、GoogleはWebロボット(クローラー)による検索システムを構築した。 Webロボットは、定期的に登録されているURLをアクセスし、 そのページ内の単語を分割しURLと共にデータベースに追加する。 さらに、ページ内にURLが含まれていると、そのURLの先で、 同様の処理を再帰的に繰り返す。
これにより、巨大なデータベースが構築されているが、これを少ない コンピュータで実現すると、処理速度が足りず、3秒ルール/5秒ルール (Web利用者は次のページ表示が3秒を越えると、次に閲覧してくれない) これを処理するには負荷分散が重要となる。
一般的に、Webシステムを構築する場合には、 1段:Webサーバ、2段:動的ページ言語、3段:データベースとなる場合も 多い。この場合、OS=Linux,Web=Apache,DB=MySQL,言語=PHPの組合せで、 LAMP構成とする場合も多い。
一方で、大量のデータを処理するDBでは、 フロントエンドDB,スレーブDB,マスタDBの3段スキーマ構成となることも多い。
データベースシステム
データベースには、ファイル内のデータを扱うためのライブラリの、 BerkleyDBといった場合もあるが、複雑なデータの問い合わせを実現する 場合には、リレーショナル・データベース(RDB)を用いる。 RDBでは、データをすべて表形式であらわし、SQLというデータベース 問い合わせ言語でデータを扱う。 また、問い合わせは、ネットワーク越しに実現可能であり、こういった RDBで有名なものとして、Oracle , MySQL , PostgreSQL などがある。 単一コンピュータ内でのデータベースには、SQLite などがある。
しかし、RDBでは複雑なデータの問い合わせはできるが、 大量のデータ処理のシステムでは、フロントエンドDB,スレーブDB,マスタDB の同期が問題となる。この複雑さへの対応として、最近は NoSQL が 注目されている。
データベースが無かったら
これらのデータベースが無かったら、どのようなプログラムを作る 必要があるのか?
情報構造論ではC言語でデータベースっぽいことをしていたが、 大量のデータを永続的に扱うのであれば、ファイルへのデータの読み書き 修正ができるプログラムが必要となる。
こういったデータをファイルで扱う場合には、1件のデータ長が途中で 変化すると、N番目のデータは何処?といった現象が発生する。 このため、簡単なデータベースを自力で書くには、1件あたりのデータ量を 固定し、lseek() , fwrite() , fread() などの 関数でランダムアクセスのプログラムを書く必要がある。
また、データの読み書きが複数同時発生する場合には、排他処理も 重要となる。例えば、銀行での預け金10万の時、3万入金と、2万引落としが 同時に発生したらどうなるか? 最悪なケースでは、 (1)入金処理で、残金10万を読み出し、 (2)引落し処理で、残金10万を読み出し、 (3)入金処理で10万に+3万で、13万円を書き込み、 (4)引落し処理で、残金10万-2万で、8万円を書き込み。 で、本来なら11万になるべき結果が、8万になるかもしれない。
さらに、コンピュータといってもハードディスクの故障などは発生する。 障害が発生してもデータの一貫性を保つためには、バックアップや 障害対応が重要となる。
2015年9月27日(第442回)
収録でお送りしました。
- 後期スタート!
- 旅行の話
- 食べのもの話
- 好きな行事について
- ジャズバー歴史 14杯目「最初の~~」
担当:山岸(3C)、稲葉(2EI、MC)、島脇(2B)、田中(2B、MIX)、鷲田(1EI)、西(教員)
2015年9月20日(第441回)
- 越前ものづくりフェスタについて
- 鯖江市地域活性化プランコンテストについて
- 夏休みに思い残したこと
- ジャズバー歴史 13杯目「歴史と人名」
担当:松島(4C)、川﨑(2EI、MIX)、木下(2EI)、田中(2B、MC)、西(教員)
2015年9月13日(第440回)
- 鯖江市地域活性化プランコンテストについて
- 越前ものづくりフェスタについて
- 鯖江市のイベントについて
- ジャズバー歴史 12杯目「鉄道と軍隊」
担当:松島(4C)、植村(2E)、小藤(2B)、西島(1E)、中村(教員)
Raspberry-Piのカメラをサーボで制御したい
I2Cを認識させる
(( i2cを認識させる設定 )) $ sudo raspi-config ## 8 Advenced Options" -> "A7 I2C" よりI2Cを標準で認識するように設定 ## /etc/modprobe.d/raspi-blacklist.confのblacklistがコメントアウト # blacklist i2c-bcm2708 ## /etc/modules に以下の行が追加される i2c-dev i2c-bcm2708 $ sudo reboot (( i2cが認識されたか確認 )) $ sudo aptitude install i2c-tools $ ls /dev/i2c-* /dev/i2c-1 ## Raspberry-Pi によっては、/dev/i2c-0 となるかも。 $ sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- ## まだi2c機器を何も繋げていない... (( i2cをユーザで使えるように )) $ ls /dev/i2c-1 crw-rw---T 1 root i2c 89, 1 9月 10 09:02 /dev/i2c-1 ## i2cを使うためのグループにユーザpiを加える。 $ sudo adduser pi i2c