158 lines
No EOL
3.7 KiB
Nim
158 lines
No EOL
3.7 KiB
Nim
import print
|
|
import arraymancer
|
|
import sequtils
|
|
import sugar
|
|
import json
|
|
import std/jsonutils
|
|
type tile = ref object of RootObj
|
|
N : float
|
|
K : float
|
|
P : float
|
|
S : float
|
|
M : float
|
|
type plant = ref object of tile
|
|
plantGrowProgress : float
|
|
noGrowth : int
|
|
|
|
proc wheatUptake(a :var plant, b : var tile, baseEfficiency : float) =
|
|
var
|
|
drawnS = b.S*baseEfficiency
|
|
#young plants draw more K
|
|
drawnK = b.K*(baseEfficiency)+0.1
|
|
|
|
drawnN = b.N*baseEfficiency
|
|
drawnP = b.P*baseEfficiency
|
|
|
|
let nToS = drawnN / drawnS
|
|
|
|
#leads to nitrogen deficiency
|
|
if nToS > 19.0 and 22.0 > nToS:
|
|
drawnN = drawnN * 0.5
|
|
elif nToS > 22.0:
|
|
drawnN = drawnN * 0.1
|
|
elif 12 > nToS and nToS > 9:
|
|
drawnN = drawnN * 0.5
|
|
elif 9 > nToS:
|
|
drawnN = drawnN * 0.1
|
|
#etc
|
|
#
|
|
b.S-=drawnS
|
|
b.K-=drawnK
|
|
b.N-=drawnN
|
|
b.P-=drawnP
|
|
a.S+=drawnS
|
|
a.K+=drawnK
|
|
a.N+=drawnN
|
|
a.P+=drawnP
|
|
|
|
proc wheatGrowth(a :var plant) =
|
|
var nToS = a.N / a.S
|
|
var nToK = a.N / a.K
|
|
var nToP = a.N / a.P
|
|
#print(nToS,nToP, nToK)
|
|
var baseGrowthPoint = 1.0
|
|
let minimumMass = 5.0
|
|
let maxBoost = 4
|
|
if a.plantGrowProgress >= 100.0 or a.noGrowth >= 20:
|
|
a.plantGrowProgress = 0.0
|
|
a.noGrowth = 0
|
|
if nToK > 1.7:
|
|
a.noGrowth+=1
|
|
return
|
|
elif nToK > 1.3 and 1.5 > nToK:
|
|
baseGrowthPoint+= 1.0
|
|
elif 1.3 > nToK and nToK > 0.7:
|
|
discard
|
|
elif 0.7 > nTok:
|
|
a.noGrowth+=1
|
|
return
|
|
|
|
if nToS > 19.0 and 22.0 > nToS:
|
|
baseGrowthPoint-= 0.5
|
|
elif nToS > 22.0:
|
|
a.noGrowth+=1
|
|
return
|
|
elif 12 > nToS and nToS > 9:
|
|
baseGrowthPoint+= 0.2
|
|
elif 9 > nToS:
|
|
a.noGrowth+=1
|
|
return
|
|
|
|
let mass = a.K + a.P + a.S + a.N
|
|
|
|
if minimumMass > mass:
|
|
a.noGrowth+=1
|
|
return
|
|
var massBoost = mass / minimumMass
|
|
|
|
massBoost = min(4.0, massBoost)
|
|
|
|
a.plantGrowProgress+=massBoost*baseGrowthPoint
|
|
|
|
|
|
let m = 1.0
|
|
let km = 1.227
|
|
|
|
let minDraw = 10
|
|
let maxBonus = 4
|
|
let drawRateBase = 0.001
|
|
|
|
proc copyRef[T: ref](r: T): T =
|
|
new result
|
|
result[] = r[]
|
|
|
|
proc addToPool(pool, source : var tile, portion : float ) =
|
|
let
|
|
drawnS = source.S*portion
|
|
drawnK = source.K*portion
|
|
drawnN = source.N*portion
|
|
drawnP = source.P*portion
|
|
source.S-=drawnS
|
|
source.K-=drawnK
|
|
source.N-=drawnN
|
|
source.P-=drawnP
|
|
pool.S+=drawnS
|
|
pool.K+=drawnK
|
|
pool.N+=drawnN
|
|
pool.P+=drawnP
|
|
|
|
let genericTile = tile(S : 22*3, K : (194*km)*3, P : 54*3, M: m, N: (261)*3 )
|
|
var soil = newTensor[tile](toMetadata(30, 30))
|
|
var plants = newTensor[plant](toMetadata(20, 20))
|
|
|
|
for x, v in soil:
|
|
soil[x[0], x[1]] = copyRef genericTile
|
|
for x, v in plants:
|
|
plants[x[0], x[1]] = plant()
|
|
|
|
var plot : (seq[int], seq[float])
|
|
for x in 0 .. 2000:
|
|
block:
|
|
let pos = (0, 0)
|
|
var tileBelow = soil[pos[0], pos[1]]
|
|
var whatever = copyRef genericTile
|
|
#slowly restore nutrients
|
|
addToPool(tileBelow, whatever, drawRateBase)
|
|
|
|
block:
|
|
let pos = (0, 0)
|
|
var tileBelow = soil[pos[0], pos[1]]
|
|
#concentrate to of crops, simulates drawing from around nearby soil
|
|
|
|
#bleeds away plants nutrients over time
|
|
var plant = plants[pos[0], pos[1]]
|
|
var devnull = tile()
|
|
addToPool(devnull, tile(plant), 0.358)
|
|
|
|
block:
|
|
let pos = (0, 0)
|
|
var tileBelow = soil[pos[0], pos[1]]
|
|
var plant = plants[pos[0], pos[1]]
|
|
#the uptake regulates
|
|
wheatUptake(plant, tileBelow, drawRateBase*4)
|
|
wheatGrowth(plant)
|
|
plot[1].add(plant.plantGrowProgress)
|
|
print plants[0, 0]
|
|
print soil[0, 0]
|
|
|
|
writeFile("harapa.json", $(toJson(plot[1]))) |