Blog Tutorial Android Bagi Pemula

Monday, January 17, 2022

Membuat Game Android Tic Tac Toe Menggunakan Java

Selamat malam sobat koding sekalian! Lama sekali tidak posting karena kesibukan yang menumpuk. Pada postingan ini saya akan berbagi sebuah game sederhana, yaitu game Tic Tac Toe atau silang-bulat-silang dalam versi bahasa Indonesia, menggunakan Android Studio dengan bahasa Java. Bagi yang belum tahu bagaimana cara bermain game ini bisa melihat di Wikipedia.

Making android Tic Tac Toe game
Gambar 1 : Permainan Tic Tac Toe

Baik, tidak berlama-lama kita mulai langsung dengan membuat sebuah project empty activity baru pada android studio, dalam contoh ini saya berikan nama Tic Tac Toe (com.gwnbs.tictactoe). Karena ini sederhana, kita tidak menambahkan apapun di luar android studio, alias android studio apa adanya.

Kita langsung menambahkan komponen-komponen xml di dalam activity_main.xml, sembilan tombol (Button) utama untuk bermain game Tic Tac Toe dan beberapa komponen tambahan. Seperti berikut isinya :

activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:id="@+id/playerOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Player One"
android:textStyle="bold"
android:layout_marginTop="5dp"
android:layout_marginStart="15dp"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>

<TextView
android:id="@+id/playerOneScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:layout_marginStart="40dp"
android:textSize="25sp"
app:layout_constraintStart_toStartOf="@id/playerOne"
app:layout_constraintTop_toBottomOf="@id/playerOne"/>

<TextView
android:id="@+id/playerTwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Player Two"
android:textStyle="bold"
android:layout_marginTop="5dp"
android:layout_marginEnd="15dp"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>

<TextView
android:id="@+id/playerTwoScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:layout_marginEnd="40dp"
android:textSize="25sp"
app:layout_constraintEnd_toEndOf="@id/playerTwo"
app:layout_constraintTop_toBottomOf="@id/playerTwo"/>

<TextView
android:id="@+id/playerStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textAlignment="center"
android:layout_marginTop="20dp"
app:layout_constraintTop_toBottomOf="@id/playerOneScore"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>

<Button
android:id="@+id/btn_0"
android:layout_width="135dp"
android:layout_height="135dp"
android:textSize="60sp"
android:textStyle="bold"
android:backgroundTint="#413F43"
android:textColor="#ffffff"
app:layout_constraintTop_toBottomOf="@id/playerStatus"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_1"
android:layout_marginTop="20dp"/>

<Button
android:id="@+id/btn_1"
android:layout_width="135dp"
android:layout_height="135dp"
android:textSize="60sp"
android:textStyle="bold"
android:backgroundTint="#413F43"
android:textColor="#ffffff"
app:layout_constraintTop_toTopOf="@id/btn_0"
app:layout_constraintStart_toEndOf="@+id/btn_0"
app:layout_constraintEnd_toStartOf="@id/btn_2"/>

<Button
android:id="@+id/btn_2"
android:layout_width="135dp"
android:layout_height="135dp"
android:textSize="60sp"
android:textStyle="bold"
android:backgroundTint="#413F43"
android:textColor="#ffffff"
app:layout_constraintTop_toTopOf="@id/btn_1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_1"/>

<Button
android:id="@+id/btn_3"
android:layout_width="135dp"
android:layout_height="135dp"
android:textSize="60sp"
android:textStyle="bold"
android:backgroundTint="#413F43"
android:textColor="#ffffff"
app:layout_constraintEnd_toStartOf="@+id/btn_4"
app:layout_constraintTop_toBottomOf="@id/btn_0"
app:layout_constraintStart_toStartOf="parent"/>

<Button
android:id="@+id/btn_4"
android:layout_width="135dp"
android:layout_height="135dp"
android:textSize="60sp"
android:textStyle="bold"
android:backgroundTint="#413F43"
android:textColor="#ffffff"
app:layout_constraintTop_toTopOf="@id/btn_3"
app:layout_constraintStart_toEndOf="@+id/btn_3"
app:layout_constraintEnd_toStartOf="@id/btn_5"/>

<Button
android:id="@+id/btn_5"
android:layout_width="135dp"
android:layout_height="135dp"
android:textSize="60sp"
android:textStyle="bold"
android:backgroundTint="#413F43"
android:textColor="#ffffff"
app:layout_constraintTop_toTopOf="@id/btn_4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_4"/>

<Button
android:id="@+id/btn_6"
android:layout_width="135dp"
android:layout_height="135dp"
android:textSize="60sp"
android:textStyle="bold"
android:backgroundTint="#413F43"
android:textColor="#ffffff"
app:layout_constraintEnd_toStartOf="@+id/btn_1"
app:layout_constraintTop_toBottomOf="@id/btn_3"
app:layout_constraintStart_toStartOf="parent"/>

<Button
android:id="@+id/btn_7"
android:layout_width="135dp"
android:layout_height="135dp"
android:textSize="60sp"
android:textStyle="bold"
android:backgroundTint="#413F43"
android:textColor="#ffffff"
app:layout_constraintTop_toTopOf="@id/btn_6"
app:layout_constraintStart_toEndOf="@+id/btn_6"
app:layout_constraintEnd_toStartOf="@id/btn_8"/>

<Button
android:id="@+id/btn_8"
android:layout_width="135dp"
android:layout_height="135dp"
android:textSize="60sp"
android:textStyle="bold"
android:backgroundTint="#413F43"
android:textColor="#ffffff"
app:layout_constraintTop_toTopOf="@id/btn_7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_7"/>

<Button
android:id="@+id/resetGame"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:text="Reset Game"
android:textColor="#ffffff"
android:backgroundTint="#E1470D"
android:textStyle="bold"
app:layout_constraintTop_toBottomOf="@id/btn_6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>


Pada file diatas kita memiliki 5 komponen TextView untuk update skor, 9 Button untuk bermain dan 1 Button untuk mereset permainan. Lanjut pada koding java di MainActivity.java, tidak perlu panjang lebar berikut isi selengkapnya dari file ini.

MainActivity.java :
package com.gwnbs.tictactoe;

import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

//Global Variable
private TextView playerOneScore, playerTwoScore, playerStatus;
private final Button[] buttons = new Button[9];
private Button resetGame;
private int playerOneScoreCount, playerTwoScoreCount, rountCount;
private boolean activePlayer;
private boolean chooseSign = true;
private String playerOneSign, playerTwoSign;

//P1 => 0, P2 => 1, empty => 2
int[] gameState = {2, 2, 2, 2, 2, 2, 2, 2, 2};

//Posisi menang (mendatar menurun dan diagonal)
int[][] winningPositions = {
{0, 1, 2}, {3, 4, 5}, {6, 7, 8},
{0, 3, 6}, {1, 4, 7}, {2, 5, 8},
{0, 4, 8}, {2, 4, 6}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//inisialiasi id
playerOneScore = findViewById(R.id.playerOneScore);
playerTwoScore = findViewById(R.id.playerTwoScore);
playerStatus = findViewById(R.id.playerStatus);
resetGame = findViewById(R.id.resetGame);

if (chooseSign) dialogChooseSide();
else startGame();

}

private void dialogChooseSide() {
AlertDialog.Builder chooseSideDialog = new AlertDialog.Builder(this);
chooseSideDialog.setCancelable(false);
chooseSideDialog.setTitle("Choose your side");
chooseSideDialog.setPositiveButton("X", (dialogInterface, i) ->
readyToPlay(dialogInterface, "X", "O"));
chooseSideDialog.setNegativeButton("O", (dialogInterface, i) ->
readyToPlay(dialogInterface, "O", "X"));
chooseSideDialog.create().show();
}

