⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gamedata.java

📁 sudoku j2me手机游戏主要有游戏主类和闪屏类菜单类和模型类等
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 *  Copyright, 2005, S.E.Morris, C.Speirs
 *
 *  This file is part of SudokuME.
 *
 *  SudokuME is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  SudokuME is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with SudokuME; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package sudoku;

import java.io.*;
import java.util.Date;
import javax.microedition.rms.*;


// *********************************************************************
// This class encapsulates a single game, including its ability to
// store and recover its own state using a device's record store.
//
// One constructor is used to create a new game (based upon the grid
// size) while the other is used to recreate a list of saved games from
// a record store, via the static load() method.
//
// FIX: Load/save code needs refactoring and optimsing wrt. footprint.
// *********************************************************************
class GameData
{	int recordId;							// Record store key

	byte formatVersion;						// File format version
	Date creationDate,savedDate;			// Date
	int timer;								// Seconds so far
	String title;							// Game title
	int gridSz;								// Grid size
	byte[][] grid;							// Game data
	boolean[][] locked;						// Locked cells
	short[][] working;						// Working out
	int setW,setH;							// Set width and height
    final int DEFAULT_MAX_SOLUTIONS=20;  // if not otherwise defined, is the maximum number of solutions that will be searched for

	boolean[][] collisions;					// Collisions with current cell

	static String lastErrorMessage=null;	// Last error message accessing record store

	// -----Record store and file format constants
	private final static int TITLE_SZ = 20;

	// CONSTRUCTOR: FIX - needed to get class in static context
	// see 'load(String rName)' below
	private GameData() {}

	// -----------------------------------------------------------------
	// CONSTRUCTOR: new game - just pass the grid size.
	// -----------------------------------------------------------------
	GameData(int sz)
	{	
        this(sz,new byte[sz][sz],null);
	}
	// -----------------------------------------------------------------
	// CONSTRUCTOR: from online - grid size and initial grid data.
	// -----------------------------------------------------------------
	GameData(int sz,byte[][] g,String t)
	{	recordId=-1;  title=t;

		creationDate = new Date();
		gridSz=sz;
		grid = g;
		locked = new boolean[gridSz][gridSz];
		working = new short[gridSz][gridSz];
		for(int y=0;y<gridSz;y++)
			for(int x=0;x<gridSz;x++)
				locked[x][y]=(grid[x][y]>0);
		_init();
	}
	// -----------------------------------------------------------------
	// CONSTRUCTOR: from record store - record id and record bytes
	// -----------------------------------------------------------------
	private GameData(int id,byte[] buff) throws IOException
	{	this( new DataInputStream(new ByteArrayInputStream(buff)) );
		recordId=id;
	}
	// -----------------------------------------------------------------
	// PRIVATE CONSTRUCTOR: from data stream
	// -----------------------------------------------------------------
	private GameData(DataInputStream dis) throws IOException
	{	recordId=-1;
		formatVersion = dis.readByte();				// (2+) Format version number
        if (formatVersion >= 4)  {
            // check this is a save game
            if (dis.readByte() != SudokuME.SAVE_GAME_RECORD) {
                throw new IOException("Stream does not represent a Save Game");
            }
        }

		creationDate = new Date(dis.readLong());	// (2+) Date first started
		savedDate = new Date(dis.readLong());		// (2+) Date last saved
		if(formatVersion>=3)
		{	timer = dis.readInt();					// (3+) Timer
			title = _readASCIIString(TITLE_SZ,dis);	// (3+) String title
		}
		gridSz = dis.readByte();					// (2+) Grid size
		grid = new byte[gridSz][gridSz];
		locked = new boolean[gridSz][gridSz];
		working = new short[gridSz][gridSz];
		_readRLE_8(grid,dis);						// (2+) Grid data
		_readBools(locked,dis);						// (2+) Locked data
		_readRLE_16(working,dis);					// (2+) Working data
		dis.close();
		_init();
	}

	private void _init()
	{	if(title==null)  title=gridSz+"x"+gridSz;
		switch(gridSz)
		{	case 9 :	setW=3;  setH=3;  break;
			case 12 :	setW=4;  setH=3;  break;
		}
		collisions = new boolean[gridSz][gridSz];
		updateCollisions(0,0);
	}


