https://kotlinlang.org logo
#getting-started
Title
# getting-started
h

HighTide

10/18/2023, 5:42 PM
Hello, I want to get a slight suggestion regarding a program I am writing, so far I have created 2 singleton objects a menuLoader and an ActionHandler. The menuLoader is (for now) responsible for displaying information of objects such as player stats and options they can pick where options are taken from a repository of objects that have a parent called Action (example there can be 2 subclasses of Action like ExitGame and OpenShop) now I want to somehow find a way to pipeline any chosen option by the user to the actionHandler, one simple way would be just make it in the sequential manner and explicitly pass the action object after doing some validation, but I was wondering if there is a more efficient way to go about that functionality. If anyone wants a more detailed overview they can check out the codebase here.
s

Stephan Schröder

10/18/2023, 6:27 PM
things I noticed: • IntelliJ starts with downloading Amazon Corretto, it's a sideeffect of
jvmtoolchain
. I tend to disable the autodownload of JDKs by adding
org.gradle.java.installations.auto-download=false
into my gradle.properties file, since my installed JDK should already be able to handle JVM8 bytecode. • you don't have to specify
MenuOption<out Actions>
if you push the
out
into the declaration of
MenuOption
->
data class MenuOption<out T : Actions> (...
• having
val menuOptions: ArrayList<MenuOption<Actions>> = ArrayList()
being a global, mutable list. Global data is basically only ok, if it's immutable (not only the list, but also the elements it contains.
MenuOption
seem immutable, but they contain
Actions
which are not. Also your list type is ArrayList, which is a mutable List. Mutable data is fine(-ish), but try to wrap it in a class to make access to it safer •
MenuLoader.displayChoices
doesn't need a
MutableList/ArrayList
to work, so it should only required an unmodifiable one:
fun displayChoices(optionsToDisplay: ArrayList<MenuOption<Actions>>) {
MenuLoader.selectedOptionCaller
needs a
MutableList
but doesn't need to know that it's an
ArrayList
->
fun selectedOptionCaller(choiceIndex: Int, optionsToDisplay: MutableList<MenuOption<Actions>>): Actions {
• maybe it would be a good idea if
MenuLoader
was the owner of
menuOptions
!? It could hold a private mutable version and only provide an unmodifiable List to the outside while still being able to mutate the list itself.
Copy code
object MenuLoader {
    private val menuOptions: MutableList<MenuOption<Actions>> =
        ArrayList().apply {
            add(MenuOption(OpenShopAction(), "Open Shop"))
            add(MenuOption(ExitAction(), "Exit"))
        } 

    fun displayChoices() {
        for ((i, menuOption) in optionsToDisplay.withIndex()) {
            println("$i: ${menuOption.dialogToScreen}");
        }
    }

    fun selectedOptionCaller(choiceIndex: Int): Actions {
        val newActionToCall = menuOptions.get(choiceIndex).action
        if (newActionToCall.reducable == true) {
            menuOptions.removeAt(choiceIndex); // as long as this is single-threaded it's fine, otherwise we need a ReadWriteLock around reading from/writing to menuOptions
        }
        return newActionToCall;
    }
}
A game is a great way to learn programming. Keep at it! If you finish it, even if the game is simple, you'll have achieved something 👍
🙌 1
h

HighTide

10/18/2023, 7:32 PM
Hello, If I want to do something very personalized such as keeping the state of the game so that someone can pick up where they left off, should I use some sort of serialization to make it so that I can make that possible or is there any other way i can conserve the state of my program when someone exits so that they can pick up where they left off. Thank you so much for taking time and looking at the code and suggesting valuable changes, I am going to implement and fix the issues so that the code is safer and can only be accessed by objects that are intended to be using them.
s

Stephan Schröder

10/19/2023, 12:11 PM
saving the state of your program is -by definition- a form of serialization. Go for it 👍 The default serialization lib for Kotlin is kotlinx.serialization .