سورس بازی سودوکو در اندروید

چهارشنبه 23 فروردین 1396

در این مقاله می خواهیم سورس بازی سودوکو در اندروید را قرار دهیم این بازی به 3 مرحله تقسیم می شود مرحله اول ساده و متوسط و سخت را دارد شما باید اعداد را طوری قرار دهید که به صورت افقی و عمودی تکراری نباشد.

سورس بازی سودوکو در اندروید

در این بازی 4 تا layout دارد.

که من یکی از آن ها را توضیح می دهم:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:orientation="horizontal"
    android:padding="85dip"
    android:background="@drawable/sudoku_1"
>
<LinearLayout
    android:orientation="vertical"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_gravity="center"
>
<TextView
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_gravity="center"
    android:layout_marginBottom="25dip"
    android:textSize="24.5sp"
/>
<Button
    android:id="@+id/continue_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/continue_label" 
    android:layout_margin="5dip"
    android:background="@drawable/btn" 
/>
<Button
    android:id="@+id/new_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/new_game_label" 
    android:layout_margin="5dip"
    android:background="@drawable/btn"
/>
<Button
    android:id="@+id/about_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/about_label" 
    android:layout_margin="5dip"
    android:background="@drawable/btn"
/>
<Button
    android:id="@+id/exit_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/exit_label"
    android:background="@drawable/btn"
    android:layout_margin="5dip"
/>
</LinearLayout>
</LinearLayout>

لایه ی انتخاب شده لایه ی اول است که در آن از 4 تا دکمه برای ادامه بازی و شروع بازی مجدد و ... نمایش داده می شود.

این بازی 6 کلاس دارد که در اینجا یک کلاس را توضیح می دهم و اگر سوالی بود در مورد کلاس ها در انجمن آن را مطرح نمایید:

import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.widget.Toast;

public class Game extends Activity {
   private static final String TAG = "Sudoku";

   public static final String KEY_DIFFICULTY =
      "org.example.sudoku.difficulty";
   public static final int DIFFICULTY_EASY = 0;
   public static final int DIFFICULTY_MEDIUM = 1;
   public static final int DIFFICULTY_HARD = 2;

   private int puzzle[] = new int[9 * 9];

   
   
   private final String easyPuzzle =
      "360000000004230800000004200" +
      "070460003820000014500013020" +
      "001900000007048300000000045";
   private final String mediumPuzzle =
      "650000070000506000014000005" +
      "007009000002314700000700800" +
      "500000630000201000030000097";
   private final String hardPuzzle =
      "009000000080605020501078000" +
      "000000700706040102004000000" +
      "000720903090301080000000600";
   

   
   private PuzzleView puzzleView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      Log.d(TAG, "onCreate");

      int diff = getIntent().getIntExtra(KEY_DIFFICULTY,
            DIFFICULTY_EASY);
      puzzle = getPuzzle(diff);
      calculateUsedTiles();

      puzzleView = new PuzzleView(this);
      setContentView(puzzleView);
      puzzleView.requestFocus();
   }
   // ...
   

   
   /** Given a difficulty level, come up with a new puzzle */
   private int[] getPuzzle(int diff) {
      String puz;
      // TODO: Continue last game
      switch (diff) {
      case DIFFICULTY_HARD:
         puz = hardPuzzle;
         break;
      case DIFFICULTY_MEDIUM:
         puz = mediumPuzzle;
         break;
      case DIFFICULTY_EASY:
      default:
         puz = easyPuzzle;
         break;
      }
      return fromPuzzleString(puz);
   }
   

   
   /** Convert an array into a puzzle string */
   static private String toPuzzleString(int[] puz) {
      StringBuilder buf = new StringBuilder();
      for (int element : puz) {
         buf.append(element);
      }
      return buf.toString();
   }

   /** Convert a puzzle string into an array */
   static protected int[] fromPuzzleString(String string) {
      int[] puz = new int[string.length()];
      for (int i = 0; i < puz.length; i++) {
         puz[i] = string.charAt(i) - '0';
      }
      return puz;
   }
   

   
   /** Return the tile at the given coordinates */
   private int getTile(int x, int y) {
      return puzzle[y * 9 + x];
   }

   /** Change the tile at the given coordinates */
   private void setTile(int x, int y, int value) {
      puzzle[y * 9 + x] = value;
   }
   

   
   /** Return a string for the tile at the given coordinates */
   protected String getTileString(int x, int y) {
      int v = getTile(x, y);
      if (v == 0)
         return "";
      else
         return String.valueOf(v);
   }
   

   
   /** Change the tile only if it's a valid move */
   protected boolean setTileIfValid(int x, int y, int value) {
      int tiles[] = getUsedTiles(x, y);
      if (value != 0) {
         for (int tile : tiles) {
            if (tile == value)
               return false;
         }
      }
      setTile(x, y, value);
      calculateUsedTiles();
      return true;
   }
   

   
   /** Open the keypad if there are any valid moves */
   protected void showKeypadOrError(int x, int y) {
      int tiles[] = getUsedTiles(x, y);
      if (tiles.length == 9) {
         Toast toast = Toast.makeText(this,
               R.string.no_moves_label, Toast.LENGTH_SHORT);
         toast.setGravity(Gravity.CENTER, 0, 0);
         toast.show();
      } else {
         Log.d(TAG, "showKeypad: used=" + toPuzzleString(tiles));
         Dialog v = new Keypad(this, tiles, puzzleView);
         v.show();
      }
   }
   

   
   /** Cache of used tiles */
   private final int used[][][] = new int[9][9][];

   /** Return cached used tiles visible from the given coords */
   protected int[] getUsedTiles(int x, int y) {
      return used[x][y];
   }
   

   
   /** Compute the two dimensional array of used tiles */
   private void calculateUsedTiles() {
      for (int x = 0; x < 9; x++) {
         for (int y = 0; y < 9; y++) {
            used[x][y] = calculateUsedTiles(x, y);
            // Log.d(TAG, "used[" + x + "][" + y + "] = "
            // + toPuzzleString(used[x][y]));
         }
      }
   }
   

   
   /** Compute the used tiles visible from this position */
   private int[] calculateUsedTiles(int x, int y) {
      int c[] = new int[9];
      // horizontal
      for (int i = 0; i < 9; i++) { 
         if (i == y)
            continue;
         int t = getTile(x, i);
         if (t != 0)
            c[t - 1] = t;
      }
      // vertical
      for (int i = 0; i < 9; i++) { 
         if (i == x)
            continue;
         int t = getTile(i, y);
         if (t != 0)
            c[t - 1] = t;
      }
      // same cell block
      int startx = (x / 3) * 3; 
      int starty = (y / 3) * 3;
      for (int i = startx; i < startx + 3; i++) {
         for (int j = starty; j < starty + 3; j++) {
            if (i == x && j == y)
               continue;
            int t = getTile(i, j);
            if (t != 0)
               c[t - 1] = t;
         }
      }
      // compress
      int nused = 0; 
      for (int t : c) {
         if (t != 0)
            nused++;
      }
      int c1[] = new int[nused];
      nused = 0;
      for (int t : c) {
         if (t != 0)
            c1[nused++] = t;
      }
      return c1;
   }
   
   
}

این کلاس که بالای هر متد آن یک کامنت نوشته شده است برای تبدیل کردن آرایه به رشته و بر عکس باز کردن کیبورد و نمایش اعداد و... نوشته شده است.

خروجی به صورت زیر است:

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید