DataFrames related stack overflow

question
bug

#1

Hey there!
I’m relatively new to Julia and I’ve encountered an error I don’t understand.
It seems like I’m getting a stack overflow when indexing a DataFrame - here’s the error message:

ERROR: LoadError: StackOverflowError:
 in ht_keyindex(::Dict{Symbol,Int64}, ::Symbol) at ./dict.jl:0
 in getindex at ./dict.jl:696 [inlined]
 in getindex(::DataFrames.Index, ::Symbol) at /home/undef/.julia/v0.5/DataFrames/src/other/index.jl:114
 in getindex(::DataFrames.DataFrame, ::Int64, ::Symbol) at /home/undef/.julia/v0.5/DataFrames/src/dataframe/dataframe.jl:244
 in attack(::Dict{Int64,Int64}, ::Int64, ::Int64, ::Bool) at /home/undef/julia/gameUnitsGenModel.jl:6
 in fight(::Dict{Int64,Int64}, ::Int64, ::Int64) at /home/undef/julia/gameUnitsGenModel.jl:27
 in fight(::Dict{Int64,Int64}, ::Int64, ::Int64) at /home/undef/julia/gameUnitsGenModel.jl:31 (repeats 124 times)
while loading /home/undef/julia/gameUnitsGenModel.jl, in expression starting on line 59

And here’s the code that causes it:


using DataFrames
using Distributions

function attack( hp, self, other, retrigger=false )
    dmg = units[self, :atk]
    dmg = dmg - units[other, :def]
    if dmg<=0  return  end
    speedDelta = units[self, :spd] - units[other, :spd]
    if speedDelta<0
        avoidanceProb = -3*speedDelta/100
        if rand()<=avoidanceProb
            dmg = 0 #missed
        end
    end
    hp[other] = max( 0, hp[other] - dmg )
    if speedDelta>0 && hp[other]!=0 && !retrigger
        retriggerProb = 3*speedDelta/100
        if rand()<=retriggerProb
            return attack( hp, self, other, true )
        end
    end
end

function fight( hp, a, b )
    attack( hp, a, b )
    if hp[b]==0  return a  end
    attack( hp, b, a )
    if hp[a]==0  return b  end
    fight( hp, a, b )
end;
function combat( a, b )
    hp = Dict(a=>units[a, :hp], b=>units[b, :hp])
    winner = fight( hp, a, b )
    units[winner, winner==a ? :awins : :dwins] += 1
end

function sampleUnits( n, d = BetaBinomial( 20, 10, 10 ) )
    f() = rand( d, n )
    units = DataFrame( hp = f(), atk = f(), def = f(), spd = f(), awins = fill(0,n), dwins = fill(0,n),
                       alvl = fill(0,n), dlvl=fill(0,n))
end

function sampleCombats( clear )
    numUnits = length( units[:hp])
    if clear
        units[:awins] = fill( 0, numUnits )
        units[:dwins] = fill( 0, numUnits )
    end

    for i in 1:(numUnits-1)
        for j in (i+1):numUnits
            for _ in 1:10000
                combat( i, j )
                combat( j, i )
            end
            if units[i,:awins]>=5000  units[i, :alvl]+=1  else  units[j, :dlvl]+=1  end
            if units[i,:dwins]>=5000  units[i, :dlvl]+=1  else  units[j, :alvl]+=1  end
            units[i,:awins], units[i,:dwins], units[j,:awins], units[j,:dwins] = 0, 0, 0, 0
        end
    end
end

units = sampleUnits(10)

sampleCombats(true)

If anyone has a clue what goes wrong here, help would be highly appreciated!
Thank you very much!

undef


#2

The error message tells you where the error occurred. That would be a good place to start. From there, a smaller reproducible example would be easier to offer help on.


#3

Found the error, it was a simple misassumption that caused the function not to terminate if unlucky.
Oh well…
Thanks anyway!