Problem when instancing classes


#1

Hi,
First of all, I’m not a professional. So… sorry if my doubt sounds stupidly for you. Anyway…
When I try to run this could bellow I got this:

Error:(16, 58) Kotlin: Expression ‘CLASSES[alea.nextInt(CLASSES.size)]’ of type ‘Creature’ cannot be invoked as a function. The function ‘invoke()’ is not found

How can I deal with that? I wanto to creat randomly instances of class of type Creature (contained in a list) with the entries (in the other list).

regardless…me!

val CLASSES :  Array<Creature> =  arrayOf(Ninja(), Samurai(), Chonin(), Geicha())
val NOMES: Array<String> =  arrayOf("Maria", "João", "Makiteru", "Marcelo", "Joana", "Player", "Gamer", "Costinha")
val LISTA:  Array<Creature> =  Array(8 ){ monstro ->  CLASSES[alea.nextInt(CLASSES.size)](NOMES[alea.nextInt(NOMES.size)]) }

#2

It looks like you want to set a property like
name with one of the values in NOMES. To achieve that you should write it like:

val LISTA: Array<Creature> = Array(8){ monstro -> CLASSES[alea.nextInt(CLASSES.size)].name = NOMES[alea.nextInt(NOMES.size)]

#3

Thank you too much! But this doesn’t work, I want to initialize a pair of classes with a name in the list (the only required parameter).

Anyway, you give a good vision for this problem.

But If someone find a way to do this, tell me, please! I want to create classes, use and destroy them after! But how to initialize a class automatically?


#4

I resolved this problem in a away I don’t want. I’ve initialized the classes first and changed its name. It’s sufficiently, but was not what I was looking for… Because of that, I must to change the parameter of initialization ‘val’ to ‘var’.

val CLASSES :  List<Creature> =  listOf(Ninja(), Samurai(), Chonin(), Geicha())
val NOMES: List<String> =   listOf("Maria", "João", "Makiteru", "Marcelo", "Joana", "Player", "Gamer", "Costinha")
for (x in CLASSES)
        {
            x.name =  NOMES[alea.nextInt(NOMES.size)]
        }

#5

Then you can do something like this, create a list of lambdas that take as a parameter the name and return a new instance of the creature:

import java.util.*

fun main(args: Array<String>) {
    val alea = Random()
    
    //sampleStart
    val CLASSES: Array<(String) -> Creature> = arrayOf<(String) -> Creature>({ Ninja(it) }, { Samurai(it) }, { Chonin(it) }, { Geicha(it) })
    val NOMES: Array<String> = arrayOf("Maria", "João", "Makiteru", "Marcelo", "Joana", "Player", "Gamer", "Costinha")
    val LISTA: Array<Creature> = Array(8) { monstro -> CLASSES[alea.nextInt(CLASSES.size)](NOMES[alea.nextInt(NOMES.size)]) }
    //sampleEnd

    LISTA.forEach { println(it.toString()) }
}

abstract class Creature(private val type: String, private val name: String) {
    override fun toString() = "Creature(type='$type', name='$name')"
}

class Ninja(name: String) : Creature("Ninja", name)
class Samurai(name: String) : Creature("Samurai", name)
class Chonin(name: String) : Creature("Chonin", name)
class Geicha(name: String) : Creature("Geicha", name)

This way you can keep the name as a val