private void readyToPlay(DialogInterface dialogInterface, String signOne, String signTwo) {
dialogInterface.dismiss();
playerOneSign = signOne;
playerTwoSign = signTwo;
chooseSign = false;
startGame();
}

private void startGame() {
for (int i = 0; i < buttons.length; i++) {
String buttonID = "btn_" + i;
int resourceID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[i] = findViewById(resourceID);
buttons[i].setOnClickListener(this);
}

rountCount = 0;
playerOneScoreCount = 0;
playerTwoScoreCount = 0;
activePlayer = true;
}

@SuppressLint("SetTextI18n")
@Override
public void onClick(View v) {
if (!((Button) v).getText().toString().equals("")) {
return;
}
String buttonID = v.getResources().getResourceEntryName(v.getId());
int gameStatePointer = Integer.parseInt(buttonID.substring(buttonID.length() - 1//buttonID.length()
));

if (activePlayer) {
((Button) v).setText(playerOneSign);
((Button) v).setTextColor(Color.parseColor("#FFC34A"));
gameState[gameStatePointer] = 0;
} else {
((Button) v).setText(playerTwoSign);
((Button) v).setTextColor(Color.parseColor("#70FFEA"));
gameState[gameStatePointer] = 1;
}
rountCount++;

if (checkWinner()) {
if (activePlayer) {
playerOneScoreCount++;
updatePlayerScore();
Toast.makeText(this, "Player One Won!", Toast.LENGTH_SHORT).show();
} else {
playerTwoScoreCount++;
updatePlayerScore();
Toast.makeText(this, "Player Two Won!", Toast.LENGTH_SHORT).show();
}
playAgain();
} else if (rountCount == 9) {
playAgain();
Toast.makeText(this, "No winner!", Toast.LENGTH_SHORT).show();
} else {
activePlayer = !activePlayer;
}

if (playerOneScoreCount > playerTwoScoreCount) {
playerStatus.setText("Player One is Winning!");
} else if (playerTwoScoreCount > playerOneScoreCount) {
playerStatus.setText("Player Two is Winning!");
} else {
playerStatus.setText("");
}

resetGame.setOnClickListener(v1 -> {
playAgain();
playerOneScoreCount = 0;
playerTwoScoreCount = 0;
playerStatus.setText("");
updatePlayerScore();
dialogChooseSide();
});
}

public boolean checkWinner() {
boolean winnerResult = false;
for (int[] winningPosition : winningPositions) {
if (gameState[winningPosition[0]] == gameState[winningPosition[1]] &&
gameState[winningPosition[1]] == gameState[winningPosition[2]] && gameState[winningPosition[0]] != 2) {
winnerResult = true;
break;
}
}
return winnerResult;
}

@SuppressLint("SetTextI18n")
public void updatePlayerScore() {
playerOneScore.setText(Integer.toString(playerOneScoreCount));
playerTwoScore.setText(Integer.toString(playerTwoScoreCount));
}

public void playAgain() {
rountCount = 0;
activePlayer = true;

for (int i = 0; i < buttons.length; i++) {
gameState[i] = 2;
buttons[i].setEnabled(false);
int i2 = i;
buttons[i].animate().alpha(0f).setDuration(500).withEndAction(() -> {
buttons[i2].setText("");
buttons[i2].animate().alpha(1f).setDuration(1000).withEndAction(() ->
buttons[i2].setEnabled(true)).start();
}
).start();
}
}
}


Untuk app selengkapnya dapat dilihat pada github saya di https://github.com/DaltrayNababan/TicTacToe 

Saya kira begitu saja tidak perlu panjang-panjang, jika ada yang ingin ditanyakan atau dijelasakan bisa tinggalkan komen atau kirimkan saya email. Terima kasih.
Share:

0 comments:

Post a Comment

Hubungi Saya

Name

Email *

Message *

Terlaris 30 Hari Terakhir