SlideShare a Scribd company logo
UNIVERSITAS GUNADARMA
FAKULTAS TEKNOLOGI INDUSTRI
MANUAL BOOK PERMAINAN SIMPLY SUDOKU
Disusun Oleh :
Nama : Bagus Prayogo
NPM : 51412349
Kelas : 3IA24
Jurusan : Teknik Informatika
Dosen : Anita Sari Apriliani
Ditulis sebagai salah satu syarat kelulusan Mata Kuliah
Softskill “Pengantar Teknologi Game”
LABORATORIUM INFORMATIKA
UNIVERSITAS GUNADARMA
2015
Untuk membuat game, yang dilakukan pertama adalah menjalankan eclipse. Pastikan sudah
menginstal android sdk yang dibutuhkan untuk membuat program android dan pada eclipse
sudah terinstal ADT(Android Development Tools). Kita bisa memulainya dengan klik file -
new – android application project , lalu tentukan nama aplikasi, nama project, nama
package, serta minimum required, target sdk, sdk untuk mengcompile serta tema aplikasi.
Jika sudah, tekan next saja hingga finish.
Berikut File – File yang di butuhkan program permainan simply sudoku :
Game.java
package bagus.map.v2;
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 =
"my.difficulty";
private static final String PREF_PUZZLE = "puzzle" ;
public static final int DIFFICULTY_EASY = 0;
public static final int DIFFICULTY_MEDIUM = 1;
public static final int DIFFICULTY_HARD = 2;
protected static final int DIFFICULTY_CONTINUE = -1;
private int puzzle[] = new int[9 * 9];
// ini adalah nilai dari blok 9 x 9, edit dengan sangat hati-hati
private final String easyPuzzle =
"360000000004230800000004200" +
"070460003820000014500013020" +
"001900000007048300000000045";
private final String mediumPuzzle =
"650000070000506000014000005" +
"007009000002314700000700800" +
"500000630000201000030000097";
private final String hardPuzzle =
"009000000080605020501078000" +
"000000700706040102004000000" +
"000720903090301080000000600";
private Puzzle 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 Puzzle(this);
setContentView(puzzleView);
puzzleView.requestFocus();
// Jika activity di-restart, maka akan dilanjutkan sesuai dengan activity terakhir
getIntent().putExtra(KEY_DIFFICULTY, DIFFICULTY_CONTINUE);
}
@Override
protected void onResume() {
super.onResume();
Musik.play(this, R.raw.game);
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
Musik.stop(this);
// ini adalah untuk menyimpan sususan puzzle
getPreferences(MODE_PRIVATE).edit().putString(PREF_PUZZLE,
toPuzzleString(puzzle)).commit();
}
// ini adalah blok kondisi permainan sudoku
private int[] getPuzzle(int diff) {
String puz;
switch (diff) {
case DIFFICULTY_CONTINUE:
puz = getPreferences(MODE_PRIVATE).getString(PREF_PUZZLE,
easyPuzzle);
break;
// ...
case DIFFICULTY_HARD:
puz = hardPuzzle;
break;
case DIFFICULTY_MEDIUM:
puz = mediumPuzzle;
break;
case DIFFICULTY_EASY:
default:
puz = easyPuzzle;
break;
}
return fromPuzzleString(puz);
}
// ini blok yang akan mengkonversi nilai array ke dalam string puzzle
static private String toPuzzleString(int[] puz) {
StringBuilder buf = new StringBuilder();
for (int element : puz) {
buf.append(element);
}
return buf.toString();
}
// ini blok yang akan mengkonversi value dari string puzzle ke dalam 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;
}
// mengembalikan nilai pada tiap tile sesuai dengan nilai koordinat
private int getTile(int x, int y) {
return puzzle[y * 9 + x];
}
// merubah tile berdasarkan koordinat
private void setTile(int x, int y, int value) {
puzzle[y * 9 + x] = value;
}
// mengembalikan string untuk tile berdasarkan koordinat
protected String getTileString(int x, int y) {
int v = getTile(x, y);
if (v == 0)
return "";
else
return String.valueOf(v);
}
// mengganti tile jika movement benar
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;
}
// membuka popup keypad jika values isian pada tile koordinat benar
protected void showKeypadOrError(int x, int y) {
int tiles[] = getUsedTiles(x, y);
if (tiles.length == 9) {
Toast toast = Toast.makeText(this,
R.string.lblCobaLagi, 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();
}
}
// simpan cache tile
private final int used[][][] = new int[9][9][];
// mengembalikan cache tile berdasarkan koordinat
protected int[] getUsedTiles(int x, int y) {
return used[x][y];
}
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]));
}
}
}
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;
}
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;
}
}
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;
}
}
Merupakan file java yang menyimpan code program untuk mendefinisikan sudoku dengan
blok 9x9 beserta fungsinya. Kelas ini yang juga menentukan tingkat kesulitan sudoku.
Keypad.java
package bagus.map.v2;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
public class Keypad extends Dialog {
protected static final String TAG = "Sudoku";
private final View keys[] = new View[9];
private View keypad;
private final int useds[];
private final Puzzle puzzleView;
public Keypad(Context context, int useds[], Puzzle puzzleView) {
super(context);
this.useds = useds;
this.puzzleView = puzzleView;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(R.string.lblKeypad);
setContentView(R.layout.keypad);
findViews();
for (int element : useds) {
if (element != 0)
keys[element - 1].setVisibility(View.INVISIBLE);
}
setListeners();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
int tile = 0;
switch (keyCode) {
case KeyEvent.KEYCODE_0:
case KeyEvent.KEYCODE_SPACE: tile = 0; break;
case KeyEvent.KEYCODE_1: tile = 1; break;
case KeyEvent.KEYCODE_2: tile = 2; break;
case KeyEvent.KEYCODE_3: tile = 3; break;
case KeyEvent.KEYCODE_4: tile = 4; break;
case KeyEvent.KEYCODE_5: tile = 5; break;
case KeyEvent.KEYCODE_6: tile = 6; break;
case KeyEvent.KEYCODE_7: tile = 7; break;
case KeyEvent.KEYCODE_8: tile = 8; break;
case KeyEvent.KEYCODE_9: tile = 9; break;
default:
return super.onKeyDown(keyCode, event);
}
if (isValid(tile)) {
returnResult(tile);
}
return true;
}
// mengembalikan tile berdasakan parameter yang dipanggil
private void returnResult(int tile) {
puzzleView.setSelectedTile(tile);
dismiss();
}
private boolean isValid(int tile) {
for (int t : useds) {
if (tile == t)
return false;
}
return true;
}
private void findViews() {
keypad = findViewById(R.id.keypad);
keys[0] = findViewById(R.id.keypad_1);
keys[1] = findViewById(R.id.keypad_2);
keys[2] = findViewById(R.id.keypad_3);
keys[3] = findViewById(R.id.keypad_4);
keys[4] = findViewById(R.id.keypad_5);
keys[5] = findViewById(R.id.keypad_6);
keys[6] = findViewById(R.id.keypad_7);
keys[7] = findViewById(R.id.keypad_8);
keys[8] = findViewById(R.id.keypad_9);
}
private void setListeners() {
for (int i = 0; i < keys.length; i++) {
final int t = i + 1;
keys[i].setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
returnResult(t);
}});
}
keypad.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
returnResult(0);
}});
}
}
Merupakan file java yang menyimpan code program untuk mendefinisikan keypad yang di
gunakan user untuk menginput nilai pada grid – grid yang kosong.
Musik.java
package bagus.map.v2;
import android.content.Context;
import android.media.MediaPlayer;
public class Musik {
private static MediaPlayer mp = null;
// stop musik dan mulai memainkan musik baru (bila di resource lebih dari satu)
public static void play(Context context, int resource) {
stop(context);
// play musik jika pada preferences tidak disabled
if (Prefs.getMusic(context)) {
mp = MediaPlayer.create(context, resource);
mp.setLooping(true);
mp.start();
}
}
// stop musik
public static void stop(Context context) {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
}
}
Merupakan file java yang menyimpan code program untuk memainkan musik ketika
memasuki mode permainan.
package bagus.map.v2;
import android.content.Context;
import android.content.SharedPreferences;
public class Pengaturan {
private static final String SUDOKU_OPTIONS = Sudoku.class.getName();
private static final String OPT_MUSIC = "music";
private static final boolean OPT_MUSIC_DEF = true;
private static final String OPT_HINTS = "hints";
private static final boolean OPT_HINTS_DEF = true;
private static SharedPreferences getSudokuPreferences(
Context context) {
return context.getSharedPreferences(SUDOKU_OPTIONS,
Context.MODE_PRIVATE);
}
public static boolean getMusic(Context context) {
return getSudokuPreferences(context).getBoolean(
OPT_MUSIC, OPT_MUSIC_DEF);
}
public static boolean getHints(Context context) {
return getSudokuPreferences(context).getBoolean(
OPT_HINTS, OPT_HINTS_DEF);
}
public static boolean putMusic(Context context, boolean value) {
return getSudokuPreferences(context)
.edit()
.putBoolean(OPT_MUSIC, value)
.commit();
}
public static boolean putHints(Context context, boolean value) {
return getSudokuPreferences(context)
.edit()
.putBoolean(OPT_HINTS, value)
.commit();
}
}
Merupakan file java yang menyimpan code program untuk pengaturan musik.
Prefs.java
package bagus.map.v2;
import android.content.Context;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
public class Prefs extends PreferenceActivity {
// opsi dan default values
private static final String OPT_MUSIC = "music";
private static final boolean OPT_MUSIC_DEF = true;
private static final String OPT_HINTS = "hints";
private static final boolean OPT_HINTS_DEF = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pengaturan);
}
// fungsi untuk mengambil value dari musik
public static boolean getMusic(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(OPT_MUSIC, OPT_MUSIC_DEF);
}
// fungsi untuk mengambil value dari hints
public static boolean getHints(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(OPT_HINTS, OPT_HINTS_DEF);
}
}
Merupakan kelas dengan fungsi untuk mengambil value dari musik dan hints
Puzzle.java
package bagus.map.v2;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AnimationUtils;
public class Puzzle extends View {
private static final String TAG = "Sudoku";
private static final String SELX = "selX";
private static final String SELY = "selY";
private static final String VIEW_STATE = "viewState";
private static final int ID = 42;
private float width;
private float height;
private int selX;
private int selY;
private final Rect selRect = new Rect();
private final Game game;
public Puzzle(Context context) {
super(context);
this.game = (Game) context;
setFocusable(true);
setFocusableInTouchMode(true);
// ...
setId(ID);
}
@Override
protected Parcelable onSaveInstanceState() {
Parcelable p = super.onSaveInstanceState();
Log.d(TAG, "onSaveInstanceState");
Bundle bundle = new Bundle();
bundle.putInt(SELX, selX);
bundle.putInt(SELY, selY);
bundle.putParcelable(VIEW_STATE, p);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
Log.d(TAG, "onRestoreInstanceState");
Bundle bundle = (Bundle) state;
select(bundle.getInt(SELX), bundle.getInt(SELY));
super.onRestoreInstanceState(bundle.getParcelable(VIEW_STATE));
return;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
width = w / 9f;
height = h / 9f;
getRect(selX, selY, selRect);
Log.d(TAG, "onSizeChanged: width " + width + ", height "
+ height);
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
// gambar background
Paint background = new Paint();
background.setColor(getResources().getColor(
R.color.puzzle_background));
canvas.drawRect(0, 0, getWidth(), getHeight(), background);
// Gambar board...
// mendefinisikan warna untuk setiap grid
Paint dark = new Paint();
dark.setColor(getResources().getColor(R.color.puzzle_dark));
Paint hilite = new Paint();
hilite.setColor(getResources().getColor(R.color.puzzle_hilite));
Paint light = new Paint();
light.setColor(getResources().getColor(R.color.puzzle_light));
for (int i = 0; i < 9; i++) {
canvas.drawLine(0, i * height, getWidth(), i * height,
light);
canvas.drawLine(0, i * height + 1, getWidth(), i * height
+ 1, hilite);
canvas.drawLine(i * width, 0, i * width, getHeight(),
light);
canvas.drawLine(i * width + 1, 0, i * width + 1,
getHeight(), hilite);
}
for (int i = 0; i < 9; i++) {
if (i % 3 != 0)
continue;
canvas.drawLine(0, i * height, getWidth(), i * height,
dark);
canvas.drawLine(0, i * height + 1, getWidth(), i * height
+ 1, hilite);
canvas.drawLine(i * width, 0, i * width, getHeight(), dark);
canvas.drawLine(i * width + 1, 0, i * width + 1,
getHeight(), hilite);
}
// gambar angka...
// mendefinisikan warna dan style untuk setiap angka
Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG);
foreground.setColor(getResources().getColor(
R.color.puzzle_foreground));
foreground.setStyle(Style.FILL);
foreground.setTextSize(height * 0.75f);
foreground.setTextScaleX(width / height);
foreground.setTextAlign(Paint.Align.CENTER);
FontMetrics fm = foreground.getFontMetrics();
float x = width / 2;
float y = height / 2 - (fm.ascent + fm.descent) / 2;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
canvas.drawText(this.game.getTileString(i, j), i
* width + x, j * height + y, foreground);
}
}
if (Prefs.getHints(getContext())) {
// gambar hints
Paint hint = new Paint();
int c[] = { getResources().getColor(R.color.puzzle_hint_0),
getResources().getColor(R.color.puzzle_hint_1),
getResources().getColor(R.color.puzzle_hint_2), };
Rect r = new Rect();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
int movesleft = 9 - game.getUsedTiles(i, j).length;
if (movesleft < c.length) {
getRect(i, j, r);
hint.setColor(c[movesleft]);
canvas.drawRect(r, hint);
}
}
}
}
Log.d(TAG, "selRect=" + selRect);
Paint selected = new Paint();
selected.setColor(getResources().getColor(
R.color.puzzle_selected));
canvas.drawRect(selRect, selected);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_DOWN)
return super.onTouchEvent(event);
select((int) (event.getX() / width),
(int) (event.getY() / height));
game.showKeypadOrError(selX, selY);
Log.d(TAG, "onTouchEvent: x " + selX + ", y " + selY);
return true;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.d(TAG, "onKeyDown: keycode=" + keyCode + ", event="
+ event);
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_UP:
select(selX, selY - 1);
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
select(selX, selY + 1);
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
select(selX - 1, selY);
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
select(selX + 1, selY);
break;
case KeyEvent.KEYCODE_0:
case KeyEvent.KEYCODE_SPACE: setSelectedTile(0); break;
case KeyEvent.KEYCODE_1: setSelectedTile(1); break;
case KeyEvent.KEYCODE_2: setSelectedTile(2); break;
case KeyEvent.KEYCODE_3: setSelectedTile(3); break;
case KeyEvent.KEYCODE_4: setSelectedTile(4); break;
case KeyEvent.KEYCODE_5: setSelectedTile(5); break;
case KeyEvent.KEYCODE_6: setSelectedTile(6); break;
case KeyEvent.KEYCODE_7: setSelectedTile(7); break;
case KeyEvent.KEYCODE_8: setSelectedTile(8); break;
case KeyEvent.KEYCODE_9: setSelectedTile(9); break;
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_DPAD_CENTER:
game.showKeypadOrError(selX, selY);
break;
default:
return super.onKeyDown(keyCode, event);
}
return true;
}
public void setSelectedTile(int tile) {
if (game.setTileIfValid(selX, selY, tile)) {
invalidate();
} else {
Log.d(TAG, "setSelectedTile: invalid: " + tile);
startAnimation(AnimationUtils.loadAnimation(game,
R.anim.shake));
}
}
private void select(int x, int y) {
invalidate(selRect);
selX = Math.min(Math.max(x, 0), 8);
selY = Math.min(Math.max(y, 0), 8);
getRect(selX, selY, selRect);
invalidate(selRect);
}
private void getRect(int x, int y, Rect rect) {
rect.set((int) (x * width), (int) (y * height), (int) (x
* width + width), (int) (y * height + height));
}
// ...
}
Merupakan file java yang menyimpan code program untuk mendefinisikan gambar board,
warna untuk setiap grid. Gambar angka, warna dan style untuk setiap angka. Dan juga
gambar hints.
Sudoku.java
package bagus.map.v2;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
public class Sudoku extends Activity implements OnClickListener {
private static final String TAG = "Sudoku";
// panggil activity saat pertama kali running
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View continueButton = findViewById(R.id.continue_button);
continueButton.setOnClickListener(this);
View newButton = findViewById(R.id.new_button);
newButton.setOnClickListener(this);
View aboutButton = findViewById(R.id.about_button);
aboutButton.setOnClickListener(this);
View exitButton = findViewById(R.id.exit_button);
exitButton.setOnClickListener(this);
}
@Override
protected void onResume() {
super.onResume();
/**Music.play(this, R.raw.main);**/
}
@Override
protected void onPause() {
super.onPause();
Musik.stop(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.continue_button:
startGame(Game.DIFFICULTY_CONTINUE);
break;
// ...
case R.id.about_button:
Intent i = new Intent(this, Tentang.class);
startActivity(i);
break;
case R.id.new_button:
openNewGameDialog();
break;
case R.id.exit_button:
finish();
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
startActivity(new Intent(this, Prefs.class));
return true;
}
return false;
}
private void openNewGameDialog() {
new AlertDialog.Builder(this)
.setTitle(R.string.lblMulaiBaruLevel)
.setItems(R.array.difficulty,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialoginterface,
int i) {
startGame(i);
}
})
.show();
}
private void startGame(int i) {
Log.d(TAG, "clicked on " + i);
Intent intent = new Intent(Sudoku.this, Game.class);
intent.putExtra(Game.KEY_DIFFICULTY, i);
startActivity(intent);
}
}
Merupakan file java yang menyimpan code program untuk mendefinisikan button pada
layout utama seperti “Lanjutkan”, “Mulai Baru”, “Tentang”, “Keluar”. Button “Lanjutkan”
akan melanjutkan program dengan mode permainan yang sudah ditentukan ketika pertama
memulai game. Button “Mulai Baru” akan mengarahkan user pada mode permainan awal
yang juga menentukan tingkat kesulitan sudoku. Button “Tentang” akan menampilkan
layout tentang game dan pembuatnya. Button “Keluar” akan mengarahkan user keluar dari
game.
keypad.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keypad"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:stretchColumns="*">
<TableRow>
<Button android:id="@+id/keypad_1"
android:text="1">
</Button>
<Button android:id="@+id/keypad_2"
android:text="2">
</Button>
<Button android:id="@+id/keypad_3"
android:text="3">
</Button>
</TableRow>
<TableRow>
<Button android:id="@+id/keypad_4"
android:text="4">
</Button>
<Button android:id="@+id/keypad_5"
android:text="5">
</Button>
<Button android:id="@+id/keypad_6"
android:text="6">
</Button>
</TableRow>
<TableRow>
<Button android:id="@+id/keypad_7"
android:text="7">
</Button>
<Button android:id="@+id/keypad_8"
android:text="8">
</Button>
<Button android:id="@+id/keypad_9"
android:text="9">
</Button>
</TableRow>
</TableLayout>
File ini menyimpan informasi mengenai pembuatan keypad sudoku
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@drawable/depan"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:padding="30dip"
android:orientation="horizontal">
<LinearLayout
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_gravity="center">
<TextView
android:text="@string/mainApp"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="165dip"
android:textSize="24.5sp" />
<Button
android:id="@+id/continue_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/lblLanjutkan" />
<Button
android:id="@+id/new_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/lblMulaiBaru" />
<Button
android:id="@+id/about_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/lblTentang" />
<Button
android:id="@+id/exit_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/lblKeluar" />
</LinearLayout>
</LinearLayout>
File ini menyimpan informasi mengenai pembuatan layout utama pada program.
Tentang.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip">
<TextView
android:id="@+id/about_content"
android:layout_width="wrap_content"
android:layout_height="117dp"
android:text="@string/lblTentangStr" />
</ScrollView>
File yang menyimpan informasi penentuan tampilan apa yang akan ditampilkan ketika user
menekan button “Tentang”.
Output :
Layout utama
Layout tentang permainan
Tampilan pilihan tingkatan ketika memulai game
Tampilan permainan sudoku tingkat mudah
Tampilan ketika permainan sudoku tingkat mudah berhasil di selesaikan
Sekian. Untuk lebih jelasnya, saya sertakan juga source code dari game ini.

More Related Content

PDF
Java AWT Calculadora
PDF
Bài tập tuần 2
PDF
RIA - Entwicklung mit Ext JS
PDF
Ejercicios resueltos Practica 4 informatica II
PDF
Writeup ctf online idsecconf 2017
PDF
RxJava, Getting Started - David Wursteisen - 16 Octobre 2014
PDF
Java term project final
PDF
Luong giac chuong 7
Java AWT Calculadora
Bài tập tuần 2
RIA - Entwicklung mit Ext JS
Ejercicios resueltos Practica 4 informatica II
Writeup ctf online idsecconf 2017
RxJava, Getting Started - David Wursteisen - 16 Octobre 2014
Java term project final
Luong giac chuong 7

What's hot (15)

PDF
Quicksort: illustrated step-by-step walk through
PDF
Www.mathvn.com bt-mu logarit-mathvn.com
PPT
Handbook - From jQuery to YUI 3
DOC
Pogram menghitung bangun datar dan ruang dengan java
PDF
Informática ii ejercicios resueltos - practica 3
TXT
PDF
ゲーム理論BASIC 第28回 - 交渉ゲーム : 4つの公理とナッシュ交渉解-
DOCX
Sistema de ecuaciones no lineales
PDF
Chuong13
PDF
Bai tap tham khao CSPE
PDF
Вы ещё пишете код руками? Тогда мы идём к вам! - Сергей Садовников
PPT
Toan 1 bai_05_đạo hàm - bookbooming
PDF
Luonggiac chuong3
DOC
Baitap ktlt code
PDF
Luonggiac chuong4
Quicksort: illustrated step-by-step walk through
Www.mathvn.com bt-mu logarit-mathvn.com
Handbook - From jQuery to YUI 3
Pogram menghitung bangun datar dan ruang dengan java
Informática ii ejercicios resueltos - practica 3
ゲーム理論BASIC 第28回 - 交渉ゲーム : 4つの公理とナッシュ交渉解-
Sistema de ecuaciones no lineales
Chuong13
Bai tap tham khao CSPE
Вы ещё пишете код руками? Тогда мы идём к вам! - Сергей Садовников
Toan 1 bai_05_đạo hàm - bookbooming
Luonggiac chuong3
Baitap ktlt code
Luonggiac chuong4
Ad

