Help implementing a random card generator/ need code review

Godot Version###

4.4.1

Question###

I was wondering if someone could review my code and give me feedback on how to improve it and tell me if there was a better way to implement what I am trying to implement here.

A little bit of background: the game I am working on uses a system called crazy cards which are randomly generated cards that affect the way you gamble for now I’ve hard coded the generator and the system that applies the effects I’ve worked on some of them but it is only about 5-9 out of 30 so I would like to hear if any body has a way better way of implementing a system that generates 3 random cards from a database then displays them on screen at the end of the round for the player to choose and then applies the effect of the card that was selected or stack it

the code is in spanish so if you need me to translate any of the variable names please ask
##code for generator and effect applier##
’ ’ 'gdscript

extends Node
#Nodos/Objetos
@onready var cartas_locas_canvas: CanvasLayer = %cartasLocasCanvas
@onready var ui_canvas: CanvasLayer = %uiCanvas
@onready var carta_loca_1: Sprite2D = %cartaLoca1
@onready var carta_loca_2: Sprite2D = %cartaLoca2
@onready var carta_loca_3: Sprite2D = %cartaLoca3
@export var info:PersonajeInfo
@export var prestamoInfo:infoPrestamo
@export var infoCasino:casinoInfo
@onready var sub_0_sprite: Sprite2D = %sub0Sprite
@onready var fondo_451: Sprite2D = %fondo451
@onready var _451_sprite: Sprite2D = %"451Sprite"
@onready var fondo_sub_0: Sprite2D = %fondoSub0
@onready var no: Label = %no
@onready var si: Label = %si
@onready var pregunta: Label = %pregunta
@onready var cuadrado_grande: Sprite2D = %cuadradoGrande
@onready var maquina_slot_sprite: Sprite2D = %maquinaSlotSprite
@onready var canvas_prestamos: CanvasLayer = %canvasPrestamos
@export var CasinoRojoInfo:infoCasinoRojo
@onready var sprite_plata: Sprite2D = %spritePlata
@onready var sprite_oro: Sprite2D = %spriteOro




#Variables
var nivelMaquina = 0
var luckyHat = false
var contadorLoco = 0
var numRandAnt = []
var infoCarta1 = []
var infoCarta2 = []
var infoCarta3 = []
var arregloCartaEscojida = []
var cartasLocas = []
var probabilidadPolicia = 0
var gananciasMejoradas = 0 
var puedeEnfriar = false
var puedeCalentar = false
var calentarPagado = false
var enfriarPagado = false
var fichas = 0
var quiereActivar = false
var casinoactual:int = 0

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	pass # Replace with function body.

func recivirCasinoActual():	
	pass

func _on_boton_carta_loca_1_button_down() -> void:
	print("Estoy activando la carta")
	arregloCartaEscojida.append(infoCarta1[0])
	cartasLocas.append([arregloCartaEscojida[0][0],arregloCartaEscojida[0][1]])
	info.cartasLocas.append(cartasLocas[0])
	activarTarjeta()
	infoCarta2.clear()
	infoCarta3.clear()
	cartas_locas_canvas.visible = false
	ui_canvas.visible = true
	numRandAnt.clear()
	pass # Replace with function body.


func _on_slot_machine_hacer_targetas() -> void:
	contadorLoco = 0
	arregloCartaEscojida.clear()
	infoCarta1.clear()
	infoCarta2.clear()
	infoCarta3.clear()
	while contadorLoco < 3:
		queryTarjetas()
	ui_canvas.visible = false
	cartas_locas_canvas.visible = true
	pass # Replace with function body.

#Hacer un query para generar tres tarjetas aleatoriamente
func queryTarjetas():
	#despues de generar las tarjetas aadelas al array de cartasLocas del jugador
	print("Hola")
	var database : SQLite
	var numRand = randi_range(18,47)
	while numRand in numRandAnt:
		numRand = randi_range(18,47)
	var rng = RandomNumberGenerator.new()
	database = SQLite.new()
	database.path = "res://data.db"
	database.open_db()
	database.select_rows("cartas_locas", "id = " + str(numRand), ["*"])
	
	for j in database.query_result:
		var id = int(j.ID)
		var desc = j.descripcion
		var limite = j.Duracion
		var image = Image.new()
		image.load_png_from_buffer(j.Imagen)
		var texture = ImageTexture.create_from_image(image)
		contadorLoco = contadorLoco + 1
		if numRand not in numRandAnt:
			match contadorLoco:
				1:
					carta_loca_1.texture = texture
					infoCarta1.append([id,limite,desc])
					print("infoCarta1:", infoCarta1)

				2:
					carta_loca_2.texture = texture
					infoCarta2.append([id,limite,desc])
				3:
					carta_loca_3.texture = texture
					infoCarta3.append([id,limite,desc])
			numRandAnt.append(numRand)
		else:
			contadorLoco = contadorLoco - 1