	static void _readRLE_8(byte[][] arr,DataInputStream dis) throws IOException
	{	int gridSz=arr.length;
		//System.out.println("--");
		for(int i=0;i<gridSz*gridSz;i++)
		{	int val=dis.readByte();
			if((val&0x80)!=0)
			{	int rpt=val&0x7f;
				val=dis.readByte();
				//System.out.println("C:"+rpt+":"+val);
				for(int j=i;j<i+rpt;j++)  arr[j%gridSz][j/gridSz]=(byte)val;
				i+=(rpt-1);
			}
			else
			{	//System.out.println("B:"+val);
				arr[i%gridSz][i/gridSz]=(byte)val;
			}
		}
	}
	private static void _readRLE_16(short[][] arr,DataInputStream dis) throws IOException
	{	int gridSz=arr.length;
		//System.out.println("--");
		for(int i=0;i<gridSz*gridSz;i++)
		{	int val=dis.readShort();
			if((val&0x8000)!=0)
			{	int rpt=val&0x7fff;
				val=dis.readShort();
				//System.out.println("C:"+rpt+":"+val);
				for(int j=i;j<i+rpt;j++)  arr[j%gridSz][j/gridSz]=(short)val;
				i+=(rpt-1);
			}
			else
			{	//System.out.println("B:"+val);
				arr[i%gridSz][i/gridSz]=(short)val;
			}
		}
	}
	private static void _readBools(boolean[][] arr,DataInputStream dis) throws IOException
	{	int gridSz=arr.length;
		int l=gridSz*gridSz;
		short[] buff = new short[((l%8)==0) ? l/8 : l/8+1];
		// -----Read in byte array
		for(int i=0;i<buff.length;i++)
			buff[i]=(short)(dis.readByte()&0xff);
		// -----Extract booleans from bits
		for(int i=0;i<l;i++)
		{	int bit=(1 << (7-i%8));
			int byt=i/8;
			arr[i%gridSz][i/gridSz] = ( (buff[byt] & bit) > 0 );
		}
	}
	private static String _readASCIIString(int sz,DataInputStream dis) throws IOException
	{	StringBuffer sb = new StringBuffer();
		int i=0;
		do
		{	int b=dis.readByte();			// Next byte
			if(b>0)  sb.append((char)b);	// Zero?  No: append
				else  i=sz;					// Yes: exit loop
			i++;
		}while(i<sz);
		return sb.toString();
	}

	// -----------------------------------------------------------------
	// Save this game.  If new game, append, else update.
	// -----------------------------------------------------------------
	boolean save()
	{	RecordStore rs=null;
		try
		{	ByteArrayOutputStream baos = new ByteArrayOutputStream();
			DataOutputStream dos = new DataOutputStream(baos);

			dos.writeByte(SudokuME.FORMAT_VERSION);
			dos.writeByte(SudokuME.SAVE_GAME_RECORD);
			dos.writeLong(creationDate.getTime());		// (2+) Date first started
			dos.writeLong(new Date().getTime());		// (2+) Date last saved
			dos.writeInt(timer);						// (3+) Timer
			_writeASCIIString(title,TITLE_SZ,dos);		// (3+) String title
			dos.writeByte((byte)(gridSz&0x7f));			// (2+) Grid size
			_writeRLE_8(grid,dos);						// (2+) Grid data
			_writeBools(locked,dos);					// (2+) Locked data
			_writeRLE_16(working,dos);					// (2+) Working data
			dos.close();
			byte[] buff = baos.toByteArray();

			rs = RecordStore.openRecordStore(SudokuME.REC_STORE_NAME,true);
			if(recordId==-1)
			{	// -----New game, so append record
				if(buff.length<=rs.getSizeAvailable())
				{	recordId=rs.addRecord(buff,0,buff.length);
					return true;
				}
				else
				{	lastErrorMessage="Not enough space in record store.";
					return false;
				}
				// FIX else show warning
			}
			else
			{	// -----Existing game, so update record
				rs.setRecord(recordId,buff,0,buff.length);
				return true;
			}
		}
		catch(Exception e)
		{	if(SudokuME.debug)  e.printStackTrace();
			lastErrorMessage="Exception: "+e.toString();
			return false;
		}
		finally
		{	try { rs.closeRecordStore(); }catch(Exception e) {}
		}
	}
	private static void _writeRLE_8(byte[][] arr,DataOutputStream dos) throws IOException
	{	int gridSz=arr.length;
		//System.out.println("--");
		for(int i=0;i<gridSz*gridSz;i++)
		{	int val=arr[i%gridSz][i/gridSz];
			int end=_findRepeat_8(arr,i);
			if((end-i)>3)
			{	int a=(end-i)&0x7f;
				//System.out.println("C:"+a+":"+val);
				dos.writeByte(0x80+a);	// frrrrrrr
				dos.writeByte(val);
				i=end-1;
			}
			else
			{	//System.out.println("B:"+val);
				dos.writeByte(val);
			}
			//System.out.println( val+" "+(start%gridSz)+","+(start/gridSz)+" "+(i%gridSz)+","+(i/gridSz) );
		}
	}
	private static int _findRepeat_8(byte[][] arr,int start)
	{	int gridSz=arr.length;
		int end=start;
		byte val=arr[start%gridSz][start/gridSz];
		while
		(	end<gridSz*gridSz && 			// Smaller than grid?
			end<=0x7f &&					// Smaller than max repeat token size
			arr[end%gridSz][end/gridSz]==val // Same value?
		)  end++;
		return end;
	}
	private static void _writeRLE_16(short[][] arr,DataOutputStream dos) throws IOException
	{	int gridSz=arr.length;
		//System.out.println("--");
		for(int i=0;i<gridSz*gridSz;i++)
		{	int val=arr[i%gridSz][i/gridSz];
			int end=_findRepeat_16(arr,i);
			if((end-i)>3)
			{	int a=(end-i)&0x7fff;
				//System.out.println("C:"+a+":"+val);
				dos.writeShort((short)0x8000+a);	// frrrrrrr.rrrrrrrr
				dos.writeShort((short)val);
				i=end-1;
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -