Game.java
上传用户:xmjingguan
上传日期:2009-07-06
资源大小:2054k
文件大小:6k
源码类别:

android开发

开发平台:

Java

  1. /***
  2.  * Excerpted from "Hello, Android!",
  3.  * published by The Pragmatic Bookshelf.
  4.  * Copyrights apply to this code. It may not be used to create training material, 
  5.  * courses, books, articles, and the like. Contact us if you are in doubt.
  6.  * We make no guarantees that this code is fit for any purpose. 
  7.  * Visit http://www.pragmaticprogrammer.com/titles/eband for more book information.
  8. ***/
  9. package org.example.sudoku;
  10. import android.app.Activity;
  11. import android.app.Dialog;
  12. import android.os.Bundle;
  13. import android.util.Log;
  14. import android.view.Gravity;
  15. import android.widget.Toast;
  16. public class Game extends Activity {
  17.    private static final String TAG = "Sudoku";
  18.    public static final String KEY_DIFFICULTY =
  19.       "org.example.sudoku.difficulty";
  20.    public static final int DIFFICULTY_EASY = 0;
  21.    public static final int DIFFICULTY_MEDIUM = 1;
  22.    public static final int DIFFICULTY_HARD = 2;
  23.    private int puzzle[] = new int[9 * 9];
  24.    
  25.    
  26.    private final String easyPuzzle =
  27.       "360000000004230800000004200" +
  28.       "070460003820000014500013020" +
  29.       "001900000007048300000000045";
  30.    private final String mediumPuzzle =
  31.       "650000070000506000014000005" +
  32.       "007009000002314700000700800" +
  33.       "500000630000201000030000097";
  34.    private final String hardPuzzle =
  35.       "009000000080605020501078000" +
  36.       "000000700706040102004000000" +
  37.       "000720903090301080000000600";
  38.    
  39.    
  40.    private PuzzleView puzzleView;
  41.    @Override
  42.    protected void onCreate(Bundle savedInstanceState) {
  43.       super.onCreate(savedInstanceState);
  44.       Log.d(TAG, "onCreate");
  45.       int diff = getIntent().getIntExtra(KEY_DIFFICULTY,
  46.             DIFFICULTY_EASY);
  47.       puzzle = getPuzzle(diff);
  48.       calculateUsedTiles();
  49.       puzzleView = new PuzzleView(this);
  50.       setContentView(puzzleView);
  51.       puzzleView.requestFocus();
  52.    }
  53.    // ...
  54.    
  55.    
  56.    /** Given a difficulty level, come up with a new puzzle */
  57.    private int[] getPuzzle(int diff) {
  58.       String puz;
  59.       // TODO: Continue last game
  60.       switch (diff) {
  61.       case DIFFICULTY_HARD:
  62.          puz = hardPuzzle;
  63.          break;
  64.       case DIFFICULTY_MEDIUM:
  65.          puz = mediumPuzzle;
  66.          break;
  67.       case DIFFICULTY_EASY:
  68.       default:
  69.          puz = easyPuzzle;
  70.          break;
  71.       }
  72.       return fromPuzzleString(puz);
  73.    }
  74.    
  75.    
  76.    /** Convert an array into a puzzle string */
  77.    static private String toPuzzleString(int[] puz) {
  78.       StringBuilder buf = new StringBuilder();
  79.       for (int element : puz) {
  80.          buf.append(element);
  81.       }
  82.       return buf.toString();
  83.    }
  84.    /** Convert a puzzle string into an array */
  85.    static protected int[] fromPuzzleString(String string) {
  86.       int[] puz = new int[string.length()];
  87.       for (int i = 0; i < puz.length; i++) {
  88.          puz[i] = string.charAt(i) - '0';
  89.       }
  90.       return puz;
  91.    }
  92.    
  93.    
  94.    /** Return the tile at the given coordinates */
  95.    private int getTile(int x, int y) {
  96.       return puzzle[y * 9 + x];
  97.    }
  98.    /** Change the tile at the given coordinates */
  99.    private void setTile(int x, int y, int value) {
  100.       puzzle[y * 9 + x] = value;
  101.    }
  102.    
  103.    
  104.    /** Return a string for the tile at the given coordinates */
  105.    protected String getTileString(int x, int y) {
  106.       int v = getTile(x, y);
  107.       if (v == 0)
  108.          return "";
  109.       else
  110.          return String.valueOf(v);
  111.    }
  112.    
  113.    
  114.    /** Change the tile only if it's a valid move */
  115.    protected boolean setTileIfValid(int x, int y, int value) {
  116.       int tiles[] = getUsedTiles(x, y);
  117.       if (value != 0) {
  118.          for (int tile : tiles) {
  119.             if (tile == value)
  120.                return false;
  121.          }
  122.       }
  123.       setTile(x, y, value);
  124.       calculateUsedTiles();
  125.       return true;
  126.    }
  127.    
  128.    
  129.    /** Open the keypad if there are any valid moves */
  130.    protected void showKeypadOrError(int x, int y) {
  131.       int tiles[] = getUsedTiles(x, y);
  132.       if (tiles.length == 9) {
  133.          Toast toast = Toast.makeText(this,
  134.                R.string.no_moves_label, Toast.LENGTH_SHORT);
  135.          toast.setGravity(Gravity.CENTER, 0, 0);
  136.          toast.show();
  137.       } else {
  138.          Log.d(TAG, "showKeypad: used=" + toPuzzleString(tiles));
  139.          Dialog v = new Keypad(this, tiles, puzzleView);
  140.          v.show();
  141.       }
  142.    }
  143.    
  144.    
  145.    /** Cache of used tiles */
  146.    private final int used[][][] = new int[9][9][];
  147.    /** Return cached used tiles visible from the given coords */
  148.    protected int[] getUsedTiles(int x, int y) {
  149.       return used[x][y];
  150.    }
  151.    
  152.    
  153.    /** Compute the two dimensional array of used tiles */
  154.    private void calculateUsedTiles() {
  155.       for (int x = 0; x < 9; x++) {
  156.          for (int y = 0; y < 9; y++) {
  157.             used[x][y] = calculateUsedTiles(x, y);
  158.             // Log.d(TAG, "used[" + x + "][" + y + "] = "
  159.             // + toPuzzleString(used[x][y]));
  160.          }
  161.       }
  162.    }
  163.    
  164.    
  165.    /** Compute the used tiles visible from this position */
  166.    private int[] calculateUsedTiles(int x, int y) {
  167.       int c[] = new int[9];
  168.       // horizontal
  169.       for (int i = 0; i < 9; i++) { 
  170.          if (i == y)
  171.             continue;
  172.          int t = getTile(x, i);
  173.          if (t != 0)
  174.             c[t - 1] = t;
  175.       }
  176.       // vertical
  177.       for (int i = 0; i < 9; i++) { 
  178.          if (i == x)
  179.             continue;
  180.          int t = getTile(i, y);
  181.          if (t != 0)
  182.             c[t - 1] = t;
  183.       }
  184.       // same cell block
  185.       int startx = (x / 3) * 3; 
  186.       int starty = (y / 3) * 3;
  187.       for (int i = startx; i < startx + 3; i++) {
  188.          for (int j = starty; j < starty + 3; j++) {
  189.             if (i == x && j == y)
  190.                continue;
  191.             int t = getTile(i, j);
  192.             if (t != 0)
  193.                c[t - 1] = t;
  194.          }
  195.       }
  196.       // compress
  197.       int nused = 0; 
  198.       for (int t : c) {
  199.          if (t != 0)
  200.             nused++;
  201.       }
  202.       int c1[] = new int[nused];
  203.       nused = 0;
  204.       for (int t : c) {
  205.          if (t != 0)
  206.             c1[nused++] = t;
  207.       }
  208.       return c1;
  209.    }
  210.    
  211.    
  212. }