📄 sudokume.java
字号:
GridDisplay() {
int fh=Font.getDefaultFont().getHeight();
int i;
if (programmedKeyCodes.useFullScreen && hasMIDP2) {
setFullScreenMode(true);
}
for (i=0; i<programmedKeyCodes.funcStr.length; i++) {
if (programmedKeyCodes.funcKeyCommand[i] != null) {
addCommand(programmedKeyCodes.funcKeyCommand[i]);
}
}
keyHelper = new KeyHelper(game.gridSz);
int w=getWidth() , h=getHeight();
int usableH = h - (keyHelper.hasCommands ? (int) 0 : fh + 2 );
setCommandListener(this);
// -----Reset cursor to top left
cursorX=0; cursorY=0;
// -----Undo buffer
undoBuffer = new short[20];
undoPosition=0; undoCurrent=game.grid[cursorX][cursorY];
// -----Determine cell size and load appropriate image
try
{ int size=0;
// Save space for soft key usage
//int w=160,h=200;
if (w > usableH) {
// display is wider than it is tall - we will fit in more if we put working on
// the side of the grid
horizWorking=false;
}
int[] sizes = { 10,12,16 };
for(i=0;i<sizes.length;i++) {
// factor in the added size of the working grid when choosing size.
if(game.gridSz*(sizes[i]+(horizWorking?0:1))<=w && game.gridSz*(sizes[i]+(horizWorking?1:0))<=usableH) {
size=i;
}
}
cellW=sizes[size]; cellH=sizes[size];
// for working in cell - define the X,Y and W,H of each of the dots, dependant on size of grid and size
// of cell. this needs to hand customized to ensure good distribution given the few pixels available
// Here are the graphical representations of the cells:
// Key: -=light blue (border); .=white;
// 1-9 = position of the dit corresponding to this working being set. (*,0,# corresponds to 10,11,12)
//
// Grid Size:
// | 9x9 / 16 | 9x9 / 12 | 9x9 / 10 || | 12x12 / 16 | 12x12 / 12 | 12x12 / 10 |
// ====0123456789012345===012345678901===0123456789=======0123456789012345===012345678901===0123456789==
// =========================================================================================================
// 0| ---------------- | ------------ | ---------- || 0| ---------------- | ------------ | ---------- |
// 1| -1111.2222.3333- | -111.22.333- | -11.22.33- || 1| -1111.2222.3333- | -111.22.333- | -11.22.33- |
// 2| -1111.2222.3333- | -111.22.333- | -11.22.33- || 2| -1111.2222.3333- | -111.22.333- | -11.22.33- |
// 3| -1111.2222.3333- | -111.22.333- | -........- || 3| -1111.2222.3333- | -..........- | -44.55.66- |
// 4| -1111.2222.3333- | -..........- | -44.55.66- || 4| -..............- | -444.55.666- | -44.55.66- |
// 5| -..............- | -444.55.666- | -44.55.66- || 5| -4444.5555.6666- | -444.55.666- | -77.88.99- |
// 6| -4444.5555.6666- | -444.55.666- | -........- || 6| -4444.5555.6666- | -777.88.999- | -77.88.99- |
// 7| -4444.5555.6666- | -..........- | -77.88.99- || 7| -4444.5555.6666- | -777.88.999- | -**.00.##- |
// 8| -4444.5555.6666- | -777.88.999- | -77.88.99- || 8| -7777.8888.9999- | -..........- | -**.00.##- |
// 9| -4444.5555.6666- | -777.88.999- | ---------- || 9| -7777.8888.9999- | -***.00.###- | ---------- |
// 10| -..............- | -777.88.999- | |10| -7777.8888.9999- | -***.00.###- |
// 11| -7777.8888.9999- | ------------ | |11| -..............- | ------------ |
// 12| -7777.8888.9999- | |12| -****.0000.####- |
// 13| -7777.8888.9999- | |13| -****.0000.####- |
// 14| -7777.8888.9999- | |14| -****.0000.####- |
// 15| ---------------- | |15| ---------------- |
switch (sizes[size]) {
case 10:
workingDotX = new byte[]{1,4,7};
workingDotW = new byte[]{2,2,2};
if (game.gridSz == 9) {
workingDotY = workingDotX;
workingDotH = workingDotW;
} else {
workingDotY = new byte[]{1,3,5,7};
workingDotH = new byte[]{2,2,2,2};
}
break;
case 12:
workingDotX = new byte[]{1,5,8};
workingDotW = new byte[]{3,2,3};
if (game.gridSz == 9) {
workingDotY = workingDotX;
workingDotH = workingDotW;
} else {
workingDotY = new byte[]{1,4,6,9};
workingDotH = new byte[]{2,2,2,2};
}
break;
case 16:
workingDotX = new byte[]{1,6,11};
workingDotW = new byte[]{4,4,4};
if (game.gridSz == 9) {
workingDotY = workingDotX;
workingDotH = workingDotW;
} else {
workingDotY = new byte[]{1,5,8,12};
workingDotH = new byte[]{3,3,3,3};
}
break;
}
digits = Image.createImage("/digits"+sizes[size]+".png");
}
catch(IOException e)
{ if(debug) e.printStackTrace();
}
// -----Other initialisation
if (horizWorking) {
workingH = cellH +2;
workingW = 0;
workingX = 0;
workingY = (cellH*game.gridSz) + 2;
} else {
workingH = 0;
workingW = cellW +2;
workingX = (cellW*game.gridSz) + 2;
workingY = 0;
}
xOff = (getWidth()-(game.gridSz*cellW)-workingW)/2;
yOff = (usableH-(game.gridSz*cellH)-workingH)/2;
// -----Optimised painting data
optPaintPrevious = new int[game.gridSz][game.gridSz];
optPaintPrevious2 = new int[game.gridSz];
optPaintAll=true;
// -----Timer
startTimer();
}
// -------------------------------------------------------------
// Undo code. The undo buffer is a 'rolling cache', with a packed
// 16 bit value, where the value of the cell is stored in the high
// byte and the x/y co-ords of the cell take up a nibble each in
// the low byte. So that zero (empty) cells can be stored, the
// highest bit of the value byte is alwats set, thus zero is
// stored as 0x80. This is to distinguish zero cell entries from
// unused entries in the undoBuffer.
// -------------------------------------------------------------
private void undoRestore() {
if(game.grid[cursorX][cursorY]!=undoCurrent) {
// -----If current cell's value changed, undo that first
keyNumPressed(undoCurrent);
} else {
// -----Else, undo previous cell using undo buffer
// -----Move to previous pos
undoPosition=(undoPosition+undoBuffer.length-1)%undoBuffer.length;
// -----Get value from current pos and unpack, restore to grid
int a=undoBuffer[undoPosition]&0xffff;
if(a>0) { // Zero means no data
int cy=a&0xf; a=a>>4; // Low nibble = y
int cx=a&0xf; a=a>>4; // Next nibble = x
a=(a&0x7f); // Next 7 bits = value
cursorX=cx;
cursorY=cy;
undoCurrent=(byte) a; // So that further undoRestores work
keyNumPressed(a); // Assign
//System.out.println("Restore: "+cx+","+cy+":"+a);
undoBuffer[undoPosition]=0; // Set to zero (no data)
}
}
game.updateCollisions(cursorX,cursorY);
}
private void undoUpdate(int oldX,int oldY) {
// -----Has cursor position changed?
if(oldX!=cursorX || oldY!=cursorY) {
// -----Contents of old cell changed?
if(game.grid[oldX][oldY] != undoCurrent) {
// -----Store x/y/value in current pos, and move to next pos
undoBuffer[undoPosition]=(short)(((0x80+undoCurrent)<<8)+((oldX&0xf)<<4)+(oldY&0xf));
//System.out.println("Stored: "+Integer.toHexString(undoBuffer[undoPosition]));
undoPosition=(undoPosition+1)%undoBuffer.length;
}
// -----Remember value in new cell (so we know when it changes)
undoCurrent=game.grid[cursorX][cursorY];
}
}
// -------------------------------------------------------------
// Redraw display
// -------------------------------------------------------------
private boolean prev_shift = false;
public void paint(Graphics g) {
// -----When resuming a paused game, the constructor has not
// -----finished loading 'digits' before this code runs. (Is
// -----image loading handled on a thread?)
if(digits==null) return;
// -----Clear background (only when painting entire screen)
if(optPaintAll) {
g.setColor(0xcc,0xcc,0xff);
g.fillRect(0,0,getWidth(),getHeight());
if (SudokuME.programmedKeyCodes.autoWorking) {
game.createWorking();
}
}
// Draw soft key labels if we do not have any commands defined
// if shift has changed or if optPaintAll
if (keyHelper.hasCommands == false) {
if (prev_shift != shiftFlag || optPaintAll) {
_paint_soft_keys(g);
prev_shift = shiftFlag;
}
}
g.translate(xOff,yOff);
// -----Draw grid (uses optimised painting)
optPaintDebug=0;
for(int x=0;x<game.gridSz;x++) {
for(int y=0;y<game.gridSz;y++) {
_plot(g,x,y);
}
}
for(int i=0;i<game.gridSz;i++) {
_working(g,i);
}
// -----Draw set lines over grid (always drawn)
int sW=cellW*game.setW , sH=cellH*game.setH;
g.setClip(0,0,game.gridSz*cellW+workingW,game.gridSz*cellH+workingH);
g.setColor(0x00,0x00,0xff);
for(int x=0;x<game.gridSz/game.setW;x++)
for(int y=0;y<game.gridSz/game.setH;y++)
g.drawRect(x*sW,y*sH , sW-1,sH-1);
// -----Draw cursor (always drawn)
if(editGrid) g.setColor(0xff,0x00,0x00);
else g.setColor(0x00,0x00,0xff);
g.drawRect(cursorX*cellW,cursorY*cellH,cellW-1,cellH-1);
if(!editGrid)
{ g.setColor(0x00,0x00,0xff);
if (keyHelper.useNumKeys) {
// we do not have a cursor in the Working - surround the whole grid
if (horizWorking) {
g.drawRect(0,workingY,game.gridSz*cellW-1,cellH-1);
} else {
g.drawRect(workingX,0,cellW-1,game.gridSz*cellH-1);
}
} else {
if (horizWorking) {
g.drawRect(workCursorX*cellW,workingY,cellW-1,cellH-1);
} else {
g.drawRect(workingX,workCursorX*cellH,cellW-1,cellH-1);
}
}
}
// -----Show timer at foot of screen
if(shiftFlag) _centreMessage(g,"<< SHIFT >>");
if(showTimer) _centreMessage(g,getTimerString());
// -----Switch off master paint switch (assuming it was ever on!)
optPaintAll=false;
//System.out.println(optPaintDebug);
}
private void _plot(Graphics g,int x,int y) {
int d=game.grid[x][y];
// -----'x' and 'vPos' are the tile offsets to draw from 'digits' image
// vPos=3 is used for cells shown with "workingInCell"
int vOff = 1; // Locked (bold)
if(game.collisions[x][y]) vOff=2; // Collision (red)
else if(!game.locked[x][y]) vOff=0; // Faded (not locked)
if (d == 0) {
if (SudokuME.programmedKeyCodes.workingInCell) {
_workingInCell(g,x,y);
return;
} else if ((game.working[x][y] & (1 << game.gridSz)) > 0) {
vOff=1; // Dot marker, shows cell with working
} else if ((game.working[x][y]&((1 << game.gridSz)-1)) > 0) {
vOff=2; // ? marker, cell with working but not completed
} else {
vOff=0; // blank cell
}
}
int a=(d<<2)+vOff; // Work out contents as int
if(cursorX==x && cursorY==y) a+=0x100; // Factor in cursor position
// -----drawImage is expensive on low spec phones. Call only
// -----if cell needs updating.
if(optPaintAll || a!=optPaintPrevious[x][y]) {
g.setClip(x*cellW,y*cellH,cellW,cellH);
g.drawImage(digits , x*cellW-d*cellW , y*cellH-vOff*cellH , TOPLEFT);
optPaintPrevious[x][y]=a; optPaintDebug++;
}
}
// Plot the working values in the cell - fill in top left corner for a '1', middle top for a '2', middle left
// for a '4', ...
// for a 12x12, have 3 columns and 4 rows (to match a normal keyboard) - first row = 1,2,3. last row = 10,11,12
// locked cells are filled in black, unlocked cells in grey
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -