Membuat Aplikasi Unscramble Word App

  Burhanudin Rifa - 5025201191

PPB - D

Github: Link

Youtube: Link




/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.android.unscramble

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

/**
* Creates an Activity that hosts the Game fragment in the app
*/
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
}
}


/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.android.unscramble.ui.game

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.example.android.unscramble.R
import com.example.android.unscramble.databinding.GameFragmentBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder

/**
* Fragment where the game is played, contains the game logic.
*/
class GameFragment : Fragment() {

// Binding object instance with access to the views in the game_fragment.xml layout
private lateinit var binding: GameFragmentBinding

// Create a ViewModel the first time the fragment is created.
// If the fragment is re-created, it receives the same GameViewModel instance created by the
// first fragment.
private val viewModel: GameViewModel by viewModels()

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout XML file and return a binding object instance
binding = DataBindingUtil.inflate(inflater, R.layout.game_fragment, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

// Set the viewModel for data binding - this allows the bound layout access
// to all the data in the VieWModel
binding.gameViewModel = viewModel
binding.maxNoOfWords = MAX_NO_OF_WORDS
// Specify the fragment view as the lifecycle owner of the binding.
// This is used so that the binding can observe LiveData updates
binding.lifecycleOwner = viewLifecycleOwner

// Setup a click listener for the Submit and Skip buttons.
binding.submit.setOnClickListener { onSubmitWord() }
binding.skip.setOnClickListener { onSkipWord() }
if (viewModel.isGameOver()) { showFinalScoreDialog() }
}

/*
* Checks the user's word, and updates the score accordingly.
* Displays the next scrambled word.
* After the last word, the user is shown a Dialog with the final score.
*/
private fun onSubmitWord() {
val playerWord = binding.textInputEditText.text.toString()

if (viewModel.isUserWordCorrect(playerWord)) {
setErrorTextField(false)
if (!viewModel.nextWord()) {
showFinalScoreDialog()
}
} else {
setErrorTextField(true)
}
}

/*
* Skips the current word without changing the score.
* Increases the word count.
* After the last word, the user is shown a Dialog with the final score.
*/
private fun onSkipWord() {
if (viewModel.nextWord()) {
setErrorTextField(false)
} else {
showFinalScoreDialog()
}
}

/*
* Creates and shows an AlertDialog with final score.
*/
private fun showFinalScoreDialog() {
MaterialAlertDialogBuilder(requireContext())
.setTitle(getString(R.string.congratulations))
.setMessage(getString(R.string.you_scored, viewModel.score.value))
.setCancelable(false)
.setNegativeButton(getString(R.string.exit)) { _, _ ->
exitGame()
}
.setPositiveButton(getString(R.string.play_again)) { _, _ ->
restartGame()
}
.show()
}

/*
* Re-initializes the data in the ViewModel and updates the views with the new data, to
* restart the game.
*/
private fun restartGame() {
viewModel.reinitializeData()
setErrorTextField(false)
}

/*
* Exits the game.
*/
private fun exitGame() {
activity?.finish()
}

/*
* Sets and resets the text field error status.
*/
private fun setErrorTextField(error: Boolean) {
if (error) {
binding.textField.isErrorEnabled = true
binding.textField.error = getString(R.string.try_again)
} else {
binding.textField.isErrorEnabled = false
binding.textInputEditText.text = null
}
}
}
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.android.unscramble.ui.game

import android.text.Spannable
import android.text.SpannableString
import android.text.style.TtsSpan
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel

/**
* ViewModel containing the app data and methods to process the data
*/
class GameViewModel : ViewModel() {
private val _score = MutableLiveData(0)
val score: LiveData<Int>
get() = _score

private val _currentWordCount = MutableLiveData(0)
val currentWordCount: LiveData<Int>
get() = _currentWordCount

private val _currentScrambledWord = MutableLiveData<String>()
val currentScrambledWord: LiveData<Spannable> = Transformations.map(_currentScrambledWord) {
if (it == null) {
SpannableString("")
} else {
val scrambledWord = it.toString()
val spannable: Spannable = SpannableString(scrambledWord)
spannable.setSpan(
TtsSpan.VerbatimBuilder(scrambledWord).build(),
0,
scrambledWord.length,
Spannable.SPAN_INCLUSIVE_INCLUSIVE
)
spannable
}
}

// List of words used in the game
private var wordsList: MutableList<String> = mutableListOf()
private lateinit var currentWord: String

private var isGameOver: Boolean = false


init {
getNextWord()
}

/*
* Updates currentWord and currentScrambledWord with the next word.
*/
private fun getNextWord() {
currentWord = allWordsList.random()
val tempWord = currentWord.toCharArray()
tempWord.shuffle()

while (String(tempWord).equals(currentWord, false)) {
tempWord.shuffle()
}
if (wordsList.contains(currentWord)) {
getNextWord()
} else {
Log.d("Unscramble", "currentWord= $currentWord")
_currentScrambledWord.value = String(tempWord)
_currentWordCount.value = _currentWordCount.value?.inc()
wordsList.add(currentWord)
}
}

/*
* Re-initializes the game data to restart the game.
*/
fun reinitializeData() {
_score.value = 0
_currentWordCount.value = 0
wordsList.clear()
getNextWord()
isGameOver = false
}

/*
* Increases the game score if the player’s word is correct.
*/
private fun increaseScore() {
_score.value = _score.value?.plus(SCORE_INCREASE)
}

/*
* Returns true if the player word is correct.
* Increases the score accordingly.
*/
fun isUserWordCorrect(playerWord: String): Boolean {
if (playerWord.equals(currentWord, true)) {
increaseScore()
return true
}
return false
}

/*
* Returns true if the current word count is less than MAX_NO_OF_WORDS
*/
fun nextWord(): Boolean {
return if (_currentWordCount.value!! < MAX_NO_OF_WORDS) {
getNextWord()
true
} else {
isGameOver = true
false
}
}

fun isGameOver() = isGameOver
}
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.android.unscramble.ui.game


const val MAX_NO_OF_WORDS = 10
const val SCORE_INCREASE = 20

// List with all the words for the Game
val allWordsList: List<String> =
listOf("animal",
"auto",
"anecdote",
"alphabet",
"all",
"awesome",
"arise",
"balloon",
"basket",
"bench",
"best",
"birthday",
"book",
"briefcase",
"camera",
"camping",
"candle",
"cat",
"cauliflower",
"chat",
"children",
"class",
"classic",
"classroom",
"coffee",
"colorful",
"cookie",
"creative",
"cruise",
"dance",
"daytime",
"dinosaur",
"doorknob",
"dine",
"dream",
"dusk",
"eating",
"elephant",
"emerald",
"eerie",
"electric",
"finish",
"flowers",
"follow",
"fox",
"frame",
"free",
"frequent",
"funnel",
"green",
"guitar",
"grocery",
"glass",
"great",
"giggle",
"haircut",
"half",
"homemade",
"happen",
"honey",
"hurry",
"hundred",
"ice",
"igloo",
"invest",
"invite",
"icon",
"introduce",
"joke",
"jovial",
"journal",
"jump",
"join",
"kangaroo",
"keyboard",
"kitchen",
"koala",
"kind",
"kaleidoscope",
"landscape",
"late",
"laugh",
"learning",
"lemon",
"letter",
"lily",
"magazine",
"marine",
"marshmallow",
"maze",
"meditate",
"melody",
"minute",
"monument",
"moon",
"motorcycle",
"mountain",
"music",
"north",
"nose",
"night",
"name",
"never",
"negotiate",
"number",
"opposite",
"octopus",
"oak",
"order",
"open",
"polar",
"pack",
"painting",
"person",
"picnic",
"pillow",
"pizza",
"podcast",
"presentation",
"puppy",
"puzzle",
"recipe",
"release",
"restaurant",
"revolve",
"rewind",
"room",
"run",
"secret",
"seed",
"ship",
"shirt",
"should",
"small",
"spaceship",
"stargazing",
"skill",
"street",
"style",
"sunrise",
"taxi",
"tidy",
"timer",
"together",
"tooth",
"tourist",
"travel",
"truck",
"under",
"useful",
"unicorn",
"unique",
"uplift",
"uniform",
"vase",
"violin",
"visitor",
"vision",
"volume",
"view",
"walrus",
"wander",
"world",
"winter",
"well",
"whirlwind",
"x-ray",
"xylophone",
"yoga",
"yogurt",
"yoyo",
"you",
"year",
"yummy",
"zebra",
"zigzag",
"zoology",
"zone",
"zeal")



Comments

Popular posts from this blog

Aplikasi Expense Tracker - Expenz

Membuat Aplikasi Login Page Sederhana