/**
* 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);
}
}