Skip to content

Commit

Permalink
V0.1.2 (#3)
Browse files Browse the repository at this point in the history
v0.1.2
  • Loading branch information
garbados authored Nov 13, 2023
1 parent abba6dc commit c12b0b3
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 66 deletions.
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject the-longtime-game "0.1.1-SNAPSHOT"
(defproject the-longtime-game "0.1.2"
:description "The Longtime"
:url "https//github.com/garbados/the-longtime-game"
:license {:name "CC BY-NC-SA"
Expand Down
1 change: 1 addition & 0 deletions src/the_longtime_game/building.clj
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
:filter
{:skills {:herbalism 200 :craftwork 200}
:stores {:wood 300 :rations 150 :poultices 100}
:terrain :forest
:contacts :er-sol}}
{:name :flyer-market
:description "A market for birds and friends of birds."
Expand Down
2 changes: 1 addition & 1 deletion src/the_longtime_game/contact_text.clj
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
but who, to whom, and how much, of what, is necessarily contentious.
No one goes hungry, not in centuries, but a clan without face
has been known to know lean years.
Borrowers, as they are known, are obliged to provide a gift for what is taken,
By giftright, borrowers are expected to provide a gift for what is taken,
which provides an opportunity to attain face,
and in these meetings such things are also arranged.
But now, with such close proximity to the herd's syndicates,
Expand Down
26 changes: 14 additions & 12 deletions src/the_longtime_game/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -221,24 +221,24 @@
(s/def ::traits (s/coll-of ::trait :kind set?))
(s/def ::fulfillment (s/int-in 0 (inc max-fulfillment)))

(defn can-inc-skill? [individual skill]
(> max-skill (get-in individual [:skills skill])))
(defn can-inc-skill? [{:keys [skills]} skill]
(> max-skill (get skills skill 0)))

(s/fdef can-inc-skill?
:args (s/cat :individual ::individual
:args (s/cat :individual (s/keys :req-un [::skills])
:skill ::skill)
:ret boolean?)

(defn inc-some-skill [individual & {:keys [skills]
:or {skills skills}}]
(if-let [skills* (seq (filter (partial can-inc-skill? individual) skills))]
(let [skill (rand-nth skills*)]
(update-in individual [:skills skill] inc))
(update-in individual [:skills skill] #(if % (inc %) 1)))
individual))

(s/fdef inc-some-skill
:args (s/cat :skills ::skills)
:ret ::individual)
:args (s/cat :individual (s/keys :req-un [::skills]))
:ret (s/keys :req-un [::skills]))

(defn get-age [{:keys [month]} {:keys [born]}]
(int (/ (- month born) 12)))
Expand Down Expand Up @@ -618,9 +618,8 @@
::index
::month
::path])
(let [gen-herd* (memoize gen-herd)]
#(g/fmap (fn [_] (gen-herd*))
(g/return 0)))))
#(g/fmap (fn [[individuals]] (gen-herd :individuals individuals))
(g/tuple (s/gen ::individuals)))))

(s/fdef gen-herd
:args (s/keys* :opt-un [::name
Expand Down Expand Up @@ -712,7 +711,7 @@
(let [population (-> herd :individuals count)
optimal (calc-optimal-population herd)
delta (- optimal population)
n (inc (int (Math/abs (Math/log delta))))]
n (+ 2 (int (Math/log (max 1 (Math/abs delta)))))]
(if (> delta 0)
[(rand-int n) (rand-int 2)]
[(rand-int 2) (rand-int n)])))
Expand Down Expand Up @@ -955,10 +954,13 @@
:ret (s/keys :req-un [::path]))

(defn has-lost? [herd]
(= max-hunger (:hunger herd)))
(or (= max-hunger (:hunger herd))
(< 1 (/ (:sickness herd) (count (:individuals herd))))))

(s/fdef has-lost?
:args (s/cat :herd (s/keys :req-un [::hunger]))
:args (s/cat :herd (s/keys :req-un [::hunger
::sickness
::individuals]))
:ret boolean?)

(defn next-location
Expand Down
17 changes: 15 additions & 2 deletions src/the_longtime_game/event.clj
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@
individual
#(update % :traits disj :weary))))})

(def funeral
{:name "Funeral"
:text-fn event-text/funeral
:selects [{}]
:filter-fn
#(< 1 (count (:new-dead %)))
:marshal-fn
(fn [herd & _]
(first (:new-dead herd)))
:effect
(fn [herd & _] herd)})

(def gruxnis-attack!
{:name "Grux'nis attack"
:text-fn event-text/gruxnis-attack!
Expand Down Expand Up @@ -138,12 +150,13 @@
gruxnis-attack!
ration-rot
plague
wound-healed])
wound-healed
crossed-paths])

