凸庵の生存戦略

とあるベンチャー企業でプログラマをやっていて発達障害(ASD)をもつ私の生存戦略や技術ネタなんかを書いていきます

オススメのプログラミングの勉強方法

最近いろいろ疲れてきているのでまた自分が好きなことについて書きたい欲が出てきています。

というわけでプログラミングのお話をしようと思います。 今回は自分が学生時代のときなんかにやっていた勉強方法について書いてみようと思います。

f:id:totsuan1545:20180221233141j:plain

想定読者と要点

以下のような方の参考になるかもしれません。 - これからプログラミングを勉強したいけど何をやったらいいかわからない - じっくり腰を据えてプログラミングの勉強をしたい - 他のひとのプログラミングの勉強方法が気になる

要点は以下の通りです - 少しずつ設計や実装方法を変えてブラックジャックを作ってみよう - 作り直すごとに今までやっていなかったことや新しいものを取り入れてみるのがコツ - 10年以上使える技術が身につくかも

それでは本編スタートです。

よし!プログラミングを勉強するぞ!・・・で何から始めよう?

最初にプログラミングを勉強するときってこんな感じですよね。 まごうことなく私もそうでしたし、新しい言語を覚えるときなんていまだにこうなります。

勉強をするにあたっては実際に動くものを作るのが一番手っ取り早いとおもいます。 それもそんなに大きくないちょっとしたソフトがおすすめです。*1

学生時代の私が題材にしていたのはトランプゲームのブラックジャックでした。

シンプルなブラックジャックの簡単なルール

検索エンジンで検索するとカジノ用の超本格的なルールがヒットするので、私が当時理解していたシンプルなルールを説明します。

1.トランプを良く切って山札を作る
2.プレイヤーそれぞれに2枚ずつ配る(以下 手札と表記)
3.各プレイヤーはもう一枚カードを引くか現在の手札で勝負するかを選択できる。
4.手札の合計が他プレイヤーより大きければ勝利。ただし手札の合計が21を超えたら即敗北(これをバーストと呼ぶ)
※ ただし合計を計算するときには、Aは 1 か 11 として扱い、JQKは 10 として扱う
5.全プレイヤーが手札で勝負するかバースト状態になるまで3.を行う

結局どうやって勉強するの?

先ほど説明したルールのブラックジャックを何度も実装しました。

一度実装すると途中でもっといい方法が見つかるものです。 あるいは本を読んだりして知識が増えると、試したくなる機能や実装方法が見つかったりしていました。

作り直すたびに前回よりもかっこいい設計に変更してみたり新しい実装方法を試したりして、少しずつ内部処理を洗練させていっていました。
見た目の変更や機能追加はほとんどしていなかったと思います。

繰り返す中での変遷

では私の実装がどんな感じで変化していったのかをクラス図に似た図でざっくり解説していきます。*2

なお、当時はc++で作っていました。
ちなみに掲載している図は draw.io というサービスを使って書きました。

図は仕事上がりの死んだ頭で雑に書いているので、怪しいところがあってもご容赦を。
だいたいの雰囲気をつかんでもらえると助かります。。。

ver1(古のcプログラム)

f:id:totsuan1545:20180221222818p:plain

これはひどい

一応関数分けはしてあるけど、処理と定数群をそれぞれ1ファイルにまとまっているので二度と読みたくないソースコードが出来上がってしまいました。
とはいえ動くものはできたのでひとまず合格。

ver2(少しマシになった古のcプログラム)

f:id:totsuan1545:20180221223932p:plain

処理がファイルごとに分かれて少しマシになったような気がします。
それでもファイル分け粒度が粗すぎるので、後からソースコードを読む気にはなれないです。

手札とか山札をくくりだせたのがうれしいポイント。

ver3(とりあえずクラス化)

この辺からc++の勉強が進み、クラスを使って実装しようと思い立つ。

f:id:totsuan1545:20180221225914p:plain

とりあえずクラスにしてみました感満載の構成。
でもGameMasterという概念的な存在が出てきたのが特筆するポイントです。

クラス設計に慣れないうちは現実世界の関係に沿った設計をしがちなので要注意だと思っています。

var4(内部処理と表示処理が分離)

f:id:totsuan1545:20180221232407p:plain

カードの情報を処理する専用のクラスができました。これは進歩。
後は内部処理と表示処理を分離させることに成功しています。
それまではコンソール表示でがんばっていましたが、がんばれば内部処理はそのままでGUI化する夢が見えてきました。

ちなみに表示系の処理は全部public staticな関数です。
インスタンスがなくても処理できるのでそんな設計です。

var5(ついに継承を使うことに!)

f:id:totsuan1545:20180221232617p:plain

ついに継承をつかってみました。
ポリモーフィズムの発芽ですね。初めて知った時にはどういうときにうれしいのかわかりませんでしたが、初めてこういう実装をした時に感動した記憶があります。

CPUならロジックでカードを引くかどうかを決定し、プレイヤー(人間)ならもう一枚引くかどうか確認する処理を行うように振舞いを変えるような実装になりました。

総評

こんな感じで少しずつ設計を変えていって作り直していました。
(図を書くのが辛くなってきたのでこの辺で。。。)

実際にはバージョン2桁に達していました。
最初のうちは1回の実装に1週間くらいかかっていましたが、最後の方では1~2時間くらいで実装が終わるようになっていました。

クロージング

このように機能を増やさず内部処理を洗練させていくことをリファクタリングと呼びます。
勉強するときにリファクタリングをすると今までよりもよい設計や実装方法が見つかったりします。

ブラックジャックは判定ロジックやCPU対戦のロジックを組んだり、プレイヤー増減による拡張性を考えたりするのでいろいろなことを試すのにちょどよい題材でした。

当時は同じものばかり何度も作っていたので周りの人たちには
「なんで同じものを何回も作ってるの?新しいゲームとか作ればいいじゃん」
なんて言われたりしていました。
しかしこの時に得た知見や理解は10年以上経った今でも私を支えるコアな技術になっています。

この勉強方法はすぐに何か新しいものを作ることはできませんし、まったくもって派手ではありません。人にも自慢できないでしょう。
しかしデバッグのコツとリファクタリングのコツと変更に強い設計方法を確実に身に着けることができるので、そういう知識を身に着けたい方にはとてもオススメです。
勉強方法に悩んでいる方は参考にしてみてはいかがでしょうか?

ここまで見ていただきありがとうございました。 見ていただいた方にいいことがありますように。

*1:立派なものを作ろうとすると途中で挫折しちゃいがちですからね・・・

*2:10年以上前のものなのでソースコードは喪失しているので図でご容赦ください