Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
wyvern.jl 2.52 KiB
### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
###
### This file holds the code for the Wyvern (https://en.wikipedia.org/wiki/Wyvern).
### NOT FOR ACTUAL USE! This is of course only a test species ;-)
### Thankfully, wyverns are not a species we have to manage for...
###

"""
Beware the wyvern! This evolutionary cousin of the dragon may only have two
legs, but that doesn't make it any less dangerous...
"""
@species Wyvern begin
    popsize = 10
    fecundity = 0.02
    maxage = 365
    speed = 20
    vision = 50
    aggression = 0.2
    huntsuccess = 0.8

    @initialise(winter,
                habitat=@habitat(@landcover() in (grass, soil, agriculture, builtup)),
                popsize=popsize)
end

"""
Wyverns are ferocious hunters, scouring the landscape for their favourite
prey: wolpertingers...
"""
@phase Wyvern.summer begin
    for a in @neighbours(self.speed)
        # check if a wolpertinger is in pouncing distance
        if typeof(a) == Wolpertinger
            move_agent!(self, a.pos, model)
            if @rand() < self.huntsuccess
                @debug "$(animalid(self)) killed $(animalid(a))."
                kill!(a, model)
                @goto reproduce
            end
        elseif typeof(a) == Wyvern && @rand() < self.aggression
            # wyverns also fight against each other if they get too close
            move_agent!(self, a.pos, model)
            outcome = @rand()
            if outcome < 0.4
                @debug "$(animalid(self)) killed $(animalid(a)) in a fight."
                kill_agent!(a, model)
            elseif outcome < 0.8
                @kill 1.0 "wounds sustained in a fight"
            end
            @goto reproduce
        end
    end
    # check if a wolpertinger is in seeing distance, or walk in a random direction
    direction = Tuple(@rand([-1,1], 2))
    for a in @neighbours(self.vision)
        if typeof(a) == Wolpertinger
            direction = get_direction(self.pos, a.pos, model)
            break
        end
    end    
    for i in 1:self.speed
        walk!(animal, direction, model; ifempty=false)
    end
    # reproduce every once in a blue moon
    @label reproduce
    (@rand() < self.fecundity) && @reproduce(-1)
    # hibernate from November to March
    month(model.date) >= 11 && (@setphase(winter))
    (self.age == maxage) && @kill(1.0, "old age")
end

"""
Fortunately, wyverns hibernate in winter.
"""
@phase Wyvern.winter begin
    # hibernate from November to March
    if month(model.date) >= 3
        @setphase(summer)
    end
end