Tugas Pertemuan 11 - Game Unscramble

Tugas Pertemuan 11
Game Unscramble

Nama : Nadya Zuhria Amana

NRP : 5025211058

Kelas : Pemrograman Perangkat Bergerak B

Tahun : 2024


# File Kode Awal

 WordsData.kt

File ini menyimpan daftar kata yang digunakan dalam game, serta konstanta untuk jumlah maksimum kata per game dan poin skor untuk setiap kata yang benar.


## MainActivity.kt

File ini berisi sebagian besar kode yang dihasilkan dari template. Anda menampilkan composable `GameScreen` dalam blok `setContent{}`.


## GameScreen.kt

Semua composable UI didefinisikan di sini. Panduan untuk beberapa fungsi composable diberikan di bawah ini.


### GameStatus

Fungsi composable ini menampilkan skor game di bagian bawah layar. Skor saat ini di-hardcode menjadi 0.


### GameLayout

Fungsi composable ini menampilkan elemen utama game, termasuk kata acak, petunjuk game, dan kolom teks untuk menerima tebakan pengguna.


### GameScreen

Composable ini mencakup `GameStatus`, `GameLayout`, judul game, jumlah kata, serta tombol Submit dan Skip.


### FinalScoreDialog

Fungsi composable ini menampilkan dialog yang memberikan opsi kepada pengguna untuk bermain lagi atau keluar dari game. Anda akan mengimplementasikan logika untuk menampilkan dialog ini di akhir game.


## Menambahkan ViewModel

1. Buka `build.gradle.kts (Module :app)`, scroll ke blok dependencies, dan tambahkan dependensi berikut untuk ViewModel.


```kotlin

dependencies {

    // other dependencies

    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")

    //...

}

```


2. Di paket `ui`, buat class/file Kotlin bernama `GameViewModel` yang merupakan subclass dari `ViewModel`.


```kotlin

import androidx.lifecycle.ViewModel


class GameViewModel : ViewModel() {

}

```


3. Tambahkan class data `GameUiState` di paket `ui` untuk status UI game dengan variabel `currentScrambledWord`.


```kotlin

data class GameUiState(

    val currentScrambledWord: String = ""

)

```


## StateFlow

1. Tambahkan properti `_uiState` berikut di class `GameViewModel`.


```kotlin

import kotlinx.coroutines.flow.MutableStateFlow


// Game UI state

private val _uiState = MutableStateFlow(GameUiState())

```


2. Tambahkan properti pendukung `uiState` yang bernama `_uiState` dan berjenis `StateFlow<GameUiState>`.


```kotlin

import kotlinx.coroutines.flow.StateFlow

import kotlinx.coroutines.flow.asStateFlow


// Game UI state

private val _uiState = MutableStateFlow(GameUiState())

val uiState: StateFlow<GameUiState> = _uiState.asStateFlow()

```


## Menampilkan Kata Acak

1. Di `GameViewModel`, tambahkan properti `currentWord` dari jenis `String` untuk menyimpan kata acak saat ini.


```kotlin

private lateinit var currentWord: String

```


2. Tambahkan metode `pickRandomWordAndShuffle()` untuk memilih kata acak dari daftar dan mengacaknya.


```kotlin

import com.example.unscramble.data.allWords


private fun pickRandomWordAndShuffle(): String {

    currentWord = allWords.random()

    if (usedWords.contains(currentWord)) {

        return pickRandomWordAndShuffle()

    } else {

        usedWords.add(currentWord)

        return shuffleCurrentWord(currentWord)

    }

}

```


3. Tambahkan properti untuk menyimpan kata yang telah digunakan dalam game.


```kotlin

// Set of words used in the game

private var usedWords: MutableSet<String> = mutableSetOf()

```


4. Tambahkan metode `shuffleCurrentWord()` untuk mengacak kata saat ini.


```kotlin

private fun shuffleCurrentWord(word: String): String {

    val tempWord = word.toCharArray()

    tempWord.shuffle()

    while (String(tempWord).equals(word)) {

        tempWord.shuffle()

    }

    return String(tempWord)

}

```


