Merge remote-tracking branch 'origin/master' into develop

This commit is contained in:
Simon Brooke 2021-06-08 18:21:40 +01:00
commit 9e8d59c2d1
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
46 changed files with 515 additions and 154 deletions

5
.gitignore vendored
View file

@ -5,6 +5,7 @@ pom.xml.asc
*.log
*.stl
[0-9a-f]*-init.clj
/bin/
/lib/
/classes/
/target/
@ -31,3 +32,7 @@ libbulletjme.so
liblwjgl64.so
libopenal64.so
.settings/
.classpath
.project

40
doc/Game_Play.md Normal file
View file

@ -0,0 +1,40 @@
# Game Play
The principles of game play which I'm looking for are a reaction against all I see as wrong in modern video games. So let's set out what these are:
1. Superpower: the player character has some special powers or skills that other characters in the game fo not have.
2. Special status: the player character is 'the chosen one', 'the hero', or even just 'the Witcher' from the very beginning, without having done anything to earn those titles.
3. Boss fights: some non-player characters have special, and specially strong, combat repertoire, and block progress in the game until you overcome them.
4. Psychokiller: completing the game necessarily involves beating many, many other characters in combat.
5. Slaughterhouse: the main way to interact with other characters is to kill them.
7. The Script is King: everything is scripted. The player either can't diverge from the script, or if they do, will find no interesting content.
6. Dumb and dumber: non-player characters, even important ones, have extremely limited vocal repertoire.
Of these, the last two, I think, are key: they are the root cause of the other problems. In fact, to take it further, the real key is the last. We talk a lot about 'Game AI', but really there's nothing remotely approaching artificial intelligence ins modern games. Non-player characters do not think; they do not learn; they do not reason; they do not know. They speak only from the script. And they speak only from the script because of the fetish for voice acting.
## Death to Dumb-Dumb
As I've argued [elsewhere](), [repeatedly](), we can now generate a wide variety of naturalistic speaking voices, and have them narrate text. Now of course there's great deal of information conveyed in human vocal communication in addition to the words of which emotion is only an example, although an important one. Generating voices with the right tone, the right emphasis, for different situations may be harder than I anticipate; there may be an '[uncanny valley](Uncanny_dialogue)' in which generated speech just sounds uncomfortably off.
But it's a trade off. For possibly less than perfect vocal performance, you get the possibility of much richer repertoire. You get not only the possibility that non-player characters can talk about the weather, or gossip about their neighbours, or give you directions to local places of interest. You get the possibility that a non-player character's attitude to you may be conditioned by the fact that they've heard that you stole from their second cousin, or that you killed an outlaw who'd raped one of their friends.
Suddenly, they can have attitudes about things that happen in the world, opinions about major political figures in it, about their neighbours, about you the player, which are not scripted, which are emergent. When they learn new information which conflicts with something they already knew, their attitudes will change, as that new information is integrated. Intelligent behaviour will emerge.
And with the emergence of intelligent behaviour comes the emergence of possibilities for negotiation, for diplomacy, for dynamic, unscripted, friendships and romances. Which means, there are things you can do to interact with every non-player character, even ones who are not 'plot' characters, other than just kill them.
And as now gameplay possibilities emerge, as new stories emerge organically out of the dynamically changing relationships between non-player characters in the world, the need for scripting decreases.
The problem with scripting is that it greatly limits player agency. The story can only have one of a few predetermined -- literally, scripted -- endings. This is clearly expressed in [a review of Red Dead Redemption 2](https://youtu.be/_JRikiQyzLA) which I recomment to you; but is equally true of almost all other games.
Dynamic side quests have fallen into disfavour, because, when they've been tried in earlier generation games, there were too few possibilities, and they became repetitive and boring. I don't believe, with the wealth of compute resource we now have, this any longer need be the case. On the contrary, I think we can now dynamically generate a wide range of different, and differently complex, side quests. I think, in fact, that these can [emerge organically](Organic_Quests.md) from the structure of the game world.
## Death to Psycho-Killer
If the main way a player can interact with non-player characters is to kill them, and if the player doesn't have a systematic combat advantage over non-player characters, then it's going to be a short game. This is why players in many or most video games do start with a systematic combat advantage, and that combat advantage tends to increase over the course of the game as the player becomes more proficient with the combat system, and acquires better weapons, armour and combat buffs. This in turn means that to keep combat 'interesting', the game either has to through larger and larger armies of 'bad' non-player characters against the player a fault seen at its worst in [Dragon Age 2](https://youtu.be/Sc8Bn8yqPYQ?t=3150).

View file

@ -0,0 +1,74 @@
# Gossip, scripted plot, and Johnny Silverhand
I've been writing literally for years -- since [Voice acting considered harmful](Voice-acting-considered-harmful.html) in 2015 -- about game worlds in which the player speaks to non-player characters just by speaking the words they choose in their normal voice, and the non-player character replies using a pipeline that goes, essentially,
1. Alexa/Siri style speech interpretation;
2. A decision on whether to co-operate based on the particular NPC's general demeanor and particular attitude to the player;
3. A search of the game state and lore for relevant information;
4. A filtering of the results based on what the particular NPC can be expected to know;
5. Generation of a textual response from those results based on a library of templates which defines the particular NPC's dialect and style of speech;
6. Production of audio using a [Lyrebird]{https://www.descript.com/overdub?lyrebird=true) style generated voice.
As I've argued before, the game engine necessarily knows everything about the lore, and the current state, of the game world. It would be possible for any non-player character to answer literally any question about the game world, from who was mayor of Night City in 2020 to who lives in the apartment one floor up from yours, to what the weather is like in North Oaks just now.
What individual characters know should, of course, be more limited. People who live in Japantown or Heywood are unlikely to know who lives in a particular apartment in Watson; only real old timers, like Rogue, are likely to remember who was mayor fifty years ago. That's the reason for filtering; but the filtering really isn't a big deal.
Again, the generation of distinct voices for hundreds of non-player characters isn't any longer a big deal. Distinct social groups -- the corpos, and the different gangs such as Maelstrom or the Mox, will have their own argot, their own slang, their own habitual figures of speech which can be encoded into template libraries, while technologies like Lyrebird can produce an infinite range of realistic-sounding voices.
In particular, they can mimic real voices. They can mimic the voices of real actors. They can mimic [Keanu Reeves](https://cyberpunk.fandom.com/wiki/Keanu_Reeves).
So: how do you integrate this free form 'you can say anything to any character' style of play with scripted plot?
Obviously, my vision -- as I've set out in [Organic Quests](Organic_Quests.md) -- is that many quests should emerge organically from modelling the lives, activities and motivations of non-player characters. But that's a radical vision and not one you can really expect many people to buy into until it has been demonstrated to work. I think that investors are still going to want to have confidence that there's something exciting in the game for players to engage with, and I think directors are still going to want to tell the stories they want to tell.
So if I'm to sell the idea of free-form speech interaction with characters in the game world, I need an account of how it works with scripted characters voiced by high value actors in a scripted plot. I'm picking Johnny Silverhand as a core example, here, because I think he presents particular challenges.
But I also think these challenges can be addressed very easily.
In [Cyberpunk 2077](https://www.cyberpunk.net/), the player can't just go and find Johnny Silverhand, to speak to him. On the contrary, Johnny will just appear when the script calls for him to appear, and when he does he'll always initiate conversation. When a plot NPC initiates conversation with the player, the game could show -- as it does now -- a menu of things the player can say, with the implicit promise that selecting any one of these things will at least bring an interesting response which will expand one's knowledge of that character or of the lore.
Just as the player does now, the player in a game with free form speech interaction could choose to say one of the things presented in the menu, and the implicit contract -- that this would lead to a new revelation, or would advance the plot -- would remain unchanged. But the player could also choose to go off script, to take the conversation in an unscripted direction, or just to end it.
It should be said that in Cyberpunk 2077, unlike some other games, the player already has the choice to abruptly break off conversations, even with plot characters, so how the game handles breaking off the conversation does not need to change.
How should the game handle unscripted responses in scripted dialogues?
Well, the first and obvious thing is to parse the unscripted response to see whether it's a variant of one of the scripted responses, and if it seems that it might be, perhaps ask the player to verify that:
> **V**: Just get on with it already.
>
> **Panam**: You mean, go to the shiv camp?
>
> **V**: Yes, dammit.
But the second thing is to respond to the response exactly as the non-player character would if the player had initiated the conversation, using the pipeline given at the beginning of this essay. Of course, in the special case of Johnny Silverhand, he is -- at least initially -- decidedly hostile and extremely selfish, so his response will typically come at step two in the pipeline:
> **V**: Hey, Johnny, what's the quickest way from here to Jig Jig Street?
>
> **Johnny**: What am I now, your fucking tour guide?
>
> **V**: Oh, come on, Johnny, help me out a bit here, Where's the nearest gun dealer?
>
> **Johnny**: How the fuck should I know? I haven't been here for fifty years, all I know is ancient history.
The benefit of this interaction style is that these responses could be real acted responses by the voice actor (in this case, Keanu Reeves), which avoids the 'uncanny valley' risk that generated speech from a character the player has become used to interacting with may not sound quite natural enough.
But, if we've used Lyrebird technology to capture and mimic Reeves' voice, and if Johnny is for some reason uncharacteristically mellow, then generated voice responses should be used. So suppose the player asks something which Johnny ought reasonably to know:
> **V:** Hey, Johnny, what's between you and Rogue?
That's lore. It's in at least one of the in-game 'shard' texts. The game engine knows it. A text can be generated for Johnny to respond:
> **Johnny**: We were lovers, back in the day.
In any of these cases, in order for the scripted plot to proceed, the non-player character can circle back to the thing they said that the player hasn't yet made an appropriate response to:
> **Johnny**:But you didn't answer my question. *Repeats question*.
or
> **Johnny**: As I said before, *Repeats what he said before*.
Again, for key plot characters, the voice actors can actually record multiple different canned texts of this form, so that, when played, they don't sound excessively repetitious.
In short, it doesn't seem to me that it would be at all hard to integrate free form voice interaction with a modern scripted video game. The advantage is that player interaction with non-player characters would become far richer and more engaging, and consequently it would be much easier to allow the player to progress through the plot without the default outcome of every encounter having to be a blood-bath.

View file

@ -10,7 +10,18 @@ The structure of a modern Role Playing Came revolves around 'quests': tasks that
6. Syntax quests
7. Hybrids
'Gather quests' are more frequently referred to in the literature as 'fetch quests', and 'kill quests' are simply a specialised form of fetch quest where the item to be fetched is a trophy of the kill. A delivery quest is a sort of reverse fetch quest: instead of going to some location or NPC and getting a specific item to return to the quest giver, the player is tasked to take a specific item from the quest giver to some location or NPC.
'Gather quests' are more frequently referred to in the literature as 'fetch quests', and 'kill quests' are simply a specialised form of fetch quest where the item to be fetched is a trophy of the kill. And the trophy could be just the knowledge that the kill has happened. A delivery quest is a sort of reverse fetch quest: instead of going to some location or NPC and getting a specific item to return to the quest giver, the player is tasked to take a specific item from the quest giver to some location or NPC.
Note, however, that if we consider a delivery quest to have four locations, where some of these locations may be coincident, then a delivery quest and a fetch quest become the same thing. Thus
1. The location of the quest giver at the beginning of the quest;
2. The location from which the quest object must be collected;
3. The location to which the quest object must be delivered;
4. The location of the quest giver at the end of the quest.
This characterisation assumes that at the end of each quest, the player must rendezvous with the quest giver, either to report completion or to collect a reward. Obviously, there could be some quests where this fourth location is not required, because there is no need to report back (for example, if the quest giver was dying/has died) and no reward to be collected.
Note that a location is not necessarily a fixed x/y location on the map; in a kill quest, for example, location 2 is the current location of the target, and moves when the target moves; location 3 and 4 are both normally the current location of the quest giver, and move when the quest giver moves.
Hybrids are in effect chains of quests: do this task in order to get this precondition of this other task, in order to get the overall objective; obviously such chains can be deep and involved - the 'main quest' of every role playing game I know of is a chain or hybrid quest.
@ -32,11 +43,11 @@ Given that quests are as simple as this, it's obvious that narrative sophisticat
But, if we're thinking of a game with much more intelligent non-player characters with much more conversational repertoir, as I am, can satisfying quests emerge organically? In space trading games such as [Elite](https://www.telegraph.co.uk/games/11051122/Elite-the-game-that-changed-the-world.html), a primary activity is moving goods from markets with surplus (and thus low prices) to markets with shortage (and thus high prices). This is, in effect, a game made up of deliver quests - but rather than deliver quests which are scripted, they are deliver quests which arise organically out of the structure of the game world.
I already have working code for non-player character merchants, who move goods from city to city based on market information available to them. For player characters to join in this trading is an organic activity emerging from the structure of the world, which provides an activity. But moving merchants provides a market opportunity for bandits, who can intercept and steal cargoes, and so for mercenaries, who can protect cargoes from bandits, and so on. And because I have an architecture that allows non-player characters to fill economic niches, there will be non-player characters in all these niches.
I already have working code for non-player character merchants, who move goods from city to city based on market information available to them. For player characters to join in this trading is an organic activity emerging from the structure of the world. But moving merchants provides a market opportunity for bandits, who can intercept and steal cargoes, and so for mercenaries, who can protect cargoes from bandits, and so on. And because I have an architecture that allows non-player characters to change occupation to fill economic niches, there will be non-player characters in all these niches.
Where a non-player character can act, so can a player character: when a (non-player character) merchant seeks to hire a caravan guard and a player character responds, that's an organic escort quest.
The key idea behind organic quests is that the circumstance and requirments for quests emerges as an emergent behaviour out of the mechanics of the game world. A non-player character doesn't know that there is a player character who is different from them; rather, when a non-player character needs something they can't readily achieve for themselves, they will ask other characters to help, and that may include the player character.
The key idea behind organic quests is that the circumstance and requirements for quests emerge as an emergent behaviour out of the mechanics of the game world. A non-player character doesn't know that there is a player character who is different from them; rather, when a non-player character needs something they can't readily achieve for themselves, they will ask other characters to help, and that may include the player character.
This means, of course, that characters need a goal-seeking planning algorithm to decide their actions, with one option in any plan being 'ask for help'. Thus, 'asking for help' becomes a mechanism within the game, a normal behaviour. Ideally non-player characters will keep track of quite complex webs of loyalty and of obligation - debts of honour, duties of hospitality, collective loyalties. So that, if you do a favour for some character in the world, that character's tribe, friends, obligation circle, whatever, are now more likely to do favours for you.
@ -45,3 +56,9 @@ Obviously, this doesn't stop you doing jobs you get directly paid/rewarded for,
Related to this notion is the notion that, if you are asked to do a task by a character and you do it well, whether for pay or as a favour, your reputation for being competent in tasks of that kind will improve and the more likely it is that other characters will ask you to do similar tasks; and this will apply to virtually anything another character can ask of you in the game world, from carrying out an assassination to delivering a message to finding a quantiy of some specific commodity to having sex.
So quests can emerge organically from the mechanics of the world and be richly varied; I'm confident that will work. What I'm not confident of is that they can be narratively satisfying. This relates directly to the generation of speech.
## Stuff to consider
The games [Middle Earth: Shadow of Mordor](https://en.wikipedia.org/wiki/Middle-earth:_Shadow_of_Mordor), and [Middle Earth: Shadow of War](https://en.wikipedia.org/wiki/Middle-earth:_Shadow_of_War) have a procedural story system called [Nemesis](https://youtu.be/Lm_AzK27mZY), which is worth a look.
There's an interesting [critique of Red Dead Redemption 2](https://www.youtube.com/watch?v=MvJPKOLDSos&feature=emb_logo) which is relevant to what I'm saying here.

21
doc/Simulation-layers.md Normal file
View file

@ -0,0 +1,21 @@
# Simulation layers
In essence, the environment for The Great Game is broadly descended from games like the original Elite space trading game, and Sid Meier's Pirates!, with some elements from political simulations like for example SimCity.
That is to say there is
## An economy simulation
As goods are transported between cities, prices rise and fall based on simulated production and consumption. As prices of commodities rise, more citizens will take up trades which produce those commodities. The simulation needs to be sophisticated enough that, for example, as a city grows richer, its citizens may switch from preferring low cost textiles, eg perhaps wool or linen, to higher cost textiles, such as for example silk (or more complex weaves, or...) Similarly for foodstuffs and for beverages.
Agricultural production will be affected by climate simulation.
This is mainly a land game. Broadly, caravans take the place of ships in Elite or Pirates! Caravans are broadly made up of camels, although some may use mules or possibly horses. In any case, a merchant may own camels and hire camel drivers, or may hire contractor drivers who have their own camels; and there will also be whole teams of camel drivers with their animals which can be hired in a single contract.
## A political simulation
Broadly, aristons claim territories in an essentiallu feudal arrangement, drive out outlaws, and levy taxes.
An ariston will be popular if their regime is stable, if taxes are low, justice is considered fair, oppression is low and depredations by outlaws are minimal. The more unpopular an ariston is, the more resistant the populace will be to paying their taxes, meaning the more military force needs to be diverted to tax collection and the greater the oppression. Taxes are required to pay soldiers and to maintain high roads, bridges, markets and other infrastructure. Merchants will prefer to travel routes which are better policed and maintained, which means more merchants trading in your markets, which means more tax.
Aristons who can generate surplus can hire more soldiers, ascend the feudal hierarchy, and wage war against neighbours.

9
doc/Uncanny_dialogue.md Normal file
View file

@ -0,0 +1,9 @@
# The Uncanny Valley, and dynamically generated dialogue
If the player is allowed to just speak arbitrary dialogue, then the conversation animation of the player character cannot be designed. If non-player characters are able to engage dynamically generated dialogue, in response to events in the game which are not scripted, then their conversation animation for those dialogues cannot be designed. So conversation animation must almost always be dynamically generated, largely from an augmented text of the speech act. With non-player characters, emotional content of a speech act can be generated by exactly the same process which generates the text. Extracting emotional content information from the player character's voice may be more challenging.
It would be possible to avoid animating the player character's face by using a first-person camera. However, I don't personally find this makes for a very engaging game experience.
These thoughts were prompted by a very interesting [video](https://youtu.be/NmLPpcVQFJM) and [Twitter thread](https://twitter.com/GameAnim/status/844961601732018176) about the perceived failings in the character animation system of Mass Effect Andromeda.
This gets even more problematic if, rather than heavily signposting the player towards locations where plot points will happen, we allow the player to roam the world relatively freely, and cause plot events to occur where the player is at the appropriate phase in the plot rather than when the player arrives at a particular location. This not only means that important plot beats will happen in unpredictable locations but also that we may have to dynamically assign the non-player character(s) who interact with the player character in order to deliver the plot point.

View file

@ -26,7 +26,7 @@ Another significant point is that women's ability to bear children ceases at a m
## Why have sex at all?
If a character has 'having children' - the **Ancestor** aspiration, in my typology - as their key aim, then they will want to have sex. But to have children in this sense is to have acknowledged children, so while a male character may be motivated to have multiple female partners, he will never the less have some degree of long term committment to them, and will want both to feel confident that the children are his and to be recognised by their father.
If a character has 'having children' - the [**Ancestor**](intro.html#aspirations-and-goals) aspiration, in my typology - as their key aim, then they will want to have sex. But to have children in this sense is to have acknowledged children, so while a male character may be motivated to have multiple female partners, he will never the less have some degree of long term committment to them, and will want both to feel confident that the children are his and to be recognised by their father.
From the point of view of seeking to become an Ancestor, there is little benefit to the woman in having multiple partners, except in very harsh environments. It will be easier to give one partner confidence that all your children are his, and while a man can increase his number of potential progeny by having multiple wives, mistresses or other classes of long-term female sexual partners, a woman cannot.
@ -42,4 +42,4 @@ Sex, done right, is an extremely pleasant pastime. Sex can also be used to creat
For women, sex with other women carries with it no risk of pregnancy, so can be enjoyed or used for any of these purposes in very much the same way as it can by men; in other words, particularly for women, homosexual sex can be more lighthearted and carefree than heterosexual sex. To what extend our notions of homosexuality and heterosexuality are cultural I simply don't know. But because no children will result, a woman can afford to be more promiscuous with other women than she can with men.
## How does this impact on
##

View file

@ -14,24 +14,13 @@
<td class="with-number">Lines %</td>
<td class="with-number">Total</td><td class="with-number">Blank</td><td class="with-number">Instrumented</td>
</tr></thead>
<tr>
<td><a href="the_great_game/agent/agent.clj.html">the-great-game.agent.agent</a></td><td class="with-bar"><div class="covered"
style="width:100.0%;
float:left;"> 2 </div></td>
<td class="with-number">100.00 %</td>
<td class="with-bar"><div class="covered"
style="width:100.0%;
float:left;"> 2 </div></td>
<td class="with-number">100.00 %</td>
<td class="with-number">43</td><td class="with-number">5</td><td class="with-number">2</td>
</tr>
<tr>
<td><a href="the_great_game/gossip/gossip.clj.html">the-great-game.gossip.gossip</a></td><td class="with-bar"><div class="covered"
style="width:4.545454545454546%;
style="width:4.62962962962963%;
float:left;"> 5 </div><div class="not-covered"
style="width:95.45454545454545%;
float:left;"> 105 </div></td>
<td class="with-number">4.55 %</td>
style="width:95.37037037037037%;
float:left;"> 103 </div></td>
<td class="with-number">4.63 %</td>
<td class="with-bar"><div class="covered"
style="width:12.820512820512821%;
float:left;"> 5 </div><div class="not-covered"
@ -42,11 +31,11 @@
</tr>
<tr>
<td><a href="the_great_game/gossip/news_items.clj.html">the-great-game.gossip.news-items</a></td><td class="with-bar"><div class="covered"
style="width:92.73422562141491%;
float:left;"> 485 </div><div class="not-covered"
style="width:7.265774378585086%;
float:left;"> 38 </div></td>
<td class="with-number">92.73 %</td>
style="width:92.80155642023347%;
float:left;"> 477 </div><div class="not-covered"
style="width:7.198443579766537%;
float:left;"> 37 </div></td>
<td class="with-number">92.80 %</td>
<td class="with-bar"><div class="covered"
style="width:88.07339449541284%;
float:left;"> 96 </div><div class="partial"
@ -59,11 +48,11 @@
</tr>
<tr>
<td><a href="the_great_game/merchants/markets.clj.html">the-great-game.merchants.markets</a></td><td class="with-bar"><div class="covered"
style="width:96.71361502347418%;
float:left;"> 206 </div><div class="not-covered"
style="width:3.2863849765258215%;
style="width:96.46464646464646%;
float:left;"> 191 </div><div class="not-covered"
style="width:3.5353535353535355%;
float:left;"> 7 </div></td>
<td class="with-number">96.71 %</td>
<td class="with-number">96.46 %</td>
<td class="with-bar"><div class="covered"
style="width:93.18181818181819%;
float:left;"> 41 </div><div class="partial"
@ -76,11 +65,11 @@
</tr>
<tr>
<td><a href="the_great_game/merchants/merchant_utils.clj.html">the-great-game.merchants.merchant-utils</a></td><td class="with-bar"><div class="covered"
style="width:66.12377850162866%;
float:left;"> 203 </div><div class="not-covered"
style="width:33.876221498371336%;
style="width:65.4485049833887%;
float:left;"> 197 </div><div class="not-covered"
style="width:34.5514950166113%;
float:left;"> 104 </div></td>
<td class="with-number">66.12 %</td>
<td class="with-number">65.45 %</td>
<td class="with-bar"><div class="covered"
style="width:66.66666666666667%;
float:left;"> 48 </div><div class="partial"
@ -108,11 +97,11 @@
</tr>
<tr>
<td><a href="the_great_game/merchants/planning.clj.html">the-great-game.merchants.planning</a></td><td class="with-bar"><div class="covered"
style="width:88.88888888888889%;
float:left;"> 264 </div><div class="not-covered"
style="width:11.11111111111111%;
float:left;"> 33 </div></td>
<td class="with-number">88.89 %</td>
style="width:89.27335640138408%;
float:left;"> 258 </div><div class="not-covered"
style="width:10.726643598615917%;
float:left;"> 31 </div></td>
<td class="with-number">89.27 %</td>
<td class="with-bar"><div class="covered"
style="width:83.52941176470588%;
float:left;"> 71 </div><div class="partial"
@ -125,11 +114,11 @@
</tr>
<tr>
<td><a href="the_great_game/merchants/strategies/simple.clj.html">the-great-game.merchants.strategies.simple</a></td><td class="with-bar"><div class="covered"
style="width:0.8103727714748784%;
style="width:0.8264462809917356%;
float:left;"> 5 </div><div class="not-covered"
style="width:99.18962722852513%;
float:left;"> 612 </div></td>
<td class="with-number">0.81 %</td>
style="width:99.17355371900827%;
float:left;"> 600 </div></td>
<td class="with-number">0.83 %</td>
<td class="with-bar"><div class="covered"
style="width:4.032258064516129%;
float:left;"> 5 </div><div class="not-covered"
@ -166,11 +155,11 @@
</tr>
<tr>
<td><a href="the_great_game/time.clj.html">the-great-game.time</a></td><td class="with-bar"><div class="covered"
style="width:99.62121212121212%;
float:left;"> 263 </div><div class="not-covered"
style="width:0.3787878787878788%;
style="width:99.5850622406639%;
float:left;"> 240 </div><div class="not-covered"
style="width:0.4149377593360996%;
float:left;"> 1 </div></td>
<td class="with-number">99.62 %</td>
<td class="with-number">99.59 %</td>
<td class="with-bar"><div class="covered"
style="width:98.33333333333333%;
float:left;"> 59 </div><div class="partial"
@ -182,7 +171,7 @@
<tr>
<td><a href="the_great_game/utils.clj.html">the-great-game.utils</a></td><td class="with-bar"><div class="covered"
style="width:100.0%;
float:left;"> 72 </div></td>
float:left;"> 69 </div></td>
<td class="with-number">100.00 %</td>
<td class="with-bar"><div class="covered"
style="width:100.0%;
@ -192,11 +181,11 @@
</tr>
<tr>
<td><a href="the_great_game/world/location.clj.html">the-great-game.world.location</a></td><td class="with-bar"><div class="covered"
style="width:88.37209302325581%;
float:left;"> 76 </div><div class="not-covered"
style="width:11.627906976744185%;
style="width:87.95180722891567%;
float:left;"> 73 </div><div class="not-covered"
style="width:12.048192771084338%;
float:left;"> 10 </div></td>
<td class="with-number">88.37 %</td>
<td class="with-number">87.95 %</td>
<td class="with-bar"><div class="covered"
style="width:70.58823529411765%;
float:left;"> 12 </div><div class="partial"
@ -209,11 +198,11 @@
</tr>
<tr>
<td><a href="the_great_game/world/routes.clj.html">the-great-game.world.routes</a></td><td class="with-bar"><div class="covered"
style="width:99.21875%;
float:left;"> 127 </div><div class="not-covered"
style="width:0.78125%;
style="width:99.19354838709677%;
float:left;"> 123 </div><div class="not-covered"
style="width:0.8064516129032258%;
float:left;"> 1 </div></td>
<td class="with-number">99.22 %</td>
<td class="with-number">99.19 %</td>
<td class="with-bar"><div class="covered"
style="width:97.61904761904762%;
float:left;"> 41 </div><div class="partial"
@ -224,11 +213,11 @@
</tr>
<tr>
<td><a href="the_great_game/world/run.clj.html">the-great-game.world.run</a></td><td class="with-bar"><div class="covered"
style="width:4.918032786885246%;
style="width:5.0%;
float:left;"> 3 </div><div class="not-covered"
style="width:95.08196721311475%;
float:left;"> 58 </div></td>
<td class="with-number">4.92 %</td>
style="width:95.0%;
float:left;"> 57 </div></td>
<td class="with-number">5.00 %</td>
<td class="with-bar"><div class="covered"
style="width:15.0%;
float:left;"> 3 </div><div class="not-covered"
@ -239,11 +228,11 @@
</tr>
<tr>
<td><a href="the_great_game/world/world.clj.html">the-great-game.world.world</a></td><td class="with-bar"><div class="covered"
style="width:95.89041095890411%;
style="width:96.10983981693364%;
float:left;"> 420 </div><div class="not-covered"
style="width:4.109589041095891%;
float:left;"> 18 </div></td>
<td class="with-number">95.89 %</td>
style="width:3.8901601830663615%;
float:left;"> 17 </div></td>
<td class="with-number">96.11 %</td>
<td class="with-bar"><div class="covered"
style="width:97.01492537313433%;
float:left;"> 65 </div><div class="not-covered"
@ -254,9 +243,9 @@
</tr>
<tr><td>Totals:</td>
<td class="with-bar"></td>
<td class="with-number">66.90 %</td>
<td class="with-number">66.55 %</td>
<td class="with-bar"></td>
<td class="with-number">68.74 %</td>
<td class="with-number">68.63 %</td>
</tr>
</table>
</body>

View file

@ -118,13 +118,13 @@
<span class="not-covered" title="0 out of 3 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
<span class="not-covered" title="0 out of 3 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(&nbsp;=&nbsp;g&nbsp;%)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filter
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
<span class="not-covered" title="0 out of 7 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(=&nbsp;(:location&nbsp;%)&nbsp;(:location&nbsp;g))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">

View file

@ -331,7 +331,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;[gossip&nbsp;character]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
<span class="covered" title="1 out of 1 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;(count
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
@ -358,7 +358,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;[gossip&nbsp;character]
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
<span class="covered" title="6 out of 6 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(interest-in-character&nbsp;gossip&nbsp;character)&nbsp;0))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -388,7 +388,7 @@
<span class="covered" title="5 out of 5 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[d&nbsp;(distance-between&nbsp;location&nbsp;home)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;(&#x2F;&nbsp;10000&nbsp;d)&nbsp;;;&nbsp;10000&nbsp;at&nbsp;metre&nbsp;scale&nbsp;is&nbsp;10km;&nbsp;interest&nbsp;should
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
@ -397,7 +397,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
131&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
<span class="covered" title="6 out of 6 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(&gt;&nbsp;i&nbsp;1)&nbsp;i&nbsp;0))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
@ -424,13 +424,13 @@
<span class="not-tracked" title="0 out of 0 forms covered">
140&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
<span class="covered" title="1 out of 1 forms covered">
141&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(count
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
142&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filter
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
<span class="covered" title="9 out of 9 forms covered">
143&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(some&nbsp;(fn&nbsp;[x]&nbsp;(=&nbsp;x&nbsp;location))&nbsp;(:location&nbsp;%))
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
@ -454,7 +454,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
150&nbsp;&nbsp;&nbsp;&nbsp;[gossip&nbsp;item]
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
<span class="covered" title="8 out of 8 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(interest-in-location&nbsp;gossip&nbsp;(:location&nbsp;item))&nbsp;0))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -547,7 +547,7 @@
<span class="covered" title="3 out of 3 forms covered">
181&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
182&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(=&nbsp;%&nbsp;:verb)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
@ -706,7 +706,7 @@
<span class="covered" title="5 out of 5 forms covered">
234&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;(:nth-hand&nbsp;item))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
<span class="not-covered" title="0 out of 4 forms covered">
235&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(inc&nbsp;(:nth-hand&nbsp;item))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">

View file

@ -37,13 +37,13 @@
<span class="covered" title="1 out of 1 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;(let
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
<span class="covered" title="10 out of 10 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[delta&nbsp;(dec&#x27;&nbsp;(&#x2F;&nbsp;(max&nbsp;supply&nbsp;demand&nbsp;1)&nbsp;(max&nbsp;stock&nbsp;1)))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scaled&nbsp;(&#x2F;&nbsp;delta&nbsp;100)]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(+&nbsp;old&nbsp;scaled)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -91,7 +91,7 @@
<span class="covered" title="10 out of 10 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;su&nbsp;(or&nbsp;(-&gt;&nbsp;c&nbsp;:supplies&nbsp;commodity)&nbsp;0)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;decrement&nbsp;(min&nbsp;st&nbsp;d)
</span><br/>
<span class="partial" title="5 out of 6 forms covered">
@ -103,7 +103,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;stock,&nbsp;halt&nbsp;production
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
<span class="covered" title="5 out of 5 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;st&nbsp;(*&nbsp;su&nbsp;2))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
@ -115,7 +115,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;craftspeople&nbsp;of&nbsp;the&nbsp;city&nbsp;will&nbsp;do&nbsp;so.
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
<span class="covered" title="4 out of 4 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;p&nbsp;1)&nbsp;su
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
@ -127,10 +127,10 @@
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;incoming&nbsp;merchants&nbsp;to&nbsp;buy
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;su&nbsp;st)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(-&nbsp;su&nbsp;st)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
@ -148,7 +148,7 @@
<span class="covered" title="4 out of 4 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not=&nbsp;p&nbsp;n)
</span><br/>
<span class="covered" title="26 out of 26 forms covered">
<span class="covered" title="24 out of 24 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;info&nbsp;&quot;Price&nbsp;of&quot;&nbsp;commodity&nbsp;&quot;at&quot;&nbsp;id&nbsp;&quot;has&nbsp;changed&nbsp;from&quot;&nbsp;(float&nbsp;p)&nbsp;&quot;to&quot;&nbsp;(float&nbsp;n)))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
@ -157,7 +157,7 @@
<span class="covered" title="3 out of 3 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:stock
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
<span class="covered" title="7 out of 7 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{commodity&nbsp;(+&nbsp;(-&nbsp;st&nbsp;decrement)&nbsp;increment)}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">

View file

@ -94,7 +94,7 @@
<span class="covered" title="3 out of 3 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
<span class="covered" title="11 out of 11 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(*&nbsp;(cargo&nbsp;%)&nbsp;(-&gt;&nbsp;world&nbsp;:commodities&nbsp;%&nbsp;:weight))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
@ -133,16 +133,16 @@
<span class="covered" title="1 out of 1 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;merchant)]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
<span class="covered" title="2 out of 2 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(max
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
<span class="covered" title="1 out of 1 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(quot
</span><br/>
<span class="partial" title="13 out of 14 forms covered">
<span class="partial" title="12 out of 13 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(-&nbsp;(or&nbsp;(:capacity&nbsp;m)&nbsp;0)&nbsp;(burden&nbsp;m&nbsp;world))
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
@ -199,7 +199,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
<span class="covered" title="1 out of 1 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(quot
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
@ -238,7 +238,7 @@
<span class="covered" title="3 out of 3 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="partial" title="20 out of 21 forms covered">
<span class="partial" title="19 out of 20 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(hash-map&nbsp;%&nbsp;(+&nbsp;(or&nbsp;(a&nbsp;%)&nbsp;0)&nbsp;(or&nbsp;(b&nbsp;%)&nbsp;0)))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">

View file

@ -136,13 +136,13 @@
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
<span class="covered" title="1 out of 1 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:distance&nbsp;(count
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(find-route&nbsp;world&nbsp;origin&nbsp;%))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
<span class="covered" title="1 out of 1 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:dist-to-home&nbsp;(count
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
@ -157,7 +157,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%)))
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
<span class="covered" title="11 out of 11 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove&nbsp;#(=&nbsp;%&nbsp;origin)&nbsp;(-&gt;&nbsp;world&nbsp;:cities&nbsp;keys)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -304,7 +304,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;to&nbsp;home.
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
<span class="not-covered" title="0 out of 5 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(-&nbsp;0&nbsp;(:dist-to-home&nbsp;%))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
@ -376,7 +376,7 @@
<span class="covered" title="5 out of 5 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(can-afford&nbsp;merchant&nbsp;world&nbsp;c))
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
<span class="covered" title="9 out of 9 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;(*&nbsp;q&nbsp;(-&nbsp;(:expected-price&nbsp;plan)&nbsp;(:buy-price&nbsp;plan)))]
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
@ -442,7 +442,7 @@
<span class="covered" title="10 out of 10 forms covered">
146&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(let&nbsp;[q&nbsp;(-&gt;&nbsp;world&nbsp;:cities&nbsp;origin&nbsp;:stock&nbsp;%)]
</span><br/>
<span class="partial" title="9 out of 10 forms covered">
<span class="partial" title="8 out of 9 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(number?&nbsp;q)&nbsp;(pos?&nbsp;q)))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
@ -460,7 +460,7 @@
<span class="covered" title="3 out of 3 forms covered">
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(sort-by
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
<span class="not-covered" title="0 out of 5 forms covered">
153&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(-&nbsp;0&nbsp;(:dist-to-home&nbsp;%))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">

View file

@ -109,7 +109,7 @@
<span class="not-covered" title="0 out of 3 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[c&nbsp;(:commodity&nbsp;plan)
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
<span class="not-covered" title="0 out of 7 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;(*&nbsp;(:quantity&nbsp;plan)&nbsp;(:buy-price&nbsp;plan))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
@ -127,7 +127,7 @@
<span class="not-covered" title="0 out of 13 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:stock&nbsp;(add-stock&nbsp;(:stock&nbsp;m)&nbsp;{c&nbsp;q})
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
<span class="not-covered" title="0 out of 5 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:cash&nbsp;(-&nbsp;(:cash&nbsp;m)&nbsp;p)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
@ -142,16 +142,16 @@
<span class="not-covered" title="0 out of 2 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{location
</span><br/>
<span class="not-covered" title="0 out of 17 forms covered">
<span class="not-covered" title="0 out of 16 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:stock&nbsp;(assoc&nbsp;(:stock&nbsp;market)&nbsp;c&nbsp;(-&nbsp;(-&gt;&nbsp;market&nbsp;:stock&nbsp;c)&nbsp;q))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
<span class="not-covered" title="0 out of 5 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:cash&nbsp;(+&nbsp;(:cash&nbsp;market)&nbsp;p)}}})
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;if&nbsp;no&nbsp;plan,&nbsp;then&nbsp;if&nbsp;at&nbsp;home&nbsp;stay&nbsp;put
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
<span class="not-covered" title="0 out of 7 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(:location&nbsp;m)&nbsp;(:home&nbsp;m))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
@ -172,7 +172,7 @@
<span class="not-covered" title="0 out of 8 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[route&nbsp;(find-route&nbsp;world&nbsp;location&nbsp;(:home&nbsp;m))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
<span class="not-covered" title="0 out of 3 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next-location&nbsp;(nth&nbsp;route&nbsp;1)]
</span><br/>
<span class="not-covered" title="0 out of 20 forms covered">
@ -310,7 +310,7 @@
<span class="not-covered" title="0 out of 3 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 12 forms covered">
<span class="not-covered" title="0 out of 11 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(*&nbsp;(-&gt;&nbsp;m&nbsp;:stock&nbsp;%)&nbsp;(-&gt;&nbsp;market&nbsp;:prices&nbsp;m))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
@ -322,7 +322,7 @@
<span class="not-covered" title="0 out of 1 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
<span class="not-covered" title="0 out of 5 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;(:cash&nbsp;market)&nbsp;stock-value)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
@ -352,7 +352,7 @@
<span class="not-covered" title="0 out of 5 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:stock&nbsp;{}
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
<span class="not-covered" title="0 out of 5 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:cash&nbsp;(+&nbsp;(:cash&nbsp;m)&nbsp;stock-value)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
@ -367,7 +367,7 @@
<span class="not-covered" title="0 out of 11 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:stock&nbsp;(add-stock&nbsp;(:stock&nbsp;m)&nbsp;(:stock&nbsp;market))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
<span class="not-covered" title="0 out of 5 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:cash&nbsp;(-&nbsp;(:cash&nbsp;market)&nbsp;stock-value)}}})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
@ -412,7 +412,7 @@
<span class="not-covered" title="0 out of 3 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;(:id&nbsp;m)
</span><br/>
<span class="not-covered" title="0 out of 17 forms covered">
<span class="not-covered" title="0 out of 16 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at-destination?&nbsp;(and&nbsp;(:plan&nbsp;m)&nbsp;(=&nbsp;(:location&nbsp;m)&nbsp;(-&gt;&nbsp;m&nbsp;:plan&nbsp;:destination)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
@ -421,7 +421,7 @@
<span class="not-covered" title="0 out of 2 forms covered">
139&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next-location&nbsp;(if&nbsp;plan
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
<span class="not-covered" title="0 out of 2 forms covered">
140&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(nth
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">

View file

@ -136,7 +136,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&quot;This&nbsp;world&nbsp;has&nbsp;an&nbsp;eight&nbsp;day&nbsp;week.&quot;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
<span class="covered" title="2 out of 2 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;(count&nbsp;days-of-week))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -190,7 +190,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;different.&quot;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
<span class="covered" title="2 out of 2 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;(count&nbsp;seasons-of-year))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -220,7 +220,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;five&nbsp;weeks.&quot;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
<span class="covered" title="2 out of 2 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;(count&nbsp;weeks-of-season))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -229,7 +229,7 @@
<span class="covered" title="1 out of 1 forms covered">
075&nbsp;&nbsp;(def&nbsp;^:const&nbsp;days-in-season
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;weeks-in-season&nbsp;days-in-week))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -250,13 +250,13 @@
<span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;([timestamp]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(-&nbsp;timestamp&nbsp;game-start-time)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
084&nbsp;&nbsp;
</span><br/>
<span class="covered" title="63 out of 63 forms covered">
<span class="covered" title="54 out of 54 forms covered">
085&nbsp;&nbsp;(defmacro&nbsp;day-of-year
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
@ -289,7 +289,7 @@
<span class="covered" title="1 out of 1 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[game-time]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
<span class="covered" title="1 out of 1 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
@ -316,10 +316,10 @@
<span class="covered" title="4 out of 4 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(waiting-day?&nbsp;game-time)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(nth&nbsp;weeks-of-season&nbsp;day-of-week)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(nth&nbsp;days-of-week&nbsp;day-of-week))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -337,7 +337,7 @@
<span class="covered" title="9 out of 9 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[day-of-season&nbsp;(mod&nbsp;(day-of-year&nbsp;game-time)&nbsp;days-in-season)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;week&nbsp;(&#x2F;&nbsp;day-of-season&nbsp;days-in-week)]
</span><br/>
<span class="partial" title="4 out of 5 forms covered">
@ -346,7 +346,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:waiting
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(nth&nbsp;weeks-of-season&nbsp;week))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -358,7 +358,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;[game-time]
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
<span class="covered" title="9 out of 9 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[season&nbsp;(int&nbsp;(&#x2F;&nbsp;(day-of-year&nbsp;game-time)&nbsp;days-in-season))]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
@ -367,7 +367,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:waiting
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(nth&nbsp;seasons-of-year&nbsp;season))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -403,7 +403,7 @@
<span class="covered" title="2 out of 2 forms covered">
133&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(name
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
<span class="covered" title="1 out of 1 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(nth
</span><br/>
<span class="covered" title="1 out of 1 forms covered">

View file

@ -19,7 +19,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;[route]
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
<span class="covered" title="8 out of 8 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;(not=&nbsp;(count&nbsp;route)(count&nbsp;(set&nbsp;route))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -103,7 +103,7 @@
<span class="covered" title="6 out of 6 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;(first&nbsp;%)&nbsp;&#x27;m)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(nth&nbsp;%&nbsp;1))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">

View file

@ -112,7 +112,7 @@
<span class="partial" title="5 out of 6 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;c1&nbsp;c2)
</span><br/>
<span class="covered" title="26 out of 26 forms covered">
<span class="covered" title="23 out of 23 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(sqrt&nbsp;(+&nbsp;(expt&nbsp;(-&nbsp;(:x&nbsp;c1)&nbsp;(:x&nbsp;c2))&nbsp;2)&nbsp;(expt&nbsp;(-&nbsp;(:y&nbsp;c1)&nbsp;(:y&nbsp;c2))&nbsp;2))))))
</span><br/>
</body>

View file

@ -49,10 +49,10 @@
<span class="covered" title="3 out of 3 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
<span class="covered" title="3 out of 3 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(=&nbsp;from&nbsp;%)
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
<span class="covered" title="9 out of 9 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(some&nbsp;#(=&nbsp;%&nbsp;from)&nbsp;route)&nbsp;route)))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
@ -67,7 +67,7 @@
<span class="covered" title="2 out of 2 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;found&nbsp;(filter
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
<span class="covered" title="10 out of 10 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[step]&nbsp;(if&nbsp;(some&nbsp;#(=&nbsp;to&nbsp;%)&nbsp;step)&nbsp;step))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
@ -121,7 +121,7 @@
<span class="covered" title="3 out of 3 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;found&nbsp;(filter
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
<span class="covered" title="6 out of 6 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(=&nbsp;(last&nbsp;%)&nbsp;to)&nbsp;paths)]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">

View file

@ -58,7 +58,7 @@
<span class="not-covered" title="0 out of 6 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:path&nbsp;&quot;the-great-game.log&quot;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
<span class="not-covered" title="0 out of 3 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:max-size&nbsp;(*&nbsp;512&nbsp;1024)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">

View file

@ -571,7 +571,7 @@
<span class="not-tracked" title="0 out of 0 forms covered">
189&nbsp;&nbsp;&nbsp;&nbsp;([world]
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
<span class="not-covered" title="0 out of 12 forms covered">
190&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(run&nbsp;world&nbsp;(inc&nbsp;(or&nbsp;(:date&nbsp;world)&nbsp;0))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">

31
docs/codox/Game_Play.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

13
docs/codox/NewCh1.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

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

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

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

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

View file

@ -0,0 +1,40 @@
OK, the basic idea is this
Everything (every game object, including the world) is a map.
Every object as an :id property; every :id property is distinct.
There is a master map - the `oblist` which contains every object, keyed by its :id.
Every object has a :run function, which returns either a new copy of itself or nil, and does not have side effects.
Every object has a :location function, which takes one argument, the object, and returns its location as a coordinate pair (or coordinate triple, probably) (this may involve fetching the location from the container in which it is contained, which implies that a contained object must hold a handle to its container).
Every collection of things in the world is represented as a list of :id values, by which the actual objects can be fetched from the `oblist`.
## Circles
Among those collections are the circles. The circles include, at minimum
1. Those objects in audible/visual range of the player; these have their run method invoked avery game loop. Weather, is always in this circle. The sun and moon are in this circle from shortly becore they rise to shortly after they set.
2. Those objects which might come into audible/visual range within a short period; these have their run method invoked every N game loops, where N is probably variable depending on overall system load
3. Those objects (actors) which are necessary to maintain the gossip system, etc. These should each have their run method invoked once per game day, but that is done by invoking the run method of a share of them each game loop.
So `run` takes three arguments - the object, the world and the circle; and returns nil if it makes no change, or a new copy of itself; and probably each of the main functions that run calls have the same behaviour. So, for example, a hierarchy of needs can be represented by
(defn run [character world circle]
(first
(handle-immediate-threat character world circle) ;; if being attacked, deal with it
(complete-current-action character world circle) ;; otherwise, continue the current
;; short-term unless completed
(handle-thirst character world circle) ;; perhaps adjust tactical plan to find water
(handle-hunger character world circle) ;; perhaps adjust tactical plan to find food
(handle-fatigue character world circle) ;; perhaps rest if safe to do so
(advance-current-plan character world circle) ;; select next step of current strategic plan
(select-next-plan character world circle) ;; plan new strategic objective
(return-home character world circle))) ;; if no other strategic objective, return
;; to home location
Atoms? Background threads?