0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Reversi をつくろう! - 1

Last updated at Posted at 2021-03-29

趣旨

今まで学んだことを簡単なゲームを作りながら整理していく。

  • コードは github に公開する。
  • githubのissue単位でTDD方式で開発を進める。
  • 開発した内容を整理して記事に投稿していく。

開発する前に

可読性を意識してコーディングすること。

なぜなら開発には多くの人が関わるため、他人に理解しやすいものを提供する必要がある。
理想は英語でWikipediaを書く感覚でコーディングする。

初期構築

ひとまずはSpring BootでjUnitを使って開発する。

  1. ローカル環境に git clone でリポジトリを取得する。
  2. Springのサイトで必要な情報をダウンロードする。
    • Project: Gradle Project
    • Language: Java(11)
    • Spring Boot: 2.5.0(M3)
  3. ./gradlew build コマンドでSpring Bootの環境を構築する。

以上。

リバーシの初期状態の盤面を取得する

まずはここから。単純に初期状態の盤面を取得するところまで開発する。

モデルを抽出する

必要なモデルを手っ取り早く「オセロ(ボードゲーム) - Wikipedia」から抽出する。

必要なモデルを抽出したら、それを英語に翻訳する。
(英語だとどう表現しているのかReversi - Wikipedia から抽出する)

  • 盤: board
    • 位置 : pieces
      • 横: horizontal (a - h)
      • 縦: vertical (1 - 8)
  • 石: disk
    • 色: color
      • 白: light
      • 黒: dark
  • 初期状態の盤面: starting position
    • クロス: normal version
    • パラレル: (英語版に説明なし。なのでこのローカルルールは削除)
    • オリジナル: historical version

どうやら、初期リバーシは空の状態から中央4マスに黒から配置するバージョンがあるらしい。

対応ブランチを作成する

対応する内容を把握したら Issue を起票し、対応ブランチを作成する。

TDD方式で開発する

以下の手順で開発を進めていく。

  • テストケースを作成する。
  • テストケースが正しく動作するように実装する。
  • リファクタリングを行う。

テストケースを作成する

テストケースは以下を想定。

  • クロスの場合は中央4マスに石を配置(白黒をクロス)
  • オリジナルの場合は配置なし。

今回のテストは初期状態がクロスかオリジナルかの2パターンなので@ParameterizedTestで作成。
初期状態の指定で盤の情報が期待値となるかどうかをチェックする。

StartPositionService.java

    @Autowired
    StartPositionService service;

    Stream<Arguments> 初期状態の盤面一覧() {
        return Stream.of(arguments(StartPosition.historical,
                                   "[]"),
                         arguments(StartPosition.normal,
                                   "[{light:(d, 4)}, {dark:(e, 4)}, {dark: (d, 5)}, {light: (e, 5)}]")
        );
    }

    @ParameterizedTest
    @MethodSource("初期状態の盤面一覧")
    public void 初期状態の盤面を取得する(
            StartPosition startPosition,
            String 期待する盤面) {
        Board board = service.get(startPosition);
        assertThat(board.toString(), is(期待する盤面));
    }

コミットした状態はこちら

テストケースが正しく動作するように実装する

Boardモデルの構成を作成する

必要なモデルはすでに抽出済みなので、それを元にBoardの構成を作成する。
今回は以下のようになった。

class1.png

サービス層には業務ロジックのみ

サービス層は業務ロジックのみコーディングするように徹底する。
不要な情報を削ぎ落とすことで可読性が上がり、調査や機能改修のスピードが向上する。

ここでは クロス形式の盤かオリジナル形式の盤を取得する 以外不要。
削ぎ落とした情報はモデル層の BoardFactory に任せてしまう。

StartPositionService.java

@Service
public class StartPositionService {

    final BoardFactory factory;

    public Board get(StartPosition startPosition) {
        return factory.create(startPosition);
    }

コミットした状態はこちら

リファクタリング

テストが正常に動くようになったタイミングで、リファクタリングを行う。
今回の場合、StartPositionService.getが初期状態サービスとよくわからないネーミングだったので、BoardService.startにリネーム。

BoardService.java
@Service
public class BoardService {

    final BoardFactory factory;

    public Board start(StartPosition startPosition) {
        return factory.create(startPosition);
    }

コミットした状態はこちら

最後に

今回はここまで。

最終的にこういうクラス構成になりました。
refactored_class.png

とりあえず、github + TDD で開発する際の雰囲気だけでも伝わっていると幸いです。
最終的に普通にオンライン対戦でリバーシで遊べる。。といいなぁ。。

次の記事>

0
1
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?