5. Tambahkan fungsi `resetGame()` untuk menginisialisasi game.


```kotlin

fun resetGame() {

    usedWords.clear()

    _uiState.value = GameUiState(currentScrambledWord = pickRandomWordAndShuffle())

}

```


6. Tambahkan blok `init` ke `GameViewModel` dan panggil `resetGame()`.


```kotlin

init {

    resetGame()

}

```


## Merancang Compose UI dan Meneruskan Data

1. Pada fungsi `GameScreen`, teruskan argumen kedua dari jenis `GameViewModel` dengan nilai default `viewModel()`.


```kotlin

import androidx.lifecycle.viewmodel.compose.viewModel


@Composable

fun GameScreen(

    gameViewModel: GameViewModel = viewModel()

) {

    // ...

}

```


2. Tambahkan variabel `gameUiState` pada fungsi `GameScreen` dengan delegasi `by` dan panggil `collectAsState()` pada `uiState`.


```kotlin

import androidx.compose.runtime.collectAsState

import androidx.compose.runtime.getValue


@Composable

fun GameScreen(

    gameViewModel: GameViewModel = viewModel()

) {

    val gameUiState by gameViewModel.uiState.collectAsState()

    // ...

}

```


3. Teruskan `gameUiState.currentScrambledWord` ke `GameLayout`.


```kotlin

GameLayout(

    currentScrambledWord = gameUiState.currentScrambledWord,

    modifier = Modifier

        .fillMaxWidth()

        .wrapContentHeight()

        .padding(mediumPadding)

)

```


4. Tambahkan `currentScrambledWord` sebagai parameter ke fungsi `GameLayout`.


```kotlin

@Composable

fun GameLayout(

    currentScrambledWord: String,

    modifier: Modifier = Modifier

) {

}

```


5. Perbarui fungsi `GameLayout` untuk menampilkan `currentScrambledWord`.


```kotlin

@Composable

fun GameLayout(

    currentScrambledWord: String,

    modifier: Modifier = Modifier

) {

    Column(

        verticalArrangement = Arrangement.spacedBy(24.dp)

    ) {

        Text(

            text = currentScrambledWord,

            // ...

        )

        // ...

    }

}

```


6. Jalankan dan bangun aplikasi untuk melihat kata yang ejaannya diacak.


## Menampilkan Kata Tebakan

1. Pada `GameLayout`, setel `onValueChange` ke `onUserGuessChanged` dan `onKeyboardDone()` ke tindakan keyboard `onDone`.


```kotlin

OutlinedTextField(

    value = "",

    singleLine = true,

    modifier = Modifier.fillMaxWidth(),

    onValueChange = onUserGuessChanged,

    label = { Text(stringResource(R.string.enter_your_word)) },

    isError = false,

    keyboardOptions = KeyboardOptions.Default.copy(

        imeAction = ImeAction.Done

    ),

    keyboardActions = KeyboardActions(

        onDone = { onKeyboardDone() }

    ),

)

```


2. Tambahkan argumen `onUserGuessChanged` dan `onKeyboardDone` ke `GameLayout`.


```kotlin

@Composable

fun GameLayout(

    currentScrambledWord: String,

    onUserGuessChanged: (String) -> Unit,

    onKeyboardDone: () -> Unit,

    modifier: Modifier = Modifier

) {

}

```


3. Pada `GameScreen`, tambahkan lambda untuk `onUserGuessChanged` dan `onKeyboardDone`.


```kotlin

GameLayout(

    currentScrambledWord = gameUiState.currentScrambledWord,

    onUserGuessChanged = { gameViewModel.updateUserGuess(it) },

    onKeyboardDone = { gameViewModel.checkUserGuess() }

)

```


4. Tambahkan metode `updateUserGuess` di `GameViewModel` untuk memperbarui tebakan pengguna.


```kotlin

fun updateUserGuess(guessedWord: String) {

    userGuess = guessedWord

}

```


5. Tambahkan properti `userGuess` di `GameViewModel`.