func activarTarjeta():
	#activar la tarjeta que corresponde
	var id = arregloCartaEscojida[0][0]
	print(id)
	var limite = arregloCartaEscojida[0][1]
	var desc = arregloCartaEscojida[0][2]
	match id:
		#sub 0
		18:
			print("Puede enfriar")
			puedeEnfriar = true
			sub_0_sprite.visible = true
			fondo_sub_0.visible = true
		#Speed round
		19:
			pass
		#NPC repellent
		20:
			info.apestoso = true
		#451 farenheiht
		21:
			print("Puede calentar")
			puedeCalentar = true
			_451_sprite.visible = true
			fondo_451.visible = true
		#Police chatter
		22:
			pass
		#Fixed game
		23:
			pass
		#Vip Access
		24:
			pass
		#Bad Omen
		25:
			pass
		#Weigthed die
		26:
			pass
		#Tony's Luck
		27:
			pass
		#Eye of Cards
		28:
			pass
		#Slot Upgrade
		29:
			nivelMaquina = CasinoRojoInfo.mejorarSlotMachine()
			actualizarSprites()
			pass
		#Winning Edge
		30:
			pass
		#Pay to Play
		31:
			pass
		#RoadSide Game
		32:
			pass
		#Hot tables
		33:
			
			pass
		#Hidden Cards
		34:
			pass
		#Game Clossings
		35:
			pass
		#Tech Savvy
		36:
			pass
		#New Player
		37:
			pass
		#Lucky Hat
		38:
			luckyHat = true
			CasinoRojoInfo.luckyHat = luckyHat
			pass
		#Smart Team
		39:
			pass
		#Finnancial Advisor
		40:
			pass
		#Black Tuesday
		41:
			pass
		#Risky stocks
		42:
			pass
		#Bribery
		43:
			pass
		#Stonks
		44:
			pass
		#Back street Game
		45:
			pass
		#An Expert lier
		46:
			pass
		#We play fairly
		47:
			pass

func desactivarTarjeta():
	pass

signal pagoFrio
signal pagoCaliente
signal quierePrestamos
func _on_boton_si_button_down() -> void:
	fichas = info.fichas
	var precio = 2000
	if info.cartaFria:
		if fichas - precio < 10:
			canvas_prestamos.visible
			emit_signal("quierePrestamos")
		elif fichas - precio >= 10:
			fichas = fichas - precio
			info.fichas = fichas
			info.actualizarFichas()
			enfriarPagado = true
			if enfriarPagado:
				gananciasMejoradas = 0
				probabilidadPolicia = 0
				infoCasino.probabilidadPolicia = probabilidadPolicia
				infoCasino.gananciasMejoradas = gananciasMejoradas
				emit_signal("pagoFrio")
	elif info.cartaCaliente:
		if fichas - precio < 10:
			canvas_prestamos.visible
			emit_signal("quierePrestamos")
		elif fichas - precio >= 10:
			fichas = fichas - precio
			info.fichas = fichas
			info.actualizarFichas()
			calentarPagado = true
			if calentarPagado:
				gananciasMejoradas = 0.5
				probabilidadPolicia = 0.8
				infoCasino.probabilidadPolicia = probabilidadPolicia
				infoCasino.gananciasMejoradas = gananciasMejoradas
				emit_signal("pagoCaliente")
	cuadrado_grande.visible = false
	si.visible = false
	no.visible = false
	pregunta.visible = false
	hacerVisible()
func _on_slot_machine_activar_tarjeta() -> void:
	pass


func hacerVisible():
	ui_canvas.visible = true
	maquina_slot_sprite.visible = true
	cuadrado_grande.visible = false
	pregunta.text = "Do  you wish to activate the Sub0  card for $" + str(2000)
	si.visible = false
	no.visible = false
	pregunta.visible = false
	info.cartaFria = false


func _on_boton_carta_loca_2_button_down() -> void:
	print("Estoy activando la carta")
	arregloCartaEscojida.append(infoCarta2[0])
	cartasLocas.append([arregloCartaEscojida[0][0],arregloCartaEscojida[0][1]])
	info.cartasLocas.append(cartasLocas[0])
	activarTarjeta()
	infoCarta1.clear()
	infoCarta3.clear()
	cartas_locas_canvas.visible = false
	ui_canvas.visible = true
	numRandAnt.clear()
	pass # Replace with function body.


func _on_boton_carta_loca_3_button_down() -> void:
	print("Estoy activando la carta")
	arregloCartaEscojida.append(infoCarta3[0])
	cartasLocas.append([arregloCartaEscojida[0][0],arregloCartaEscojida[0][1]])
	info.cartasLocas.append(cartasLocas[0])
	activarTarjeta()
	infoCarta1.clear()
	infoCarta2.clear()
	cartas_locas_canvas.visible = false
	ui_canvas.visible = true
	numRandAnt.clear()
	pass # Replace with function body.

