Added a strategy for running the whole simulation
This commit is contained in:
parent
530760ee02
commit
984feb850a
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>Introduction to the-great-game</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">The-great-game</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>Introduction to the-great-game</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>the-great-game</span></div></div></li><li class="depth-2 branch"><a href="the-great-game.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>merchants</span></div></div></li><li class="depth-3 branch"><a href="the-great-game.merchants.markets.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>markets</span></div></a></li><li class="depth-3"><a href="the-great-game.merchants.merchants.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>merchants</span></div></a></li><li class="depth-2 branch"><a href="the-great-game.utils.html"><div class="inner"><span class="tree" style="top: -83px;"><span class="top" style="height: 92px;"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></div></li><li class="depth-3 branch"><a href="the-great-game.world.routes.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>routes</span></div></a></li><li class="depth-3"><a href="the-great-game.world.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#introduction-to-the-great-game" name="introduction-to-the-great-game"></a>Introduction to the-great-game</h1>
|
||||
<html><head><meta charset="UTF-8" /><title>Introduction to the-great-game</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">The-great-game</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>Introduction to the-great-game</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>the-great-game</span></div></div></li><li class="depth-2 branch"><a href="the-great-game.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gossip</span></div></div></li><li class="depth-3"><a href="the-great-game.gossip.gossip.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gossip</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>merchants</span></div></div></li><li class="depth-3 branch"><a href="the-great-game.merchants.markets.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>markets</span></div></a></li><li class="depth-3"><a href="the-great-game.merchants.merchants.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>merchants</span></div></a></li><li class="depth-2 branch"><a href="the-great-game.utils.html"><div class="inner"><span class="tree" style="top: -83px;"><span class="top" style="height: 92px;"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></div></li><li class="depth-3 branch"><a href="the-great-game.world.routes.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>routes</span></div></a></li><li class="depth-3 branch"><a href="the-great-game.world.run.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>run</span></div></a></li><li class="depth-3"><a href="the-great-game.world.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#introduction-to-the-great-game" name="introduction-to-the-great-game"></a>Introduction to the-great-game</h1>
|
||||
<h1><a href="#the-great-game" name="the-great-game"></a>The Great Game</h1>
|
||||
<p>In this essay I’m going to try to pull together a number of my architectural ideas about the Great Game which I know I’m never actually going to build - because it’s vastly too big for any one person to build - into one overall vision.</p>
|
||||
<p>So, firstly, how does one characterise this game?</p>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>the-great-game.core documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">The-great-game</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to the-great-game</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>the-great-game</span></div></div></li><li class="depth-2 branch current"><a href="the-great-game.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>merchants</span></div></div></li><li class="depth-3 branch"><a href="the-great-game.merchants.markets.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>markets</span></div></a></li><li class="depth-3"><a href="the-great-game.merchants.merchants.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>merchants</span></div></a></li><li class="depth-2 branch"><a href="the-great-game.utils.html"><div class="inner"><span class="tree" style="top: -83px;"><span class="top" style="height: 92px;"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></div></li><li class="depth-3 branch"><a href="the-great-game.world.routes.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>routes</span></div></a></li><li class="depth-3"><a href="the-great-game.world.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="the-great-game.core.html#var-foo"><div class="inner"><span>foo</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">the-great-game.core</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-foo"><h3>foo</h3><div class="usage"><code>(foo x)</code></div><div class="doc"><div class="markdown"><p>I don’t do a whole lot.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/the-great-game/blob/master/src/the_great_game/core.clj#L3">view source</a></div></div></div></body></html>
|
||||
<html><head><meta charset="UTF-8" /><title>the-great-game.core documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">The-great-game</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to the-great-game</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>the-great-game</span></div></div></li><li class="depth-2 branch current"><a href="the-great-game.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gossip</span></div></div></li><li class="depth-3"><a href="the-great-game.gossip.gossip.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gossip</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>merchants</span></div></div></li><li class="depth-3 branch"><a href="the-great-game.merchants.markets.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>markets</span></div></a></li><li class="depth-3"><a href="the-great-game.merchants.merchants.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>merchants</span></div></a></li><li class="depth-2 branch"><a href="the-great-game.utils.html"><div class="inner"><span class="tree" style="top: -83px;"><span class="top" style="height: 92px;"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></div></li><li class="depth-3 branch"><a href="the-great-game.world.routes.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>routes</span></div></a></li><li class="depth-3 branch"><a href="the-great-game.world.run.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>run</span></div></a></li><li class="depth-3"><a href="the-great-game.world.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="the-great-game.core.html#var-foo"><div class="inner"><span>foo</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">the-great-game.core</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-foo"><h3>foo</h3><div class="usage"><code>(foo x)</code></div><div class="doc"><div class="markdown"><p>I don’t do a whole lot.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/the-great-game/blob/master/src/the_great_game/core.clj#L3">view source</a></div></div></div></body></html>
|
3
docs/the-great-game.gossip.gossip.html
Normal file
3
docs/the-great-game.gossip.gossip.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
docs/the-great-game.world.run.html
Normal file
3
docs/the-great-game.world.run.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>the-great-game.world.run documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">The-great-game</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to the-great-game</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>the-great-game</span></div></div></li><li class="depth-2 branch"><a href="the-great-game.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gossip</span></div></div></li><li class="depth-3"><a href="the-great-game.gossip.gossip.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gossip</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>merchants</span></div></div></li><li class="depth-3 branch"><a href="the-great-game.merchants.markets.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>markets</span></div></a></li><li class="depth-3"><a href="the-great-game.merchants.merchants.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>merchants</span></div></a></li><li class="depth-2 branch"><a href="the-great-game.utils.html"><div class="inner"><span class="tree" style="top: -83px;"><span class="top" style="height: 92px;"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></div></li><li class="depth-3 branch"><a href="the-great-game.world.routes.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>routes</span></div></a></li><li class="depth-3 branch current"><a href="the-great-game.world.run.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>run</span></div></a></li><li class="depth-3"><a href="the-great-game.world.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="the-great-game.world.run.html#var-run"><div class="inner"><span>run</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">the-great-game.world.run</h1><div class="doc"><div class="markdown"><p>Run the whole simulation</p></div></div><div class="public anchor" id="var-run"><h3>run</h3><div class="usage"><code>(run world)</code></div><div class="doc"><div class="markdown"><p>The pipeline to run the simulation each game day. Returns a world like this world, with all the various active elements updated.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/the-great-game/blob/master/src/the_great_game/world/run.clj#L10">view source</a></div></div></div></body></html>
|
File diff suppressed because one or more lines are too long
|
@ -3,7 +3,8 @@
|
|||
:doc/format :markdown}
|
||||
:output-path "docs"
|
||||
:source-uri "https://github.com/simon-brooke/the-great-game/blob/master/{filepath}#L{line}"}
|
||||
:dependencies [[org.clojure/clojure "1.8.0"]]
|
||||
:dependencies [[org.clojure/clojure "1.8.0"]
|
||||
[com.taoensso/timbre "4.10.0"]]
|
||||
:description "Prototype code towards the great game I've been writing about for ten years, and know I will never finish."
|
||||
:license {:name "GNU General Public License,version 2.0 or (at your option) any later version"
|
||||
:url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"}
|
||||
|
|
47
src/the_great_game/gossip/gossip.clj
Normal file
47
src/the_great_game/gossip/gossip.clj
Normal file
|
@ -0,0 +1,47 @@
|
|||
(ns the-great-game.gossip.gossip
|
||||
"Interchange of news events between agents agents"
|
||||
(:require [the-great-game.utils :refer [deep-merge]]))
|
||||
|
||||
;; Note that habitual travellers are all gossip agents; specifically, at this
|
||||
;; stage, that means merchants. When merchants are moved we also need to
|
||||
;; update the location of the gossip with the same key.
|
||||
|
||||
(defn dialogue
|
||||
"Dialogue between an `enquirer` and an `agent` in this `world`; returns a
|
||||
map identical to `enquirer` except that its `:gossip` collection may have
|
||||
additional entries."
|
||||
;; TODO: not yet written, this is a stub.
|
||||
[enquirer respondent world]
|
||||
enquirer)
|
||||
|
||||
(defn gather-news
|
||||
([world]
|
||||
(reduce
|
||||
deep-merge
|
||||
world
|
||||
(map
|
||||
#(gather-news world %)
|
||||
(keys (:gossips world)))))
|
||||
([world gossip]
|
||||
(let [g (cond (keyword? gossip)
|
||||
(-> world :gossips gossip)
|
||||
(map? gossip)
|
||||
gossip)]
|
||||
{:gossips
|
||||
{(:id g)
|
||||
(reduce
|
||||
deep-merge
|
||||
{}
|
||||
(map
|
||||
#(dialogue g % world)
|
||||
(remove
|
||||
#( = g %)
|
||||
(filter
|
||||
#(= (:location %) (:location g))
|
||||
(vals (:gossips world))))))}})))
|
||||
|
||||
(defn run
|
||||
"Return a world like this `world`, with news items exchanged between gossip
|
||||
agents."
|
||||
[world]
|
||||
(gather-news world))
|
|
@ -1,6 +1,8 @@
|
|||
(ns the-great-game.merchants.merchants
|
||||
"Trade planning for merchants, primarily."
|
||||
(:require [the-great-game.world.routes :refer [find-routes]]
|
||||
(:require [taoensso.timbre :as l :refer [info error]]
|
||||
[the-great-game.utils :refer [deep-merge]]
|
||||
[the-great-game.world.routes :refer [find-route]]
|
||||
[the-great-game.world.world :refer [actual-price default-world]]))
|
||||
|
||||
|
||||
|
@ -91,15 +93,12 @@
|
|||
commodity
|
||||
%)
|
||||
:distance (count
|
||||
(first
|
||||
(find-routes (:routes world) origin %)))
|
||||
(find-route world origin %))
|
||||
:dist-to-home (count
|
||||
(first
|
||||
(find-routes
|
||||
(:routes world)
|
||||
(find-route
|
||||
world
|
||||
(:home m)
|
||||
%)))
|
||||
)
|
||||
(remove #(= % origin) (keys (-> world :cities))))))
|
||||
|
||||
(defn nearest-with-targets
|
||||
|
@ -160,6 +159,8 @@
|
|||
|
||||
|
||||
(defn can-carry
|
||||
"Return the number of units of this `commodity` which this `merchant`
|
||||
can carry in this `world`, given their current burden."
|
||||
[merchant world commodity]
|
||||
(let [m (cond
|
||||
(keyword? merchant)
|
||||
|
@ -171,6 +172,8 @@
|
|||
(-> world :commodities commodity :weight))))
|
||||
|
||||
(defn can-afford
|
||||
"Return the number of units of this `commodity` which this `merchant`
|
||||
can afford to buy in this `world`."
|
||||
[merchant world commodity]
|
||||
(let [m (cond
|
||||
(keyword? merchant)
|
||||
|
@ -226,12 +229,201 @@
|
|||
#(let [q (-> world :cities origin :stock %)]
|
||||
(and (number? q) (> q 0)))
|
||||
(keys available)))]
|
||||
(first
|
||||
(sort-by
|
||||
#(- 0 (:dist-to-home %))
|
||||
(filter
|
||||
(make-target-filter
|
||||
[[:expected-profit
|
||||
(apply max (filter number? (map :expected-profit plans)))]])
|
||||
plans)))))
|
||||
(if
|
||||
(not (empty? plans))
|
||||
(first
|
||||
(sort-by
|
||||
#(- 0 (:dist-to-home %))
|
||||
(filter
|
||||
(make-target-filter
|
||||
[[:expected-profit
|
||||
(apply max (filter number? (map :expected-profit plans)))]])
|
||||
plans))))))
|
||||
|
||||
(defn add-stock
|
||||
"Where `a` and `b` are both maps all of whose values are numbers, return
|
||||
a map whose keys are a union of the keys of `a` and `b` and whose values
|
||||
are the sums of their respective values."
|
||||
[a b]
|
||||
(reduce
|
||||
merge
|
||||
a
|
||||
(map
|
||||
#(hash-map % (+ (or (a %) 0) (or (b %) 0)))
|
||||
(keys b))))
|
||||
|
||||
(defn add-known-prices
|
||||
"Add the current prices at this `merchant`'s location in the `world`
|
||||
to a new cacke of known prices, and return it."
|
||||
[merchant world]
|
||||
(let [m (cond
|
||||
(keyword? merchant)
|
||||
(-> world :merchants merchant)
|
||||
(map? merchant)
|
||||
merchant)
|
||||
k (:known-prices m)
|
||||
l (:location m)
|
||||
d (:date world)
|
||||
p (-> world :cities l :prices)]
|
||||
(reduce
|
||||
merge
|
||||
k
|
||||
(map
|
||||
#(hash-map % (apply vector cons {:price (p %) :date d} (k %)))
|
||||
(-> world :commodities keys)))))
|
||||
|
||||
;;; Right, from here on in we're actually moving things in the world, so
|
||||
;;; functions generally return modified partial worlds.
|
||||
|
||||
(defn plan-and-buy
|
||||
"Return a world like this `world`, in which this `merchant` has planned
|
||||
a new trade, and bought appropriate stock for it. If no profitable trade
|
||||
can be planned, the merchant is simply moved towards their home."
|
||||
[merchant world]
|
||||
(deep-merge
|
||||
world
|
||||
(let [m (cond
|
||||
(keyword? merchant)
|
||||
(-> world :merchants merchant)
|
||||
(map? merchant)
|
||||
merchant)
|
||||
id (:id m)
|
||||
location (:location m)
|
||||
market (-> world :cities location)
|
||||
plan (select-cargo merchant world)]
|
||||
(cond
|
||||
(not (empty? plan))
|
||||
(let
|
||||
[c (:commodity plan)
|
||||
p (* (:quantity plan) (:buy-price plan))
|
||||
q (:quantity plan)]
|
||||
(l/info "Merchant " id " bought " q " units of " c " at " location " for " p)
|
||||
{:merchants
|
||||
{id
|
||||
{:stock (add-stock (:stock m) {c q})
|
||||
:cash (- (:cash m) p)
|
||||
:known-prices (add-known-prices m world)}}
|
||||
:cities
|
||||
{location
|
||||
{:stock (assoc (:stock market) c (- (-> market :stock c) q))
|
||||
:cash (+ (:cash market) p)}}})
|
||||
;; if no plan, then if at home stay put
|
||||
(= (:location m) (:home m))
|
||||
{}
|
||||
;; else move towards home
|
||||
true
|
||||
(let [route (find-route world location (:home m))
|
||||
next-location (nth route 1)]
|
||||
(l/info "No trade possible at " location "; merchant " id " moves to " next-location)
|
||||
{:merchants
|
||||
{id
|
||||
{:location next-location}}})))))
|
||||
|
||||
|
||||
(defn re-plan
|
||||
"Having failed to sell a cargo at current location, re-plan a route to
|
||||
sell the current cargo. Returns a revised world."
|
||||
[merchant world]
|
||||
(let [m (cond
|
||||
(keyword? merchant)
|
||||
(-> world :merchants merchant)
|
||||
(map? merchant)
|
||||
merchant)
|
||||
id (:id m)
|
||||
location (:location m)
|
||||
plan (augment-plan m world (plan-trade m world (-> m :plan :commodity)))]
|
||||
(deep-merge
|
||||
world
|
||||
{:merchants
|
||||
{id
|
||||
{:plan plan}}})))
|
||||
|
||||
|
||||
(defn sell-and-buy
|
||||
"Return a new world like this `world`, in which this `merchant` has sold
|
||||
their current stock in their current location, and planned a new trade, and
|
||||
bought appropriate stock for it."
|
||||
;; TODO: this either sells the entire cargo, or, if the market can't afford
|
||||
;; it, none of it. And it does not cope with selling different commodities
|
||||
;; in different markets.
|
||||
[merchant world]
|
||||
(let [m (cond
|
||||
(keyword? merchant)
|
||||
(-> world :merchants merchant)
|
||||
(map? merchant)
|
||||
merchant)
|
||||
id (:id m)
|
||||
location (:location m)
|
||||
market (-> world :cities location)
|
||||
stock-value (reduce
|
||||
+
|
||||
(map
|
||||
#(* (-> m :stock %) (-> market :prices m))
|
||||
(keys (:stock m))))]
|
||||
(if
|
||||
(>= (:cash market) stock-value)
|
||||
(do
|
||||
(l/info
|
||||
(apply str (flatten (list "Merchant " id " sells " (:stock m) " at " location " for " stock-value))))
|
||||
(plan-and-buy
|
||||
merchant
|
||||
(deep-merge
|
||||
world
|
||||
{:merchants
|
||||
{id
|
||||
{:stock {}
|
||||
:cash (+ (:cash m) stock-value)
|
||||
:known-prices (add-known-prices m world)}}
|
||||
:cities
|
||||
{location
|
||||
{:stock (add-stock (:stock m) (:stock market))
|
||||
:cash (- (:cash market) stock-value)}}})))
|
||||
;; else
|
||||
(re-plan merchant world))))
|
||||
|
||||
|
||||
(defn move-merchant
|
||||
"Handle general en route movement of this `merchant` in this `world`."
|
||||
[merchant world]
|
||||
(let [m (cond
|
||||
(keyword? merchant)
|
||||
(-> world :merchants merchant)
|
||||
(map? merchant)
|
||||
merchant)
|
||||
id (:id m)
|
||||
at-destination? (and (:plan m) (= (:location m) (-> m :plan :destination)))
|
||||
plan (:plan m)
|
||||
next-location (if plan
|
||||
(nth 1 (find-route world (:location m) (:destination plan)))
|
||||
(:location m))]
|
||||
(l/info "Merchant " id " at " (:location m))
|
||||
(cond at-destination?
|
||||
(sell-and-buy merchant world plan)
|
||||
(nil? (:plan m))
|
||||
(plan-and-buy merchant world)
|
||||
true
|
||||
{:merchants
|
||||
{id
|
||||
{:id id
|
||||
:location next-location
|
||||
:known-prices (add-known-prices m world)}}})))
|
||||
|
||||
|
||||
(defn run
|
||||
"Return a world like this `world`, but with each merchant moved."
|
||||
[world]
|
||||
(try
|
||||
(reduce
|
||||
deep-merge
|
||||
world
|
||||
(map
|
||||
#(try
|
||||
(move-merchant % world)
|
||||
(catch Exception any
|
||||
(l/error any "Failure while moving merchant " %)
|
||||
{}))
|
||||
(keys (:merchants world))))
|
||||
(catch Exception any
|
||||
(l/error any "Failure while moving merchants")
|
||||
world)))
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
(ns the-great-game.utils)
|
||||
|
||||
|
||||
(defn cyclic?
|
||||
"True if two or more elements of `route` are identical"
|
||||
[route]
|
||||
|
@ -15,3 +14,4 @@
|
|||
(apply merge-with m xs)
|
||||
(last xs)))]
|
||||
(reduce m maps)))
|
||||
|
||||
|
|
|
@ -44,3 +44,14 @@
|
|||
(empty? found)
|
||||
(find-routes routes from to paths)
|
||||
found)))))
|
||||
|
||||
(defn find-route
|
||||
"Find a single route from `from` to `to` in this `world-or-routes`, which
|
||||
may be either a world as defined in [[the-great-game.world.world]] or else
|
||||
a sequence of tuples of keywords."
|
||||
[world-or-routes from to]
|
||||
(first
|
||||
(find-routes
|
||||
(or (:routes world-or-routes) world-or-routes)
|
||||
from
|
||||
to)))
|
||||
|
|
17
src/the_great_game/world/run.clj
Normal file
17
src/the_great_game/world/run.clj
Normal file
|
@ -0,0 +1,17 @@
|
|||
(ns the-great-game.world.run
|
||||
"Run the whole simulation"
|
||||
(:require [taoensso.timbre :as log]
|
||||
[the-great-game.gossip.gossip :as g]
|
||||
[the-great-game.merchants.merchants :as m]
|
||||
[the-great-game.merchants.markets :as k]
|
||||
[the-great-game.world.world :as w]))
|
||||
|
||||
|
||||
(defn run
|
||||
"The pipeline to run the simulation each game day. Returns a world like
|
||||
this world, with all the various active elements updated."
|
||||
[world]
|
||||
(g/run
|
||||
(m/run
|
||||
(k/run
|
||||
(w/run world)))))
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
(def default-world
|
||||
"A basic world for testing concepts"
|
||||
{:cities
|
||||
{:date 0 ;; the age of this world in game days
|
||||
:cities
|
||||
{:aberdeen
|
||||
{:id :aberdeen
|
||||
:supplies
|
||||
|
@ -181,4 +182,9 @@
|
|||
[world commodity city]
|
||||
(-> world :cities city :prices commodity))
|
||||
|
||||
|
||||
(defn run
|
||||
"Return a world like this `world` with only the `:date` value updated
|
||||
(incremented by one). For running other aspects of the simulation, see
|
||||
[[the-great-game.world.run#var-run]]."
|
||||
[world]
|
||||
(assoc world :date (inc (or (:date world) 0))))
|
||||
|
|
Loading…
Reference in a new issue