すごろくゲーム作成(1)
最近ほったらかしにしていましたが、すごろくゲームの作成も進めていきます!
教科書通りの勉強も楽しいし大事ですが、オリジナルのアウトプットをしないことには、応用力が身につかない気がしますので。
「行き当たりばったりに作った結果、完成しなかった」という前回の反省を活かし、少しずつ作業をブレークダウンしていくことにします。
そんなわけで、レッツリベンジ!
作りたいものを決める
作りたいものは「簡単なすごろくゲーム」です。
すごろくゲームの概要
・複数人で対戦可能なすごろくゲーム。
・毎ターン順番にサイコロを振っていって、先に20マス進んだ人が勝ち。
実現したい機能
・プレイヤーのエントリー機能。人数と名前が入れられる。
・ランキング表示機能。毎ターン終了時と、全員ゴール時に表示する。
必要な処理
・プレイヤー人数と情報の入力処理。
・出た目のマスだけプレイヤーの位置を進める処理。
・ランキングを計算する処理。
・上記の処理を毎ターン、全員分繰り返す処理。
保持する必要のある情報
・各プレイヤーの名前。
・各プレイヤーの現在地。
・各プレイヤーの順位。
・プレイヤー数。
……こんなところでしょうか。
自分としては、下に行くにつれて情報の粒度が細かくなるように記載したつもりです
(必要な処理と情報は、どちらもクラスに定義するなら「同じ粒度の別の情報」と言えるかもしれませんが) 。
あとはこれらをどういうクラスに持つか……という設計をすればよいのではと思います。
各プレイヤーの情報は、「プレイヤークラス」みたいなものを作って、そこに保持するようにするとか、プレイヤー数は「プレイヤーリストクラス」みたいなものに保持したほうがよさそうだなー……とか。
具体的にアウトプットしたことで、だいぶイメージが掴めました。
実際にソースコードを作成したら、またブログを更新しようと思います。
デザインパターン勉強中(1)
そんなわけでデザインパターンの勉強を始めました。
勉強してわかったことをこつこつブログにまとめていきたいと思います。
ちなみに勉強に使っている本はこの本です。
Iteratorパターン
最初から混乱しました。
前に読んだOPPの本では、良い設計の原則として「クラスをお互いに依存させないこと」 が挙げられていたのですが、このパターンには思いっきり相互に依存し合うクラスが出てきます。
それがConcreteAggregate(具体的な集合体)クラスと、ConcreteIterator(具体的な反復子)クラスです。
「集合体クラスが修正されたら、反復子クラスにも修正が必要じゃん。何が便利なのこれ?」と思ったのですが、このパターンのキモは「集合体の実装を、それを実際に使う処理から隠すこと」のようです。
この本に載っている例では「本棚」が挙げられ、本棚クラスに収められている本が何であるかをひとつずつ数え上げるプログラムが記載されています。
例えば本棚に収められている本をfor文で順に表示しようとすると、以下のような本棚クラスの実装を数える側のプログラムが把握しなければなりません。
- 配列のサイズはいくつか。
- 配列の開始番号はいくつか。
こうなってしまうと、本棚クラスの実装が変更された場合に、それを参照している箇所は修正が必要になってしまいます(配列ではなくArrayListになった場合など)。
それが複数箇所に及んでいた場合は……修正漏れが発生することは容易に想像できます。
そこで反復処理される集合体クラスの実装を、反復子クラスで隠してしまう、というのがIteratorパターンのキモのようです。
このパターンを用いることにより、実際に反復処理する側のクラスは、本棚の実装を気にする必要がなくなります。
本棚が配列だろうとListだろうと、サイズがいくつだろうと関係なく、反復子クラスが全部数えてくれるからです。
反復子クラスは本棚のクラスに合わせて作る必要がありますが、逆に言えばそれだけでいいとも言えます。
何箇所で本棚を参照していても、反復子クラスで反復処理を実装していれば、本棚クラスが修正されても問題ありません。
つまり「『本棚を見る側の処理』と『本棚』の依存関係を解消すること」がIteratorパターンのいいところなのではないでしょうか。
そのメリットのためであれば、集合体と反復子が依存しあっているのも、さして問題にならないですね。
また勉強したら更新します。
『オブジェクト指向でなぜつくるのか』を読了しました。
以前にも触れましたが、とてもいい本でした。
オブジェクト指向でプログラミングしたことがない自分でも、その概要が少しはつかめたのではないかと思います。
特に良かったなと思うのが、ポリモーフィズムとUMLについての説明です。
ポリモーフィズムは、自分にとって少しわかりにくい概念でした。呼び出し方法を揃えるだのクラスを継承するだの言われても、実装イメージが湧かなかったので、いまいちピンとこなかったのです。
この本にはサンプルソースが載っていたので、少しはイメージが掴めた気がします。
実際にポリモーフィズムを使ったコーディングはまだしていないので、完全に理解したとは言えないと思いますが……。それはこれから練習したいと思います。
UMLの説明は、自分にとって少々意外な内容でした。
オブジェクト指向でのプログラミングを図式化するために生まれた手段だとは認識していなかったからです。
OPPやったことの無い自分でも、シーケンス図など仕事で使ったこともありました。
ですがUMLとOPP、クラス設計は、切っても切れない関係にありそうです。
とあるブログで、UMLについての解説本が以下のように紹介されていました。
(引用の許可を下さった伊藤さん、ありがとうございます)
実践UML 第3版 オブジェクト指向分析設計と反復型開発入門
- 作者: クレーグ・ラーマン,依田智夫,今野睦,依田光江
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2007/11/12
- メディア: 単行本(ソフトカバー)
- 購入: 8人 クリック: 179回
- この商品を含むブログ (29件) を見る
オブジェクト指向プログラミングに必ず出てくるのが「クラス」です。 すでに用意されているクラスを使うことは簡単でも、「自分でクラスを定義しろ」と言われたらどうすれば良いのかわからない、という人は結構多いのではないでしょうか? この本では仮想的な開発プロジェクトを題材にして、オブジェクト指向分析やオブジェクト指向設計の具体的な方法を学ぶことができます。 こういった技術書を読んで、どんなクラスが良いクラスなのか、また、どんなクラスが悪いクラスなのかを評価できるようになりましょう。
プログラマ歴12年の僕が選んだ「10年経っても役立つ技術書17選」 - give IT a try
「UMLわかるとオブジェクト指向設計が出来るようになるのん?」と気になったのでUMLについていろいろ調べてみると、ちゃんと勉強するとクラス設計能力の向上に繋がりそうなお話が至るところで見られます。
オブジェクト指向を始めたばかりで、実践的な知識がほぼ皆無の自分としては、非常に興味をそそられる話です。
ただ上の本はちょっと高すぎて手が出そうにないので(泣)、他の本で勉強してみたいと思っています。いま気になっているのはこのシリーズ。
Kindle版だと安くてびっくりです。
本屋で立ち読みして、良さそうだったら買ってみようと思ってたのですが、今日立ち寄った本屋では見つからなかった……。
でも評価も高いし値段もお手頃だし、気にせず買ってもいいかもしれません。迷う……。
とりあえずはクラス設計については、今日届いたこの本で勉強しようと思います。
クラスに関する知識が薄い状態でデザインパターンから入っても大丈夫なのかはちょっと不安ですが(しかももはやUMLの勉強ではない)、「合理的なものの仕組み」を学ぶのは好きなので、勉強ということを抜きにしても楽しめるのではないかと期待しています。
そんな感じで、オブジェクト指向の入り口に立った自分は、より実践的な勉強を始めるのでした。
今日は一日予定ないし、少しは頑張りたいですね!
アプリを開発してみてわかった、自分の勘違い、失敗、未熟なところ。
すごろくアプリを作っていて、自分がいかにプログラム設計能力がないのかが、ありありとわかりました。
コンソール上でしか動かないものですら、自分には決して簡単ではありませんでした。
ですがそこから重要な知見も得られたと思うので、今後の方針と合わせて以下にまとめてみたいと思います。
以下、目次です。
- アプリの完成イメージを持たないまま作り始めてしまった。
- I/Oが決まっていないものにTDDを導入しようとした。
- 単純にアルゴリズムに関する知識が足りなかった。
- クラスの使い方が、たぶんあまり良くない。
- まとめと対策
アプリの完成イメージを持たないまま作り始めてしまった。
これは実際に作ってみないとわからない部分もあると思うので、必ずしも悪いことではないかもしれません。
ですが自分くらいの実力では、書きながら考えるというのは少し難しかったです。
作りたいものが曖昧なままスタートしてもいいけど、書き始める前に一瞬立ち止まって考えるようにした方が、結果的には早くいいものが作れそうな気がします。
I/Oが決まっていないものにTDDを導入しようとした。
これはプログラム設計能力というより、TDDがどういうものなのかと言うのがわかっていなかったという反省点です。
自分がTDDを導入しようとしたのは、「実際に起動して動作確認するのが面倒くさかったから」なのですが、正確に言うと「後半に動作するメソッドの動きをさっさと確認したかったから」です。
すごろくアプリは、以下のような動作をイメージして作っていました。
- プレイヤーを登録する。
- 順番にサイコロを振って駒を進める。
- ゴールした順をランキングとして表示する。
このうち、1と2はほぼ出来上がっていたのですが、3がまだうまく作れていませんでした。
作ったら動かしてみないと正しく動作するかがわかりませんが、普通に動かして3の動作を確認するのは、1と2の動作を経なければならず、かなり面倒です。
そこでTDDならば、動作を確認しながら、出来ていない処理も作り込んでいけるのでは、と考えたのです。
実際はそんなことはありませんでした。
自分はまだ、ランキングの処理をどのように実装するか、具体的なイメージが出来ていなかったため、テストケースを書くことができなかったのです。
これは先述した、「アプリの完成イメージを持たないまま作り始めてしまった」と同じ問題とも言えるかもしれません。
プログラムは入出力をするものなのだから、どういうアルゴリズムにするかはともかく、入出力のイメージが曖昧すぎては書くことが出来ません。
経験豊富な人なら別かもしれませんが、自分にはそれだけの実力がありませんでした。
単純にアルゴリズムに関する知識が足りなかった。
すごろくアプリは、思いついたままに楽しく作るのが目的だったので、思いついた機能はどんどん追加していきました。ランキング表示もそのひとつです。
ですが、どのようにすればランキング表示機能が作れるのかがよくわかりませんでした。
配列やソートなどを使えばいいことはなんとなくわかるのですが、それをどう実現すればいいのか、という具体的なレベルの解答を、自力で出すことが出来ませんでした。
アプリの完成イメージが持てないこと、TDDを誤解していたことは、個人的にはまだ仕方ないと言えなくもなかったのですが(イチから開発した経験、TDDの経験がないから)、これに関してはもうただただ恥ずかしい話です。
それほど大した仕事をしているわけではなくとも、一応ソフトウェア開発の企業で働いているのに……顔から火が出るとはこのことかと思いました。
クラスの使い方が、たぶんあまり良くない。
ここに関しては、正直よくわからないです。
オブジェクト指向でプログラミングしたことがないので、いいも悪いも評価できないからです。
ですが使いこなせているという実感はないし、メソッドも変数もどういう根拠でそう設計したのかと問われると答えられないので、仮に良い設計をしていたとしても、それは自分の実力ではありません。
(ネット上で簡単に調べただけでも、あまりいい設計じゃなさそうなのはわかってきましたが……)
まとめと対策
- アプリの完成イメージを持たないまま作り始めてしまった。
- I/Oが決まっていないものにTDDを導入しようとした。
- アルゴリズムに関する知識が足りなかった。
- クラスの使い方が良くない。
……こんなところでしょうか。
そして、それぞれに対する策を考えてみました。
- アプリの完成イメージを持つために、どんなものを作りたいかを紙に書き出しながら作る。I/Oも極力明確にする。
いいものを作りたかったら、完成イメージを明確にするよりも、自由な想像力で自由に書いてもいいのではないかと思いますが(それこそ絵や詩のように)、いまの自分にはそんな実力はありません。
ちゃんと完成させるためにも、せめて外側から見たときにどんな振る舞いをするかくらいは決めてから作ろうと思います。
そのために、完成イメージはできるだけ具体的に、紙に書き出すようにします。
こうすれば、TDDも導入できそうです。
- アルゴリズムについての知識を身に付けるために、本を一冊読む。
Amazonで評判のよかった、この本を読んでみようと思います。
珠玉のプログラミング 本質を見抜いたアルゴリズムとデータ構造
- 作者: ジョン・ベントリー,小林健一郎
- 出版社/メーカー: 丸善出版
- 発売日: 2014/02/28
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
アルゴリズムは、単に答えを覚えるだけでは意味がありません。
それならば調べれば済む話です。実際、他の勉強を優先したほうがよいのではとも思いました。
ですが考え方を身につければ、それはいろんな場面で応用できそうです。
考え方の過程が詳しく書いてあると評判の本のようなので、身に付けられるように頑張ります。
- クラス設計の知識を身に付けるために、本を一冊読む。
クラス設計については、この本を読んでみようと思います。
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2004/06/19
- メディア: 大型本
- 購入: 51人 クリック: 762回
- この商品を含むブログ (397件) を見る
有名な本で、評価も高かったのでこれにしてみました。
Javaはあまりわかりませんが、細かい文法が違うだけで、本質は同じだと思いますので、読めないことはないと思います。
デザインパターンについて書かれたネットの記事が面白かったので、勉強というよりは普通に楽しめそうな気がします。
合理的に組み上げられたものの仕組みを知るのって、好きなんですよね。
対策としてはこんなところでしょうか。
まだすごろくアプリは完成していませんが、自分に足りないところが明確になっただけでも、取り組んでよかったと大いに思います。
これからも食っていけるプログラマ目指して頑張ります。
「テスト駆動開発」を試してみた。 実践編
というわけで実践。
以下はすごろくゲームのプレイヤークラスです。
クラス変数は、必要そうかなーと思うものをガシガシ入れていった感じです。
インスタンス生成時にIDとプレイヤー名を登録します。
でもって以下が、書いてみたテストコードです。
で、テストを実行してみます。
通りましたね。
通りましたが・・・なんか違う気がする。
そもそもテスト駆動開発って、テストケースから先に書いて、失敗するのを確認してから、少しずつ実装していくっていうやり方だった気がします。
今回みたいに、ある程度作ってからテスト駆動開発に切り替えるのって、なんだかテスト駆動開発のいいところを微妙に活かせていないようなもどかしさが・・・。
クラスもメソッドも、テストを書く前にある程度書いてしまっていたので、それを消すのがもったいなくてこんな順序になってしまっているのですが、いまいちしっくり来ないな・・・。
もったいなくても、一旦イチから全部作り直したほうがいいんでしょうか。
むむむ・・・自分の(甘い)想定では、TDDを取り入れた瞬間にいろんな問題がたちどころに解決して、順調にすごろくアプリが完成するはずだったのですが・・・慣れない手法は何が正しくて何が間違っているのかもわからないです。
とりあえず試行錯誤を繰り返しながら、引き続き開発を進めていきたいと思います。
「テスト駆動開発」を試してみた。
「テスト駆動開発」を試してみたくなったわけ
先日ブログの記事に書きましたが、いま自分はすごろくアプリを開発しています。
仕事が終わって帰宅してから、ちまちま動作確認しながら作り続けていたのですが、ふと思ったことがひとつ…。
テスト、めんどくさくね?
ここでこのプログラムを動かしたときのコンソールの様子をご覧ください。
最初にプレイする人数を入力したあと、プレイヤーの名前を入力して、ターン毎にエンターキーでサイコロを振る・・・という流れになっています。
自分はなんと、このプログラムの動作確認に「毎回いちいち起動して目視で動作を確認する」という、とんでもなくめんどくさい方法を採用していました。
プレイヤー名が正しく表示されないときは思い当たるところを直してから動かし、ターン数表示がおかしいときはまた直してまた動かし・・・めんどくさくて当然です。
もっと簡単に動作確認しながら作ることは出来ないものかとモヤモヤしていました。
ある日、そんな自分に、とある言葉が天啓のように舞い降りてきました。
テスト駆動開発という言葉を知ったのは最近です。Rubyの勉強を開始したあたりで知りました。
最初の印象は、正直言って「面倒くさそう」でした。
だってテストコードをいちいち書かなくたって、動かせば一目瞭然で結果がわかるのです。それって何が効率いいの? という感じでした。
ですが実際に1からコーディングをして動作確認をしていると、毎度毎度いちいち起動して確認するほうがよっぽどめんどくさいのでは? と感じるようになりました。
テストコードを書くのは確かに面倒かもしれませんが、正しいものを一度書いてしまえば、何回でも好きなだけ動作確認できます。リファクタリングする際も思い切ってソースコードを書き換えることができそうです。
ああそうか・・・テスト駆動開発はこういうときに力を発揮する手法だったのか・・・などと、ひとり勝手に納得してしまいました。
や、まだTDDという概念を知ったばかりなので、そういう理解で正しいのかはよくわからないのですが。
前置きが長くなりましたが、そんなわけで「RSpecを勉強しよう!」と思い至ったわけです。
このあと実際に試してみた結果について記載したいと考えていたのですが、長くなってしまったので実践編は別の記事で更新したいと思います。
また、「実際に動作させて確認したほうが早い」と思い込んでいたのは何故か、を自分なりに考察したので、それも合わせて書きたいなーと思っています。
2017年10月~11月の活動まとめ
「自分の腕で食っていけるエンジニア」目指してます。
以前から、自分のエンジニアとしての技術力に不安を覚えていたので、具体的なアクションを起こすことにしました。
現在の自分の目標は、「自分の腕で食っていけるエンジニアになること」です。
といってもそれだけでは抽象的すぎるし遠大すぎるので、とりあえず始められることから始めることにしました。
以下、心機一転した2017年の10月から起こしていたアクションの一覧です。
記録がないので、日付も内容も完全に正確には思い出せませんが、とにかく書いていきます。
ここにまとめることの目的の一つは、達成感を得ることなので、抜け漏れがあったらもったいないなあ・・・。
- 「自分の腕で食っていけるエンジニア」目指してます。
- 『プログラムはなぜ動くのか』を読了した。
- Githubのアカウントを作成した。
- Rubyの勉強を始めた。
- ソニックガーデンのトライアウトの受講を始めた。
- ブログを開設した。
- 『オブジェクト指向でなぜつくるのか』を読書中。
- まとめ
『プログラムはなぜ動くのか』を読了した。
プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識
- 作者: 矢沢久雄
- 出版社/メーカー: 日経ソフトウエア
- 発売日: 2007/04
- メディア: 単行本(ソフトカバー)
- 購入: 45人 クリック: 646回
- この商品を含むブログ (73件) を見る
この本のおかげで、プログラムの動作についての基本的な知識が身に付いたように思います。
おかげで実際の仕事でも、自分の書いたソースコードがどのように動いているのかをイメージしながら書けるようになりました。
仕組みのわからない道具を使っているのはどことなく落ち着きませんし、深い部分で動きを追うことが出来ないので、この本は読んで良かったです。
また知識が増えたため、会社の先輩とプログラムについて話す際にも、以前よりスムーズに会話ができるようになりました。
プログラム未経験の人を採用して、とりあえずIDEを使えるまで教育して、すぐに現場に投入する会社は多いのではないかなーという印象があります。
というか自分がそういう経緯で現場に投入されたクチです。
そういう扱いにも、最初は特に疑問を覚えませんでした。右も左もわからない状態だったので、それは仕方ないかなとも思います。
ですがそれだけでは、「自分の腕で食っていけるエンジニア」にはなれないことがわかってきました。
わかってきたので、具体的な行動を始めました。
この本を読んだことで「IDEを使えるだけの人材」から、少しだけ目標に近づけた気がしています。
Githubのアカウントを作成した。
コーディング能力を上げるためには、いいソースコードに触れるしかないと思いました。
そこで、世界中の技術者の目に晒されるOSS活動に参加してみようと思い至りGithubのアカウントを作成してみました。
いずれは有名プロジェクトにプルリクとか出してみたいと思っていますが、いまはとりあえず自分のソースコードを公開するにとどまっています。
最初はJavaをやろうと思っていましたが、いまはRubyをやっています。
公開したからって急にコーディングが上手くなるわけではないでしょうが、「人に見られる場所に継続的に作品を上げる」というのは、上手くなるためにはけっこう大事なのではないかと思っています。
この考え方は、過去にやっていた小説の執筆活動の感覚が活きている気がします。
Rubyの勉強を始めた。
まだ簡単なプログラムを書くのでさえ一苦労ですが、逆に言えば簡単なプログラム程度は書けるようになりました。
価値を生み出すというレベルには達していないかもしれないですが、最初の一歩を踏み出せたことは自分のために評価してあげたいです。
「レベルが低いことに嫌気が差して止める」というのは、自分が物事を継続できないときの典型的なパターンです。
誰にだって初心者の時期はあるのだから、レベルが低くてもそのことで自分を責めたりせず、こつこつと続けていきたいです。
ちなみに現在はすごろくゲームを作成し、ソースコードをGithubで公開しています。
思いつくままに作っているので、デタラメに書いているようにしか見えないぐっちゃぐちゃのソースコードですが・・・。
個別の要素を好き勝手に配置している感じで、「秩序ある総体」として完成していない感があります。
まあ仕事で作っているものではなく、楽しく練習するためのものなので、ある程度好き勝手に作るのを楽しんだら、そのあとに整理整頓を楽しめたらいいなーくらいに考えています。
「遊んでいたら勉強になっていた」というのが理想です。楽しむのは大事です。
ソニックガーデンのトライアウトの受講を始めた。
技術力を重視している、憧れの会社の採用課程の受講をはじめました。
正直なところ、これに一番苦労しています。
技術的に取り組んだことのない課題を提示されることはもちろん、仕事についての考え方を問われる質問がなかなか大変です。
自分の中で「こうありたい」、「こうしたい」という思いはあるのですが、それを他人に伝える形でアウトプットするのに苦労しています。
そういう思いもあって、アウトプットの練習用にこのブログを開設したのですが。
きっと、自分をよく見せたくて言葉を飾ろうとするのがいけないんだろうなーと思います。
ブログだと思ったことを素直に書ける気がするので、そういう気持ちで臨んだほうが、虚飾のない自分のいいところを伝えられるのではないかと思っています。
ブログを開設した。
先述しましたが、自分の考えをアウトプットする練習の場として、このブログを開設しました。
いまのところ記事はほとんど無いですが、とりあえず作っただけでも、不思議と開放感を感じています。
どうも自分は、無意識的にアウトプットできる場を求めていたようです。
文章を書くのは(得意じゃないけど)好きだということもあり、「誰かに何かを伝えたい」という思いがウズウズしていたのかもしれません。
アウトプットは仕事でも重要な能力ですし、上達すると自分の思考も整理されるため、人生が豊かに、楽しくなりそうです。
このブログで少しずつ練習していきたいと思います。
『オブジェクト指向でなぜつくるのか』を読書中。
最初は自分の市場価値を上げるためだけに読もうと思っていた本でした。
というのも、いまの職場ではオブジェクト指向でプログラミングすることがないからです。
「いますぐ役には立たないだろうけど、知っとかないと転職もできなさそうだしなー」くらいの気持ちで読み始めました。
ですが「いますぐ役に立たないだろう」という思いは、いい意味で裏切られました。
オブジェクト指向を扱わない自分でも役に立つ知識が、わかりやすくたくさん書かれています。
もちろんオブジェクト指向についてもわかりやすく説明されています。
この本については、読み終わった際にまた詳しく感想を書きたいと思います。
まとめ
- プログラムがコンピュータ内部で動く様子がイメージできるようになった。
- ソースコードを公開する体制を作ることができた。
- Rubyの勉強を始めることができた。
- すごろくゲームを作り始めることができた。
- ソニックガーデンのトライアウトを始めることができた。
- ブログを開設することができた。
- オブジェクト指向についての勉強を始めることができた。
最近まで漫然と生きてきたことを考えると、けっこう進歩していないでしょうか。
世の中のトップクラスのエンジニアと比べてしまえば、勉強の内容も、ペースもまだまだでしょうが、10月の自分、11月の自分と比較すれば、少しずつでも前に進んでいるのがわかります。
効率的に勉強すること、成長することは大事かもしれませんが、その方法が思いつかないために何もできないのであれば、いつまで経っても何も始めることが出来ません。
(まさしくかつての自分への言い聞かせ)
一番最初は、わけもわからず我武者羅でもいいのではないかなーと思った、そんな最近の私でした。
また来月には、「こんなに成長したぜ」という記事が書けるといいなーと思います。