Viewers also liked (13)

PPS
Mural Art Presentation
PDF
RESUME_PINKESH_ANAND
PPTX
Are Saunas Good for You?
PDF
GPC presentation
PPTX
COMPARATIVE ANALYSIS OF 2 BUSINESS
PDF
Business report (Charity Drive)
PPSX
Instructable
DOCX
Psychology journal
DOCX
COMPARATIVE ANALYSIS OF 2 RESTAURANTS REPORT
DOCX
Financial Ratio Analysis
DOCX
English 2 Compare and Contrast Essay
PPTX
Business Plan Presentation
PPTX
SUSTAINABLE WASTE WATER TREATMENT
Mural Art Presentation
RESUME_PINKESH_ANAND
Are Saunas Good for You?
GPC presentation
COMPARATIVE ANALYSIS OF 2 BUSINESS
Business report (Charity Drive)
Instructable
Psychology journal
COMPARATIVE ANALYSIS OF 2 RESTAURANTS REPORT
Financial Ratio Analysis
English 2 Compare and Contrast Essay
Business Plan Presentation
SUSTAINABLE WASTE WATER TREATMENT
Ad

Recently uploaded (7)

PPTX
Coklat Beige Ilustrasi 3 Dimensi Tugas Kelompok Presentasi.pptx
PDF
Materi seni rupa untuk sekolah dasar materi tentang seni rupa
PDF
15 AUG 2025 PS 15 AUG 2025 PS 15 AUG 2025 PS
PDF
ಶ್ರೀ ಕ್ಷೇತ್ರ ಚಂಪಕಧಾಮ ಸ್ವಾಮಿ ದೇವಾಲಯSri Kshetra Champakadham Swamy Temple
PPTX
Tahfidz Qur’an TIMING tampa musik bagian 2.pptx
PDF
فورمولر عمومی مضمون فزیک برای همه انجنیران
PPTX
science grade 7 quiz_Scientific Method.pptx
Coklat Beige Ilustrasi 3 Dimensi Tugas Kelompok Presentasi.pptx
Materi seni rupa untuk sekolah dasar materi tentang seni rupa
15 AUG 2025 PS 15 AUG 2025 PS 15 AUG 2025 PS
ಶ್ರೀ ಕ್ಷೇತ್ರ ಚಂಪಕಧಾಮ ಸ್ವಾಮಿ ದೇವಾಲಯSri Kshetra Champakadham Swamy Temple
Tahfidz Qur’an TIMING tampa musik bagian 2.pptx
فورمولر عمومی مضمون فزیک برای همه انجنیران
science grade 7 quiz_Scientific Method.pptx

