GiKrakenを用いたじゃんけんゲーム開発(異常系シナリオ)

Gitを利用して開発をすすめる際,開発者の意図しない状態にリポジトリが陥ることがある.本演習では,代表的な異常状態の対応方法を実際に体験し,学習する.

下記に示す異常系を想定した一連の開発の流れ(E1~E12)について具体的な操作方法を詳述する.各手続きで何を行っているかよく理解したうえで演習を進めること.なお,異常系シナリオは前節の正常系シナリオが終了していることを想定している.

以降の手順では主開発者が実施するStepのみ分かりやすいように太字を利用している.主開発者・共同開発者,どちらが実施すべき項目かを十分理解して作業をすすめること.

このシナリオでは,仕様にあるとおり,じゃんけんゲームに「勝敗表示」及び「スコア表示」という2つの機能を別々の開発者が追加する.共同開発者が「勝敗表示」機能を,主開発者が「スコア表示」機能を追加する過程において,異常状態が発生する.以降に示す手順に従い,2人での開発と異常状態への対応を実施せよ.

E1. 共同開発者によるブランチの作成とPush

正常系シナリオでも述べた通り,Github flowでは通常,masterブランチに対してPull RequestからのMerge以外の方法でファイルの編集を行うことはない.そのため,「勝敗表示」という新しい機能を共同開発者が実装する際には,必ず対応したブランチをローカルに作成しなければならない.

ここで共同開発者は正常系シナリオD4と同様に,ブランチを作成し,それをサーバ側リポジトリにPushする.具体的な手順は下記のとおり.

  1. 共同開発者は「add_game_result_display」という名前でmasterブランチから新しいブランチを作成する.[LOCAL]のmasterブランチを右クリックし,[Create branch here]をクリックする.中央上部にブランチ名を入力するテキストフィールドが表示されるので,分かりやすいブランチ名(今回はadd_game_result_display)を書き,Enterキーを押す.

  2. ブランチが正常に作成できると,GitKrakenの画面が「add_game_result_display」ブランチの画面に自動的に切り替わる.この時点で,ユーザのローカルリポジトリに「add_game_result_display」ブランチが作成されたことになる.

  3. GitKrakenの画面から「Push」ボタンをクリックし,ブランチのPushを行う.

確認項目

  • Push完了後に,Github上のリポジトリページから「3 branches」(ブランチの数)というリンクをクリックすると,下図のように現在Github上のリポジトリにpushされているブランチの一覧を見ることができるので,add_game_result_displayブランチがあることを確認すること.

E2. 共同開発者によるadd_game_result_displayブランチでの開発及びCommit,Push

Github Desktop上でブランチをadd_game_result_displayにした状態で,「勝敗表示」機能を共同開発者が実装する.ここでは,Gameクラスのフィールド及びgetJankenResult()メソッドとBoardクラスのupdateCommentArea()メソッドを修正する.詳細な実装内容を下記に示す.

  1. Gameクラスにint型のwin,draw,loseというフィールドを追加し,getJankenResult()メソッドを修正する.修正後のGameクラス全体を下記に示す.

    class Game {
    int win=0;
    int draw=0;
    int lose=0;
    String getJankenResult(String hand) {
     String cpuHand = this.desideCpuHand();
    
     if (hand.equals("Gu") && cpuHand.equals("Gu") 
       || hand.equals("Choki") && cpuHand.equals("Choki") 
       || hand.equals("Pa") && cpuHand.equals("Pa")) {
         draw++;
         return "Draw";
       }else if (hand.equals("Gu") && cpuHand.equals("Choki")
       || hand.equals("Choki") && cpuHand.equals("Pa")
       || hand.equals("Pa") && cpuHand.equals("Gu")) {
         win++;
         return "You Win!";
       }else if (hand.equals("Gu") && cpuHand.equals("Pa")
       || hand.equals("Choki") && cpuHand.equals("Gu")
       || hand.equals("Pa") && cpuHand.equals("Choki")) {
         lose++;
         return "CPU Win!";
       }
    
     return null;
    }
    
    String desideCpuHand() {
     int cpuHandNum = (int)random(3);
     if (cpuHandNum == 0) return "Gu";
     else if (cpuHandNum == 1) return "Choki";
     else return "Pa";
    }
    }
    
  2. BoardクラスのupdateCommentArea()メソッドを下記のように修正する.
    void updateCommentArea(String comment){
     fill(#000000);
     rect(0,150,450,75);
     fill(#FFFFFF);
     textSize(30);
     textAlign(CENTER);
     text(comment, 225, 180);
     textSize(20);
     String scoreMessage = "Win:"+game.win+" Draw:"+game.draw+ " Lose:"+game.lose;
     text(scoreMessage, 225, 200);
    }
    
  3. 実装が完了した状態で,プログラムを実行すると下記のような画面が表示され,ゲームを進めるにつれて,勝ち,負け,引き分けの数がカウントされるようになる.必ず正常に実行できるか確認しておくこと.

正常に動作することが確認できしだい,Commit及びPushを行っておくこと.なお,プログラムが正常に動作する状態であれば,それまでに細かくCommit及びPushを行っても構わない.Commit及びPushのやり方は正常系シナリオD3などを参考にすること.

E3.共同開発者によるPull Requestの作成

  • 正常系シナリオD6を参考に,Pull Requestを作成する.ここで作成するPull Requestは「add_game_result_displayブランチで開発した内容を確認してmasterブランチに統合してください」というリクエストを共同開発者から主開発者に対してGithubを介して送るためのものである.

  • 共同開発者はGithubのリポジトリページを開き, add_game_result_displayブランチについての[Compare & pull request]というボタンをクリックする.

  • その後,上から順に[base:master <- compare:add_game_result_display](add_game_result_displayブランチの内容をmasterブランチに,という意味)であることを確認し,TitleとDescriptionに実装内容を簡単に記す.最後に「Create pull request」ボタンをクリックする.

確認項目

  • リポジトリのページからPull Requestを表示させると,下図のようにadd_game_result_displayからmasterへのマージを依頼するPull Requestが作成されていることを確認すること.

E4. 主開発者によるブランチの作成とPush

正常系シナリオでも述べた通り,Github flowではmasterブランチに対してPull RequestからのMerge以外の方法でファイルの編集を行うことはない.そのため,「スコア表示」という新しい機能を主開発者が実装する際には,必ず対応したブランチをローカルに作成しなければならない.

ここで主開発者は正常系シナリオD4と同様に,ブランチを作成し,それをサーバ側リポジトリにPushする.具体的な手順は下記のとおり.

  1. 主開発者は「add_total_score」という名前でmasterブランチから新しいブランチを作成する.GitKrakenで[LOCAL]のmasterブランチを右クリックし,[Create branch here]をクリックする.中央上部にブランチ名を入力するテキストフィールドが表示されるので,分かりやすいブランチ名(今回は「add_total_score」)を書き,Enterキーを押す.

  2. ブランチが正常に作成できると,GitKrakenの画面が「add_total_score」ブランチの画面に自動的に切り替わる.この時点で,ユーザのローカルリポジトリに「add_total_score」ブランチが作成されたことになる.

  3. GitKrakenの画面から「Push」ボタンをクリックし,ブランチのPushを行う.

確認項目

  • Push完了後に,Github上のリポジトリページから「3 branches」(ブランチの数)というリンクをクリックすると,現在Github上のリポジトリにpushされているブランチの一覧を見ることができるので,add_total_scoreブランチがあることを確認すること.

E5. 主開発者によるadd_total_scoreブランチでの開発及びCommit,Push

GitKraken上でブランチをadd_total_scoreにした状態で,「スコア表示」機能を主開発者が実装する.ここでは,Gameクラスのフィールド及びgetJankenResult()メソッドとBoardクラスのupdateCommentArea()メソッドを修正する.詳細な実装内容を下記に示す.

  1. Gameクラスにint型のscoreというフィールドを追加し,getJankenResult()メソッドを修正する.修正後のGameクラス全体を下記に示す.

    class Game {
    int score=0;
    String getJankenResult(String hand) {
     String cpuHand = this.desideCpuHand();
    
     if (hand.equals("Gu") && cpuHand.equals("Gu") 
       || hand.equals("Choki") && cpuHand.equals("Choki") 
       || hand.equals("Pa") && cpuHand.equals("Pa")) {
         score++;
         return "Draw";
       }else if (hand.equals("Gu") && cpuHand.equals("Choki")
       || hand.equals("Choki") && cpuHand.equals("Pa")
       || hand.equals("Pa") && cpuHand.equals("Gu")) {
         score = score + 2;
         return "You Win!";
       }else if (hand.equals("Gu") && cpuHand.equals("Pa")
       || hand.equals("Choki") && cpuHand.equals("Gu")
       || hand.equals("Pa") && cpuHand.equals("Choki")) {
         score--;
         return "CPU Win!";
       }
    
     return null;
    }
    
    String desideCpuHand() {
     int cpuHandNum = (int)random(3);
     if (cpuHandNum == 0) return "Gu";
     else if (cpuHandNum == 1) return "Choki";
     else return "Pa";
    }
    }
    
  2. BoardクラスのupdateCommentArea()メソッドを下記のように修正する.
    void updateCommentArea(String comment){
     fill(#000000);
     rect(0,150,450,75);
     fill(#FFFFFF);
     textSize(30);
     textAlign(CENTER);
     text(comment, 225, 180);
     textSize(20);
     String scoreMessage = "Score:"+game.score;
     text(scoreMessage, 225, 200);
    }
    
  3. 実装が完了した状態で,プログラムを実行すると下記のような画面が表示され,ゲームを進めるにつれて,勝ち,負け,引き分けの結果に応じたスコアが表示される.必ず正常に実行できるか確認しておくこと.

正常に動作することが確認できしだい,Commit及びPushを行っておくこと.なお,プログラムが正常に動作する状態であれば,それまでに細かくCommit及びPushを行っても構わない.Commit及びPushのやり方は正常系シナリオD5を参考にすること.

E6. 主開発者によるPull Requestの作成

  • 正常系シナリオD6を参考に,Pull Requestを作成する.ここで作成するPull Requestは「add_total_scoreブランチで開発した内容を確認してmasterブランチに統合してください」というリクエストを共同開発者から主開発者に対してGithubを介して送るためのものである.

  • 主開発者はGithubのリポジトリページを開き, add_total_scoreブランチについての[Compare & pull request]というボタンをクリックする.

  • その後,[base:master <- compare:add_total_score](add_total_scoreブランチの内容をmasterブランチに,という意味)であることを確認し,TitleとDescriptionに実装内容を簡単に記す.最後に「Create pull request」ボタンをクリックする.

確認項目

  • リポジトリのページからPull Requestを表示させると,add_total_scoreからmasterへのマージを依頼するPull Requestが作成されていることを確認すること

以降がGitを利用する上での異常状態の体験になるため,必ずここまでが終了してから実施すること.

E7. 主開発者による共同開発者のブランチのレビュー(リモートリポジトリからのadd_game_result_displayブランチのFetch)

主開発者が共同開発者の開発したブランチ(add_game_result_display)を確認する. 手順は以下のとおり.

  • GitKrakenの[REMOTE]ブランチリストの中に下図に示すようにadd_game_result_displayがある場合,add_game_result_displayを右クリックし,[Checkout origin/add_game_result_display]をクリックする.ない場合は次の手順に従う(ある場合は次の手順は飛ばして良い).
    • GitKrakenの[REMOTE]ブランチリストの中にadd_game_result_displayがない場合,しばらく待つか,画面中央上部の[Pull]ボタン横の[▼マーク]をクリックし,[Fetch All]をクリックすれば良い.

  • GitKrakenでadd_game_result_displayブランチをcheckoutした後,Processingからプログラムを実行し,下図のように勝ち,引き分け,負けが正しく表示されることを確認する.
    • Processing IDEからJanken_学生番号.pdeを実行すれば良い.

注意!

正しく表示されない場合は,正常系シナリオD7を参考に共同開発者にプログラムの修正を行い,Commit/Pushするよう伝えること.さらに,Pushが行われた後,再度E7を実行し,正しくプログラムが実行されることを確認する.

E8.主開発者による(共同開発者の作成した)Pull RequestのmasterブランチへのMerge

E7が正常に完了した後,レビューを行った主開発者が共同開発者によって開発されたadd_game_result_displayブランチのMergeを行う. 正常系シナリオD8を参考に,「勝敗表示機能」に関するPull RequestのページをGithubのリポジトリページから表示し,「Confirm merge」をクリックする.

確認項目

  • Merge完了後,GitKraken上でmasterブランチを表示(checkout)し,[Pull]ボタンをクリックする.
  • masterブランチを「Pull」した後,Processingからプログラムを実行し,下図のように勝ち,引き分け,負けが正しく表示されることを確認する.
    • Processing IDEからJanken_学生番号.pdeを実行すれば良い.

E9. 共同開発者によるレビュー(GithubによるConflictの検知)

この時点で残っているPull Requestは主開発者によってE6で作成されたスコア表示機能(add_total_scoreブランチ)のみになり,そのPull RequestをGithubのリポジトリページから表示させると下記のようにConflictが検知される.このままではレビュー及びMergeができないため,Pull Requestのコメントとして,Conflict(競合)が発生していること記述し,主開発者に伝える.

E10. 主開発者によるConflictの解消

このConflictはadd_total_scoreの修正内容が直前にCommit/Pushされたadd_game_result_displayブランチの修正内容と重なってしまったために発生している.この演習ではわざと行ったが,実際の開発においても同様の状況が発生することは十分に考えられる.

主開発者がConflictを解消するためには,最新のmasterブランチの内容を主開発者が開発したadd_total_scoreブランチに取り込み,実装を修正してCommit/Pushをやり直す必要がある. 具体的な手順を以下に示す.

C1. masterブランチの更新

  • GitKraken上でmasterブランチを表示し,[Pull]をクリックすることで,最新のmasterブランチの内容を取得する.

C2. ローカルリポジトリでのmasterブランチのadd_total_scoreブランチへのMerge

  • C1終了後,更新されたmasterブランチの内容をadd_total_scoreブランチにMergeする.
  • 下図のようにまずGitKraken上でadd_total_scoreブランチを表示し,masterブランチを右クリックして,[Merge master into add_total_score]をクリックする
    • masterブランチの内容をadd_total_scoreに取り込むという意味

  • Mergeを行うとmasterブランチの内容とadd_total_scoreブランチの内容がConflictするため,↓のように「Merge Failed」と表示される.

  • [Merge Failed]と表示されているものを[x]をクリックして削除し,その後,下記画面の[View Conflicts]をクリックすると,Conflictを起こしているファイル名が確認できる.

C3.プログラムの修正

  • C2を実施すると,ソースコード中にConflict箇所を示す下図のような文字列が挿入される.

この例では,Boardクラスの21行目がadd_total_scoreで実装された内容であり,23行目がmasterブランチの内容であることが示されており,この2つの行がConflictすることを表している. Gameクラスにも複数のconflictがあることが表示されている.

この演習では,勝敗表示とトータルスコア表示の両方を実装することが目標であるため,Boardクラスを下記のように修正する.

class Board {

  void updateSelectArea() {
    PImage gu = loadImage("gu.png");
    PImage choki = loadImage("choki.png");
    PImage pa = loadImage("pa.png");

    image(gu, 0, 0, 150, 150);
    image(choki, 150, 0, 150, 150);
    image(pa, 300, 0, 150, 150);
  }

  void updateCommentArea(String comment){
    fill(#000000);
    rect(0,150,450,75);
    fill(#FFFFFF);
    textSize(30);
    textAlign(CENTER);
    text(comment, 225, 180);
    textSize(20);
    String scoreMessage = "Score:"+game.score + " Win:"+game.win+" Draw:"+game.draw+ " Lose:"+game.lose;
    text(scoreMessage, 225, 200);
  }

  void updateResultArea(String result) {
    fill(#000000);
    rect(0,225,450,75);
    fill(#FFFFFF);
    textSize(45);
    textAlign(CENTER);
    text(result, 225, 260);
  }
}

同様にGameクラスでも勝敗表示機能とトータルスコア表示機能が両立するように,Gameクラスを下記のように修正する.

class Game {
  int score=0;
  int win=0;
  int draw=0;
  int lose=0;
  String getJankenResult(String hand) {
    String cpuHand = this.desideCpuHand();

    if (hand.equals("Gu") && cpuHand.equals("Gu") 
      || hand.equals("Choki") && cpuHand.equals("Choki") 
      || hand.equals("Pa") && cpuHand.equals("Pa")) {
        score++;
        draw++;
        return "Draw";
      }else if (hand.equals("Gu") && cpuHand.equals("Choki")
      || hand.equals("Choki") && cpuHand.equals("Pa")
      || hand.equals("Pa") && cpuHand.equals("Gu")) {
        score = score + 2;
        win++;
        return "You Win!";
      }else if (hand.equals("Gu") && cpuHand.equals("Pa")
      || hand.equals("Choki") && cpuHand.equals("Gu")
      || hand.equals("Pa") && cpuHand.equals("Choki")) {
        score--;
        lose++;
        return "CPU Win!";
      }

    return null;
  }

  String desideCpuHand() {
    int cpuHandNum = (int)random(3);
    if (cpuHandNum == 0) return "Gu";
    else if (cpuHandNum == 1) return "Choki";
    else return "Pa";
  }
}

主開発者が2つのクラスのソースコードを修正した後,Processing IDEからプログラムを実行し,下記のようにスコアと勝敗数両方が正しく表示されることを確認する.

C4.Conflict解消後のプログラムのCommit/Push

  • C3でプログラムが正常に動作することを確認後,Conflictが解消(resolve)したことをチェックする.具体的にはGitKrakenの下記領域右上の[Mark all resolved]ボタンをクリックする.

  • conflictを解消したすべてのファイルが[Staged files]に移動したことを確認してから,CommitのTitleとDescriptionを記述し,[Commit and Merge]をクリックする.

  • Commit完了後,[Push]ボタンをクリックしてPushを行う.

確認項目

  • Push完了後に,主開発者が作成したPull Requestを確認すると,下記のようにConflictが解消され,「This branch has no conflicts」と表示が変化していることが分かる.

E11.共同開発者による(主開発者が作成し,Conflictを解消した)Pull Requestのレビュー

  • E7と同様に,共同開発者が主開発者の作成したPull Request(add_total_scoreブランチ)のレビューを行う.
  • 手順はE7と同様.

  • GitKrakenの[REMOTE]ブランチリストの中にadd_total_scoreがある場合,add_total_scoreを右クリックし,[Checkout origin/add_total_score]をクリックする.ない場合は次の手順に従う(ある場合は次の手順は飛ばして良い).

    • GitKrakenの[REMOTE]ブランチリストの中にadd_total_scoreがない場合,しばらく待つか,画面中央上部の[Pull]ボタン横の[▼マーク]をクリックし,[Fetch All]をクリックすれば良い.
  • GitKrakenでブランチをadd_total_scoreに切り替えた後,Processingからプログラムを実行し,下図のように勝ち,引き分け,負けが正しく表示されることを確認する.

    • Processing IDEからJanken_学生番号.pdeを実行すれば良い.

E12. 共同開発者による(主開発者の作成した)Pull RequestのmasterブランチへのMerge

  • E11が正常に完了した後,レビューを行った共同開発者が主開発者によって開発されたadd_total_scoreブランチをmasterブランチにMergeする.
  • 正常系シナリオD8及び本シナリオE8を参考に,「トータルスコア表示機能」に関するPull RequestのページをGithubのリポジトリページから表示し,「Confirm merge」をクリックする.

確認項目

  • Merge完了後,GitKraken上でmasterブランチを表示し,[Pull]ボタンをクリックする.
  • masterブランチを[Pull]で更新した後,Processingからプログラムを実行し,下図のようにトータルスコア及び勝ち,引き分け,負けが正しく表示されることを確認する.
    • Processing IDEからJanken_学生番号.pdeを実行すれば良い.

results matching ""

    No results matching ""