func actualizarSprites():
	match nivelMaquina:
		2:
			maquina_slot_sprite.texture = sprite_plata.texture
			pass
		3:
			maquina_slot_sprite.texture = sprite_oro.texture
			pass

‘’’

The first thing I’d say is, please put that code in backticks:

```gdscript
code
code
code
```

That will format much more nicely:

code
code
code

alright got it fixed thanks for the suggestion

1 Like

You might find it easier to do named functions for your cards and stick them in an array.

# Untested...

var card_funcs = [
    card_0,
    card_1,
    # ...
    card_sub_zero,
    card_speed_round,
    card_npc_repellant
    # ...
]

func card_sub_zero():
    print("Puede enfriar")
    puedeEnfriar         = true
    sub_0_sprite_visible = true
    fondo_sub_0.visible  = true

# ...

func activarTarjeta():
    #activar la tarjeta que corresponde
    var id = arregloCartaEscojida[0][0]
    print(id)
    var limite = arregloCartaEscojida[0][1]
    var desc = arregloCartaEscojida[0][2]
    card_funcs[id].call()

Or stick them in a dictionary so you can refer to them by name.

Something odd is going on with queryTarjetas(); I don’t think that while loop over NumRandAnt is going to do what you think it is. You’re changing whatever values you get out of the array, but since they’re int, I don’t think they get written back. They’re just being dropped.

You’re also declaring numRand and then immediately shadowing it with a different numRand in the while loop.

You probably want something more like (please excuse my poor Spanish…):

func queryTarjetas(num: int) -> Array:
    var cartas: Array = []
    cartas.resize(num)
    for c in num:
        var i = randi_range(18, 47)
        # do database fetch here...
        cartas[c] = { "index": i, "texture": tex, "limite": limite, "desc": desc }
    return cartas

Thanks for the suggestion I’ve started implementing the named functions part and it has been a lot easier going through my code. I was wondering if you could explain the problem on the while loop a bit further having a little difficulty understanding it the main part I am struggling with understanding is you said that since they are int you don’t think they get written back but instead being dropped and you also said I am shadowing my initial numRand with a new one thats inside of the while loop

func queryTarjetas():
	#despues de generar las tarjetas aadelas al array de cartasLocas del jugador
	print("Hola")
	var database : SQLite

    # This line declares `numRand` and gives it a value between 18 and 47.
	var numRand = randi_range(18,47)

    #     This pair of lines declares a new `numRand` which is only around for
    # the duration of the loop.  Inside the loop, the `numRand` on the line
    # above is shadowed, which means any attempts to read or write `numRand`
    # will access the loop var, not the var above.
	while numRand in numRandAnt:
        #     `numRand` here would be each element in `numRandAnt` in succession
        # as the while loop iterates over `numRandAnt`, except I think at this
        # point `numRandAnt` is an empty array, so this loop won't do anything.
        #     If `numRandAnt` did have some elements, this would be giving
        # `numRand` a copy of the element, since the elements are integers,
        # and integers are "value" vars, not "reference" vars.  So, say
        # `numRandAnt` was [24, 31, 19], the first iteration through the loop
        # this will do `numRand = 24` and then immediately overwrite that with
        # the random call.  Whatever is in `numRand` at that point is discarded,
        # because we're at the end of the loop iteration and it's about to do
        # `numRand = 31`.  Nothing writes any of this back into `numRandAnt`.
		numRand = randi_range(18,47)

    # As far as I can see, nothing is using `rng`.
	var rng = RandomNumberGenerator.new()
	database = SQLite.new()
	database.path = "res://data.db"
	database.open_db()

    #     `numRand` here is the first `var numRand` declared above the loop, 
    # with the first random value generated near the top of the function.
	database.select_rows("cartas_locas", "id = " + str(numRand), ["*"])

    #     I would expect you'd get only one query result, since you're
    # specifying only one ID, here, but I don't know your database schema.
	for j in database.query_result:
		var id = int(j.ID)
		var desc = j.descripcion
		var limite = j.Duracion
		var image = Image.new()
		image.load_png_from_buffer(j.Imagen)
		var texture = ImageTexture.create_from_image(image)

        #     You might find this cleaner if you get rid of the `else:` condition
        # and only increment `contadorLoco` inside the `if:`.
		contadorLoco = contadorLoco + 1
		if numRand not in numRandAnt:
            # contadorLoco += 1
			match contadorLoco:
				1:
					carta_loca_1.texture = texture
					infoCarta1.append([id,limite,desc])
					print("infoCarta1:", infoCarta1)

				2:
					carta_loca_2.texture = texture
					infoCarta2.append([id,limite,desc])
				3:
					carta_loca_3.texture = texture
					infoCarta3.append([id,limite,desc])
			numRandAnt.append(numRand)
        #     This else block could be removed if you increment inside the `if:`,
        # above.
		else:
			contadorLoco = contadorLoco - 1

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.