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

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

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

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

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

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

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

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

  1. 共同開発者は「add_game_result_display」という名前でmasterブランチから新しいブランチを作成する.ブランチアイコンをクリックし,Nameに分かりやすいブランチ名(今回は「add_game_result_display」)を書き,From branchの項目がmasterになっていることを確認後,「Create new branch」ボタンをクリックする.

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

  3. Github Desktopの画面から「Publish」ボタンをクリックし,ブランチの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のやり方は正常系シナリオD5を参考にすること.

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

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

  1. 共同開発者はGithub Desktopの画面右上にある「Pull Request」という文字をクリックし,下記のPull Request画面を表示する.
  2. その後,上から順に「from add_game_result_display into master」(add_game_result_displayブランチの内容をmasterブランチに,という意味)であることを確認し,TitleとDescriptionに実装内容を簡単に記す.最後に「Send pull request」ボタンをクリックする.

確認項目

  • リポジトリのページからPull Requestを表示させると,下図のようにadd_game_result_displayからmasterへのマージを依頼するPull Requestが作成されていることを確認すること(Github DesktopPull Request作成後に,「View Pull Request」をクリックすると表示される)

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

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

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

  1. 主開発者は「add_total_score」という名前でmasterブランチから新しいブランチを作成する.ブランチアイコンをクリックし,Nameに分かりやすいブランチ名(今回は「add_total_score」)を書き,From branchの項目がmasterになっていることを確認後,「Create new branch」ボタンをクリックする.

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

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

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

Github Desktop上でブランチを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_game_result_displayブランチで開発した内容を確認してmasterブランチに統合してください」というリクエストを共同開発者から主開発者に対してGithubを介して送るためのものである.

  1. 共同開発者はGithub Desktopの画面右上にある「Pull Request」という文字をクリックし,下記のPull Request画面を表示する.
  2. その後,上から順に「from add_total_score into master」(add_total_scoreブランチの内容をmasterブランチに,という意味)であることを確認し,TitleとDescriptionに実装内容を簡単に記す.最後に「Send pull request」ボタンをクリックする.

確認項目

  • リポジトリのページからPull Requestを表示させると,add_total_scoreからmasterへのマージを依頼するPull Requestが作成されていることを確認すること(Github DesktopPull Request作成後に,「View Pull Request」をクリックすると表示される)
  • この時点で下図のように2つのPull Requestが作成されていることを確認すること


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

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

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

  • Github Desktopのブランチリストの中に下図に示すようにadd_game_result_displayがある場合,add_game_result_displayを選択し,「Sync」ボタンをクリックする.ない場合は次の手順に従う(ある場合は次の手順は飛ばして良い).

  • Github Desktopのブランチリストの中にadd_game_result_displayがない場合,下図に示すように,リポジトリ名を右クリックしてから「Open in Git Shell」をクリックする.Gitのコマンドライン操作画面が開くので,「git fetch」と入力し,Enterキーを叩く.その後,Github Desktopのブランチリストにadd_game_result_displayが表示されるので,add_game_result_displayを選択し,「Sync」ボタンをクリックする

  • Github Desktopでブランチをadd_game_result_displayに切り替えた後,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完了後,Github Desktop上でmasterブランチを表示し,「Sync」ボタンをクリックする.
  • masterブランチを「Sync」で更新した後,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ブランチの更新

下図に示すように,Github Desktop上でmasterブランチを表示し,「Sync」をクリックすることで,最新のmasterブランチの内容を取得する.

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

C1終了後,更新されたmasterブランチの内容をadd_total_scoreブランチにMergeする.具体的には下図に示すとおり,Github Desktop上でadd_total_scoreブランチを表示し,「Update from master」をクリックする.masterブランチの内容とadd_total_scoreブランチの内容はConflictするため,「Unable to merge」画面が表示される.ここではそのまま「View conflicts」をクリックする.

C3.プログラムの修正

C2を実施すると,Github Desktop上でどこにConflictがあるのかを示してくれる.さらに, ソースコード中にConflict箇所を示す下図のような文字列が挿入される.

この例では,Boardクラスの22行目がadd_total_scoreで実装された内容であり,24行目がmasterブランチの内容であることが示されており,この2つの行が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クラスでは下図のように示されていた場合,3行目(add_total_scoreブランチ)と5~7行目(masterブランチ)がConflictしていることを表している.

ここでも勝敗表示機能とトータルスコア表示機能が両立するように,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でプログラムが正常に動作することを確認後,Github DesktopからCommitを行う.Commitする2つのファイルをチェックし,CommitのTitleとDescriptionを記述し,「Commit to add_total_score」をクリックする.Commitが正常に完了後,画面右上の「Sync」ボタンをクリックし,サーバにPushしておくこと.

確認項目

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

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

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

  • Github Desktopのブランチリストの中にadd_total_scoreがある場合,add_total_scoreを選択し,「Sync」ボタンをクリックする.ない場合は次の手順に従う(ある場合は次の手順は飛ばして良い).

  • Github Desktopのブランチリストの中にadd_total_scoreがない場合,リポジトリ名を右クリックしてから「Open in Git Shell」をクリックする.Gitのコマンドライン操作画面が開くので,「git fetch」と入力し,Enterキーを叩く.その後,Github Desktopのブランチリストにadd_total_scoreが表示されるので,add_total_scoreを選択し,「Sync」ボタンをクリックする

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

results matching ""

    No results matching ""