(def general-events
[journeying-ends
offshoot-joins
crossed-paths])
funeral])

(s/def ::event
(s/with-gen
Expand Down
78 changes: 73 additions & 5 deletions src/the_longtime_game/event_text.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns the-longtime-game.event-text
(:require [clojure.string :as string]
[the-longtime-game.core :as core]))
[the-longtime-game.core :as core]
[the-longtime-game.text :as text]))

(def -trait->adj
{:angry "strong"
Expand Down Expand Up @@ -86,8 +87,51 @@
"")))

(defn gruxnis-attack!
[herd [victim ibba] & _]
"TODO")
[_herd [victim ibba] & _]
(text/join-text
"A Grux'nis is a great beast,
a glorious testament to the fecund murk
of the Yuliak Range's swampy base.
Tough and shiny scales,
quick and vicious beak,
and toesome flippers that flop on land
but fly in water.
They eat the bottom-feeders of the upland bogs,
but can be drawn by chance down the riverfloes
to the paths of the herds."
(:name victim) "was attacked on the beach,"
"where" (:name ibba) "fought it off with adroit hand and crushing arm."
"The beast was only scared back into the water, but not to end its ways.
So the threat remained."
(:name ibba) "traveled out lonesome to riddle with other herds"
"of how to pacify a Grux'nis.
In their heart they could not accept killing the animal outright,
though some argued easily for the necessity.
Facile, they thought.
But still they took a spear and went to kill the thing.
They goaded it with caught fish,
but recognized in its rampaging eye a worm --
a worm that aggravates the temper,
and elicits rampant violence,
that can be driven out with a tincture.
Deftly they fought with the beast, as the sun rose and fell,
nipping it with a blade bathed in sleeping poison.
Blow by blow, the Grux'nis staggered,
until it felt, and slept!
Asleep," (:name ibba) "could treat it."
"It awoke bound but clear-eyed."
(:name ibba) "would not take chances,"
"not more than this chance of knowing a Grux'nis in peace,
and though it struggled she watched it.
It was nervous now more than hungry, more than vicious.
So after a time they brought it to the river's edge and undid the bonds.
It fled, disappearing into the river with all the sound of a single droplet.
After that there were no more attacks.
The relief at violence averted brought great celebration."
"But" (:name ibba) "wondered still, where that creature"
"would go now. Back to the upland bogs, perhaps?
Or perhaps... to stay near,
to protect the one that saved its mind."))

(def journeying-ends
(fn [herd & _]
Expand Down Expand Up @@ -176,8 +220,8 @@
["Disability is produced by inaccessibility."
"An order which excludes by design, limits its own potential."
"Such an order can prevail even silently,"
"as though no such barrier could exist."
"They must be rooted out," (:name healcow) "knows."
"imagining no such barrier could exist."
"It must be rooted out," (:name healcow) "knows."
"Accommodations call for quality of craft and heartful vision."
"Some wounds never really heal, mental or physical,"
"but we can make the changes we need,"
Expand All @@ -186,3 +230,27 @@
(:name sadcow) "offers a small thanks,"
"but their eyes go to the horizon,"
"the world open to them unfettered."])))

