Home > Software engineering >  How can i improve my code with functions or a class
How can i improve my code with functions or a class

Time:11-12

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")
            }
        }
    }
}
  • Related