سورس بازی سودوکو در اندروید
چهارشنبه 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;
}
}
این کلاس که بالای هر متد آن یک کامنت نوشته شده است برای تبدیل کردن آرایه به رشته و بر عکس باز کردن کیبورد و نمایش اعداد و... نوشته شده است.
خروجی به صورت زیر است:


- Android
- 2k بازدید
- 6 تشکر