(def funeral
(fn [_herd [mourncow] deadcow]
(text/join-text
"All living things return to soil.
Life comes from life through death.
That is the cycle.
For the dead, the soil is turned over,
so that they lie deep beneath it,
and a sapling is placed over them.
What remains to mark their passing
is a mound in the earth
that becomes a limb of the land."
(:name deadcow) "was a friend of" (:name mourncow) ";"
"they will try to remember them fondly,
however bitterly their absence tastes.
They leave a complex legacy, a hole in the tapestry of the herd
that will take generations to scar over.
A friend heaps dirt on a hole in the ground
where their confidant will remain forever,
until the pieces of them return,
spoken by the tongues of the wind.
Life goes on,
differently.")))
20 changes: 13 additions & 7 deletions src/the_longtime_game/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

(defn skill->multiplier
[skill-amount]
(+ 1 (Math/log10 (/ skill-amount 10))))
(Math/log10 (inc skill-amount)))

(def flora-bonus
#(:flora (core/current-location %)))
Expand Down Expand Up @@ -287,8 +287,9 @@
:ready? false)}
{:name "Hold festival"
:description "Surprise and tantalize with feats of physical prowess and dextrous excellence!"
:detail "Consumes nutrition and raises fulfillment."
:detail "Consumes 1 nutrition per 5 individuals, and raises fulfillment."
:uses [:athletics :organizing]
:filter {:stores {:nutrition 1/5}}
:filter-fn
#(core/herd-has-nutrition? % 1/5)
:effect
Expand Down Expand Up @@ -473,9 +474,9 @@
:description "Devote the herd to the development of its own abilities."
:detail "Raises skills, prioritizing passions."
:uses [:organizing]
:filter {:stores {:tools low-need
:wood low-need
:rations low-need}}
:filter {:stores {:tools 1/10
:wood 1/10
:rations 1/10}}
:effect
(fn [herd _]
(core/update-individuals herd (partial core/inc-passion-skill herd)))}
Expand Down Expand Up @@ -604,8 +605,13 @@
stores-filter (get-in project [:filter :stores])
update-stores
#(reduce
(fn [herd [resource amount]]
(update-in herd [:stores resource] - amount))
(fn [herd [resource required]]
(if (= :nutrition resource)
(core/consume-nutrition herd required)
(let [amount (if (> 1 required 0)
(int (* required (count (:individuals herd))))
required)]
(update-in herd [:stores resource] - amount))))
%
stores-filter)
power-filter (get-in project [:filter :power])
Expand Down
11 changes: 2 additions & 9 deletions src/the_longtime_game/repl.clj
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,10 @@
ok? (>= (get-in herd [:stores :poultices] 0) need)
! (if ok? "" "!")]
(println "├─ Sickness:"
(as-> (:sickness herd) $
(/ $ population)
(* $ 100)
(float $)
(format "%.2f" $)
(str $ "%"))
(str (int (* (/ (:sickness herd) population) 100)) "%")
(str "(-" need ! ")")))
(let [fulfillments (map :fulfillment (:individuals herd))
average (as-> fulfillments $
(reduce + 0 $)
(/ $ population))
average (/ (reduce + 0 fulfillments) population)
minimum (reduce min fulfillments)
maximum (reduce max fulfillments)]
(println "├─ Fulfillment:"
Expand Down
20 changes: 12 additions & 8 deletions src/the_longtime_game/select.clj
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@

(s/def ::power pos-int?)

(s/def ::stores
(s/map-of (conj core/resources :nutrition)
(s/or :n pos-int?
:x (s/and number? #(< 0 % 1)))))

(s/def ::filter (s/keys :opt-un [::skills
::core/stores
::stores
::core/season
::core/terrain
::contacts
Expand All @@ -45,15 +50,14 @@
(if season
(= (core/get-season herd) season)
true)
(reduce
(fn [ok? [resource required]]
(let [amount
(every?
(fn [[resource required]]
(if (= :nutrition resource)
(core/herd-has-nutrition? herd required)
(>= (get-in herd [:stores resource] 0)
(if (> 1 required 0)
(int (* required (count (:individuals herd))))
(get-in herd [:stores resource] 0))]
(and ok?
(>= amount required))))
true
required))))
(or stores {}))
(if (and contacts (s/valid? ::contacts contacts))
(let [[kind x] (s/conform ::contacts contacts)]
Expand Down
8 changes: 5 additions & 3 deletions src/the_longtime_game/text.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
(defn normalize-name
[x]
(cond
(keyword? x) (name x)
(string? x) x
:else (str x)))
(keyword? x) (name x)
(and (number? x)
(< 0 x 1)) (str (int (* 100 (float x))) "%")
(string? x) x
:else (str x)))

(s/fdef normalize-name
:args (s/cat :x any?)
Expand Down
13 changes: 7 additions & 6 deletions test/the_longtime_game/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
`core/inc-atomic-reactors
`core/inc-fulfillment
`core/end-month
`core/inc-passion-skill
`core/inc-season
`core/inc-some-skill
`core/individual-skill
Expand All @@ -74,21 +75,21 @@
`core/update-individuals
`core/update-nutrients]))

(defspec test-stable-population-growth 20
(defspec test-stable-population-growth 5
(props/for-all
[herd (s/gen ::core/herd)]
(let [optimal (core/calc-optimal-population herd)
delta (- (count (:individuals herd)) optimal)
herd*
(reduce
(fn [herd _]
(let [[journeyings deaths] (core/shift-population herd)
[new-adults new-dead] (core/calc-pop-changes herd journeyings deaths)]
(core/apply-pop-changes herd new-adults new-dead)))
herd
(range 100))]
(is (> (* 3/2 optimal)
(count (:individuals herd*))
(* 1/2 optimal))))))
(range 100))
delta* (- (count (:individuals herd*)) optimal)]
(is (> (Math/abs delta) (Math/abs delta*))))))

(deftest test-inc-max-skill
(testing "Skills should not change when inc'd if all skills are maxed."
Expand All @@ -97,7 +98,7 @@
(assoc all skill core/max-skill))
{}
core/skills)
skills* (core/inc-some-skill skills)]
{skills* :skills} (core/inc-some-skill {:skills skills})]
(is (= skills skills*)))))

(deftest test-all-contacts
Expand Down
Loading

0 comments on commit c12b0b3

Please sign in to comment.