[LUA] Caso muy curioso con math.random(x,y)

Bueno, este es mi primer programa en LUA (Y en todo, vamos jejejej) asi que aparte de la solucion al problema, tambien agradeceria criticas que me puedan ayudar a mejorar.
Lo que he hecho no es mas que un simulador de combates entre unidades de Warhammer, cogiendo los atributos de un archivo *.lua facil de modificar. Tambien resulta muy facil añadir otras opciones.
El problema en cuestion es que, en el primer turno SIEMPRE gana la iniciativa el jugador, este provoca 3 impactos y luego 1 herida. La respuesta de la CPU siempre es la misma tambien. Los siguientes turnos ya son diferentes en cada ejecucion, pero el primero siempre es igual, no se que pasa. El codigo en cuestion es este (La parte critica es la funcion simular(unit1,unit2)):
--Simulador de combates entre unidades de Warhammer Fantasy
white = Color.new(255,255,255)
menu = "on"
impactos = 0
heridas = 0
unidad = "jugador"
jugador = "elegir"
cpu = "sinelegir"
game = "iniciativa"
oldpad = Controls.read()
System.usbDiskModeActivate()
function startvariables(unit1,unit2)
jugadorAt = {}
dofile("./"..unit1..".lua")
jugadorAt[1] = HA
jugadorAt[2] = Fuerza
jugadorAt[3] = Resistencia
jugadorAt[4] = Heridas
jugadorAt[5] = Iniciativa
jugadorAt[6] = Ataques
jugadorAt[7] = Liderazgo
jugadorAt[8] = Salvacion
jugadorAt[9] = Unidades
cpuAt = {}
dofile("./"..unit2..".lua")
cpuAt[1] = HA
cpuAt[2] = Fuerza
cpuAt[3] = Resistencia
cpuAt[4] = Heridas
cpuAt[5] = Iniciativa
cpuAt[6] = Ataques
cpuAt[7] = Liderazgo
cpuAt[8] = Salvacion
cpuAt[9] = Unidades
end
function mostraratrib(A,B)
screen:print(5,10,"Jugador:",white)
screen:print(0,20,"HA="..A[1].."  F="..A[2].."  R="..A[3].."  H="..A[4].."  I="..A[5].."  A="..A[6].."  L="..A[7].."  S="..A[8].."+",white)
screen:print(20,30,"Unidades restantes:"..A[9],white)
screen:print(5,40,"CPU:",white)
screen:print(0,50,"HA="..B[1].."  F="..B[2].."  R="..B[3].."  H="..B[4].."  I="..B[5].."  A="..B[6].."  L="..B[7].."  S="..B[8].."+",white)
screen:print(20,60,"Unidades restantes:"..B[9],white)
end
function simular(unit1,unit2)
while true do
screen:clear()
mostraratrib(jugadorAt,cpuAt)
if game == "iniciativa" then
if cpuAt[5] > jugadorAt[5] then
init = "cpu"
end
if cpuAt[5] < jugadorAt[5] then
init = "jugador"
end
if cpuAt[5] == jugadorAt[5] then
dado = math.random(1,6)
if dado == 1 or dado == 2 or dado == 3 then
init = "jugador"
end
if dado == 4 or dado == 5 or dado == 6 then
init = "cpu"
end
end
heridas = 0
impactos = 0
screen:print(10,80,init.." tiene la iniciativa",white)
screen.flip()
game = "ingame"
end
screen.waitVblankStart(60)
if game == "ronda1jugador" then
screen.waitVblankStart()
screen:clear()
mostraratrib(jugadorAt,cpuAt)
screen:print(10, 80, "CPU responde a tu ataque",white)
screen.waitVblankStart()
screen.flip()
init = "cpu"
end
if game == "ronda1cpu" then
screen.waitVblankStart()
mostraratrib(jugadorAt,cpuAt)
screen:print(10, 80, "Respondes al ataque",white)
screen.waitVblankStart()
screen.flip()
init = "jugador"
end
if init == "cpu" then
if cpuAt[9] < 4 then
B = cpuAt[9] * cpuAt[6]
else
B = 4 * cpuAt[6]
end
if game == "ronda1jugador" then
B = B - heridas
end
heridas = 0
impactos = 0
for a=1 , B do
dado = math.random(1,6)
if cpuAt[1] > jugadorAt[1] and math.random(1,6) > 2 then
impactos = impactos + 1
end
if cpuAt[1] >= jugadorAt[1] and cpuAt[1] <= jugadorAt[1] + 2 and math.random(1,6) > 3 then
impactos = impactos + 1
end
if cpuAt[1] == 1 and jugadorAt[1] > 2 and math.random(1,6) > 4 then
impactos = impactos + 1
end
if cpuAt[1] == 2 and jugadorAt[1] > 4 and math.random(1,6) > 4 then
impactos = impactos + 1
end
if cpuAt[1] == 3 and jugadorAt[1] > 6 and math.random(1,6) > 4 then
impactos = impactos + 1
end
if cpuAt[1] == 4 and jugadorAt[1] > 8 and math.random(1,6) > 4 then
impactos = impactos + 1
end
end
screen:clear()
screen:print(10,130,"Te han hecho "..impactos.." impactos",white)
mostraratrib(jugadorAt,cpuAt)
screen.flip()
screen.waitVblankStart(180)
for a = 1 , impactos do
dado = math.random(1,6)
if cpuAt[2] == jugadorAt[3] and math.random(1,6) > 3 then
heridas = heridas + 1
end
if cpuAt[2] + 1 == jugadorAt and math.random(1,6) > 4 then
heridas = heridas + 1
end
if cpuAt[2] + 2 == jugadorAt[3] and math.random(1,6) == 6 or cpuAt[2] + 3 == jugadorAt[3] and math.random(1,6) == 6 then
heridas = heridas + 1
end
if cpuAt[2] - 1 == jugadorAt[3] and math.random(1,6) > 2 then
heridas = heridas + 1
end
if cpuAt[2] - 1 > jugadorAt[3] and math.random(1,6) > 1 then
heridas = heridas + 1
end
end
screen:clear()
screen:print(10,150,"Te han hecho "..heridas.." heridas",white)
mostraratrib(jugadorAt,cpuAt)
screen.flip()
screen.waitVblankStart(180)
if game == "ronda1jugador" then
game = "iniciativa"
else
game = "ronda1cpu"
end
jugadorAt[9] = jugadorAt[9] - heridas
end
if init == "jugador" then
if jugadorAt[9] < 4 then
B = jugadorAt[9] * jugadorAt[6]
else
B = 4 * jugadorAt[6]
end
if game == "ronda1cpu" then
B = B - heridas
end
heridas = 0
impactos = 0
for a=1 , B do
dado = math.random(1,6)
if jugadorAt[1] > cpuAt[1] and math.random(1,6) > 2 then
impactos = impactos + 1
end
if jugadorAt[1] >= cpuAt[1] and jugadorAt[1] <= cpuAt[1] + 2 and math.random(1,6) > 3 then
impactos = impactos + 1
end
if jugadorAt[1] == 1 and cpuAt[1] > 2 and math.random(1,6) > 4 then
impactos = impactos + 1
end
if jugadorAt[1] == 2 and cpuAt[1] > 4 and math.random(1,6) > 4 then
impactos = impactos + 1
end
if jugadorAt[1] == 3 and cpuAt[1] > 6 and math.random(1,6) > 4 then
impactos = impactos + 1
end
if jugadorAt[1] == 4 and cpuAt[1] > 8 and math.random(1,6) > 4 then
impactos = impactos + 1
end
end
screen:clear()
screen:print(10,130,"Has hecho "..impactos.." impactos",white)
mostraratrib(jugadorAt,cpuAt)
screen.flip()
screen.waitVblankStart(180)
for a = 1 , impactos do
dado = math.random(1,6)
if jugadorAt[2] == cpuAt[3] and math.random(1,6) > 3 then
heridas = heridas + 1
end
if jugadorAt[2] + 1 == cpuAt and math.random(1,6) > 4 then
heridas = heridas + 1
end
if jugadorAt[2] + 2 == cpuAt[3] and math.random(1,6) == 6 or jugadorAt[2] + 3 == cpuAt[3] and dado == 6 then
heridas = heridas + 1
end
if jugadorAt[2] - 1 == cpuAt[3] and math.random(1,6) > 2 then
heridas = heridas + 1
end
if jugadorAt[2] - 1 > cpuAt[3] and math.random(1,6) > 1 then
heridas = heridas + 1
end
end
screen:clear()
screen:print(10,150,"Has hecho "..heridas.." heridas",white)
mostraratrib(jugadorAt,cpuAt)
screen.flip()
screen.waitVblankStart(180)
if game == "ronda1cpu" then
game = "iniciativa"
else
game = "ronda1jugador"
end
cpuAt[9] = cpuAt[9] - heridas
end
end
end
while true do
if menu == "off" then
simular(unit1,unit2)
end
screen:clear()
screen:print(10,10,"Selecciona unidad "..unidad..":",white)
screen:print(10,20,"X - Lanceros Elfos Oscuros",white)
pad = Controls.read()
if jugador == "elegir" and pad:cross() then
unidad = "CPU"
jugador = "sinelegir"
cpu = "elegir"
unit1 = "EO"
oldpad = pad
end
if cpu == "elegir" and pad:cross() and oldpad:cross() ~= pad:cross() then
unit2 = "EO"
cpu = "sinelegir"
end
if cpu == "sinelegir" and jugador == "sinelegir" then
screen:clear()
screen:print(10,10,"Unidades elegidas",white)
screen.flip()
screen.waitVblankStart(60)
startvariables(unit1,unit2)
simular(unit1,unit2)
end
screen.flip()
screen.waitVblankStart()
oldpad = pad
end

Y el archivo EO.lua es este:
HA = 4
Fuerza = 3
Resistencia = 3
Heridas = 1
Iniciativa =5
Ataques = 1
Liderazgo = 8
Salvacion = 5
Unidades = 16


NOTA: Aun quedan algunas cosillas por implementar, pero primero queria solucionar este problema.
Desconozco Lua pero al menos en los demas lenguajes que conozco, pues random no es realmente numeros aleatorios como tal, te explico:

random se inicializa con un numero que se le llama semilla, si lo inicializas con el 5 por ejemplo, podria dar esta secuencia (me la estoy imaginando):

1, 5, 3, 6, 2....

Si la vuelves a inicializar con 5, la secuencia será igual y siempre lo será.

Entonces, la idea es inicializar random con un numero distinto cada vez para que la secuencia cambie siempre, entonces lo que se suele usar es la hora actual que siempre es distinta (ya que el numero constaria de hora, minutos y segundos).

Asi que no es un caso curioso, simplemente has pensado que random era realmente numeros aleatorios, pero no es así :)


Un saludo.
Pon al principio del codigo math.randomseed( os.time() ) y ya funcionará bien.
2 respuestas