Share
Explore

Android App: The Guessing Game

Let's create a simple Android app using Kotlin that will have a single screen where the user can guess a number between 1 and 100.
The app will then generate a random number for the computer and determine who is closer to 50.
The result will be displayed on the screen, and the user will be invited to play again.

1. Project Setup

Gradle Build Scripts

Project-level `build.gradle’
```gradle // Project level build.gradle (usually located at the root of your project) buildscript { ext.kotlin_version = "1.8.0" repositories { google() mavenCentral() } dependencies { classpath "com.android.tools.build:gradle:8.0.2" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } }
allprojects { repositories { google() mavenCentral() } } ```
**Module-level `build.gradle`**
```gradle // Module level build.gradle (usually located in app folder) plugins { id 'com.android.application' id 'kotlin-android' }
android { compileSdkVersion 33 defaultConfig { applicationId "com.example.guessgame" minSdkVersion 21 targetSdkVersion 33 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } }
dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.10.1' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.9.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' } ```

2. Layout File (`activity_main.xml`)


<!-- res/layout/activity_main.xml --> <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/instructionText" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Guess a number between 1 and 100" android:textSize="18sp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_margin="16dp" />
<EditText android:id="@+id/guessInput" android:layout_width="0dp" android:layout_height="wrap_content" android:hint="Enter your guess" android:inputType="number" app:layout_constraintTop_toBottomOf="@id/instructionText" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_margin="16dp"/>
<Button android:id="@+id/submitGuessButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Submit Guess" app:layout_constraintTop_toBottomOf="@id/guessInput" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="16dp" />
<TextView android:id="@+id/resultText" android:layout_width="0dp" android:layout_height="wrap_content" android:text="" android:textSize="18sp" app:layout_constraintTop_toBottomOf="@id/submitGuessButton" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_margin="16dp"/>
<Button android:id="@+id/playAgainButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Play Again" android:visibility="gone" app:layout_constraintTop_toBottomOf="@id/resultText" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="16dp" /> </androidx.constraintlayout.widget.ConstraintLayout> ```

3. Kotlin Code (`MainActivity.kt`)

```kotlin

// src/main/java/com/example/guessgame/MainActivity.kt package com.example.guessgame
import android.os.Bundle import android.view.View import android.widget.Button import android.widget.EditText import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import kotlin.random.Random
class MainActivity : AppCompatActivity() {
private lateinit var instructionText: TextView private lateinit var guessInput: EditText private lateinit var submitGuessButton: Button private lateinit var resultText: TextView private lateinit var playAgainButton: Button
private var targetNumber = Random.nextInt(1, 101)
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
instructionText = findViewById(R.id.instructionText) guessInput = findViewById(R.id.guessInput) submitGuessButton = findViewById(R.id.submitGuessButton) resultText = findViewById(R.id.resultText) playAgainButton = findViewById(R.id.playAgainButton)
submitGuessButton.setOnClickListener { val userGuess = guessInput.text.toString().toIntOrNull() if (userGuess != null) { playGame(userGuess) } else { resultText.text = "Please enter a valid number!" resultText.visibility = View.VISIBLE } }
playAgainButton.setOnClickListener { resetGame() } }
private fun playGame(userGuess: Int) { val computerGuess = Random.nextInt(1, 101) val userDelta = kotlin.math.abs(50 - userGuess) val computerDelta = kotlin.math.abs(50 - computerGuess)
val winner = when { userDelta < computerDelta -> "User wins! (User: $userGuess, Computer: $computerGuess)" computerDelta < userDelta -> "Computer wins! (User: $userGuess, Computer: $computerGuess)" else -> "It's a tie! (User: $userGuess, Computer: $computerGuess)" }
resultText.text = winner resultText.visibility = View.VISIBLE playAgainButton.visibility = View.VISIBLE }
private fun resetGame() { guessInput.text.clear() resultText.text = "" resultText.visibility = View.GONE playAgainButton.visibility = View.GONE targetNumber = Random.nextInt(1, 101) } } ```
Explanation
1. Project-level build.gradle
Sets up the Kotlin plugin and repositories for the project.
2. **Module-level build.gradle**:
Configures Android-specific settings and dependencies for the app.
3. **activity_main.xml**:
Defines the UI layout for the main screen, including the instruction text, input field, submit button, result text, and play again button.
4. **MainActivity.kt**: - Initializes UI elements and sets click listeners for buttons. - Handles user input validation and game logic. - Determines the winner based on who is closer to 50. - Resets the game when the user chooses to play again.

This lab provides straightforward example of building an Android app with basic UI interactions and game logic.

megaphone

Let's break it down with an illustrative example of how the MainActivity.kt connects to and interacts with the layout activity_main.xml.

