I am trying to program a little dice app which consist of three dices and there should be some actions like for example "rolling all dices" or "put a side a dice if it's a 1 or a 6".
For now I am not finished but my coding isn't really that exemplary. Thats why I am asking if you can help me to reduce my code, I just repeat a lot. It's definitely possible with the half of the lines I guess.
I am happy for any help/hint.
This is my Main:
package com.example.notfall_kit
import android.os.Bundle
import android.widget.Button
import android.widget.ImageButton
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Find the Button, the 3 ImageButtons and the 3 ImageViews in the layout
val rollButton: Button = findViewById(R.id.wuerfelButton)
val centerButton: ImageButton = findViewById(R.id.imageButtonCenter)
val leftButton: ImageButton = findViewById(R.id.imageButtonLeft)
val rightButton: ImageButton = findViewById(R.id.imageButtonRight)
val centerImage: ImageView = findViewById(R.id.imageViewCenter)
val leftImage: ImageView = findViewById(R.id.imageViewLeft)
val rightImage: ImageView = findViewById(R.id.imageViewRight)
// What happens when pressing "WÜRFELN" Button
rollButton.setOnClickListener { rollDice()
}
// What happens when pressing the center dice ImageButton
centerButton.setOnClickListener{
centerImage.isVisible = true
centerButton.isVisible = false
}
// What happens when pressing the left dice ImageButton
leftButton.setOnClickListener{
leftImage.isVisible = true
leftButton.isVisible = false
}
// What happens when pressing the right dice ImageButton
rightButton.setOnClickListener{
rightImage.isVisible = true
rightButton.isVisible = false
}
}
private fun rollDice() {
// Create a new Dice object with 6 sides and roll it
val dice = Dice(6)
// Create 3 dices and roll them, see Class "Dice" for roll-function
val diceRollCenter = dice.roll()
val diceRollLeft = dice.roll()
val diceRollRight = dice.roll()
// Find the ImageButtons in the layout for the 3 dices
val diceImageCenter: ImageButton = findViewById(R.id.imageButtonCenter)
val diceImageLeft: ImageButton = findViewById(R.id.imageButtonLeft)
val diceImageRight: ImageButton = findViewById(R.id.imageButtonRight)
//Change the images of the center dice
when (diceRollCenter) {
1 -> diceImageCenter.setImageResource(R.drawable.dice_1)
2 -> diceImageCenter.setImageResource(R.drawable.dice_2)
3 -> diceImageCenter.setImageResource(R.drawable.dice_3)
4 -> diceImageCenter.setImageResource(R.drawable.dice_4)
5 -> diceImageCenter.setImageResource(R.drawable.dice_5)
6 -> diceImageCenter.setImageResource(R.drawable.dice_6)
}
//Change the images of the left dice
when (diceRollLeft) {
1 -> diceImageLeft.setImageResource(R.drawable.dice_1)
2 -> diceImageLeft.setImageResource(R.drawable.dice_2)
3 -> diceImageLeft.setImageResource(R.drawable.dice_3)
4 -> diceImageLeft.setImageResource(R.drawable.dice_4)
5 -> diceImageLeft.setImageResource(R.drawable.dice_5)
6 -> diceImageLeft.setImageResource(R.drawable.dice_6)
}
//Change the images of the right dice
when (diceRollRight) {
1 -> diceImageRight.setImageResource(R.drawable.dice_1)
2 -> diceImageRight.setImageResource(R.drawable.dice_2)
3 -> diceImageRight.setImageResource(R.drawable.dice_3)
4 -> diceImageRight.setImageResource(R.drawable.dice_4)
5 -> diceImageRight.setImageResource(R.drawable.dice_5)
6 -> diceImageRight.setImageResource(R.drawable.dice_6)
}
//call compareDices function to check if there is a 1 or a 6
compareDices(diceRollCenter,diceRollLeft, diceRollRight)
}
private fun compareDices(Center: Int, Left: Int, Right:Int) {
// Create 3 Images on top of the display and find them in the layout
val diceImageCenter: ImageView = findViewById(R.id.imageViewCenter)
val diceImageLeft: ImageView = findViewById(R.id.imageViewLeft)
val diceImageRight: ImageView = findViewById(R.id.imageViewRight)
// Find the ImageButtons in the layout for the 3 dices
val centerButton: ImageButton = findViewById(R.id.imageButtonCenter)
val leftButton: ImageButton = findViewById(R.id.imageButtonLeft)
val rightButton: ImageButton = findViewById(R.id.imageButtonRight)
// Only if the center-dice shows 1 or 6, the dice can moved to the top
if (centerButton.isVisible) {
when (Center) {
1 -> diceImageCenter.setImageResource(R.drawable.dice_1)
6 -> diceImageCenter.setImageResource(R.drawable.dice_6)
else -> println("JAUCHE")
}
}
// Only if the left dice shows 1 or 6, the dice can moved to the top
if (leftButton.isVisible) {
when (Left) {
1 -> diceImageLeft.setImageResource(R.drawable.dice_1)
6 -> diceImageLeft.setImageResource(R.drawable.dice_6)
else -> println("JAUCHE")
}
}
// Only if the right dice shows 1 or 6, the dice can moved to the top
if (rightButton.isVisible) {
when (Right) {
1 -> diceImageRight.setImageResource(R.drawable.dice_1)
6 -> diceImageRight.setImageResource(R.drawable.dice_6)
else -> println("JAUCHE")
}
}
}
}
And this is my Class:
package com.example.notfall_kit
class Dice(val numSides: Int) {
fun roll(): Int {
return (1..numSides).random()
}
}
CodePudding user response:
Okay alright, thanks anyway. Cheers
CodePudding user response:
The basic pattern you can use is to create lists of the things you are using repeatedly, so you can set them up in loops.
You can create class properties that describes the view and image Ids so they are easy to reuse. We wrap them in by lazy
so it is safe to define them before onCreate()
.
private val imageButtons by lazy {
listOf(R.id.imageButtonCenter, R.id.imageButtonLeft, R.id.imageButtonRight)
.map { findViewById<ImageButton>(it) }
}
private val imageViews by lazy {
listOf(R.id.imageViewCenter, R.id.imageViewLeft, R.id.imageViewRight)
.map { findViewById<ImageView>(it) }
}
In onCreate()
, you can iterate the list to set them up:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.wuerfelButton)
rollButton.setOnClickListener {
rollDice()
}
for ((button, imageView) in imageButtons zip imageViews) {
button.setOnClickListener {
imageView.isVisible = true
button.isVisible = false
}
}
}
To help with your rollDice()
function, you should create a list property of the images to use:
private val diceDrawables = with(R.drawable) {
listOf(dice_1, dice_2, dice_3, dice_4, dice_5, dice_6)
}
Then in rollDice()
, you should create your three dice as a list and iterate them. Since the drawables are in a list, you don't need to set them with when statements.
private fun rollDice() {
val dice = Dice(6)
val diceRolls = List(3) { dice.roll() }
for ((diceValue, imageButton) in diceRolls zip imageButtons) {
imageButton.setImageResource(diceDrawables[value - 1])
}
compareDices(diceRolls)
}
And notice I have changed compareDices
to take a list of dice instead of three parameters. It also works by iterating the lists. Here since we're working with three lists, I'm iterating using indices instead of using zip
.
private fun compareDices(values: List<Int>) {
for (i in 0..2) {
val button = imageButtons[i]
val image = imageViews[i]
val value = values[i]
if (button.isVisible) {
when(value) {
1, 6 -> image.setImageResource(diceDrawables[value - 1])
else -> println("JAUCHE")
}
}
}
}