/** * IgoPlayModel クラスは、再生モードのモデルを提供します。 * @author Jiro Suzuki */ public class IgoPlayModel extends IgoModel implements Runnable{ private Kifu kifuForPlay; private int numForPlay; private boolean isAutoPlay; private int second; private int milSecond1; private int milSecond2; private Thread autoPlay; /** * 指定された親インスタンスに対するインスタンスを生成します。 * @param parent 親インスタンス */ IgoPlayModel(IgoModel parent){ super(parent); } /** * インスタンスを初期化します。 * @param view ビュー */ public void initialize(IgoView view){ super.initialize(view); kifuForPlay=new Kifu(); numForPlay=-1; isAutoPlay=false; second=0; milSecond1=0; milSecond2=0; } /** * ファイルを開くときに呼び出します。 */ public void open(){ isAutoPlay=false; view.changeController(parent); parent.start(); parent.open(); } /** * ファイルを新規作成するときに呼び出します。 */ public void record(){ isAutoPlay=false; IgoNewModel newModel=new IgoNewModel(parent); newModel.initialize(view); view.changeController(newModel); newModel.start(); } /** * 現行モードを終了するときに呼び出します。 */ public void exit(){ System.exit(0); } /** * メインダイアログを閉じるときに呼び出します。 */ public void close(){ isAutoPlay=false; view.changeController(parent); parent.start(); } /** * 編集状態にするときに呼び出します。 */ public void startEdit(){ isAutoPlay=false; IgoModModel modModel=new IgoModModel(parent); view.changeController(modModel); modModel.initialize(view); modModel.start(kifu,numOfMoves,fileName,turn); } /** * 一手戻るときに呼び出します。 */ public void back(){ isAutoPlay=false; if(numOfMoves>0){ numOfMoves--; intBoard.initialize(); for(int i=0;i<=numOfMoves;i++){ Move move=kifu.getOrderOfMoves().getMove(i); intBoard.update(move.getStoneColor(),move.getRow(),move.getCol()); } if(isExam){ turn.setTurn(kifu.getOrderOfMoves().getMove(numOfMoves).getStoneColor()); turn.changeTurn(); } }else if(numOfMoves==0){ numOfMoves--; intBoard.initialize(); if(isExam){ turn.setTurn(Turn.TURN_BLACK); } } view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } /** * 一手進むときに呼び出します。 */ public void forward(){ OrderOfMoves order=kifu.getOrderOfMoves(); if(numOfMoves<order.size()-1){ numOfMoves++; Move move=order.getMove(numOfMoves); intBoard.update(move.getStoneColor(),move.getRow(),move.getCol()); turn.setTurn(move.getStoneColor()); turn.changeTurn(); view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } } /** * 五手戻るときに呼び出します。 */ public void back5(){ isAutoPlay=false; intBoard.initialize(); if(numOfMoves>4){ numOfMoves=numOfMoves-5; for(int i=0;i<=numOfMoves;i++){ Move move=kifu.getOrderOfMoves().getMove(i); intBoard.update(move.getStoneColor(),move.getRow(),move.getCol()); } turn.setTurn(kifu.getOrderOfMoves().getMove(numOfMoves).getStoneColor()); turn.changeTurn(); }else{ numOfMoves=-1; turn.setTurn(Turn.TURN_BLACK); } view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } /** * 五手進むときに呼び出します。 */ public void forward5(){ isAutoPlay=false; numOfMoves=numOfMoves+5; OrderOfMoves order=kifu.getOrderOfMoves(); if(numOfMoves>order.size()-1){ numOfMoves=order.size()-1; } intBoard.initialize(); for(int i=0;i<=numOfMoves;i++){ Move move=order.getMove(i); intBoard.update(move.getStoneColor(),move.getRow(),move.getCol()); } if(numOfMoves>-1){ turn.setTurn(kifu.getOrderOfMoves().getMove(numOfMoves).getStoneColor()); turn.changeTurn(); }else{ turn.setTurn(Turn.TURN_BLACK); } view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } /** * 初手に戻るときに呼び出します。 */ public void backAll(){ isAutoPlay=false; numOfMoves=-1; turn.setTurn(Turn.TURN_BLACK); intBoard.initialize(); view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } /** * 終局面にするときに呼び出します。 */ public void forwardAll(){ isAutoPlay=false; OrderOfMoves order=kifu.getOrderOfMoves(); numOfMoves=order.size()-1; intBoard.initialize(); for(int i=0;i<=numOfMoves;i++){ Move move=order.getMove(i); intBoard.update(move.getStoneColor(),move.getRow(),move.getCol()); } if(numOfMoves>-1){ turn.setTurn(kifu.getOrderOfMoves().getMove(numOfMoves).getStoneColor()); turn.changeTurn(); }else{ turn.setTurn(Turn.TURN_BLACK); } view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } /** * パスをするときに呼び出します。 */ public void pass(){ if(isExam){ turn.changeTurn(); } } /** * 設計途中で変更が生じたため、棚上げ。 */ public void pause(){} //棚上げ /** * 検討モードと再生モードを行き来するときに呼び出します。 */ public void examine(){ isAutoPlay=false; if(isExam){ kifuForExam=null; turn=new Turn(); isExam=false; intBoard.initialize(); kifu=kifuForPlay; numOfMoves=numForPlay; for(int i=0;i<=numOfMoves;i++){ Move move=kifu.getOrderOfMoves().getMove(i); intBoard.update(move.getStoneColor(),move.getRow(),move.getCol()); } view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); }else{ kifuForExam=kifu.createExamClone(numOfMoves); kifu=kifuForExam; numForPlay=numOfMoves; if(numOfMoves>-1){ int stoneColor=kifu.getOrderOfMoves().getMove(numOfMoves).getStoneColor(); turn.setTurn(stoneColor); turn.changeTurn(); }else{ turn.setTurn(Turn.TURN_BLACK); } isExam=true; view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } } /** * 石を置くときに呼び出します。 * @param row 行番号 * @param col 列番号 */ public void putStone(int row,int col){ if(isExam){ OrderOfMoves order=kifu.getOrderOfMoves(); if((intBoard.getIntBoard())[row][col]==0){ for(int i=order.size()-1;i>numOfMoves;i--){ order.remove(i); } kifu.addMove(new Move(turn.getTurn(),row,col)); turn.changeTurn(); numOfMoves++; Move move=order.getMove(numOfMoves); intBoard.update(move.getStoneColor(),move.getRow(),move.getCol()); view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } } } /** * 対局情報を更新するときに呼び出します。 */ public void updateGameInfo(GameInformation gameInfo){ isAutoPlay=false; kifu.getGameInformation().setBlackPlayer(gameInfo.getBlackPlayer()); kifu.getGameInformation().setWhitePlayer(gameInfo.getWhitePlayer()); kifu.getGameInformation().setBlackRank(gameInfo.getBlackRank()); kifu.getGameInformation().setWhiteRank(gameInfo.getWhiteRank()); kifu.getGameInformation().setEvent(gameInfo.getEvent()); kifu.getGameInformation().setGameName(gameInfo.getGameName()); kifu.getGameInformation().setDate(gameInfo.getDate()); kifu.getGameInformation().setKomi(gameInfo.getKomi()); kifu.getGameInformation().setResult(gameInfo.getResult()); view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } /** * 自動再生にするときに呼び出します。 */ public void autoPlay(){ if(isAutoPlay){ stopAutoPlay(); }else if(isExam==false && numOfMoves<kifu.getOrderOfMoves().size()-1){ startAutoPlay(); } } /** * 自動再生の再生速度を変更するときに呼び出します。 */ public void updateInterval(){ isAutoPlay=false; if(numOfMoves<kifu.getOrderOfMoves().size()-1){ second=view.askIntervalTime(); startThread(); } } //--------------------------------------- 自動再生関連メソッド private void stopAutoPlay(){ isAutoPlay=false; view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } private void startAutoPlay(){ if(second==0){ second=view.askIntervalTime(); } startThread(); } private boolean isContinue(){ if(isAutoPlay && numOfMoves<kifu.getOrderOfMoves().size()-1){ return true; }else{ return false; } } private void startThread(){ if(second!=0){ isAutoPlay=true; view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); milSecond1=700; milSecond2=second * 1000 - milSecond1; autoPlay=new Thread(this); autoPlay.start(); } } /** * 独立して実行されるスレッド内で、このメソッドが呼び出されます。 * Runnable インターフェースが実装しているメソッドのオーバーライドです。 */ public void run(){ while(isContinue()){ try{ autoPlay.sleep(milSecond1); }catch(InterruptedException e){} forward(); if(!isContinue()){ break; } try{ autoPlay.sleep(milSecond2); }catch(InterruptedException e){ System.out.println(e); } } stopAutoPlay(); } /** * 対局情報を表示ときに呼び出します。 */ public void displayGameInfo(){ view.showGameInfoDialog(kifu.getGameInformation()); } /** * ビューを更新するときに呼び出します。 */ public void doUpdateView(){ view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } /** * 再生モードを開始するときに呼び出します。 * @param fileName ファイル名(フルパス指定) */ public void start(String fileName){ this.fileName=fileName; SgfReader sr=new SgfReader(); kifuForPlay=sr.read(fileName); kifu=kifuForPlay; mode.setMode(Mode.MODE_PLAY); view.updateView(mode,isExam,intBoard,kifu.getGameInformation(),numOfMoves,isAutoPlay); } }