Lecture: Connecting MainActivity.kt with activity_main.xml

In Android development, the Activity class serves as the entry point for interacting with the user. It's where you place the logic to control what the user sees and how they can interact with your app. The layout file (activity_main.xml) defines the user interface (UI) elements.

Step-by-Step Breakdown

Setting Up the Layout in MainActivity
When an activity is created, it needs to be associated with a layout. This is done using the setContentView method in the onCreate method of the Activity class.
kotlin
Copy code
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}

Here, R.layout.activity_main refers to the activity_main.xml layout file in the res/layout directory.
Referencing UI Elements
To interact with UI elements defined in the layout file, we use findViewById to get references to these elements.
kotlin
Copy code
// Declaring UI elements
private lateinit var instructionText: TextView
private lateinit var guessInput: EditText
private lateinit var submitGuessButton: Button
private lateinit var resultText: TextView
private lateinit var playAgainButton: Button

Within the onCreate method, we initialize these elements by their IDs as specified in the XML layout file.
kotlin
Copy code
instructionText = findViewById(R.id.instructionText)
guessInput = findViewById(R.id.guessInput)
submitGuessButton = findViewById(R.id.submitGuessButton)
resultText = findViewById(R.id.resultText)
playAgainButton = findViewById(R.id.playAgainButton)

Setting Up Click Listeners
To make the buttons functional, we set click listeners on them.
kotlin
Copy code
submitGuessButton.setOnClickListener {
val userGuess = guessInput.text.toString().toIntOrNull()
if (userGuess != null) {
playGame(userGuess)
} else {
resultText.text = "Please enter a valid number!"
resultText.visibility = View.VISIBLE
}
}

playAgainButton.setOnClickListener {
resetGame()
}

Game Logic Methods
Define the methods that handle the game logic.
playGame(userGuess: Int): Compares the user's guess with a randomly generated computer guess and determines the winner.
resetGame(): Resets the game state for a new round.
kotlin
Copy code
private fun playGame(userGuess: Int) {
val computerGuess = Random.nextInt(1, 101)
val userDelta = kotlin.math.abs(50 - userGuess)
val computerDelta = kotlin.math.abs(50 - computerGuess)

val winner = when {
userDelta < computerDelta -> "User wins! (User: $userGuess, Computer: $computerGuess)"
computerDelta < userDelta -> "Computer wins! (User: $userGuess, Computer: $computerGuess)"
else -> "It's a tie! (User: $userGuess, Computer: $computerGuess)"
}

resultText.text = winner
resultText.visibility = View.VISIBLE
playAgainButton.visibility = View.VISIBLE
}

private fun resetGame() {
guessInput.text.clear()
resultText.text = ""
resultText.visibility = View.GONE
playAgainButton.visibility = View.GONE
}

Illustrative Example Code

To make it more concrete, here’s the complete MainActivity.kt code again with comments for clarity:
kotlin
Copy code
// src/main/java/com/example/guessgame/MainActivity.kt
package com.example.guessgame

import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import kotlin.random.Random

class MainActivity : AppCompatActivity() {

// Declaring UI elements
private lateinit var instructionText: TextView
private lateinit var guessInput: EditText
private lateinit var submitGuessButton: Button
private lateinit var resultText: TextView
private lateinit var playAgainButton: Button

// Random number for the game
private var targetNumber = Random.nextInt(1, 101)

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

// Initializing UI elements
instructionText = findViewById(R.id.instructionText)
guessInput = findViewById(R.id.guessInput)
submitGuessButton = findViewById(R.id.submitGuessButton)
resultText = findViewById(R.id.resultText)
playAgainButton = findViewById(R.id.playAgainButton)

// Setting up click listener for the submit button
submitGuessButton.setOnClickListener {
val userGuess = guessInput.text.toString().toIntOrNull()
if (userGuess != null) {
playGame(userGuess)
} else {
resultText.text = "Please enter a valid number!"
resultText.visibility = View.VISIBLE
}
}

// Setting up click listener for the play again button
playAgainButton.setOnClickListener {
resetGame()
}
}

// Method to handle the game logic
private fun playGame(userGuess: Int) {
val computerGuess = Random.nextInt(1, 101)
val userDelta = kotlin.math.abs(50 - userGuess)
val computerDelta = kotlin.math.abs(50 - computerGuess)

val winner = when {
userDelta < computerDelta -> "User wins! (User: $userGuess, Computer: $computerGuess)"
computerDelta < userDelta -> "Computer wins! (User: $userGuess, Computer: $computerGuess)"
else -> "It's a tie! (User: $userGuess, Computer: $computerGuess)"
}

resultText.text = winner
resultText.visibility = View.VISIBLE
playAgainButton.visibility = View.VISIBLE
}

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.