Makalah game sudoku

  • 1. UNIVERSITAS GUNADARMA FAKULTAS TEKNOLOGI INDUSTRI MANUAL BOOK PERMAINAN SIMPLY SUDOKU Disusun Oleh : Nama : Bagus Prayogo NPM : 51412349 Kelas : 3IA24 Jurusan : Teknik Informatika Dosen : Anita Sari Apriliani Ditulis sebagai salah satu syarat kelulusan Mata Kuliah Softskill “Pengantar Teknologi Game” LABORATORIUM INFORMATIKA UNIVERSITAS GUNADARMA 2015
  • 2. Untuk membuat game, yang dilakukan pertama adalah menjalankan eclipse. Pastikan sudah menginstal android sdk yang dibutuhkan untuk membuat program android dan pada eclipse sudah terinstal ADT(Android Development Tools). Kita bisa memulainya dengan klik file - new – android application project , lalu tentukan nama aplikasi, nama project, nama package, serta minimum required, target sdk, sdk untuk mengcompile serta tema aplikasi. Jika sudah, tekan next saja hingga finish. Berikut File – File yang di butuhkan program permainan simply sudoku : Game.java package bagus.map.v2; 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 = "my.difficulty"; private static final String PREF_PUZZLE = "puzzle" ; public static final int DIFFICULTY_EASY = 0; public static final int DIFFICULTY_MEDIUM = 1; public static final int DIFFICULTY_HARD = 2; protected static final int DIFFICULTY_CONTINUE = -1; private int puzzle[] = new int[9 * 9]; // ini adalah nilai dari blok 9 x 9, edit dengan sangat hati-hati private final String easyPuzzle = "360000000004230800000004200" + "070460003820000014500013020" + "001900000007048300000000045"; private final String mediumPuzzle = "650000070000506000014000005" + "007009000002314700000700800" + "500000630000201000030000097"; private final String hardPuzzle = "009000000080605020501078000" + "000000700706040102004000000" + "000720903090301080000000600"; private Puzzle puzzleView;
  • 3. @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 Puzzle(this); setContentView(puzzleView); puzzleView.requestFocus(); // Jika activity di-restart, maka akan dilanjutkan sesuai dengan activity terakhir getIntent().putExtra(KEY_DIFFICULTY, DIFFICULTY_CONTINUE); } @Override protected void onResume() { super.onResume(); Musik.play(this, R.raw.game); } @Override protected void onPause() { super.onPause(); Log.d(TAG, "onPause"); Musik.stop(this); // ini adalah untuk menyimpan sususan puzzle getPreferences(MODE_PRIVATE).edit().putString(PREF_PUZZLE, toPuzzleString(puzzle)).commit(); } // ini adalah blok kondisi permainan sudoku private int[] getPuzzle(int diff) { String puz; switch (diff) { case DIFFICULTY_CONTINUE: puz = getPreferences(MODE_PRIVATE).getString(PREF_PUZZLE, easyPuzzle); break; // ... case DIFFICULTY_HARD: puz = hardPuzzle; break; case DIFFICULTY_MEDIUM: puz = mediumPuzzle; break; case DIFFICULTY_EASY: default: puz = easyPuzzle; break;
  • 4. } return fromPuzzleString(puz); } // ini blok yang akan mengkonversi nilai array ke dalam string puzzle static private String toPuzzleString(int[] puz) { StringBuilder buf = new StringBuilder(); for (int element : puz) { buf.append(element); } return buf.toString(); } // ini blok yang akan mengkonversi value dari string puzzle ke dalam 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; } // mengembalikan nilai pada tiap tile sesuai dengan nilai koordinat private int getTile(int x, int y) { return puzzle[y * 9 + x]; } // merubah tile berdasarkan koordinat private void setTile(int x, int y, int value) { puzzle[y * 9 + x] = value; } // mengembalikan string untuk tile berdasarkan koordinat protected String getTileString(int x, int y) { int v = getTile(x, y); if (v == 0) return ""; else return String.valueOf(v); } // mengganti tile jika movement benar 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; } // membuka popup keypad jika values isian pada tile koordinat benar protected void showKeypadOrError(int x, int y) { int tiles[] = getUsedTiles(x, y); if (tiles.length == 9) { Toast toast = Toast.makeText(this, R.string.lblCobaLagi, Toast.LENGTH_SHORT);
  • 5. 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(); } } // simpan cache tile private final int used[][][] = new int[9][9][]; // mengembalikan cache tile berdasarkan koordinat protected int[] getUsedTiles(int x, int y) { return used[x][y]; } 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])); } } } 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; } 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; } } int nused = 0; for (int t : c) { if (t != 0) nused++; } int c1[] = new int[nused];
  • 6. nused = 0; for (int t : c) { if (t != 0) c1[nused++] = t; } return c1; } } Merupakan file java yang menyimpan code program untuk mendefinisikan sudoku dengan blok 9x9 beserta fungsinya. Kelas ini yang juga menentukan tingkat kesulitan sudoku. Keypad.java package bagus.map.v2; import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; public class Keypad extends Dialog { protected static final String TAG = "Sudoku"; private final View keys[] = new View[9]; private View keypad; private final int useds[]; private final Puzzle puzzleView; public Keypad(Context context, int useds[], Puzzle puzzleView) { super(context); this.useds = useds; this.puzzleView = puzzleView; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTitle(R.string.lblKeypad); setContentView(R.layout.keypad); findViews(); for (int element : useds) { if (element != 0) keys[element - 1].setVisibility(View.INVISIBLE); } setListeners(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { int tile = 0; switch (keyCode) { case KeyEvent.KEYCODE_0: case KeyEvent.KEYCODE_SPACE: tile = 0; break; case KeyEvent.KEYCODE_1: tile = 1; break;
  • 7. case KeyEvent.KEYCODE_2: tile = 2; break; case KeyEvent.KEYCODE_3: tile = 3; break; case KeyEvent.KEYCODE_4: tile = 4; break; case KeyEvent.KEYCODE_5: tile = 5; break; case KeyEvent.KEYCODE_6: tile = 6; break; case KeyEvent.KEYCODE_7: tile = 7; break; case KeyEvent.KEYCODE_8: tile = 8; break; case KeyEvent.KEYCODE_9: tile = 9; break; default: return super.onKeyDown(keyCode, event); } if (isValid(tile)) { returnResult(tile); } return true; } // mengembalikan tile berdasakan parameter yang dipanggil private void returnResult(int tile) { puzzleView.setSelectedTile(tile); dismiss(); } private boolean isValid(int tile) { for (int t : useds) { if (tile == t) return false; } return true; } private void findViews() { keypad = findViewById(R.id.keypad); keys[0] = findViewById(R.id.keypad_1); keys[1] = findViewById(R.id.keypad_2); keys[2] = findViewById(R.id.keypad_3); keys[3] = findViewById(R.id.keypad_4); keys[4] = findViewById(R.id.keypad_5); keys[5] = findViewById(R.id.keypad_6); keys[6] = findViewById(R.id.keypad_7); keys[7] = findViewById(R.id.keypad_8); keys[8] = findViewById(R.id.keypad_9); } private void setListeners() { for (int i = 0; i < keys.length; i++) { final int t = i + 1; keys[i].setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { returnResult(t); }}); } keypad.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { returnResult(0); }}); } } Merupakan file java yang menyimpan code program untuk mendefinisikan keypad yang di gunakan user untuk menginput nilai pada grid – grid yang kosong.
  • 8. Musik.java package bagus.map.v2; import android.content.Context; import android.media.MediaPlayer; public class Musik { private static MediaPlayer mp = null; // stop musik dan mulai memainkan musik baru (bila di resource lebih dari satu) public static void play(Context context, int resource) { stop(context); // play musik jika pada preferences tidak disabled if (Prefs.getMusic(context)) { mp = MediaPlayer.create(context, resource); mp.setLooping(true); mp.start(); } } // stop musik public static void stop(Context context) { if (mp != null) { mp.stop(); mp.release(); mp = null; } } } Merupakan file java yang menyimpan code program untuk memainkan musik ketika memasuki mode permainan. package bagus.map.v2; import android.content.Context; import android.content.SharedPreferences; public class Pengaturan { private static final String SUDOKU_OPTIONS = Sudoku.class.getName(); private static final String OPT_MUSIC = "music"; private static final boolean OPT_MUSIC_DEF = true;
  • 9. private static final String OPT_HINTS = "hints"; private static final boolean OPT_HINTS_DEF = true; private static SharedPreferences getSudokuPreferences( Context context) { return context.getSharedPreferences(SUDOKU_OPTIONS, Context.MODE_PRIVATE); } public static boolean getMusic(Context context) { return getSudokuPreferences(context).getBoolean( OPT_MUSIC, OPT_MUSIC_DEF); } public static boolean getHints(Context context) { return getSudokuPreferences(context).getBoolean( OPT_HINTS, OPT_HINTS_DEF); } public static boolean putMusic(Context context, boolean value) { return getSudokuPreferences(context) .edit() .putBoolean(OPT_MUSIC, value) .commit(); } public static boolean putHints(Context context, boolean value) { return getSudokuPreferences(context) .edit() .putBoolean(OPT_HINTS, value) .commit(); } } Merupakan file java yang menyimpan code program untuk pengaturan musik. Prefs.java package bagus.map.v2; import android.content.Context; import android.os.Bundle; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; public class Prefs extends PreferenceActivity { // opsi dan default values private static final String OPT_MUSIC = "music"; private static final boolean OPT_MUSIC_DEF = true; private static final String OPT_HINTS = "hints"; private static final boolean OPT_HINTS_DEF = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.pengaturan); }
  • 10. // fungsi untuk mengambil value dari musik public static boolean getMusic(Context context) { return PreferenceManager.getDefaultSharedPreferences(context) .getBoolean(OPT_MUSIC, OPT_MUSIC_DEF); } // fungsi untuk mengambil value dari hints public static boolean getHints(Context context) { return PreferenceManager.getDefaultSharedPreferences(context) .getBoolean(OPT_HINTS, OPT_HINTS_DEF); } } Merupakan kelas dengan fungsi untuk mengambil value dari musik dan hints Puzzle.java package bagus.map.v2; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Paint.FontMetrics; import android.graphics.Paint.Style; import android.os.Bundle; import android.os.Parcelable; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.animation.AnimationUtils; public class Puzzle extends View { private static final String TAG = "Sudoku"; private static final String SELX = "selX"; private static final String SELY = "selY"; private static final String VIEW_STATE = "viewState"; private static final int ID = 42; private float width; private float height; private int selX; private int selY; private final Rect selRect = new Rect(); private final Game game; public Puzzle(Context context) { super(context);
  • 11. this.game = (Game) context; setFocusable(true); setFocusableInTouchMode(true); // ... setId(ID); } @Override protected Parcelable onSaveInstanceState() { Parcelable p = super.onSaveInstanceState(); Log.d(TAG, "onSaveInstanceState"); Bundle bundle = new Bundle(); bundle.putInt(SELX, selX); bundle.putInt(SELY, selY); bundle.putParcelable(VIEW_STATE, p); return bundle; } @Override protected void onRestoreInstanceState(Parcelable state) { Log.d(TAG, "onRestoreInstanceState"); Bundle bundle = (Bundle) state; select(bundle.getInt(SELX), bundle.getInt(SELY)); super.onRestoreInstanceState(bundle.getParcelable(VIEW_STATE)); return; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { width = w / 9f; height = h / 9f; getRect(selX, selY, selRect); Log.d(TAG, "onSizeChanged: width " + width + ", height " + height); super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onDraw(Canvas canvas) { // gambar background Paint background = new Paint(); background.setColor(getResources().getColor( R.color.puzzle_background)); canvas.drawRect(0, 0, getWidth(), getHeight(), background); // Gambar board... // mendefinisikan warna untuk setiap grid Paint dark = new Paint(); dark.setColor(getResources().getColor(R.color.puzzle_dark)); Paint hilite = new Paint(); hilite.setColor(getResources().getColor(R.color.puzzle_hilite)); Paint light = new Paint(); light.setColor(getResources().getColor(R.color.puzzle_light)); for (int i = 0; i < 9; i++) { canvas.drawLine(0, i * height, getWidth(), i * height, light);
  • 12. canvas.drawLine(0, i * height + 1, getWidth(), i * height + 1, hilite); canvas.drawLine(i * width, 0, i * width, getHeight(), light); canvas.drawLine(i * width + 1, 0, i * width + 1, getHeight(), hilite); } for (int i = 0; i < 9; i++) { if (i % 3 != 0) continue; canvas.drawLine(0, i * height, getWidth(), i * height, dark); canvas.drawLine(0, i * height + 1, getWidth(), i * height + 1, hilite); canvas.drawLine(i * width, 0, i * width, getHeight(), dark); canvas.drawLine(i * width + 1, 0, i * width + 1, getHeight(), hilite); } // gambar angka... // mendefinisikan warna dan style untuk setiap angka Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG); foreground.setColor(getResources().getColor( R.color.puzzle_foreground)); foreground.setStyle(Style.FILL); foreground.setTextSize(height * 0.75f); foreground.setTextScaleX(width / height); foreground.setTextAlign(Paint.Align.CENTER); FontMetrics fm = foreground.getFontMetrics(); float x = width / 2; float y = height / 2 - (fm.ascent + fm.descent) / 2; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { canvas.drawText(this.game.getTileString(i, j), i * width + x, j * height + y, foreground); } } if (Prefs.getHints(getContext())) { // gambar hints Paint hint = new Paint(); int c[] = { getResources().getColor(R.color.puzzle_hint_0), getResources().getColor(R.color.puzzle_hint_1), getResources().getColor(R.color.puzzle_hint_2), }; Rect r = new Rect(); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { int movesleft = 9 - game.getUsedTiles(i, j).length; if (movesleft < c.length) { getRect(i, j, r); hint.setColor(c[movesleft]); canvas.drawRect(r, hint); } } } }
  • 13. Log.d(TAG, "selRect=" + selRect); Paint selected = new Paint(); selected.setColor(getResources().getColor( R.color.puzzle_selected)); canvas.drawRect(selRect, selected); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() != MotionEvent.ACTION_DOWN) return super.onTouchEvent(event); select((int) (event.getX() / width), (int) (event.getY() / height)); game.showKeypadOrError(selX, selY); Log.d(TAG, "onTouchEvent: x " + selX + ", y " + selY); return true; } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.d(TAG, "onKeyDown: keycode=" + keyCode + ", event=" + event); switch (keyCode) { case KeyEvent.KEYCODE_DPAD_UP: select(selX, selY - 1); break; case KeyEvent.KEYCODE_DPAD_DOWN: select(selX, selY + 1); break; case KeyEvent.KEYCODE_DPAD_LEFT: select(selX - 1, selY); break; case KeyEvent.KEYCODE_DPAD_RIGHT: select(selX + 1, selY); break; case KeyEvent.KEYCODE_0: case KeyEvent.KEYCODE_SPACE: setSelectedTile(0); break; case KeyEvent.KEYCODE_1: setSelectedTile(1); break; case KeyEvent.KEYCODE_2: setSelectedTile(2); break; case KeyEvent.KEYCODE_3: setSelectedTile(3); break; case KeyEvent.KEYCODE_4: setSelectedTile(4); break; case KeyEvent.KEYCODE_5: setSelectedTile(5); break; case KeyEvent.KEYCODE_6: setSelectedTile(6); break; case KeyEvent.KEYCODE_7: setSelectedTile(7); break; case KeyEvent.KEYCODE_8: setSelectedTile(8); break; case KeyEvent.KEYCODE_9: setSelectedTile(9); break; case KeyEvent.KEYCODE_ENTER: case KeyEvent.KEYCODE_DPAD_CENTER: game.showKeypadOrError(selX, selY); break; default: return super.onKeyDown(keyCode, event); } return true; } public void setSelectedTile(int tile) { if (game.setTileIfValid(selX, selY, tile)) { invalidate(); } else { Log.d(TAG, "setSelectedTile: invalid: " + tile);
  • 14. startAnimation(AnimationUtils.loadAnimation(game, R.anim.shake)); } } private void select(int x, int y) { invalidate(selRect); selX = Math.min(Math.max(x, 0), 8); selY = Math.min(Math.max(y, 0), 8); getRect(selX, selY, selRect); invalidate(selRect); } private void getRect(int x, int y, Rect rect) { rect.set((int) (x * width), (int) (y * height), (int) (x * width + width), (int) (y * height + height)); } // ... } Merupakan file java yang menyimpan code program untuk mendefinisikan gambar board, warna untuk setiap grid. Gambar angka, warna dan style untuk setiap angka. Dan juga gambar hints. Sudoku.java package bagus.map.v2; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; public class Sudoku extends Activity implements OnClickListener { private static final String TAG = "Sudoku"; // panggil activity saat pertama kali running @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); View continueButton = findViewById(R.id.continue_button); continueButton.setOnClickListener(this); View newButton = findViewById(R.id.new_button); newButton.setOnClickListener(this); View aboutButton = findViewById(R.id.about_button); aboutButton.setOnClickListener(this); View exitButton = findViewById(R.id.exit_button);
  • 15. exitButton.setOnClickListener(this); } @Override protected void onResume() { super.onResume(); /**Music.play(this, R.raw.main);**/ } @Override protected void onPause() { super.onPause(); Musik.stop(this); } public void onClick(View v) { switch (v.getId()) { case R.id.continue_button: startGame(Game.DIFFICULTY_CONTINUE); break; // ... case R.id.about_button: Intent i = new Intent(this, Tentang.class); startActivity(i); break; case R.id.new_button: openNewGameDialog(); break; case R.id.exit_button: finish(); break; } } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.settings: startActivity(new Intent(this, Prefs.class)); return true; } return false; } private void openNewGameDialog() { new AlertDialog.Builder(this) .setTitle(R.string.lblMulaiBaruLevel) .setItems(R.array.difficulty,
  • 16. new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { startGame(i); } }) .show(); } private void startGame(int i) { Log.d(TAG, "clicked on " + i); Intent intent = new Intent(Sudoku.this, Game.class); intent.putExtra(Game.KEY_DIFFICULTY, i); startActivity(intent); } } Merupakan file java yang menyimpan code program untuk mendefinisikan button pada layout utama seperti “Lanjutkan”, “Mulai Baru”, “Tentang”, “Keluar”. Button “Lanjutkan” akan melanjutkan program dengan mode permainan yang sudah ditentukan ketika pertama memulai game. Button “Mulai Baru” akan mengarahkan user pada mode permainan awal yang juga menentukan tingkat kesulitan sudoku. Button “Tentang” akan menampilkan layout tentang game dan pembuatnya. Button “Keluar” akan mengarahkan user keluar dari game. keypad.xml <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/keypad" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:stretchColumns="*"> <TableRow> <Button android:id="@+id/keypad_1" android:text="1"> </Button> <Button android:id="@+id/keypad_2" android:text="2"> </Button> <Button android:id="@+id/keypad_3" android:text="3"> </Button> </TableRow> <TableRow> <Button android:id="@+id/keypad_4" android:text="4"> </Button> <Button android:id="@+id/keypad_5" android:text="5"> </Button> <Button android:id="@+id/keypad_6" android:text="6"> </Button> </TableRow> <TableRow> <Button android:id="@+id/keypad_7" android:text="7"> </Button> <Button android:id="@+id/keypad_8"
  • 17. android:text="8"> </Button> <Button android:id="@+id/keypad_9" android:text="9"> </Button> </TableRow> </TableLayout> File ini menyimpan informasi mengenai pembuatan keypad sudoku main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/depan" android:layout_height="fill_parent" android:layout_width="fill_parent" android:padding="30dip" android:orientation="horizontal"> <LinearLayout android:orientation="vertical" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_gravity="center"> <TextView android:text="@string/mainApp" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_gravity="center" android:layout_marginTop="165dip" android:textSize="24.5sp" /> <Button android:id="@+id/continue_button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/lblLanjutkan" /> <Button android:id="@+id/new_button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/lblMulaiBaru" /> <Button android:id="@+id/about_button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/lblTentang" /> <Button android:id="@+id/exit_button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/lblKeluar" /> </LinearLayout> </LinearLayout> File ini menyimpan informasi mengenai pembuatan layout utama pada program. Tentang.xml <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10dip"> <TextView android:id="@+id/about_content" android:layout_width="wrap_content"
  • 18. android:layout_height="117dp" android:text="@string/lblTentangStr" /> </ScrollView> File yang menyimpan informasi penentuan tampilan apa yang akan ditampilkan ketika user menekan button “Tentang”. Output : Layout utama
  • 20. Tampilan pilihan tingkatan ketika memulai game
  • 21. Tampilan permainan sudoku tingkat mudah
  • 22. Tampilan ketika permainan sudoku tingkat mudah berhasil di selesaikan Sekian. Untuk lebih jelasnya, saya sertakan juga source code dari game ini.