# Guessing Game – Play the game

In this chapter of the Guessing Game tutorial we are going to implement the core part, which is how we can play the game. For this, we are going to create one more ViewModel. This ViewModel will contain the business logic about the game.

In the very last chapter (Guessing Game – ViewModel), we have implement a ViewModel class already, which is responsible to change the username, and store it indside of a LiveData.

First, we are going to create an enum. This enum will hold the 4 states of the game. Then, we gonna start the implementation of the GameViewModel, which will contain the business logic. It means, here we gonna generate the random numbe to guess, then compare this number to the number of the guess, show the result and start a new game. Inside of this ViewModel we gonna implement two more methods, which will help us to show and hide the soft keyboard after every guess.

So, let’s start coding! 😎

#### GitHub

If you haven’t done the previous chapters, then from GitHub you can download the starter project for this chapter.

GitHub – viewmodel branch

#### Step 1 – Create the enum of the result

We gonna create an enum, which hold the result and the state of the game, when it is running. In the consciousness of this we can separate 4 states.

• When the guessed number is lower then the number we need to figure out. (LOWER)
• When the number is higher… (HIGHER)
• or the numbers are equal. (WIN)
• and we are typing a new guess (GUESSING)
###### Create new package
We will have the enum in a new package. So, from the left Project tab, inside of the java folder, click on the package name with the right mouse button, then select New -> Package option. In the popup window name the package as utils”.
###### Create new file

Next, click again with the right mouse button on the newly created utils folder, and from the quick menu select New -> Kotlin File/Class. Name it as “GuessResult”. Then, copy and paste the below code into the new file.

``````enum class GuessResult
{
LOWER,
HIGHER,
WIN,
GUESSING
}

GuessResult enum``````

#### Step 2 – Create the GameViewModel

The second step is to create the GameViewModel, which will be inside of the viewmodel package also.

So, click on the viewmodel package with the right mouse button, then from the quick menu select New -> Kotlin File/Class. Name it as “GameViewModel”. Then extend the class with ViewModel().

###### Create the member variables

Inside of the GameViewModel, we gonna have 2 LiveDatas and an Integer variable, which will store the generated number.

So, copy and paste the below lines into the GameViewModel::class.

``````private val _result = MutableLiveData<GuessResult?>()
val result: LiveData<GuessResult?>
get() = _result

private val _isRunning = MutableLiveData(false)
val isRunning: LiveData
get() = _isRunning

private var generatedNumber = 0

Member variables``````
###### generateRandom() method

First of all, we are going to implement the method, which will generate a new number. It looks like below.

``````private fun generateRandom(): Int
{
return Random.nextInt(1, 10)
}

generateRandom()``````
In Kotlin, you can generate random Integer number between 2 numbers, if you call the nextInt(from: Int, until: Int) method on the Random object.
###### Play() method

When the app starts and we click on the blue button, then a whole new game has to be started, otherwise the typed number has to be compared to the hidden, automatically generated number.

If the game is finished or should be started, then the newGame() method will set the game to the start position and generate a new number, what we should figure out. If it is running, then the compareGuess() method will be called.

The decision, which method should be called, is going to be made in the play() method.

So, copy and paste the below play() method after the member variables.

``````fun play(context: Context, guessTextView: TextInputEditText, gameIsState: Boolean)
{
if (gameIsState)
{
compareGuess(context, guessTextView)
}
else
{
newGame(guessTextView)
}
}

play()``````

After the paste you will have 2 errors, because we haven’t implemented the newGame() and compareGuess() methods yet. We gonna solve these issue now.

###### newGame() method

The newGame() method will generate a new number, reset the EditText of the guessed number, and set the state of the game to running.

So, copy and paste the below method into the GameViewModel::class.

``````private fun newGame(guessTextView: TextInputEditText)
{
generatedNumber = generateRandom()

guessTextView.isEnabled = true
guessTextView.setText("")
guessTextView.hint = ""

_isRunning.value = true
_result.value = GuessResult.GUESSING
}

