/*	ShogiGame.java	a shogi game	97-feb-26 ped created*/import java.lang.* ;import java.util.* ;import java.io.* ;public class ShogiGame implements Enum_PGNTokens{	private ShogiBoard	startBoard	= null ;	private ShogiBoard	board		= null ;	private Vector		moves		= new Vector( ) ;	private int			startPly 	= 0 ;	private int			currentMove = 0 ;	private Properties	headers		= new Properties( ) ;	//	game comments	ShogiGame( InputStream is )	{		ShogiInputStream sis = new ShogiInputStream( is ) ;		int	variationLevel	= 0 ;		ShogiBoard	scratch	= null ;		ShogiMove	move	= null ;		try {			readgame:			while( true ) {				int tokenType = sis.nextToken( ) ;				switch( tokenType ) {					case CTT_EOF :					case CTT_EOG :						break readgame ;					case CTT_GAME_COMMENT :						addGameComment( sis.getString( ) ) ;						break ;					case CTT_MOVE_COMMENT :						if( move != null )							move.putComment( sis.getString( ) ) ;						break ;					case CTT_VARIATION_OPEN :						variationLevel ++ ;						break ;					case CTT_VARIATION_CLOSE :						variationLevel -- ;						break ;					case CTT_MOVE :						if( scratch == null ) {							setupBoard( ) ;							scratch = startBoard.copy( ) ;						}						if( variationLevel == 0 ) {							move = new ShogiMove( sis.getString( ), scratch ) ;							moves.addElement( move ) ;							scratch.makeMove( move ) ;						}						break ;				}			}		}		catch( RuntimeException e ) {			//	debug			//	e.printStackTrace( ) ;		}		//	debug		//	headers.list( System.out ) ;	}	private void setupBoard( )	{		String fen = headers.getProperty( "fen" ) ;		if( fen != null )			startBoard = new ShogiBoard( fen ) ;		else {			String handicap = headers.getProperty( "handicap" ) ;			if( handicap != null )				startBoard = new ShogiBoard( handicap ) ;			else				startBoard = new ShogiBoard( ) ;		}		startPly = ShogiBoard.globalPly ;		board = startBoard.copy( ) ;	}		public ShogiBoard getBoard( )	{		return board ;	}	public ShogiMove getLastMove( )	{		if( currentMove > 0 )			return ( ShogiMove ) moves.elementAt( currentMove - 1 ) ;		return null ;	}	public int getCurrentMoveCount( )	{		return currentMove + startPly ;	}	public boolean advance( )	{		if( currentMove < moves.size( ) ) {			ShogiMove move = ( ShogiMove ) moves.elementAt( currentMove ) ;			board.makeMove( move ) ;			currentMove ++ ;			return true ;		}		return false ;	}		public boolean back( )	{		if( currentMove > 0 ) {			int count = currentMove - 1 ;			board = startBoard.copy( ) ;			currentMove = 0 ;			while( currentMove < count )				advance( ) ;			return true ;		}		return false ;	}		public boolean toEnd( )	{		if( currentMove >= moves.size( ) )			return false ;		while( currentMove < moves.size( ) )			board.makeMove( ( ShogiMove ) moves.elementAt( currentMove ++ ) ) ;		return true ;	}		public boolean toStart( )	{		if( currentMove > 0 ) {			board = startBoard.copy( ) ;			currentMove = 0 ;			return true ;		}		return false ;	}		private void addGameComment( String str )	{		//	get key		String key = new String( ) ;		int i = 0 ;		char ch = str.charAt( i ) ;		while( ! Character.isSpace( ch ) ) {			key += ch ;			i ++ ;			ch = str.charAt( i ) ;		}		//	search for quote		do {			i ++ ;		} while( str.charAt( i ) != '"' ) ;		//	get value		String value = new String( ) ;		i ++ ;		ch = str.charAt( i ) ;		while( ch != '"' ) {			value += ch ;			i ++ ;			ch = str.charAt( i ) ;		}				//	add key, value pair		headers.put( key.toLowerCase( ), value ) ;	}		public Properties getGameComments( )	{		return headers ;	}		public int getMoveCount( )	{		return moves.size( ) ;	}	}
