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.    private final String easyPuzzle =
  25.       "360000000004230800000004200" +
  26.       "070460003820000014500013020" +
  27.       "001900000007048300000000045";
  28.    private final String mediumPuzzle =
  29.       "650000070000506000014000005" +
  30.       "007009000002314700000700800" +
  31.       "500000630000201000030000097";
  32.    private final String hardPuzzle =
  33.       "009000000080605020501078000" +
  34.       "000000700706040102004000000" +
  35.       "000720903090301080000000600";
  36.    private PuzzleView puzzleView;
  37.    @Override
  38.    protected void onCreate(Bundle savedInstanceState) {
  39.       super.onCreate(savedInstanceState);
  40.       Log.d(TAG, "onCreate");
  41.       int diff = getIntent().getIntExtra(KEY_DIFFICULTY,
  42.             DIFFICULTY_EASY);
  43.       puzzle = getPuzzle(diff);
  44.       calculateUsedTiles();
  45.       puzzleView = new PuzzleView(this);
  46.       setContentView(puzzleView);
  47.       puzzleView.requestFocus();
  48.    }
  49.    
  50.    @Override
  51.    protected void onResume() {
  52.       super.onResume();
  53.       Music.play(this, R.raw.game);
  54.    }
  55.    @Override
  56.    protected void onPause() {
  57.       super.onPause();
  58.       Music.stop(this);
  59.    }
  60.    
  61.    /** Given a difficulty level, come up with a new puzzle */
  62.    private int[] getPuzzle(int diff) {
  63.       String puz;
  64.       // TODO: Continue last game
  65.       switch (diff) {
  66.       case DIFFICULTY_HARD:
  67.          puz = hardPuzzle;
  68.          break;
  69.       case DIFFICULTY_MEDIUM:
  70.          puz = mediumPuzzle;
  71.          break;
  72.       case DIFFICULTY_EASY:
  73.       default:
  74.          puz = easyPuzzle;
  75.          break;
  76.       }
  77.       return fromPuzzleString(puz);
  78.    }
  79.    /** Convert an array into a puzzle string */
  80.    static private String toPuzzleString(int[] puz) {
  81.       StringBuilder buf = new StringBuilder();
  82.       for (int element : puz) {
  83.          buf.append(element);
  84.       }
  85.       return buf.toString();
  86.    }
  87.    /** Convert a puzzle string into an array */
  88.    static protected int[] fromPuzzleString(String string) {
  89.       int[] puz = new int[string.length()];
  90.       for (int i = 0; i < puz.length; i++) {
  91.          puz[i] = string.charAt(i) - '0';
  92.       }
  93.       return puz;
  94.    }
  95.    /** Return the tile at the given coordinates */
  96.    private int getTile(int x, int y) {
  97.       return puzzle[y * 9 + x];
  98.    }
  99.    /** Change the tile at the given coordinates */
  100.    private void setTile(int x, int y, int value) {
  101.       puzzle[y * 9 + x] = value;
  102.    }
  103.    /** Return a string for the tile at the given coordinates */
  104.    protected String getTileString(int x, int y) {
  105.       int v = getTile(x, y);
  106.       if (v == 0)
  107.          return "";
  108.       else
  109.          return String.valueOf(v);
  110.    }
  111.    /** Change the tile only if it's a valid move */
  112.    protected boolean setTileIfValid(int x, int y, int value) {
  113.       int tiles[] = getUsedTiles(x, y);
  114.       if (value != 0) {
  115.          for (int tile : tiles) {
  116.             if (tile == value)
  117.                return false;
  118.          }
  119.       }
  120.       setTile(x, y, value);
  121.       calculateUsedTiles();
  122.       return true;
  123.    }
  124.    /** Open the keypad if there are any valid moves */
  125.    protected void showKeypadOrError(int x, int y) {
  126.       int tiles[] = getUsedTiles(x, y);
  127.       if (tiles.length == 9) {
  128.          Toast toast = Toast.makeText(this,
  129.                R.string.no_moves_label, Toast.LENGTH_SHORT);
  130.          toast.setGravity(Gravity.CENTER, 0, 0);
  131.          toast.show();
  132.       } else {
  133.          Log.d(TAG, "showKeypad: used=" + toPuzzleString(tiles));
  134.          Dialog v = new Keypad(this, tiles, puzzleView);
  135.          v.show();
  136.       }
  137.    }
  138.    /** Cache of used tiles */
  139.    private final int used[][][] = new int[9][9][];
  140.    /** Return cached used tiles visible from the given coords */
  141.    protected int[] getUsedTiles(int x, int y) {
  142.       return used[x][y];
  143.    }
  144.    /** Compute the two dimensional array of used tiles */
  145.    private void calculateUsedTiles() {
  146.       for (int x = 0; x < 9; x++) {
  147.          for (int y = 0; y < 9; y++) {
  148.             used[x][y] = calculateUsedTiles(x, y);
  149.             // Log.d(TAG, "used[" + x + "][" + y + "] = "
  150.             // + toPuzzleString(used[x][y]));
  151.          }
  152.       }
  153.    }
  154.    /** Compute the used tiles visible from this position */
  155.    private int[] calculateUsedTiles(int x, int y) {
  156.       int c[] = new int[9];
  157.       // horizontal
  158.       for (int i = 0; i < 9; i++) {
  159.          if (i == y)
  160.             continue;
  161.          int t = getTile(x, i);
  162.          if (t != 0)
  163.             c[t - 1] = t;
  164.       }
  165.       // vertical
  166.       for (int i = 0; i < 9; i++) {
  167.          if (i == x)
  168.             continue;
  169.          int t = getTile(i, y);
  170.          if (t != 0)
  171.             c[t - 1] = t;
  172.       }
  173.       // same cell block
  174.       int startx = (x / 3) * 3;
  175.       int starty = (y / 3) * 3;
  176.       for (int i = startx; i < startx + 3; i++) {
  177.          for (int j = starty; j < starty + 3; j++) {
  178.             if (i == x && j == y)
  179.                continue;
  180.             int t = getTile(i, j);
  181.             if (t != 0)
  182.                c[t - 1] = t;
  183.          }
  184.       }
  185.       // compress
  186.       int nused = 0;
  187.       for (int t : c) {
  188.          if (t != 0)
  189.             nused++;
  190.       }
  191.       int c1[] = new int[nused];
  192.       nused = 0;
  193.       for (int t : c) {
  194.          if (t != 0)
  195.             c1[nused++] = t;
  196.       }
  197.       return c1;
  198.    }
  199. }