研修でJavaを勉強しており、学習の成果を1週間という期間を設けた自主制作という形で披露することになったので、その題材としてオセロを作ることにしました。
何故オセロ?
本当は自主制作の題材として小さくとも日常に存在する課題をちゃんと解決するモノを作りたかったのですが、スケジュールと現状の技術力を考えると難しいと判断されたため急遽代替案を用意することに。
そこで、スケジュール感を把握しやすい既存のゲームであり、初学者の多くが通る道であるオセロを自分でもやってみることにしました。
既にありふれているモノを自主制作の題材として選ぶことに抵抗はありましたが、研修を受けている身としての自分の現時点での技術力を試すという観点では丁度よい難易度の題材だと考えました。
また、ネット上にコードが溢れているという点もそれを見ずに完成させる事で自身のコードと他人のコードを比較できるという点もメリットの一つだと考えました。
早速つくった
各クラス・メソッドの動きについてはREADMEに記載してあります。
皆さんが自分でオセロを作ってみる際の比較材料の一つにしていただけたら幸いです。
完成後にネットで公開されているコードと比較してみた主な違いは以下になります。
- オセロ盤にコマを置いた際のひっくり返し処理について、8方向の処理を一つずつ書いていくのが冗長な気がしたので一つにまとめた
// 周囲8方向に対してreverseSpecifiedDirectionを呼び出す
public void reverseSurroundedSquare(int[] position) {
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
ArrayList<int[]> checkedPositionList = new ArrayList<>();
checkedPositionList.add(position);
reverseSpecifiedDirection(checkedPositionList, i,j);
}
}
}
// 指定された1方向に対して裏返せるコマを配列に追加し最後に裏返しのメソッドを呼び出す
public void reverseSpecifiedDirection(ArrayList<int[]> checkedPositionList, int directionX, int directionY){
int x = Misc.getLastElement(checkedPositionList)[0] + directionX;
int y = Misc.getLastElement(checkedPositionList)[1] + directionY;
if (!(isInRange(x,y))) {
return;
}
if (squareList[y][x] == 0) {
return;
}
if (squareList[y][x] != Game.playerTurn) {
checkedPositionList.add(new int[] {x,y});
reverseSpecifiedDirection(checkedPositionList, directionX, directionY);
} else {
reversePieces(checkedPositionList);
}
}
やりたかったこと
- クラス・メソッドをなるべく切り分けることで可読性・保守性の高いコードにする
- 説明変数を使うことで可読性の高いコードにする
- テストを書いてみる
できたこと
- そこそこ切り分けられた気がする
- 見ただけで中身がわからない変数を潰せた(はず)
- テスト、一応体験ぐらいはできた
- 多少のアルゴリズム(ロジック?)を必要とするオセロを作れた
自信がなかったこと、もっと頑張りたいこと
- Boardクラスが突出してコード量が多くなってしまったが、これ以上切り分ける方法が思いつかなかった
- テストが結局後書きになってしまった
- ちゃんとテストがかけたかというと、ぱっと思いつくT/Fパターンを書いたのとバグを見つけたときにそれを直すためのデバッグに使ったくらいで理想とされる使い方じゃなかった
- 結局保守性を高いまま維持できたかというと、そんなでもない気がする
やらなかったけどあったら面白そうな機能
- GUIでの実装
- モンテカルロ木探索でのCPU実装
- ヘルプ機能(置けるマスを教えてもらえる、プレイヤーの手番でも上記探索での最善手を教えてもらえる)
- 待った!機能
- 盤面再現機能
学んだこと
- 配列やオブジェクトが参照渡しであるため、メソッドの呼び出し先で書き換えた値が呼び出し元でも反映されるということをちゃんと認識した(気付かずに詰まってた)
- テストのきほんの”k”ぐらいは学べた
- 最初にちゃんと設計しておくことの大切さ
まとめ
ということで、オセロの制作レポートでした。
まだまだJavaにもオブジェクト指向にも慣れていないし、テストコードなんかは書き方もあまりよく分かっていない段階なので、今後も学習を続けその成長記録を報告していけたらと思います。
同じ学習者の皆さん、引き続き一緒によろしくお願いします。