```kotlin

import androidx.compose.runtime.mutableStateOf

import androidx.compose.runtime.getValue

import androidx.compose.runtime.setValue


var userGuess by mutableStateOf("")

    private set

```


6. Tambahkan parameter `userGuess` ke `GameLayout`.


```kotlin

fun GameLayout(

    currentScrambledWord: String,

    userGuess: String,

    onUserGuessChanged: (String) -> Unit,

    onKeyboardDone: () -> Unit,

    modifier: Modifier = Modifier

) {

    Column(

        verticalArrangement = Arrangement.spacedBy(24.dp)

    ) {

        OutlinedTextField(

            value = userGuess,

            //...

        )

    }

}

```


7. Perbarui panggilan fungsi `GameLayout` untuk menyertakan `userGuess`.


```kotlin

GameLayout(

    currentScrambledWord = gameUiState.currentScrambledWord,

    userGuess = gameViewModel.userGuess,

    onUserGuessChanged = { gameViewModel.updateUserGuess(it) },

    onKeyboardDone = { gameViewModel.checkUserGuess() }

)

```


8. Bangun dan jalankan aplikasi untuk melihat kolom teks yang dapat menampilkan tebakan pengguna.


## Memverifikasi Kata Tebakan dan Memperbarui Skor

1. Tambahkan metode `checkUserGuess` di `GameViewModel`.


```kotlin

fun checkUserGuess() {

    if (userGuess.equals(currentWord, ignoreCase = true)) {

        // User's guess is correct

    } else {

        // User's guess is wrong

        _uiState.update { currentState ->

            currentState.copy(isGuessedWordWrong = true)

        }

    }

    // Reset user guess

    updateUserGuess("")

}

```


2. Tambahkan `isGuessedWord


Wrong` ke `GameUiState`.


```kotlin

data class GameUiState(

    val currentScrambledWord: String = "",

    val isGuessedWordWrong: Boolean = false

)

```


3. Tambahkan metode `updateGameState` ke `GameViewModel` untuk memperbarui skor dan jumlah kata.


```kotlin

private fun updateGameState(updatedScore: Int) {

    if (usedWords.size == MAX_NO_OF_WORDS) {

        _uiState.update { currentState ->

            currentState.copy(

                isGuessedWordWrong = false,

                score = updatedScore,

                isGameOver = true

            )

        }

    } else {

        _uiState.update { currentState ->

            currentState.copy(

                isGuessedWordWrong = false,

                currentScrambledWord = pickRandomWordAndShuffle(),

                score = updatedScore,

                currentWordCount = currentState.currentWordCount.inc()

            )

        }

    }

}

```


4. Perbarui fungsi `checkUserGuess` untuk memperbarui status game dan skor pengguna jika tebakan benar.


```kotlin

fun checkUserGuess() {

    if (userGuess.equals(currentWord, ignoreCase = true)) {

        val updatedScore = _uiState.value.score.plus(SCORE_INCREASE)

        updateGameState(updatedScore)

    } else {

        _uiState.update { currentState ->

            currentState.copy(isGuessedWordWrong = true)

        }

    }

    updateUserGuess("")

}

```


5. Perbarui fungsi `GameLayout` untuk menyertakan skor saat ini.


```kotlin

@Composable

fun GameLayout(

    currentScrambledWord: String,

    userGuess: String,

    onUserGuessChanged: (String) -> Unit,

    onKeyboardDone: () -> Unit,

    score: Int,

    modifier: Modifier = Modifier

) {

    //...

    Text(

        text = stringResource(R.string.word_count, score),

        // ...

    )

}

```


6. Perbarui panggilan fungsi `GameLayout` di `GameScreen`.


```kotlin

GameLayout(

    currentScrambledWord = gameUiState.currentScrambledWord,

    userGuess = gameViewModel.userGuess,

    onUserGuessChanged = { gameViewModel.updateUserGuess(it) },

    onKeyboardDone = { gameViewModel.checkUserGuess() },

    score = gameUiState.score

)

```


7. Bangun dan jalankan aplikasi untuk melihat skor yang diperbarui saat kata ditebak dengan benar.

Posting Komentar

Lebih baru Lebih lama