MEMBUAT APLIKASI SCRAMBLE WORD
Tugas 8 - Membuat Aplikasi Scramble Word
Nama : Wahyu Tri Saputro
NRP : 5025201217
Kelas : PPB - B
Halo, pada tugas kali ini saya akan membuat aplikasi The Unscramble atau Scramble Word menggunakan Jetpack Compose dengan mengikuti tutorial dari ViewModel and State in Compose (android.com).
1. MainActivity.kt
package com.example.scrambleword
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.scrambleword.ui.theme.GameScreen
import com.example.scrambleword.ui.theme.ScrambleWordTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent {
ScrambleWordTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
) {
GameScreen()
}
}
}
}
}
2. GameScreen.kt
package com.example.scrambleword
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.scrambleword.ui.theme.GameScreen
import com.example.scrambleword.ui.theme.ScrambleWordTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent {
ScrambleWordTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
) {
GameScreen()
}
}
}
}
}
3. GameViewModel.kt
package com.example.scrambleword.ui.theme
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import com.example.scrambleword.data.MAX_NO_OF_WORDS
import com.example.scrambleword.data.SCORE_INCREASE
import com.example.scrambleword.data.allWords
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
class GameViewModel : ViewModel() {
// Game UI state
private val _uiState = MutableStateFlow(GameUiState())
val uiState: StateFlow<GameUiState> = _uiState.asStateFlow()
var userGuess by mutableStateOf("")
private set
// Set of words used in the game
private var usedWords: MutableSet<String> = mutableSetOf()
private lateinit var currentWord: String
init {
resetGame()
}
/*
* Re-initializes the game data to restart the game.
*/
fun resetGame() {
usedWords.clear()
_uiState.value = GameUiState(currentScrambledWord = pickRandomWordAndShuffle())
}
/*
* Update the user's guess
*/
fun updateUserGuess(guessedWord: String){
userGuess = guessedWord
}
/*
* Checks if the user's guess is correct.
* Increases the score accordingly.
*/
fun checkUserGuess() {
if (userGuess.equals(currentWord, ignoreCase = true)) {
// User's guess is correct, increase the score
// and call updateGameState() to prepare the game for next round
val updatedScore = _uiState.value.score.plus(SCORE_INCREASE)
updateGameState(updatedScore)
} else {
// User's guess is wrong, show an error
_uiState.update { currentState ->
currentState.copy(isGuessedWordWrong = true)
}
}
// Reset user guess
updateUserGuess("")
}
/*
* Skip to next word
*/
fun skipWord() {
updateGameState(_uiState.value.score)
// Reset user guess
updateUserGuess("")
}
/*
* Picks a new currentWord and currentScrambledWord and updates UiState according to
* current game state.
*/
private fun updateGameState(updatedScore: Int) {
if (usedWords.size == MAX_NO_OF_WORDS){
//Last round in the game, update isGameOver to true, don't pick a new word
_uiState.update { currentState ->
currentState.copy(
isGuessedWordWrong = false,
score = updatedScore,
isGameOver = true
)
}
} else{
// Normal round in the game
_uiState.update { currentState ->
currentState.copy(
isGuessedWordWrong = false,
currentScrambledWord = pickRandomWordAndShuffle(),
currentWordCount = currentState.currentWordCount.inc(),
score = updatedScore
)
}
}
}
private fun shuffleCurrentWord(word: String): String {
val tempWord = word.toCharArray()
// Scramble the word
tempWord.shuffle()
while (String(tempWord) == word) {
tempWord.shuffle()
}
return String(tempWord)
}
private fun pickRandomWordAndShuffle(): String {
// Continue picking up a new random word until you get one that hasn't been used before
currentWord = allWords.random()
return if (usedWords.contains(currentWord)) {
pickRandomWordAndShuffle()
} else {
usedWords.add(currentWord)
shuffleCurrentWord(currentWord)
}
}
}
4. GameUiState.kt
package com.example.scrambleword.ui.theme
data class GameUiState(
val currentScrambledWord: String = "",
val currentWordCount: Int = 1,
val score: Int = 0,
val isGuessedWordWrong: Boolean = false,
val isGameOver: Boolean = false
)
Source Code: KobamYo/Scramble_Word_PPB-B (github.com)
Referensi: ViewModel and State in Compose (android.com)
Comments
Post a Comment