newGame()``````
###### validateGuessText() method

Before we are going to implement the comparison, we have to check the content of the EdiText, where should be basically an Integer number.

Previously, we have defined this EditText to accept only numbers as input type . So, we just need to check if the field is empty

As before, copy and paste the below method into the GameViewModel::class.

``````private fun validateGuessText(guessText: String): Boolean
{
return guessText.isNotEmpty()
}

validateGuessText()``````
###### hideKeyboard() method

When we click on the Guess Button, then below it, we will see the result of the comparison, but basically the soft keyboard remains open. We should hide it, when we click on the Button.

We can do by calling the below method. This is an extension function of the Context object.

``````fun Context.hideKeyboard(view: View)
{
(getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.apply {
hideSoftInputFromWindow(view.windowToken, 0)
}
}

hideKeyboard()``````
###### compareGuess() method

Finally, this gonna be the last method, what we are going to implement in this chapter. This method will first check the content of the EditText. If it is empty, then an error message will be shown for the player until it is empty.

If the content is ok, then the soft keyboard gonna be hidden.

After thet, we are going to compare the guessed number and the number to guess using a when-statement. In the statement we gonna set the LiveData of the result, and set to running the state of the game.

Still we can only print out the result in Logcat, because we are going to implement the BindingAdapters in the next chapter.

So, paste the below code into the GameViewModel::class.

``````private fun compareGuess(context: Context, guessEditText: TextInputEditText)
{
if(!validateGuessText(guessEditText.text.toString()))
{
guessEditText.error = "This field can not be empty"
return
}

context.hideKeyboard(guessEditText)

val guess = guessEditText.text.toString().toInt()
when
{
guess > generatedNumber -> {
_result.value = GuessResult.LOWER
_isRunning.value = true
Log.d("GameViewModel", "LOWER")
}
guess < generatedNumber -> {
_result.value = GuessResult.HIGHER
_isRunning.value = true
Log.d("GameViewModel", "HIGHER")
}
else -> {
_result.value = GuessResult.WIN
guessEditText.isEnabled = false
guessEditText.hint = "You Win!"
_isRunning.value = false
Log.d("GameViewModel", "WIN")
}
}
}

compareGuess()``````

#### Step 3 – Layout variable

In the next step, we are going to create a layout variable for the GameViewModel, as we have done it in case of the PlayerViewModel.

So, open the fragment_game.xml file from the res->layout folders and paste the below variable into the <data> tag.

``````<variable
name="gameViewModel"
type="com.inspirecoding.guessinggame.viewmodel.GameViewModel" />

gameViewModel``````

#### Step 4 – Layout expression

After the implementation of the layout variable, we can start using it inside of the onClick of the Button as a layout expression.

So, go to the btn_guess Button, and add the next line to it.

``````android:onClick="@{() ->  gameViewModel.play(context, tietGuessNumber, gameViewModel.running)}"

android:onClick``````

#### Step 5 – Init the gameViewModel

Next, open the GameFragment class from the ui package and paste after the playerViewModel variable the instance of the gameViewModel.

``````private val gameViewModel by navGraphViewModels(R.id.navigation_graph)

gameViewModel ``````

Finally, the last step is to initialize the gameViewModel in the onCreate() method as below.

binding.gameViewModel = gameViewModel

#### Run the app

It’s time to run the app. Still the btn_guess Button don’t have any texts (we gonna solve this later also), but you can start the game like this also.

Click on it, and enter a number. If you open the Logcat in Android Studio and search the tag of “GameViewModel”, then you will see the result of the guess.

In the next chapter, we are going to implement BindingAdapter. With it, we can show for the user the result.

See you there. 😎

#### GitHub

The source code is available on GitHub

GitHub – play_the_game branch

#### Questions

I hope the description was understandable and clear. But, if you have still questions, then leave me comments below! 😉

Have a nice a day! 🙂

Click to rate this post!
[Total: 0 Average: 0]