diff --git a/.calva/output-window/.clj-kondo/config.edn b/.calva/output-window/.clj-kondo/config.edn new file mode 100644 index 0000000..1a10f5a --- /dev/null +++ b/.calva/output-window/.clj-kondo/config.edn @@ -0,0 +1 @@ +^:replace {:linters {}} \ No newline at end of file diff --git a/.gitignore b/.gitignore index d8f18e4..3e0df74 100644 --- a/.gitignore +++ b/.gitignore @@ -18,11 +18,39 @@ pom.xml.asc .lein-failures .nrepl-port .cpcache/ +.calva/ +.idea/ *~ +.calva/output-window/output.calva-repl .settings/ - -.classpath - .project + +.lsp/sqlite.db + +libbulletjme.so + +liblwjgl64.so + +libopenal64.so + +.settings/ +.classpath +.project + +.calva/ +.lsp/ + + +*.so + +docs/cloverage/codecov.json + +docs/cloverage/coverage.xml + +src/cc/journeyman/the_great_game/cloverage.clj + +.DS_Store + +.portal/ diff --git a/LICENSE b/LICENSE index d921d3d..8147eb0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,214 +1,361 @@ -THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC -LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM -CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. +### GNU GENERAL PUBLIC LICENSE -1. DEFINITIONS +Version 2, June 1991 -"Contribution" means: + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. -a) in the case of the initial Contributor, the initial code and -documentation distributed under this Agreement, and +### Preamble -b) in the case of each subsequent Contributor: +The licenses for most software are designed to take away your freedom +to share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. -i) changes to the Program, and +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. -ii) additions to the Program; +To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the software, or if you modify it. -where such changes and/or additions to the Program originate from and are -distributed by that particular Contributor. A Contribution 'originates' from -a Contributor if it was added to the Program by such Contributor itself or -anyone acting on such Contributor's behalf. Contributions do not include -additions to the Program which: (i) are separate modules of software -distributed in conjunction with the Program under their own license -agreement, and (ii) are not derivative works of the Program. +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. -"Contributor" means any person or entity that distributes the Program. +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. -"Licensed Patents" mean patent claims licensable by a Contributor which are -necessarily infringed by the use or sale of its Contribution alone or when -combined with the Program. +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, +we want its recipients to know that what they have is not the +original, so that any problems introduced by others will not reflect +on the original authors' reputations. -"Program" means the Contributions distributed in accordance with this -Agreement. +Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at +all. -"Recipient" means anyone who receives the Program under this Agreement, -including all Contributors. +The precise terms and conditions for copying, distribution and +modification follow. -2. GRANT OF RIGHTS +### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -a) Subject to the terms of this Agreement, each Contributor hereby grants -Recipient a non-exclusive, worldwide, royalty-free copyright license to -reproduce, prepare derivative works of, publicly display, publicly perform, -distribute and sublicense the Contribution of such Contributor, if any, and -such derivative works, in source code and object code form. +**0.** This License applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work +based on the Program" means either the Program or any derivative work +under copyright law: that is to say, a work containing the Program or +a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is +included without limitation in the term "modification".) Each licensee +is addressed as "you". -b) Subject to the terms of this Agreement, each Contributor hereby grants -Recipient a non-exclusive, worldwide, royalty-free patent license under -Licensed Patents to make, use, sell, offer to sell, import and otherwise -transfer the Contribution of such Contributor, if any, in source code and -object code form. This patent license shall apply to the combination of the -Contribution and the Program if, at the time the Contribution is added by the -Contributor, such addition of the Contribution causes such combination to be -covered by the Licensed Patents. The patent license shall not apply to any -other combinations which include the Contribution. No hardware per se is -licensed hereunder. +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does. -c) Recipient understands that although each Contributor grants the licenses -to its Contributions set forth herein, no assurances are provided by any -Contributor that the Program does not infringe the patent or other -intellectual property rights of any other entity. Each Contributor disclaims -any liability to Recipient for claims brought by any other entity based on -infringement of intellectual property rights or otherwise. As a condition to -exercising the rights and licenses granted hereunder, each Recipient hereby -assumes sole responsibility to secure any other intellectual property rights -needed, if any. For example, if a third party patent license is required to -allow Recipient to distribute the Program, it is Recipient's responsibility -to acquire that license before distributing the Program. +**1.** You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. -d) Each Contributor represents that to its knowledge it has sufficient -copyright rights in its Contribution, if any, to grant the copyright license -set forth in this Agreement. +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a +fee. -3. REQUIREMENTS +**2.** You may modify your copy or copies of the Program or any +portion of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: -A Contributor may choose to distribute the Program in object code form under -its own license agreement, provided that: -a) it complies with the terms and conditions of this Agreement; and +**a)** You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. -b) its license agreement: -i) effectively disclaims on behalf of all Contributors all warranties and -conditions, express and implied, including warranties or conditions of title -and non-infringement, and implied warranties or conditions of merchantability -and fitness for a particular purpose; +**b)** You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any part +thereof, to be licensed as a whole at no charge to all third parties +under the terms of this License. -ii) effectively excludes on behalf of all Contributors all liability for -damages, including direct, indirect, special, incidental and consequential -damages, such as lost profits; -iii) states that any provisions which differ from this Agreement are offered -by that Contributor alone and not by any other party; and +**c)** If the modified program normally reads commands interactively +when run, you must cause it, when started running for such interactive +use in the most ordinary way, to print or display an announcement +including an appropriate copyright notice and a notice that there is +no warranty (or else, saying that you provide a warranty) and that +users may redistribute the program under these conditions, and telling +the user how to view a copy of this License. (Exception: if the +Program itself is interactive but does not normally print such an +announcement, your work based on the Program is not required to print +an announcement.) -iv) states that source code for the Program is available from such -Contributor, and informs licensees how to obtain it in a reasonable manner on -or through a medium customarily used for software exchange. +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. -When the Program is made available in source code form: +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. -a) it must be made available under this Agreement; and +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. -b) a copy of this Agreement must be included with each copy of the Program. +**3.** You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: -Contributors may not remove or alter any copyright notices contained within -the Program. -Each Contributor must identify itself as the originator of its Contribution, -if any, in a manner that reasonably allows subsequent Recipients to identify -the originator of the Contribution. +**a)** Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections 1 +and 2 above on a medium customarily used for software interchange; or, -4. COMMERCIAL DISTRIBUTION -Commercial distributors of software may accept certain responsibilities with -respect to end users, business partners and the like. While this license is -intended to facilitate the commercial use of the Program, the Contributor who -includes the Program in a commercial product offering should do so in a -manner which does not create potential liability for other Contributors. -Therefore, if a Contributor includes the Program in a commercial product -offering, such Contributor ("Commercial Contributor") hereby agrees to defend -and indemnify every other Contributor ("Indemnified Contributor") against any -losses, damages and costs (collectively "Losses") arising from claims, -lawsuits and other legal actions brought by a third party against the -Indemnified Contributor to the extent caused by the acts or omissions of such -Commercial Contributor in connection with its distribution of the Program in -a commercial product offering. The obligations in this section do not apply -to any claims or Losses relating to any actual or alleged intellectual -property infringement. In order to qualify, an Indemnified Contributor must: -a) promptly notify the Commercial Contributor in writing of such claim, and -b) allow the Commercial Contributor to control, and cooperate with the -Commercial Contributor in, the defense and any related settlement -negotiations. The Indemnified Contributor may participate in any such claim -at its own expense. +**b)** Accompany it with a written offer, valid for at least three +years, to give any third party, for a charge no more than your cost of +physically performing source distribution, a complete machine-readable +copy of the corresponding source code, to be distributed under the +terms of Sections 1 and 2 above on a medium customarily used for +software interchange; or, -For example, a Contributor might include the Program in a commercial product -offering, Product X. That Contributor is then a Commercial Contributor. If -that Commercial Contributor then makes performance claims, or offers -warranties related to Product X, those performance claims and warranties are -such Commercial Contributor's responsibility alone. Under this section, the -Commercial Contributor would have to defend claims against the other -Contributors related to those performance claims and warranties, and if a -court requires any other Contributor to pay any damages as a result, the -Commercial Contributor must pay those damages. -5. NO WARRANTY +**c)** Accompany it with the information you received as to the offer +to distribute corresponding source code. (This alternative is allowed +only for noncommercial distribution and only if you received the +program in object code or executable form with such an offer, in +accord with Subsection b above.) -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON -AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER -EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR -CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A -PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the -appropriateness of using and distributing the Program and assumes all risks -associated with its exercise of rights under this Agreement , including but -not limited to the risks and costs of program errors, compliance with -applicable laws, damage to or loss of data, programs or equipment, and -unavailability or interruption of operations. +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. -6. DISCLAIMER OF LIABILITY +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY -CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION -LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE -EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGES. +**4.** You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and +will automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. -7. GENERAL +**5.** You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. -If any provision of this Agreement is invalid or unenforceable under -applicable law, it shall not affect the validity or enforceability of the -remainder of the terms of this Agreement, and without further action by the -parties hereto, such provision shall be reformed to the minimum extent -necessary to make such provision valid and enforceable. +**6.** Each time you redistribute the Program (or any work based on +the Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. -If Recipient institutes patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Program itself -(excluding combinations of the Program with other software or hardware) -infringes such Recipient's patent(s), then such Recipient's rights granted -under Section 2(b) shall terminate as of the date such litigation is filed. +**7.** If, as a consequence of a court judgment or allegation of +patent infringement or for any other reason (not limited to patent +issues), conditions are imposed on you (whether by court order, +agreement or otherwise) that contradict the conditions of this +License, they do not excuse you from the conditions of this License. +If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, +then as a consequence you may not distribute the Program at all. For +example, if a patent license would not permit royalty-free +redistribution of the Program by all those who receive copies directly +or indirectly through you, then the only way you could satisfy both it +and this License would be to refrain entirely from distribution of the +Program. -All Recipient's rights under this Agreement shall terminate if it fails to -comply with any of the material terms or conditions of this Agreement and -does not cure such failure in a reasonable period of time after becoming -aware of such noncompliance. If all Recipient's rights under this Agreement -terminate, Recipient agrees to cease use and distribution of the Program as -soon as reasonably practicable. However, Recipient's obligations under this -Agreement and any licenses granted by Recipient relating to the Program shall -continue and survive. +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. -Everyone is permitted to copy and distribute copies of this Agreement, but in -order to avoid inconsistency the Agreement is copyrighted and may only be -modified in the following manner. The Agreement Steward reserves the right to -publish new versions (including revisions) of this Agreement from time to -time. No one other than the Agreement Steward has the right to modify this -Agreement. The Eclipse Foundation is the initial Agreement Steward. The -Eclipse Foundation may assign the responsibility to serve as the Agreement -Steward to a suitable separate entity. Each new version of the Agreement will -be given a distinguishing version number. The Program (including -Contributions) may always be distributed subject to the version of the -Agreement under which it was received. In addition, after a new version of -the Agreement is published, Contributor may elect to distribute the Program -(including its Contributions) under the new version. Except as expressly -stated in Sections 2(a) and 2(b) above, Recipient receives no rights or -licenses to the intellectual property of any Contributor under this -Agreement, whether expressly, by implication, estoppel or otherwise. All -rights in the Program not expressly granted under this Agreement are -reserved. +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. -This Agreement is governed by the laws of the State of New York and the -intellectual property laws of the United States of America. No party to this -Agreement will bring a legal action under this Agreement more than one year -after the cause of action arose. Each party waives its rights to a jury trial -in any resulting litigation. +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +**8.** If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +**9.** The Free Software Foundation may publish revised and/or new +versions of the General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a +version number of this License, you may choose any version ever +published by the Free Software Foundation. + +**10.** If you wish to incorporate parts of the Program into other +free programs whose distribution conditions are different, write to +the author to ask for permission. For software which is copyrighted by +the Free Software Foundation, write to the Free Software Foundation; +we sometimes make exceptions for this. Our decision will be guided by +the two goals of preserving the free status of all derivatives of our +free software and of promoting the sharing and reuse of software +generally. + +**NO WARRANTY** + +**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +### END OF TERMS AND CONDITIONS + +### How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + +To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + one line to give the program's name and an idea of what it does. + Copyright (C) yyyy name of author + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +Also add information on how to contact you by electronic and paper +mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details + type `show w'. This is free software, and you are welcome + to redistribute it under certain conditions; type `show c' + for details. + +The hypothetical commands \`show w' and \`show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than \`show w' and +\`show c'; they could even be mouse-clicks or menu items--whatever +suits your program. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the program, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright + interest in the program `Gnomovision' + (which makes passes at compilers) written + by James Hacker. + + signature of Ty Coon, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, +you may consider it more useful to permit linking proprietary +applications with the library. If this is what you want to do, use the +[GNU Lesser General Public +License](https://www.gnu.org/licenses/lgpl.html) instead of this +License. diff --git a/README.md b/README.md index 89375b5..81c5126 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,9 @@ Prototype code towards the great game I've been writing about for ten years, and ## Awful warning -This doesn't work and isn't ever likely to fully work: it's way too ambitious for any -single person to actually build. Feel free to mine it for algorithms and ideas, but -don't expect a game you can actually play any time soon. +This doesn't work and isn't ever likely to fully work: it's way too ambitious for any single person to actually build. Feel free to mine it for algorithms and ideas, but don't expect a game you can actually play any time soon. -## There is documentation +## There is (masses of) documentation [here](https://simon-brooke.github.io/the-great-game/) diff --git a/doc/A-generic-planning-algorithm-for-craftworker-npcs.md b/doc/A-generic-planning-algorithm-for-craftworker-npcs.md new file mode 100644 index 0000000..8fab45c --- /dev/null +++ b/doc/A-generic-planning-algorithm-for-craftworker-npcs.md @@ -0,0 +1,86 @@ +# A Generic Planning Algorithm for craftworker NPCs + +## Preamble + +The Great Game requires a number of different crafts to be performed, both because the economy depends on the products of those crafts and to provide verisimilitude and set dressing. Some of those crafts, the relations between them, and the progression within them are set out in [Populating a game world](Populating-a-game-world.html). + +For the purposes of planning work, only Master craftspeople are considered. + +A Master craftsperson has + +1. a house and appropriate workshop, within a settlement; +2. zero or more apprentices; +3. zero or more journeyman; +4. a spouse, who is usually of lower status; +5. zero of more coresident children; +6. zero or more coresident non-working parents/elders. + +There are limits to the number of apprentices and journeymen a master may take on, essentially based on demand in the local market. The master is responsible for housing and feeding all of the household including apprentices and journeymen, and for obtaining sufficient craft supplies. All craft work done in the household belongs to the master. + +Apprentices are definitely not paid. Journeymen should be paid, but this is a detail to ignore until we have other things working. + +Journeymen will move on from master to master from time to time — infrequently, but it will happen; and may be dismissed by masters when markets are tight. Journeymen probably learn their craft recipes — which is to say, the items and qualities of item they are able to craft — from the masters they work with. Consequently, journeymen will seek out masters with higher reputation; masters will prefer journeymen with more experience. + +Apprentices do not move on until the end of their period of apprenticeship (16th birthday?) when they become journeymen. + +The master will plan work in four hour sessions - essentially, a morning session and an afternoon session each day. + +All craftspeople have regular schedules covering mealtimes, sleep, and festivals. A lower status person within the household will have regular schedules covering each of fetching water, fetching fuel wood, taking out night soil, feeding chickens, washing dishes and laundry, and so on. + +When the master works in the workshop, all the apprentices and journeymen will also work in the workshop; when the master is engaging in recreation, they're also engaging in recreation. What they do when the master is e.g. going to market, I haven't yet decided. + +## Commodity items and special commissions + +In principle all craftspeople may make both commodity items and special commission items, but in practice many crafts will be mostly commodity and a few will be almost entirely special commission (for example a diplomat doesn't produce peace treaties prèt-à-porter); but I don't yet have a good model of how I'm going to handle special commissions, so I'm just doing some hand waving here to say they will exist and must be handled. + +## The algorithm + +A master craftsperson needs to keep stock of a number of things + +1. Sufficient food for the household; +2. Sufficient craft materials for immediate production; +3. Sufficient funds to buy more food/craft materials when needed; +4. Commodity craft items produced; +5. Craft items work in progress. + +### Choosing tasks + +So in planning a period of work, the master has to decide: + +1. Do I need to go to market? + 1. Is there news of a travelling merchant who buys what I produce arriving at my nearest market? -> go to market; + 2. Is the household running low on food? -> go to market; + 3. Is the household running low on craft materials? -> go to market; +2. Do I have any commissioned items to produce? -> produce commissioned items; +3. Should I work on commodities or take the day off? + This is a throw-of-the-dice decision, influenced by + 1. Cash on hand (if there's little, greater incentive to work); + 2. Weather (if it's especially good, less incentive to work); + 3. Gossip (if there's interesting news, less incentive to work) + +### Commodity production + +If the decision is to work on commodities, the next decision is what commodity item to produce. + +For each craft recipe the master knows there will be + +1. A list of quantities of different craft materials needed per item, for example a sword might need two kilograms of steel of a particular quality, ten kilograms of charcoal, one kilogram of timber, half a square metre of leather; +2. An amount of craftsperson time - for example, a standard infantry sword might take ten hours; +3. Memory of prices achieved by item to that recipe in the local market. + +The master will choose a recipe for which there are sufficient materials on hand, and which is profitable to make — the more profitable, the more likely to be selected (but I think there's probably some furtive dice rolling under the table here too; you don't want all the smiths in town producing infantry swords at the same time, because that would swamp the market and drive prices down). + +When an item is started, the materials for it are removed from stock and assigned to the item, which is added to the work in progress list. The number of items that can be produced in a work session is + +```clojure + (/ (* hours-in-session people-in-team) + hours-to-produce-one-item) +``` + +At the end of the session, the integer number of items produced is removed from the work in progress queue and added to stock, and the modulus is added as `:work-done` to the remaining item, which is left in the work in progress queue. + +Obviously items in the work in progress queue may need to be completed at the start of the next commodity work session. + +Obviously, none planned at sufficient granularity to be animated unless the workplace is in the `:active` circle, and none of it gets actually animated unless it's actually on camera, but the book-keeping in terms of food and craft materials consumed and of items produced must be done. + +This implies that at least many master craftspeople must be in the `:background` circle, i.e. woken up once every game day to plan a work session, no matter how far away the player character is. diff --git a/doc/API_Spec.md b/doc/API_Spec.md new file mode 100644 index 0000000..2070d99 --- /dev/null +++ b/doc/API_Spec.md @@ -0,0 +1,33 @@ +# API Spec (unfinished) + +If the Gossip system is ever to be deployed in practice at all, it will need to be deployed as a library add-on to someone else's game, since in practice The Great Game will never be even nearly finished. The game engine already knows many of the things the Gossip system needs to know; that we need to define is an interface which allows Gossip, considered as a subsystem, to query the game engine. + +My preference is still that Gossip should be written in a Lisp-like language - and, for now, in Clojure - simply because that is most comfortable to me. It needs bidirectional socket communication with the game engine, over which it sends either [extensible data notation](https://github.com/edn-format/edn) or [JavaScript Object Notation](https://www.json.org/json-en.html), with a preference for the former. + +## Tracking what happens in the world + +Existing game engines don't tend to track in convenient form things which have happened off-camera - indeed, mostly, things don't happen at all when the player isn't present. They don't even track much that happens when the player is present, and they usually track what they do track in fairly ad-hoc ways. So generally Gossip-as-library will have to maintain its own history of what has happened, and who knows what about what has happened; and will have to model the major life events of non-player characters happening off-camera (if this is done at all) itself. + +## Interrogating lore + +Many games have a great deal of lore and many lore texts. It's reasonable to expect each non-player character to know a certain amount of lore, certainly lore which is local to their home location, or relevant to their trade. In order to make that available to Gossip, you probably need to construct a searchable corpus of all the lore, which can be simply queried. + +That obviously then needs to be filtered by what the respondent can be expected to know, but that's a problem Gossip has to handle anyway. + +## Interrogating the map + +### get-character-location *id* + +Returns the player location in the world of the character with the specified id, as at minimum a three dimensional coordinate tuple, with heading; optionally with hierarchical region ids. + +### get-potential-auditors *id* + +### get-potential-auditors *id*, *volume* + +Return an ordered list of ids of characters spatially close to the character with the specified id, ordered by their likelihood of being the character addressed (i.e. preferring characters in front of the character with the specified id to those off to the side or behind, on a sort of cardioid pattern). The set is bounded by the distance at which speech is deemed to be intelligible, which may be a constant, or maybe modified by some modelling of ambient noise, or the volume of the character's speech act. + +### get-potentially-aware *id* + +### get-potentially-aware *id*, *volume* + +As above, but return a list of ids of characters within a distance in which speech may be heard but not intelligibly. \ No newline at end of file diff --git a/doc/Appraisal.md b/doc/Appraisal.md new file mode 100644 index 0000000..182a703 --- /dev/null +++ b/doc/Appraisal.md @@ -0,0 +1,33 @@ +# Appraisal (unfinished) + +## What is Appraisal + +There's an thing that all non player characters can do, which varies greatly from person to person, and which is of particular importance to merchants, and that is appraisal. + +Each category of goods has different dimensions of quality. A sword may be evaluated, for example, on + +| Dimension | Better is | Ease of appraisal | +| -------------------- | ---------------------------------- | ----------------- | +| Hardness | More | Difficult | +| Toughness | More | Difficult | +| Wear | Less | Intermediate | +| Weight | There's a sweet spot, but it's low | Easy | +| Length | Judgement call | Easy | +| Decoration/Showiness | Judgement call | Intermediate | +| Workmanship | Better | Intermediate | + +A person learns to appraise the qualities of a sword by having direct experience of swords with a range of values for the particular quality. A person who's only ever handled one sword does not know whether that sword heavy or light, pristine or worn. However, once a person has handled a dozen swords of different weights, they'll have some idea of what weight an average sword is, even if their idea may actually be a little off. Weight and length are easy to assess. + +Similarly, once someone has handled a few dozen swords with different degrees of wear, will have an idea of how many chips, how much corrosion or pitting, is normal. Wear is harder to assess, but it doesn't need particular techniques or skills to assess, just observation. To assess hardness, you really need to have sharpened the blade and then used it to the extent that it needs sharpening again, but if you've handled a lot of blades of varying qualities you may associate patterns in the steel, such as pattern welding, damascus steel, or a hamun, or particular markers' marks, with varying hardnesses. Toughness is even harder to assess (without actually chipping or breaking the blade) and is really going to come down to recognising either high quality steels or particular makers' marks. + +## Developing appraisal skill + +So: how does one gain experience? I'm going to assume that anyone who's bought a sword has handled it before making the choice. That anyone who's survived on the winning side f a battle unwounded will also have handled eight of each type of weapon used, for each such battle (the victors will have the pick of the spoils on the battlefield). That a weapon smith has handled sixteen for each year they've been working. And possibly that a master weapon smith will at least examine more weapons in a year than a journeyman, who will at least examing more than an apprentice. But, essentially, appraisal skill develops with exposure to items in the particular category. The exact mechanism for tracking this I'm unsure of, because there is a tradeoff between richness of records and data compactness, and this game looks like getting rather big. + +Of course, some people may be more observant than others, so it's possible that some people may gain appraisal skill on the basis of less exposure than others. But at this moment that's not a thing I'm planning to model. + +## What does appraisal skill buy you? + +In any category of goods, some individual items are better than others, and this difference may be significant. A person with good appraisal skill will recognise this difference. So a person with good skills, offered two items at the same price, will be able to select the better one; if bargaining for an item, will be prepared to offer a higher price for the better one; if selling items, will be prepared to sell the better one only for a higher price. + +Price arbitrage is how a static merchant makes money. \ No newline at end of file diff --git a/doc/Baking-the-world.md b/doc/Baking-the-world.md index a2f3739..c66d281 100644 --- a/doc/Baking-the-world.md +++ b/doc/Baking-the-world.md @@ -2,7 +2,9 @@ #### Wednesday, 8 May 2019 -![Devogilla's Bridge in Dumfries, early foourteenth century](https://2.bp.blogspot.com/-qxkySlJNmtY/XNKvJksmSjI/AAAAAAAAnXU/z1Zv2LmjydMmi_1q2mWdwVALmdfi9OItwCLcBGAs/s1600/Devorgillas-Bridge.jpg) +![Devorgilla's Bridge in Dumfries, early fourteenth century](https://2.bp.blogspot.com/-qxkySlJNmtY/XNKvJksmSjI/AAAAAAAAnXU/z1Zv2LmjydMmi_1q2mWdwVALmdfi9OItwCLcBGAs/s1600/Devorgillas-Bridge.jpg) + +*Devorgilla's Bridge in Dumfries, early fourteenth century. This clearly shows how a genetic buildings approach to bridges can be made to work: a single element is repeated to span the necessary distance. That element can be stretched vertically and laterally to match the location, and can be rendered in different stone finishes to match local geology.* In previous posts, I've described algorithms for dynamically [populating](Populating-a-game-world.html) and dynamically [settling](Settling-a-game-world.html) a game world. But at kilometre scale (and I think we need a higher resolution than that - something closer to hectare scale), settling the British Isles using my existing algorithms takes about 24 hours of continuous compute on an eight core, 3GHz machine. You cannot do that every time you launch a new game. @@ -72,7 +74,7 @@ ## Phase four: eating! - At the end, though, you have a game, and a player plays it. How much of the dynamic, organic life that brought the game through proving continues on into the playing phase? If the [gossip](The-spread-of-knowledge-in-a-large-game.html) ideas are to work, if unscripted, non-plot-related events (as well as scripted, plot related events) are to happen while the player plays, if news of these events is to percolate through the world and reach the player in organic, unscripted ways, if a lot of the emergent gameplay I'm imagining is to work, then quite a lot of the dynamic things must be happening. + At the end, though, you have a game, and a player plays it. How much of the dynamic, organic life that brought the game through proving continues on into the playing phase? If the [gossip](The-spread-of-knowledge-in-a-large-game-world.html) ideas are to work, if unscripted, non-plot-related events (as well as scripted, plot related events) are to happen while the player plays, if news of these events is to percolate through the world and reach the player in organic, unscripted ways, if a lot of the emergent gameplay I'm imagining is to work, then quite a lot of the dynamic things must be happening. Of course, part of this depends on the length of 'game world time' is expected to elapse in the course of one play through of the game. If it's less than a year, then you don't need children dynamically being born, and characters dynamically growing older; but if more, then you do. Similarly, you don't need a real simulation of trading to dynamically drive prices in markets, but for a fun trading sub-game to emerge, you probably do, and if you are using merchants as news spreading agents the additional compute cost is not high. diff --git a/doc/Biomes_and_ecology.md b/doc/Biomes_and_ecology.md new file mode 100644 index 0000000..2dd83d8 --- /dev/null +++ b/doc/Biomes_and_ecology.md @@ -0,0 +1,130 @@ +# Biomes and ecology (unfinished) +*The motivation for this document was to explain the mulberry trees in the Tcha valley, and think about why Tchahua is especially a centre for the silk trade* + +## Broader geography + +The broader geography of the world is not a matter for this document, but TODO: there isn't yet a document which usefully describes it, and there needs to be. + + +## Biomes relevant at this stage + +### 1. Steppe + +The centre of the continent is the steppe; it is generally too arid for forest growth, and is therefore scrub and grassland. There is one principal river system, which feeds into a marshland in the south, from which the water then goes underground beneath the limestone plateau to become the Tcha and Sind rivers. In late summer there's little water in the river, and few other waterholes. Antelope, camels, horses, goats, possibly sheep are native to the steppe, and there are probably something like leopards which predate on them, but I haven't fleshed it out. + +Big dragons don't hunt on the steppe because they can't take off from flat ground, but smaller dragons may do so. + +Settled by the steppe tribes, who are nomadic herders, extremely warlike but not technically highly developed. They are the game world's principle horse breeders. Basically in the game as I'm working on it at present, the player cannot go north across the steppe because the steppe tribes are too hostile. + +A single major road, the Caravan Road, runs north to south across the steppe. There were in the past fortified caravanserrais along the length of the road, established and protected by Hans'hua, but they have been progressively overrun and destroyed by the steppe tribes and are now ruinous. Only one remains: the North Inn, just below the northern slope of the plateau. There is some limited horticulture on land close to the South Inn, supplying markets in Hans'hua. + +### 2. Plateau + +The limestone plateau runs along the whole of the southern edge of the steppe, from the western massif to the rim of the crater which forms The Great Place. It is a landscape of clints and grykes, on which nothing grows, and on which there is no water. It is about four day's journey by fast horse from north to south. The caravan road crosses the plateau from the North Inn to another caravanserrai, the South Inn, located in the north end of the Tcha valley. Because of the dense chaotic pattern of clints and grykes and the lack of accessible water, it is effectively impossible to cross the plateau other than by the caravan road, or by another path to the extreme east of the plateau, where it abuts the mountains of the Rim. + +#### 2.1 Hans'hua + +There is one city, Hans'hua, on the caravan road about half way across the plateau, where wind-pumps lift water from the underground river. Apart from this one city, nothing lives on the plateau. Migrating birds cross it, and that is all. + +The city is small, walled, and run as an extreme neoliberal oligarchy; the city's main industry is maintaining the wind pumps, and its entire income is from tolls on caravans passing along the caravan road. This has been, and is still, extremely lucrative, but it is obvious both to the long distance merchants and to the oligarchs that the new ships are going to make the caravans too slow, too risky and too expensive to compete, and that as more ships are built, traffic on the caravan road will dwindle. + +### 3. Massif + +There's a granite intrusion which forms the entire western coast of the continent. It's geologically old and consequently the hills, though high, are rounded rather than jagged; at the southern end of the range (which is the only part that's in the least fleshed out yet) they're not snow covered in summer. As the prevailing winds are westerly, this massif intercepts most of the rain, which is why the steppe is arid. + +Consequently it's pretty thoroughly forested, and the southern parts of it are mainly broadleaf forests including high quality hardwoods and many fruiting trees. Understory typical of mediterranean littoral forests, about which I don't really know enough. + +Deer, cattle, pigs, wolves, leopards, badgers, squirrels… masses of birds of all appropriate types. + +Because it's an old granite intrusion, the soil in the valleys is largely clay. There are mineral rich veins with a considerable range of minerals, but, obviously, not all in the same place. + +Settled by the Western Clans, a negroid people living mainly in small isolated villages in the forest, with mostly limited agriculture. + +#### 3.1 Northern massif + +I haven't yet fleshed this out, but there are probably permanent snows and the forests are probably coniferous. It's my current working assumption that the new great ships are built from old growth conifers, taken from forests in the northern massif; but as I say this is not yet fleshed out. + +The northern culture have developed very high quality ceramics using clay from the massif, including stonewares and porcelaines. I think the same clays also exist in the south of the massif, but the technology for producing high quality ceramics does not exist there. The northerners are also making high quality steels from magnetite and haematite from the massif. Whether these ores exist in the south I don't yet know. + +#### 3.2 Dor + +The northernmost of the western clans, the Dor, live in the central massif north of Andale, but apart from the fact that they exist and they're there, I don't yet really know much. + +#### 3.3 Andale + +The river An rises in the east of the massif near the south-west corner of the steppe, west of where the village and market of Dawnhold now stand, and flows more or less due westward. There are two major drops in the river's course, the upper a day's travel east of Silverhold, which is an actual fall of at least six metres, and the lower at Anghold. Between Anghold and Silverhold the river is navigable by small shallow draught boats; west of Anghold it is navigable down to the sea at Anmouth. + +There are freshwater and migratory fish in the river, and fishing is a source of protein and livelihood the whole length of the valley. + +The valley is largely forested. Apart from wild animals, domestic cattle and pigs are herded in the forest. Trees include alder, almond, apple, apricot, ash, beech, birch, cherry, chestnut, hazel, holly, lime, maple, mulberry, oak, orange, pear, walnut, yew. + +##### 3.3.1 Dawnhold + +Dawnhold isn't strictly geographically in Andale — it's east of, on the steppe side of, the watershead, but it marks the eastern border of the lands settled by clan An. There's an annual market, a village, and a garrisoned fortification to deter raids by the steppe tribes. + +##### 3.3.2 Silverhold + +Small town serving the only significant silver mine in the world. A tributary flows in from the north here, but I know nothing about it yet. There is a major fortification/refinery/treasury. All around Silverhold, right up to the headwaters of the An and right down to Anghold, the valley is forested with only small clearings round villages, which are mainly close to the river. + +Many other metals — certainly inluding lead, tin, and small quantities of gold, probably not copper — come out of the mines at Silverhold. + +The An produce enough ferrous metals for their own tools and weapons, but their iron smelting technology is not advanced and they don't export iron or iron products. They produce eathernware ceramics for domestic consumption. They produce leather and linen, and textiles from nettle fibres. They produce timber, which is their principal building material, but they don't export it. In practice their major export is silver coinage. + +##### 3.3.3 Longwater + +Longwater is a long, narrow lake, like Loch Lomond, on a tributary which flows into the An from the south, joining upstream from Anghold. There is no major nucleated settlement on Longwater, but there are sufficient small villages and hamlets on its banks to form an identifiable settlement cluster. Small boats can make it downstream from Longwater from the An and back, probably with some degree of portage around rapids. There's a pass over from the south of the Longwater valley to Gor territory, but it's high, difficult, and not much used. The whole of the Longwater valley is broadleaf forest. + +##### 3.3.4 Anghold + +There's a small town, market and fortification — Anghold — on the south bank of the An, just above first cataract, where boats are portaged up from the lower river to the middle reach. Downstream from Anghold the river is wider, slower and more meandering, with marshy banks. The valley west of Anghold, especially on the southern side, is also more populated, with more of the forest cleared and more arable agriculture. + +##### 3.3.5 Anmouth + +The An meets the sea at Anmouth, where there is a deep harbour at a bend in the river just east of a long estuary, There is a bar, making it dangerous to enter the harbour in bad weather, and the whole estuary is pretty exposed to western storms, although there may be some islands providing some shelter for emergency anchorages — I don't have that level of detail yet. Certainly the big new ships do not yet call in here, but could. + +There are farming and sea-fishing villages down both sides of the estuary. There is no tradition of ship building, however. + +#### 3.4 Gor + +Clan Gor occupy the south-western peninsula of the continent, and the south slope of the massif, east almost as far as the Tcha valley. Their land is forested with a similar mix of trees to Andale. They have no major rivers, but several minor ones. They live mainly in coastal villages, and sea fishing is a major economic activity. They have no deep water ports. + +In addition they do mine iron, and they have exported swords, but the market for their swords is being undercut by better crucible steel swords from the north now being imported into the Cities of the Coast by the new ships. Similarly, the Gor used to export earthenware, but that too is now being undercut by stonewares and porcelaines from the north. + +Because of a history of being victims of raiding from the Cities of the Coast, the Gor maintain a fortified eastern border along the line of hills to the west of the Tcha valley. Nevertheless they have mostly good trading relationships with Tchahua. In particular they export large quantities of raw and spun silk, and some woven silk cloth, to Tchahua. + +I don't yet have nearly a clear enough picture of the organisation and layout of the Gor lands, but their major stronghold and administrative centre must be to the east. While they traditionally had the communist and democratic culture of the other Western Clans, one family have become dominant and have become effectively hereditary leaders, influenced by the cultures to their east. However the leading family do not self-identify as aristons. + +### 4. Coast + +"The Coast" is the name given to the southern littoral of the continent, west of the Great Place and east of the Massif. It's limestone, with deeply cut, steep sided valleys separated by high, arid uplands, with scrubby vegetation, grazed by domestic sheep and both domestic and wild goats. + +The native culture were peaceable, communistic agriculturalists, not greatly different from the Western Clans. However some several hundred years ago they were invaded by a warrior group from the steppe tribes, who established themselves as a military aristocracy — the Aristae — and started to build cities — and impose taxes onto the peasantry, forcing them into a more or less cash oriented economy. + +The valleys were once forested, but the central valleys, which were in any case rather dryer and where the Aristae first settled and established cities, are now mostly cleared, and are a mix of pastoral and arable, with considerable viticulture. + +#### 4.1 Tcha valley + +The Tcha is the westernmost — and largest — river of the coast. It emerges from under the plateau at a pool under the South Tower marking the southern limit of Hans'hua territory and runs south more or less along the divide between the granite to the west and the limestone to the east. It is still largely forested, partly because it is relatively recently occupied by the Aristae, but partly because of the growth of the silk industry. This has led to some forested areas, especially near the navigable reaches of the river, being converted into mulberry orchards. However, there's still a great deal of mixed forest, and the majority of mulberry leaves for feeding to silk worms are gathered from natural forest. + +A road branches off from the main Caravan Road at the South Inn and runs down the eastern side of the valley, to a ferry across the Sind river, where it joins the Tcha as a tributary, at the village helpfully known as Sind Ferry, and thence to Tchahua. + +Mulberries, by-products of the silk industry, are used in the production of brandy. Mulberry wine is produced in villages in the forest, and transported down river to a distillery at Sind Ferry, where it is distilled. Some mulberry wine may be sold in Tchahua for drinking as wine (and it is certainly drunk in the villages), but it is generally considered inferior to grape wine. + +There is some arable and mixed agriculture, mainly towards the southern end of the valley on the western (less steep) side, although this side is also largely forested. + +##### 4.1.1 Tchahua + +The city of Tchahua lies on the east bank of the river at the head of its estuary, and has deep water — the only really usable deep water port on the coast, being not only the largest river but also the least silted. Until quite recently it had been a small provincial silk weaving city, nominally independent but in fact paying tribute to both Sinhua to its east and the Gor to its west, in order to avoid being formally conquered by either. + +There's a multi-span bridge here — I think a pontoon bridge — of which the eastern most span is a drawbridge which can be lifted into a fortified gateway on the eastern (Tchahua) shore. There is a fishing industry, but as the eastern side + +Industries are silk weaving and dying, and fishing. Very recently, a new deep water quay has been constructed and the first large ships have begun to call. It is obvious that the city is going to become much more important as a strategic market and transport hub, but that has only just begun to have effect. + +### 4.2 Sind valley + +#### 4.2.1 Sinhua + + + + + diff --git a/doc/Building_on_microworld.md b/doc/Building_on_microworld.md new file mode 100644 index 0000000..5b5ac3f --- /dev/null +++ b/doc/Building_on_microworld.md @@ -0,0 +1,9 @@ +# Building on Microworld + +In [Settling a Game World](Settling-a-game-world.html) I intended that a world should be populated by setting agents - settlers - to explore the map and select places to settle according to particular rules. In the meantime, I've built [MicroWorld](https://github.com/simon-brooke/mw-ui), a rule driven cellular automaton which makes a reasonably good job of modelling human settlement. It works, and I now plan to use it, as detailed in this note; but there are issues. + +First and foremost, it's slow, and both processor and memory hungry. That means that at continent scale, a cell of one kilometre square is the minimum size which is really possible, which isn't small enough to create a settlement map of the density that a game will need. Even with 1 km cells, even on the most powerful machines I have access to, a continent-size map will take many days to run. + +Of course it would be possible to do a run at one km scale top identify areas which would support settlement, and then to do a run on a ten metre grid on each of those areas to more precisely plot settlement. That's an idea which I haven't yet explored, which might prove fruitful. + +Secondly, being a cellular automaton, MicroWorld works on a grid. This means that everything is grid aligned, which is absolutely not what I want! So I think the way to leverage this is to use MicroWorld to establish which kilometre square cells om the grid should be populated (and roughly with what), and then switch to *ad hoc* code to populate those cells. diff --git a/doc/Canonical-dictionary.md b/doc/Canonical-dictionary.md new file mode 100644 index 0000000..39d0fe5 --- /dev/null +++ b/doc/Canonical-dictionary.md @@ -0,0 +1,55 @@ +# Canonical dictionary for this documentation + +Where a word is used in the documentation for The Great Game and its related projects, this file describes the canonical meaning of that word. This is because a lot of the concepts in play are messy and ambiguous, so that at times even I am confused by what I mean. The presence of this file is an acknowledment of this difficulty, and an implicit admission that not all the documentation is, at this stage anyway, consistent. + +#### Actor + +An `actor` is a thing which performs actions within the game world. Thus a tree is (almost certainly) not an actor, and things like sheep and rabbits that run about are probably not actors, but an animal which may pro-actively interact with the player character (such as a predator, or a beast of burden, or even a prey species which may flee) is an actor. In [god mode](#God_mode), if implemented, the player can inhabit any actor within the game world. + +#### Agent + +`Agent` is probably just a synonym for `actor`. If it is different in any way, that way has not yet been determined. + +#### Gossip + +A `gossip` is an `actor` who exchanges news with other `actors`, even when the player character is not nearby. Thus `gossips` are the mechanism by which news propagates through the game world, and also the mechanism by which information degrades. Broadly: + +1. `innkeepers` (and possibly some others) are `gossips` who do not move; rather, they gather information from gossips who do move, and all `non-player characters` local to the are deemed to know everything that their local `innkeeper` knows; +2. `merchants` (and possibly some others) are `gossips` who do move from place to place, and thus transfer news. + +See [the spread of knowledge in a large game world](The-spread-of-knowledge-in-large-game.html). + +#### Heightmap + +A `heightmap` is a raster image of the world, such that the intensity in which an area is coloured represents the value of some variable, by default height, of that area. + +#### Holding + +A `holding` is a polygon 'owned' by an `actor` on which are built appropriate building units representing the `actors` craft and status. + +#### Location + +A `location` value is a sequence comprising at most the x/y coordinate location and the ids of the settlement and region (possibly hierarchically) that contain the location. If the x/y is not local to the home of the receiving agent, they won't remember it and won't pass it on; if any of the ids are not interesting, they won't be passed on. So location information will degrade progressively as the item is passed along. + +It is assumed that the `:home` of a character is a location in this sense. + +**Examples** + +1. \[{:x 5445678 :y 9684351}\] +2. \[{:x 5445678 :y 9684351} :karalin-palace :hanshua\] + +#### Merchant + +A `merchant` is an `actor` and `gossip` who trades goods, and incidentally conveys news, between `markets`. + +#### Non-player character + +A `non-player character` is, for our purposes, an `actor` capable of engaging in conversation with the `player character`. Note, however, that, from a software point of view, the `player character` is just a special case of a `non-player character`. + +#### Player character + +The `player character` is the unique `actor` within the game currently controlled and inhabited by the player. + +#### Route + +A `route` is a pre-prepared path through the game world that an `actor` may take. Most `actors` are not constrained to follow `routes`, but in general `routes` have lower traversal cost than other terrain. diff --git a/doc/Division_of_tasks_between_server_and_client.md b/doc/Division_of_tasks_between_server_and_client.md new file mode 100644 index 0000000..fd0ce96 --- /dev/null +++ b/doc/Division_of_tasks_between_server_and_client.md @@ -0,0 +1,27 @@ +# Division of tasks between server and client + +An alternative nomentclature I may use for this dichotomy would be _planner_ and _performer_; it would be the same dichotomy. 'Planner' and 'server' are synonyms; 'performer' and 'client' are synonyms. + +## What do I mean by the 'server'? + +There is something which manages game state and things like the gossip network, merchant network, and major world events. This something is almost certainly written in some form of Lisp; I'd prefer Clojure but I don't think it's performant enough so probably Common Lisp. This means that it has inevitable pauses for garbage collection. Underneath this is a database which handles persistent storage of game state, which is probably an SQL database and quite likely [SQLite](https://www.sqlite.org/index.html). + +The initial idea of The Great Game is that it is a single player game, but it actually doesn't need to be and it would be quite possible for one server to support multiple clients, each being used by a different player. + +The server/planner decides what each actor does, models what each character knows, plans and records all actions and transactions. It plans speech acts, and handles conversations which happen off screen, but hands speech texts over to the client/performer layer for actual performance. It also plans journeys as described in [Pathmaking](Pathmaking.html), but it doesn't deal with movement within a polygon or with collision avoidance. It deals with fights which happen off screen, but not those that happen on screen. + +## What do I mean by the client? + +There is something that renders an interesting and lively display of the part of the game world that the player can see from their current position. This display has to run without significant pauses — it's not OK, for example, for all conversation to stop suddenly in a market place just because the server is garbage collecting. + +The client is written in some high level game engine system, possibly Unreal Engine (although for ideological reasons I'd prefer an open source one). + +The client/performer renders and animates everything the player character can see, and performs every sound the player character can hear. In doing this it is responsible for + +1. The rendering of landscape, vegetation, buildings, furniture, and everything else that is fixed within the visible scene; +2. The animation of everything which moves within the visible scene, and, to facilitate this, detailed route planning and collision avoidance; +3. The performance of all speech acts and gestures, all musical performance, and the playing of all [foley](https://en.wikipedia.org/wiki/Foley_(filmmaking)) sounds; +4. Combat which happens in the field of view, including specifically all combat (including sparring) involving the player character. This means that the client/performer is the bit of the system which decides what blows are struck and whether they hit their targets, and consequently which character wins each fight. It reports this information back to the server. + + + diff --git a/doc/Dynamic-consequences.md b/doc/Dynamic-consequences.md new file mode 100644 index 0000000..a40fc51 --- /dev/null +++ b/doc/Dynamic-consequences.md @@ -0,0 +1,63 @@ +# On the consequences of a dynamic game environment for storytelling + +First, a framing disclaimer: in [Racundra's First Cruise](https://books.google.co.uk/books?id=Ol1-DwAAQBAJ&lpg=PP1&pg=PT77#v=twopage&q&f=false), Arthur Ransome describes coming across a half built — and by the time he saw it, already obsolete — wooden sailing ship, in a Baltic forest. An old man was building it, by himself. He had been building it since he had been a young man. It's clear that Ransome believed the ship would never be finished. It's not clear whether the old man believed that it would, but nevertheless he was building it. + +I will never build a complete version of The Great Game; it will probably never even be a playable prototype. It is a minor side-project of someone who + +1. Is old and ill, and consequently has inconsistent levels of energy and concentration; +2. Has other things to do in the real world which necessarily take precedence. + +Nevertheless, in making design choices I want to specify something which could be built, which could, except for the technical innovations I'm trying myself to build, be built with the existing state of the art, and which if built, would be engaging and interesting to play. + +The defining characteristic of Role Playing Games — the subcategory of games in which I am interested — is that the actions, decisions and choices of the player make a significant difference to the outcome of the plot, significantly affect change in the world. This already raises challenges for the cinematic elements in telling the game story, and those cinematic elements are one of the key rewards to the player, one of the elements of the game's presentation which most build, and hold, player engagement. These challenges are clearly expressed in two very good videos I've watched recently: [Who's Commanding Shepard in Mass Effect?](https://youtu.be/bm0S4cn_rfw), which discusses how much control the player actually has/should have over the decisions of the character they play as; and [What Happened with Mass Effect Andromeda’s Animation?](https://youtu.be/NmLPpcVQFJM), which discusses how the more control the player has, the bigger the task of authoring animation of all conversations and plot events becomes. + +There are two key innovations I want to make in The Great Game which set it apart from existing Role Playing Games, both of which make the production of engaging cinematic presentation of conversation more difficult, and I'll handle each in turn. But before I do, there's something I need to make clear about the nature of video games themselves: what they are for. Video games are a vehicle to tell stories, to convey narrative. They're a rich vehicle, because the narrative is not fixed: it is at least to some degree mutable, responsive to the input of the audience: the player. + +Clear? Let's move on. + +The innovations I am interested in are + +## Unconstrained natural speech input/output + +I want the player to be able to interact with non-player characters (and, indeed, potentially with other player characters, in a multi-player context) simply by speaking to them. This means that the things the player character says cannot be scripted: there is no way for the game designer to predict the full repertoire of the player's input. It also means that the game must construct, and put into the mouth of the non-player character being addressed, an appropriate response, given + +1. The speech interpretation engine's interpretation of what it is the player said; +2. The immediate game and plot context; +3. The particular non-player character addressed's knowledge of the game world; +4. The particular non-player character's attitude towards the player; +5. The particular non-player character's speech idiosyncracies, dialect, and voice + +and it must be pretty clear that the full range of potential responses is extremely large. Consequently, it's impossible that all non-player character speech acts can be voice acted; rather, this sort of generated speech must be synthesised. But a consequence of this is that the non-player character's facial animation during the conversation also cannot be motion captured from a human actor; rather, [it, too, must be synthesized](https://youtu.be/fa3_Mfqu8KA). + +This doesn't mean that speech acts by non-player characters which make plot points or advance the narrative can't be voice acted, but it does mean that the voice acting must be consistent with the simulated voice used for that non-player character — which is to say, probably, that the non-player character must use a synthetic voice derived from the voice performance of that particular voice actor in that role. + +**Note that** this has interesting consequences for social equity with regard to those whose current profession is voice acting video games. Automating work people do generally has the consequence of putting those people out of work, or at least of making their work less valuable and consequently less remunerative. Almost everyone who has worked in software has to some extent done this. I'm not avoiding or ignoring the ethical issue here. I would argue in mitigation that because games of the type I am suggesting can never be voice acted, I'm not replacing work any real actors will ever do, but that is tendentious since if games of this sort are built and are successful they will compete for audience attention with games which are voice acted. + +## Dynamic game environment + +Modern Role Playing Games are, in effect, extremely complex state machines: if you do the same things in the same sequence, the same outcomes will always occur. In a world full of monsters, bandits, warring armies and other dangers, the same quest givers will be in the same places at the same times. They are clockwork worlds, filled with clockwork automata. Of course, this has the advantage that is makes testing easier — and in a game with a complex branching narrative and many quests, testing is inevitably hard. + +Interestingly, [Kenshi](https://lofigames.com/) — a game I'm increasingly impressed and influenced by — is not quite clockwork in this sense. As the player upsets the equilibrium of the game's political economy, factions not impacted negatively will move against competing factions which are impacted negatively, in a way which *may* be scripted, but it's so well done it's hard to tell. + +My vision for The Great Game is different. It is that the economy — and with it, the day to day choices of non-player characters — should be modelled. This means, non-player characters may unexpectedly die. Of course, you could implement a tag for plot-relevant characters which prevents them being killed (except when required by the plot). + +## Plot follows player + +As Role Playing Games have moved towards open worlds — where the player's movement in the environment is relatively unconstrained — the clockwork has become strained. The player has to get to particular locations where particular events happen, and so the player has to be very heavily signposted. Sometimes the mark you have to hit to trigger the next advance of the plot can be extremely awkward; [an example from Cyberpunk 2077](https://youtu.be/GEYkuctBUYE?t=2990) is finding the right spot, in the quest 'They Won't Go When I Go', to trigger the button which raises the cross. + +Another solution — which I'd like to explore — is 'plot follows character'. The player is free to wander at will in the world, and plot relevant events will happen on their path. And by that I don't mean that we associate a set of non-player characters which each quest — as current Role Playing Games do — and then uproot the whole set from wherever they normally live in the world and dump them down in the player's path; but rather, for each role in a quest or plot event, we define a set of characteristics required to fulfil that role, and then, when the player comes to a place where there are a set of characters who have those characteristics, the quest or plot event will happen. + +## Cut scenes, cinematics and rewarding the player + +There's no doubt at all that 'cut scenes' — in effect, short movies spliced into game play during which the player has no decisions to make but can simply watch the scene unroll — are elements of modern games which players enjoy, and see to some extent as 'rewards'. And in many games, these are beautifully constructed works. It is a very widely held view that the quality of cutscenes depends to a large degree on human authorship. The choices I've made above: + +1. We can't always know exactly what non-player characters will say (although perhaps we can in the context of cut scenes where the player has no input); +2. We can't always know exactly which non-player characters will speak the lines; +3. We can't predict what a non-player character will say in response to a question, or how long that will take; +4. We can't always know where any particular plot event will take place; + +each make the task of authoring an animation harder. The general summary of what I'm saying here is that, although in animating a conversation or cutscene what the animator is essentially animating is the skeletons of the characters, and, provided that all character models are rigged on essentially similar skeletons, substituting one character model for another in an animated scene isn't a huge issue, with so much unknowable it is impossible that hand-authoring will be practicable, and so a lot will depend on the quality of the conversation system not merely to to produce convincingly enunciated and emoted sound, but also appropriate character animation and attractive cinematography. As you will have learned from the Mass Effect analysis videos I linked to above, that's a big ask. + +Essentially the gamble here is that players will find the much richer conversations, and consequent emergent gameplay, possible with non-player charcaters who have dynamic knowledge about their world sufficiently engaging to compensate for a less compelling cinematic experience. I believe that they would; but really the only way to find out would be to try. + +Interestingly, an [early preview](https://youtu.be/VwwZx5t5MIc?t=327) of CD Project Red's [Cyberpunk 2077](https://www.cyberpunk.net/us/en/cyberpunk-2077) has relatively few cutscenes, suggesting that these very experienced storytellers don't feel they need cutscenes either to tell their story or maintain player engagement. diff --git a/doc/economy.md b/doc/Economy.md similarity index 56% rename from doc/economy.md rename to doc/Economy.md index 15111dc..f6d8dd9 100644 --- a/doc/economy.md +++ b/doc/Economy.md @@ -6,7 +6,7 @@ Broadly this essay extends ideas presented in [Populating a game world](Populati ### Herdsfolk -Herdsfolk are nomadic; it's reasonable to think they'll bring their herds to market, rather than selling it lots of tiny markets. So in the spring, shepherds will visit specific towns at the edge of open land, to hold a shearing festival/carnevale; and that both shepherds and cattle herders will visit towns on the edge of open land to sell fatstock in the autumn. +Herdsfolk are nomadic; it's reasonable to think they'll bring their herds to market, rather than selling at lots of tiny markets. So in the spring, shepherds will visit specific towns at the edge of open land, to hold a shearing festival/carnevale; and that both shepherds and cattle herders will visit towns on the edge of open land to sell fatstock in the autumn. ### Miners @@ -32,18 +32,22 @@ Farmers are settled. Farmers occupy standard runrig plots, but because they don' * fibres: linen, hemp and silk (from silk-moths in mulberry orchards) * possibly other stuff I've forgotten. -Farmers are all basically subsistence farmers, farming first to feed their own household and selling only surplus in the market. +Farmers are all primarily subsistence farmers, farming first to feed their own household and selling only surplus in the market. ## Crafts -Crafts generally process primary goods into secondary goods - whether intermediate stages or final consumer items. Some elite 'crafts' deal with abstract primary goods like law and knowledge, and they may be seen as somewhat separate. +Crafts generally process primary goods into secondary goods — whether intermediate stages or final consumer items. Some elite 'crafts' deal with abstract primary goods like law and knowledge, and they may be seen as somewhat separate. -A master craftsperson occupies a standard runrig plot, much like a farmer's plot. Like a farmer, a poor master crafter household will cultivate part of the plot to produce food for the house - at least grow vegetables and keep hens. However, as the crafter takes on apprentices and journeymen - and gets richer - more buildings will be required as accommodation, workshop space and materials stores. +A master craftsperson may occupy a standard runrig plot, much like a farmer's plot. Like a farmer, a poor master crafter household will cultivate part of the plot to produce food for the house — at least grow vegetables and keep hens. However, as the crafter takes on apprentices and journeymen — and gets richer — more buildings will be required as accommodation, workshop space and materials stores. -Generally, primary goods aren't transported over land - because overland transport is expensive, by the time they've been transported they're no longer low cost goods. So often the craftspeople who process primary produce into at least commodity intermediate forms will live close to the source of the primary goods. +Also, Tchahua is much more a gold-rush town than an organic, grew over hundreds of years sort of town, so it is not ex-runrig; and additionally the original settlement was probably along the river bank, land which has now been redeveloped as warehouses and as rich merchant residences. Generally, town house plots are small from the get go. + +Hans'hua is again an exception from normal organic development, as it has no agricultural land close to the city at all. + +Generally, primary goods aren't transported over land — because overland transport is expensive, by the time they've been transported they're no longer low cost goods. So often the craftspeople who process primary produce into at least commodity intermediate forms will live close to the source of the primary goods. So, for example, the town(s) where the shepherds hold their shearing fairs will tend to have a lot of weavers. While around mines there will be smelters producing ingots and bar stock to be marketed to smiths all over the place, there will also be smiths close to the mines producing commodity tools and weapons. -See the table in Populating a game world. +See the tables in [Populating a game world](Populating-a-game-world.html). diff --git a/doc/Further-reading.md b/doc/Further-reading.md new file mode 100644 index 0000000..8832dd1 --- /dev/null +++ b/doc/Further-reading.md @@ -0,0 +1,11 @@ +# Further Reading (and watching) + +Work by other people which is relevant to what I'm doing, and which I should study. + +## Modelling the natural environment + +1. [Synthetic Silviculture: Multi-scale Modeling of Plant Ecosystems](https://storage.googleapis.com/pirk.io/projects/synthetic_silviculture/index.html) — see also [this video](https://youtu.be/8YOpFsZsR9w). + +## Systemic games + +1. [This video](https://youtu.be/SnpAAX9CkIc) is thought provoking with excellent examples. diff --git a/doc/Game-engine-integration.md b/doc/Game-engine-integration.md new file mode 100644 index 0000000..e6f8fa4 --- /dev/null +++ b/doc/Game-engine-integration.md @@ -0,0 +1,7 @@ +# Game-engine integration (unfinished) + +To build a game using these ideas we need a lot of things that are well understood and already implemented: rendering a world, moving models of characters in a world, and so on. This collection of technologies which allow us to realise an interactive realisation of a world is typically called a game engine. + +It's my intention that the bits that I add to the mix should be open source in the hard sense of that phrase, fully free software released under GPL. They cannot therfore be directly linked to a proprietary game engine. + +But the current state of play is that the best and easiest to work with game engines are not open source; and while I could build a demo game using, for example, the [Godot engine](https://godotengine.org/) or [jMonkeyEngine](https://jmonkeyengine.org/) the result wouldn't be as compelling and *I believe* the effort would be more considerable than if I use [Unreal Engine](https://www.unrealengine.com/en-US), which is my current plan. \ No newline at end of file diff --git a/doc/Game_Play.md b/doc/Game_Play.md index ec9b948..c3c6bac 100644 --- a/doc/Game_Play.md +++ b/doc/Game_Play.md @@ -2,25 +2,25 @@ 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. +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. +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. +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. +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. +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. +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. +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. +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 in 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 +## Death to Dum-Dum -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. +As I've argued [elsewhere](Voice-acting-considered-harmful.html), [repeatedly](Selecting_Character.html), 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.html)' 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. @@ -28,13 +28,13 @@ Suddenly, they can have attitudes about things that happen in the world, opinion 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. +And as new 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. +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). +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 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). diff --git a/doc/Genetic-buildings.md b/doc/Genetic-buildings.md new file mode 100644 index 0000000..59f1edb --- /dev/null +++ b/doc/Genetic-buildings.md @@ -0,0 +1,61 @@ +# Genetic Buildings + +### Building selection based on location + + The objective of this note is to create a landscape with varied and believable buildings, with the minimum possible data storage per instance. + + Like plants, buildings will 'grow' from a seed which has northing and easting attributes. These locate a position on the map. Again, like trees, some aspects of the building type selector are location based. Aspects of the location which are relevant to building type are + +* **elevation** — derived from the map location by interpolation from grid. The actual interpolation algorithm is probably some form of spline, but in any case it's the same one as for everything else. +* **orientation of slope** — derived by taking altitude at four corners of a 100 metre square centred on the seed point, and then taking the highest and lowest of these. If highest is northwest, lowest is southeast, the slope is considered to be oriented southeast; if highest is northwest and lowest southwest, the orientation is considered to be south, and so on. Eight orientation values are sufficient. +* **gradient of slope** — derived from the difference in altitude across the same 100 metre square +* **neighbours** — number of other buildings in 500 metre square centred on seed point. + + The reason orientation is relevant is exactly the same as the reason it's relevant to trees. West facing slopes are assumed wetter (coriolis winds), so grow trees better, so better availability of better quality timber, so a higher probability of timber as a primary building material. But also, in areas of higher rainfall, rain shedding is an important consideration, so a higher value is placed on pitched roofs. + + So you have the following general relationships + +* west (or southwest or northwest) facing, moderate gradient, moderate altitude: high probability of timber construction; construction techniques involving large timbers (e.g. cruck frame); greater probability of shingled roofs; +* west (or southwest or northwest) facing, moderate gradient, higher altitude or northern latitude: high probability of building styles adapted to straight-trunk conifers, e.g. log cabins, stave buildings; greater probability of shingled roofs; +* east facing, generally: greater probability of flat roofs; +* steeper gradients: greater probability of stone buildings (steeper gradients = shallower topsoil and greater ease of quarrying = access to stone); greater probability of slate roofs; +* shallower gradients: greater probability of mud, cobb, brick or wattle-and-daub as building materials; greater probability of thatch or turf roofs; +* Higher number of neighbours: higher probability of two or more stories; + + These factors allow classes of building to be selected. Having got past that point, we need to consider how classes of genetic building can work. + +### Rectangular genetic buildings + + Some genetic buildings will have cells with rectangular plan. This doesn't mean that genetic buildings are required to have rectangular cells, but they provide a starting point for discussion. For a given class of building (for example, timber frame), a number of prototype models of cells exist. These models are fully realised three dimensional models. Possibly all cells belonging to the building class have two open ends, and end walls exist as separate models; equally possibly, some cells have only one extensible end. In any case, a building will not normally comprise a single cell. Normally it will comprise multiple cells. So the cells belonging to a particular building class will be designed to 'plug together'. Multi story building classes will have some cells which are specifically ground floor only (flat ceiling, no roof), and such cells will always have an upper floor cell added above them. Where an upper floor cell has an outside door, an outside stair will automatically be added. + +### Cell mutability + + Although cell models are repeatedly reused they don't have to look the same every time they are reused. Within limits, every cell can be stretched along any of its three axes. Obviously, the degree of stretch on a given axis for every cell in a given building must be the same, otherwise they won't line up. Another mutable area is skinning — it may be possible to have alternate skins for cells, and even if there are not alternate skins, it will be possible to mutably darken, lighten or otherwise tint the skins used, within ranges which are appropriate to the materials represented. Obviously there are limits to stretching — timber comes in only such a length, stone lintels will only support such a span. + +### Functional cells + + Some trade functions require cells of particular kinds. Thus a smith needs a working building with one cell which is explicitly a forge. A water mill must have one cell which explicitly houses the mill gear. A forge cell or a waterwheel cell should never appear in weavers workshop. But most cells are not dedicated in this way. A bedroom cell is a bedroom cell, more or less; wealth may alter how it is furnished, but it may appear in any dwelling. Similarly, except for the very wealthy, a living cell is pretty much a living cell. And any building may incorporate a storage cell. If a given building class has twelve distinct 'generic' cells' and half a dozen distinct functional cells, and if buildings in the class average four cells each, then ignoring variance caused by skin mutability, a street of fifty buildings could have every one different. + +### Reproducibility + + It's critical that if a player visits a location, leaves it, and then returns, the buildings should not all have changed. So it must be possible to repeatedly reproduce the building at the location (this, of course, applies to other procedural scene dressing, such as trees, roads, boundaries, bridges and so on). This is possible if a deterministic random number generator is used which is seeded from the latitude and longitude attributes of the location. Other attributes which should be cached on the seed even though they are determined procedurally when the building is first instantiated include building class, purpose, and wealth. Using these attributes and the deterministic random number generator, the same building can be reproduced on the same site each time it is visited, with a very small amount of data stored. + + Buildings will normally be built at the edge of the associated land holding. If an edge of the land holding adjoins a road, then the building will be built with one long side aligned to the road. Otherwise, the building will be built at right angles to the orientation of the slope. The orientation will be 'frozen' once the building has been instantiated and will be cached on the seed. + + So, to build a building, use the following algorithm: + + Seed the random number generator with latitude and longitude + + ``` + while ( building value is less than wealth) { + select a cell selected from the building class using the next number from the random number generator modulo the number of generic cells in the class; + if the selected cell is not inappropriate to the building's function { + fit the cell to the building at the point determined by a deterministic algorithm + furnish cell using the random number generator to determine + furnishing types and locations from a selection appropriate to the cell + if the selected cell was not a top story cell { +          add a requirement that the next cell selected must be an upper story cell} + } + } + ``` + diff --git a/doc/Gossip_scripted_plot_and_Johnny_Silverhand.md b/doc/Gossip_scripted_plot_and_Johnny_Silverhand.md index a311a01..5f5cb88 100644 --- a/doc/Gossip_scripted_plot_and_Johnny_Silverhand.md +++ b/doc/Gossip_scripted_plot_and_Johnny_Silverhand.md @@ -1,33 +1,33 @@ # 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, +I've been writing literally for years — since [Voice acting considered harmful](Voice-acting-considered-harmful.md) 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. +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. +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). +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). (Interestingly, since I first wrote this note, CD Projekt Red have used Lyrebird-like technology to [resurrect a voice actor](https://www.theverge.com/2023/10/13/23915535/cyberpunk-2077-phantom-liberty-polish-voice-actor-ai-ripperdock-viktor-vektor) in Phantom Liberty, proving that the technology is good enough). 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. +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. +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. +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. @@ -41,7 +41,7 @@ Well, the first and obvious thing is to parse the unscripted response to see whe > > **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: +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? > diff --git a/doc/MVP-Roadmap.md b/doc/MVP-Roadmap.md new file mode 100644 index 0000000..54c35ca --- /dev/null +++ b/doc/MVP-Roadmap.md @@ -0,0 +1,59 @@ +# Minimum Viable Product, and a road map + +Right, I'm bogged down thinking about the immensity of what I want to build, so I'm achieving nothing. So the first thing I need to state is what the Minimum Viable Product is, and the second is to outline a rough road map which takes us forwards a few steps from the MVP. + +The core idea here is to have a game world in which you can just say anything you like to game characters, and they can say sensible things back. + +But actually, I know that speech to text can be reasonably effectively done; and I believe with a slightly lower degree of confidence that text to convincing speech can also be done. + +I also know that the movement of a character around a convincing three dimensional representation of a world can be done, but that a great deal of effort is needed to build that world. + +The minimum viable product does not need to demonstrate features which people have reasonable confidence can be done. What I need to demonstrate is the things which people haven't seen done, or haven't seen done well. + +## Prototype one: the minimum viable product + +The minimum viable product can have just a text adventure style interface: + +> You are in the market square. It is mid morning. To the north is the guild hall; to the east there are market stalls; to the south is the residence; to the west is the bridge gate. + +> There is a merchant here; there is a guardsman here. + +To which the user can type (for example) + +> Say to the guardsman, "Can you direct me to Master Dalwhiel's house?" + +Within that interface, you should be able to interact with characters who: + +1. have different levels of knowledge of the world, partly driven by their age, trade and personal history; +2. move about and exchange gossip, even when the player is not present to see/hear this; +3. have different attitudes towards the player and other characters, which will be modified by what they learn in gossip; +4. have their own hierarchies of needs, which they make plans to satisfy; +5. have homes and trades; +6. will respond to speech addressed to them by the player depending on their attitude to the player, how busy they are and their knowledge of the world; and +7. as a stretch goal, will have different dialects in which they will express their responses to the player. + +There should be one or two multiple decision point quests in this world which can be resolved by talking to characters. + +## Prototype two: adding organic quests + +Extends prototype one only by adding [organic quests](Organic_Quests.html). + +## Prototype three: voice interaction + +Extends prototype two by adding speech to text, so that the player can directly talk (via a microphone) to characters, and text to speech, so that the system can voice the characters' responses. + +Different characters should have different voices. + +## Prototype four: performative speech + +This one is hard because I'm not absolutely sure how I can do it, but I need characters' voices to convey emotion; the player needs to know from their voice whether they are angry, or frightened, or impatient, or bored. + +There is a [W3C specification](https://www.w3.org/TR/speech-synthesis11/) for an XML markup for speech performance, and I can certainly generate that, but I'd need to find a text-to-speech library which could consume it. There's also a separate [specification](https://www.w3.org/TR/pronunciation-lexicon/) to associate pronunciations with lexical tokens, which is also potentially useful, especially for names. + +Google has a '[Cloud Text-to-Speech](https://cloud.google.com/text-to-speech/docs/ssml)' service which understands SSML and might be good enough for a demo but is more likely just embarrassingly bad. + +## Prototype five traversible world + +Now, a small section of a three dimensional open world, with at this stage simple block buildings that the player cannot enter, within which the characters act out their lives. + +Stretch goal, [JALI](https://www.youtube.com/watch?v=uFIxiz0jwRE)-like lip sync. \ No newline at end of file diff --git a/doc/Modelling_democracy_and_morale.md b/doc/Modelling_democracy_and_morale.md new file mode 100644 index 0000000..aa35d29 --- /dev/null +++ b/doc/Modelling_democracy_and_morale.md @@ -0,0 +1,29 @@ +# The Red Company: modelling democracy and morale (unfinished) + +## Background + +The Great Game exists as a project on two levels. One one level, it's a framework for building algorithms to build much more vibrant, and thus enjoyable game worlds; at another level, it's about building a particular world, in which I want to tell stories. + +The world in which I want to tell stories is a world which is based roughly on late bronze age to medieval Europe. It's a world in which the region known as 'The Coast' -- the southern littoral of the continent -- had been a mostly-peaceful matrideic dispersed agrarian tribal society, which had been invaded some hundreds of years past by a warrior tribe with substantially better military technology. + +These warrior tribesmen have settled down as local tyrants or robber barons, parasitising on the indigenous communities, and have evolved into an aristocratic ('Ariston') class. In the meantime, a mercantile class has grown up and established important long distance overland trade routes; and significant towns (called 'cities', but of only at most a few tens of thousand inhabitants) have grown up around markets. + +These mercantile cities have been under the governance of powerful aristons known as tyrranoi, and the cities under their tyrranoi have competed militarily as well as commercially for control of strategic features on trade routes, such as bridges, fords, oases, mountain passes, and so on. + +In the very earliest days of the warrior invasion, the warriors themselves fought against the indigenous peoples, who had very limited military equipment and tactics. Later, as they settled into Aristons, they fought by leading feudal levies of partially-trained peasants. Over the past hundred years or so, mercenary companies have emerged of specialist, trained warriors, and because these have more fighting experience (and often better equipment) they tend to beat feudal levies. These mercenary companies are base loosely on the condottierri of fourteenth century Italy. + +So more and more, tyrranoi, rather than leading their own feudal levies, instead tax their peasantry and mercantile class more and hire condottierri to fight their wars. + +Mercenary companies evolve out of feudal levies, and in the period of The Great Game, are mostly owned and led by aristons who employ their soldiers by paying them a wage. + +One company, the Red Company, has become essentially a workers' co-op, after its former ariston leader fled in the course of a battle which looked like an inevitable defeat (but which the company, without him, won). In this company, soldiers are paid a salary, probably lower than salaries in other companies, but also at the end of the year get a share in the profits. The soldiers are organised into squads of eight who elect their own sergeants; squads are organised into companies of eight squads, and the sergeants elect the captain; companies are organised into legions of eight companies, and the captains elect the captain-general. + +However, while in combat this represents a chain of command, out of combat it is much more a delegate structure; when making significant decisions, the captains general will consult with the captains who will consult with the sergeants who will consult with the soldiers. + +One of the themes of the stories I want to tell is that this more democratic structure contributes to higher morale and hence to greater military success. I could model this by just making membership of the Red Company a factor in the function which computes morale. However... + +## Modelling democracy + +If each individual character has a hierarchy of needs, and plans actions based on that hierarchy of needs, then they have the mechanism in place to choose which of two options better conforms to their hierarchy of needs. + +This implies that soldiers are likely to vote for the people (or ideas presented by the people) they consider most competent and/or most trustworthy. Which comes back to modelling reputation; which comes back to the [gossip](the-great-game.gossip.gossip.html). \ No newline at end of file diff --git a/doc/modelling_trading_cost_and_risk.md b/doc/Modelling_trading_cost_and_risk.md similarity index 96% rename from doc/modelling_trading_cost_and_risk.md rename to doc/Modelling_trading_cost_and_risk.md index 78ae9dd..a62daeb 100644 --- a/doc/modelling_trading_cost_and_risk.md +++ b/doc/Modelling_trading_cost_and_risk.md @@ -1,4 +1,4 @@ -# Modelling trading cost and risk +# Modelling trading cost and risk (unfinished) In a dynamic pre-firearms world with many small states and contested regions, trade is not going to be straightforward. Not only will different routes have different physical characteristics - more or less mountainous, more or fewer unbridged river crossings - they will also have different political characteristics: more of less taxed, more or less effectively policed. diff --git a/doc/naming-of-characters.md b/doc/Naming-of-characters.md similarity index 100% rename from doc/naming-of-characters.md rename to doc/Naming-of-characters.md diff --git a/doc/Not_my_problem.md b/doc/Not_my_problem.md new file mode 100644 index 0000000..5f3b6b7 --- /dev/null +++ b/doc/Not_my_problem.md @@ -0,0 +1,26 @@ +# Not my problem + +## Introduction + +This document is essentially a catalogue of side-tracks which I do not have to go down when implementing The Great Game. Solved problems; or problems which are common to many other games, so if I don't solve them someone else will. The object of doing this is to work down to a constrained set of problems which are genuinely things I'm trying to innovate, which I should focus on; which essentially come down to + +1. Gossip +2. Reputation +3. Dynamic character motivation and action, and hence +4. Dynamic economy, and +5. Dynamic plot +6. Procedural ('genetic') buildings. + +(Note that although procedural vegetation is in principle a solved problem and so I don't need to solve it, I need repeatable procedural vegetation so I need to be a bit careful about the procedural vegetation library I pick). + +## Animation + +I envisage a well rendered three dimensional world in which many non-player characters interact with one another and with the player character. All of my characters are either human, quadrupeds, or birds (my dragons animate like very large birds). The humans are all just human; there are infants, children, adolescents, youths, adults, elderly; there are multiple racial types — but they're all human. Systems for creating varied distinct human models exist; systems for animating them exist; systems for applying and animating clothing exist. Even systems for animating continuous speech exist. + +## Rendering + +Ideally I'd like a stylised, not-quite-photorealistic render, because such things age, in my opinion, better than things which do seek to be photorealistic. But actually that does not matter very much; the game won't be made or broken by its rendering. Photorealistic renders are sort of the current default, that most game engines. + +## Continuous Open World + +I've done a great deal of thinking about how to render a continuous open world over the years, and I think at least some of it is reasonably good; but I haven't actually written any code, and in the same time period other people have written continuous open world libraries which do work, so I'd be much better choosing an existing one. diff --git a/doc/on-dying.md b/doc/On-dying.md similarity index 57% rename from doc/on-dying.md rename to doc/On-dying.md index 0251f2d..95ee755 100644 --- a/doc/on-dying.md +++ b/doc/On-dying.md @@ -1,4 +1,4 @@ -# On Dying +# On Dying, and Injury Death is the end of your story. One of the tropes in games which, for me, most breaks immersion is when you lose a fight and are presented with a screen that says 'you are dead. Do you want to reload your last save?' Life is not like that. We do not have save-states. We die. @@ -11,3 +11,17 @@ Time has passed; events in the game world have moved on. You can talk to your sa So who are the non-enemies? It depends on context. If you have a party, and some of that party survived the fight, it's your party. Otherwise, if you're in a populated place, it's locals. If it's on a road or other route, it's passing merchants. If you're in the wilderness, a hunting party. It's a bunch of non-hostiles who might reasonably be expected to be around: that's what matters. It's about not breaking immersion. Obviously losing a fight must have weight, it must have meaning, it must have in-game consequences; otherwise it is meaningless. + +## Injury + +Similarly to death, injury must have meaning. Any injury takes time to recover from. It takes a certain amount of time if you're able to rest somewhere safe, and considerably longer if you're not. If you fight while injured, you'll have less strength, less stramina, and probably also less agility. Depending where you're injured, there will be certain things you cannot do. If you fight while injured, also, your recovery time will be extended, even if you take no further injury. + +Some serious injuries will lead to permanent scarring, and permanent loss of agility; you'll be just slightly slower in fights. + +It should be said that [Kenshi](https://lofigames.com/) — a game I've only recently become aware of and greatly admire — handles all of this extremely well, and is worth studying. + +## Reciprocity + +If the player is going to depend on good samaritans for rescue after losing a fight, then there must be at least a social convention that people should assist people found injured on the wayside. Consequently, if the player fails to do this, that should in itself become a 'gossip' event which will lower the player's reputation with non-player characters. + +On the other hand, helping NPCs found injured at the wayside can be another category of [organic quest](Organic_Quests.html), as a special subcategory of an escort quest. \ No newline at end of file diff --git a/doc/On-sex-and-sexual-violence.md b/doc/On-sex-and-sexual-violence.md new file mode 100644 index 0000000..3bdaaca --- /dev/null +++ b/doc/On-sex-and-sexual-violence.md @@ -0,0 +1,73 @@ +# On Sex, and Sexual Violence, in Games + +For me the purpose of games is to provide worlds in which players can explore moral actions, and the consequences of moral actions. Sexual violence is something that happens in the real world, and which happens, even within the real world, more frequently in areas of poor governance and open conflict; and those are areas in which there are important moral actions, and important moral consequences, so they are areas in which it is interesting to set games. + +It would be ludicrous to argue 'sexual violence is wrong, therefore we should not represent it in games.' Killing people is also wrong, yet it is extremely common in games. However, sexual violence — and in particular the representation of sexual violence — does pose some specific problems that need to be addressed. + +Firstly, sexual violence is extremely gendered. Yes, male people are sometimes subjected to sexual violence, but nevertheless the overwhelming majority of victims of sexual violence are female. Yes, female people are sometimes — extraordinarily rarely, but sometimes — perpetrators of sexual violence, but nevertheless perpetrators of sexual violence are almost exclusively male. + +Secondly, it is extremely tricky to represent sexual violence in visual media without eroticising it. There's a [very famous scene in Last Tango in Paris](https://www.independent.co.uk/arts-entertainment/films/news/last-tango-in-paris-butter-scene-b2270513.html) which the director might claim is consented in context, but which appears to me to be a clear case of anal rape, which is nevertheless highly erotic. There's a scene in [High Plains Drifter](https://en.wikipedia.org/wiki/High_Plains_Drifter#Plot) where no part of the rape is actually represented — it happens off screen — but it is nevertheless perceived by many people (including me) as eroticised. Many people — I suspect more men than women, but certainly including many women — do find the idea of rape erotic. It seems to me highly undesirable that a game should be seen to be rewarding immoral action. + +(Yes, I know many modern games do quite explicitly reward killing, including of characters whose culpability is at best trivial, but — surely — this is something we should be seeking to move away from.) + +## Subtlety and Nuance + +A final issue here is that sexual interactions between people are subtle, and are subtle even around issues of consent. A less powerful person (normally a woman) — alone or as a member of a weak party, a party of perhaps older people, other women, children — may submit to sex with more powerful others without protest in order to protect others in their party, or to avoid death or serious injury, or to avoid starvation, or to escape debt. Do any of these things truly count as consent? + +Again, a less powerful person may submit to sex with more powerful others transactionally in return to protection, or shelter, or food, or other resources. In modern society we might see this as sex work, and we might argue that sex work falls into the same moral category as any other labour entered into transactionally. But, generally, is it moral that people should be put into a position where their survival depends on their ability to sell any sort of unwilling labour? + +(This is not to deny that some people, who do have secure living conditions or who could choose to do other things in order to gain secure living conditions do choose, willingly and voluntarily, to engage in sex work; and it isn't to criticise those people in any way). + +Games are not very good at subtly and nuance. When, while playing a game, the character who is our avatar in the game, who we thought we were controlling, does something which we didn't intend them to do, it's very wrenching and immersion-breaking. + +At the same time, if other characters in the game interpret something the player's character has done as sexual violence when the player did not intend sexual violence, that's also undesirable. + +So, questions: + +## Sex between non-player characters + +People have sex. If people didn't have sex, there wouldn't be people; but more, if people didn't have sex, there wouldn't be (many) stories, since most stories are driven at least in part by sex. So pretending that non-player characters don't have sex is worse than unrealistic. + +We live in a pathologically repressed society, in which open sex — sex in public places, sex with other people present — is rare, is seen as deviant, is (perhaps in consequence) highly eroticised. Does that mean that all the societies we represent in our games must be similarly repressed? + +I would argue strongly to the contrary. Games are environments in which we can explore moral possibilities, and a society in which public sexuality was normal is clearly a possibility. Would such a society be a better society? Games are a mechanism through which we can ask that question, and questions of that sort. + +If we're going to represent a society in which public sex is normal, then we're going to have to represent public sex on screen. It can take one of many forms: + +1. Sex as normal activity — it's just going on in the background, and no other non-player characters pay much attention; +2. Sex as conscious performance — sex where the participants intend to be watched, and other non-player characters do pay attention (this may include consciously eroticised performance); +3. Sex as part of a religious or other ritual event — this is related to, and is, sex as conscious performance, but the purpose of the performance is symbolic and/or sacramental. This doesn't mean it is not eroticised, but it may not be eroticised. + +By 'eroticised', I'm meaning deliberately intended to trigger sexual feelings in the audience — which, if the player character is present, includes the player. + +## Sexual violence between non-player characters + +In a world in which there are characters who are thuggish, who seek to dominate, terrorise and subdue other characters, whether those characters are outlaws or soldiers or aristocrats, to pretend that rape would not be used as a means to dominate, terrorise or subdue is… bowdlerisation. It's unrealistic, and it's a morally indefensible choice. + +So there has to be a mechanism for non-player characters to decide to commit acts of sexual violence towards other non-player characters. The player must at least hear of such events through the gossip network, and should be able to find the specific non-player characters involved, and speak to them. Whether it's necessary to portray acts of sexual violence on screen is something I'm much less persuaded by, simply because it runs the risk of eroticising them. + +## Mutually consented sexual activity between the player character and non-player characters + +Mutually consented sexual behaviour between the player character and (certain, scripted) non-player characters has been a feature of video games for some time, and has occasionally been portrayed with real sensitivity and eroticism. Two cases I would point to are + +1. The sex scene between Geralt and Shani in The Witcher; +2. The sex scene between V and Judy in Cyberpunk 2077. + +Cyberpunk is a largely non-cutscene game, but the sex scenes is a cutscenes and I completely understand why, from a technical point of view: the player does not have, either with mouse and keyboard or with a game controller, nearly enough control over their character to convey the subtlety and nuance of a good sex scene. Sex scenes in most video games are also pretty rare, and that must be at least partly because of cultural prurience. + +But if a game allows a player to have a long lasting, narratively sexual relationship with a non-player character, as many games do, then sex is a behaviour which may happen repeatedly, and just playing the same cutscene over and over again is not going to be an adequate way of representing that. + +The ideal would be to have a moderately large library of brief motion captures of people authentically having sex, and to be able to select performances at random from that library to apply to the body models of the characters who in the game are having sex, whether that be the player character with a non-player character, or two non-player characters. In the case where the player character is involved, this would happen in the location where the player chose to initiate it, so it wouldn't be a cutscene in the normal sense; but I think that the controller should be disabled for the duration of the performance. + +## Sexual violence by one non-player character towards another + +This is at least implicitly represented in existing video games, and while caution about eroticising it should be maintained, I think it's something which should be narratively possible. + +## Sexual violence from the player character towards non-player characters + +This would be extremely tricky (and controversial!) to handle; I *think* it ought to be in the narrative toolkit, but I have no specification to offer just now. + +## Sexual violence from a non-player character towards the player character + +Even trickier! + diff --git a/doc/Pathmaking.md b/doc/Pathmaking.md index 216446b..a0f0ced 100644 --- a/doc/Pathmaking.md +++ b/doc/Pathmaking.md @@ -2,11 +2,11 @@ **NOTE**: this file is called 'pathmaking', not 'pathfinding', because 'pathfinding' has a very specific meaning/usage in game design which is only part of what I want to talk about here. +**NOTE**: Work on this is being carried on in a separate library, [Walkmap](https://github.com/simon-brooke/walkmap), q.v. + ## Stages in creating routes between locations -### The 'procedural' phase - -*see also [[Baking-the-world]]* +*see also [Baking the world](Baking-the-world.html)* Towards the end of the procedural phase of the build process, every agent within the game world must move through the complete range of their needs-driven repertoire. Merchants must traverse their trading routes; soldiers must patrol routes within their employers domain; primary producers and craftspeople must visit the craftspeople who supply them; every character must visit their local inn, and must move daily between their dwelling and their workplace if different; and so on. They must do this over a considerable period - say 365 simulated days. @@ -16,17 +16,55 @@ The algorithmic part of choosing a route is the same during this baking phase as Thus the 'weight' of any section of route is a function of the total number of times that route segment has been traversed by an agent during this baking phase. At the end of the baking phase, routes travelled more than `R` times are rendered as roads, `T` times as tracks, and `P` times as footpaths, where `R`, `T` and `P` are all chosen by the game designer but generally `R > T > P`. -### Algorithmic rules +### Routing -1. No route may pass through any part of a reserved holding, except the holding which is its origin, if any, and the holding which is its destination (and in any case we won't render paths or roads within holdings, although traversal information may be used to determine whether a holding, or part of it, is paved/cobbled; +Routing is fundamentally by [A\*](https://www.redblobgames.com/pathfinding/a-star/introduction.html), I think. + +#### Algorithmic rules + +1. No route may pass through any part of a reserved holding, except the holding which is its origin, if any, and the holding which is its destination, if any (and in any case we won't render paths or roads within holdings, although traversal information may be used to determine whether a holding, or part of it, is paved/cobbled; 2. No route may pass through any building, with the exception of a city gate; 3. We don't have bicycles: going uphill costs work, and you don't get that cost back on the down hill. Indeed, downhills are at least as expensive to traverse as flat ground; 4. Any existing route segment costs only a third as much to traverse as open ground having the same gradient; 5. A more used route costs less to traverse than a less used route. +#### Step costing: + +Step cost is something like: + + (/ + (- + (+ distance + (expt height-gained height-gain-exponent) + (reduce + (map crossing-penalty watercourses-crossed))) + (reduce + (map bridge-bonus bridges-crossed))) + (or road-bonus 1)) + +**Where** + +* `distance` traversed is in metres; +* `height-gained` is in metres; +* `height-gain-exponent` is tunable; +* river `crossing-penalty` varies with a (tunable) exponent of the flow; +* `bridge-bonus` works as follows: bridge bonus for a bridge entirely cancels the river crossing penalty +for the watercourse the bridge crosses; bridge bonus for a ferry cancels a (tunable) fraction the river +crossing penalty. +* road-bonus for a road is substantial - probably about 8; for a track is less than road but greater than footpath, say 5; for a footpath has to be at least 3, to provide an incentive to +stick to paths. All these values are tunable. Road bonus ought also to increase a small amount with each traversal of the path segment, but that's still to be worked on. + +A lot of this is subject to tuning once we have prototype code running. + +Somewhere into all this I need to factor tolls charged by local aristons, +especially for bridges/ferries, and risk factors of hostile action, whether +by outlaws or by hostile factions. But actually, that is at a per actor +level, rather than at a pathmaking level: richer actors are less deterred +by tolls, better armed actors less deterred by threat of hostile action. + ### River crossings -Crossing rivers is expensive - say five times as expensive as level open ground (but this will probably need tuning). Where a river is shallow enough, (i.e. where the amount of water passing is below some threshold) then a path crossing will be rendered as stepping stones and a track crossing as a ford. Where it's deeper than that, a path crossing either isn't rendered at all or is rendered as a light footbridge. A track or road crossing is rendered as a bridge. However, the maximum length of a bridge varies with the amount of traffic on the route segment, and if the crossing exceeds that length then a ferry is used. Road bridges will be more substantial than track bridges, for example in a biome with both timber and stone available road bridges might be rendered as stone bridges while track bridges were rendered as timber. If the watercourse is marked as `navigable`, the bridge must have a lifting section. It is assumed here that bridges are genetic buildings like most other in-game buildings, and so don't need to be individually designed. +River crossings appear automatically when the number of traversals of a particular route across a watercourse passes some threshhold. The threshold probably varies with an exponent of the flow; the threshold at which a ferry will appear is lower (by half?) than the threshold for a bridge. Of course river crossings, like roads, can also be pre-designed by game designers. + +Where a river is shallow enough, (i.e. where the flow is below some threshold) then a path crossing will be rendered as stepping stones and a track crossing as a ford. Where it's deeper than that, a path crossing either isn't rendered at all or is rendered as a light footbridge. A track or road crossing is rendered as a bridge. However, the maximum length of a bridge varies with the amount of traffic on the route segment, and if the crossing exceeds that length then a ferry is used. Road bridges will be more substantial than track bridges, for example in a biome with both timber and stone available road bridges might be rendered as stone bridges while track bridges were rendered as timber. If the watercourse is marked as `navigable`, the bridge must have a lifting section. It is assumed here that bridges are genetic buildings like most other in-game buildings, and so don't need to be individually designed. ### Representation @@ -65,17 +103,7 @@ I'm working on a separate library, [walkmap](https://simon-brooke.github.io/walk ### Pathmaking and scale -Dealing with large heightmaps - doing anything at all with them - is extremely compute intensive. Just converting a 1000x1000 heightmap from STL to SVG is currently taking 8 hours and 15 minutes; and it ends up with a 46 megabyte SVG file! However, most of the time cost is in writing. Reading the STL file takes four and a quarter seconds; converting that STL to SVG in memory takes less than five seconds. So the huge cost is writing the file with Dali. - - walkmap.core=> (time (def stl (decode-binary-stl "../the-great-game/resources/maps/heightmap.stl"))) - "Elapsed time: 4285.231513 msecs" - #'walkmap.core/stl - walkmap.core=> (time (def svg (stl-to-svg stl))) - "Elapsed time: 4865.798059 msecs" - #'walkmap.core/svg - - -"Elapsed time: 2.969569560662E7 msecs" +Dealing with large heightmaps - doing anything at all with them - is extremely compute intensive. We cannot effectively do routing at metre scale - which is what we ultimately need in settlements - across the entire thousand kilometre square map in one pass. But also we don't need to because much of the continent is by design relatively unpeopled and relatively untracked. The basic concept of the Steppe is that there are two north/south routes, the one over the Midnight Pass into the Great Place and the one via Hans'hua down to the Cities of the Coast, and those can be part of the 'designed roads' map. So we can basically exclude most of the Steppe from routing altogether. We can also - for equally obvious reasons exclude the ocean. The ocean makes up roughly half of the 1000x1000 kilometre map, the steppe and plateau take up half of what's left, mountain massifs eat into the remainder and my feeling is that much of the eastern part of the continent is probably too arid to be settled. So we probably end up only having to dynamically route about 20% of the entire map. @@ -107,6 +135,10 @@ we can then collect contiguous groups of zones each having at least one holding, At least one of phases three, four, five and six is probably redundant; but without trying I'm not sure which. +#### Relevant actor classes by phase + +Craftspeople and primary producers do travel between settlements, but only exceptionally. They mainly travel within at most a few kilometres of home; so they are primarily relevant in phases four and five, and need not be activated during phase six. Similarly, merchants primarily travel between settlements, and rarely within settlements; therefore, they need not be activated in phase four, and probably not even in phase five; but they must do a lot of journeys - substantially their full repertoire - in phase six. + ### Tidying up After the full set of increasing-scale passes is complete, we should automatically cull any route segments generated in the settlement phase which have never actually been traversed. diff --git a/doc/Populating-a-game-world.md b/doc/Populating-a-game-world.md index 1783a78..14d6974 100644 --- a/doc/Populating-a-game-world.md +++ b/doc/Populating-a-game-world.md @@ -2,7 +2,7 @@ #### Saturday, 6 July 2013 - *(You might want to read this essay in conjunction with my older essay, [Settling a game world](../../2009/12/settling-game-world.html), which covers similar ground but which this hopefully advances on)* + *(You might want to read this essay in conjunction with my older essay, [Settling a game world](Settling-a-game-world.html), which covers similar ground but which this hopefully advances on)* For an economy to work people have to be able to move between occupations to fill economic niches. In steady state, non player character (NPC) males become adult as 'vagrants', and then move through the state transitions described in this document. The pattern for females is different. @@ -12,7 +12,7 @@ -| Occupation | Dwelling | condition | New trade | Notes | +| Occupation | Dwelling | Condition | New trade | Notes | | --- | --- | --- | --- | --- | | Vagrant | None | land available and animals available | Herdsman | | | Vagrant | None | arable land available | Farmer | See crops | @@ -43,70 +43,81 @@ Crafts are occupations which require acquired skills. In the initial seeding of the game world there are probably 'pioneers', who are special vagrants who, on encountering the conditions for a particular craft to thrive, instantly become masters of that craft. + + + + + +
Craft Dwelling Supplies Perishable? Customer types Needs market? Customers Supplier Suppliers Recruits
Solo Per journeyman Per apprentice
Min Max Min Max Min Max
Smith Forge Metal Items no Farmer, Soldier No 6 10 4 6 1 3 Miner 1 Vagrant +
Baker Bakery Bread yes All NPCs No 20 30 12 18 6 10 Miller 1 Vagrant +
Miller Mill Flour, meal no Baker, Innkeeper No 2 3 1 2 1 1 Farmer 6 Vagrant +
Weaver Weaver's house Cloth no All NPCs Yes 6 10 4 6 1 3 Herdsman 2 Vagrant +
Innkeeper Inn Food, hospitality yes Merhant, Soldier, Farmer, Lord No 10 20 5 10 2 4 Farmer,Herdsman 2 Vagrant +
Miner Mine Ores no Smith Yes 2 3 1 2 1 1 Farmer 1 Vagrant +
Butcher Butchery Meat yes All NPCs No 10 20 4 8 2 4 Farmer, Herdsman 2 Vagrant +
Merchant Townhouse Transport, logistics n/a Craftsmen, nobility Yes 10 20 4 8 2 4 n/a n/a Vagrant +
Banker Bank Financial services yes Merchant Yes 10 20 4 8 2 4 n/a n/a Merchant +
Scholar Academy Knowledge n/a Ariston, Tyrranos, General, Banker No 1 4 1 2 0.25 0.5 n/a n/a Vagrant +
Priest Temple Religion n/a All NPCs No 50 100 Scholar +
Chancellor Chancellory Administration n/a Ariston, Tyrranos No 1 1 0 0 0 0 Scholar +
Lawyer Townhouse Legal services n/a Ariston, Merchant, Banker No 4 6 2 3 1 2 Scholar +
Magus Townhouse Magic n/a Tyrranos, General No 3 4 1 2 0.25 0.5 Scholar +
-| Craft | Dwelling | Supplies | Perishable? | Customer types | Needs market? | Customers | Supplier | Suppliers | Recruits | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| | | | | | | Solo | Per journeyman | Per apprentice | | | | -| | | | | | | --- | --- | --- | | | | -| | | | | | | Min | Max | Min | Max | Min | Max | | | | -| --- | | | | | | --- | --- | --- | --- | --- | --- | | | | -| Smith | Forge | Metal Items | no | Farmer, Soldier | No | 6 | 10 | 4 | 6 | 1 | 3 | Miner | 1 | Vagrant | -| Baker | Bakery | Bread | yes | All NPCs | No | 20 | 30 | 12 | 18 | 6 | 10 | Miller | 1 | Vagrant | -| Miller | Mill | Flour, meal | no | Baker, Innkeeper | No | 2 | 3 | 1 | 2 | 1 | 1 | Farmer | 6 | Vagrant | -| Weaver | Weaver's house | Cloth | no | All NPCs | Yes | 6 | 10 | 4 | 6 | 1 | 3 | Herdsman | 2 | Vagrant | -| Innkeeper | Inn | Food, hospitality | yes | Merhant, Soldier, Farmer, Lord | No | 10 | 20 | 5 | 10 | 2 | 4 | Farmer,Herdsman | 2 | Vagrant | -| Miner | Mine | Ores | no | Smith | Yes | 2 | 3 | 1 | 2 | 1 | 1 | Farmer | 1 | Vagrant | -| Butcher | Butchery | Meat | yes | All NPCs | No | 10 | 20 | 4 | 8 | 2 | 4 | Farmer, Herdsman | 2 | Vagrant | -| Merchant | Townhouse | Transport, logistics | n/a | Craftsmen, nobility | Yes | 10 | 20 | 4 | 8 | 2 | 4 | n/a | n/a | Vagrant | -| Banker | Bank | Financial services | yes | Merchant | Yes | 10 | 20 | 4 | 8 | 2 | 4 | n/a | n/a | Merchant | -| Scholar | Academy | Knowledge | n/a | Ariston, Tyrranos, General, Banker | No | 1 | 4 | 1 | 2 | 0.25 | 0.5 | n/a | n/a | Vagrant | -| Priest | Temple | Religion | n/a | All NPCs | No | 50 | 100 | | | | | | | Scholar | -| Chancellor | Chancellory | Administration | n/a | Ariston, Tyrranos | No | 1 | 1 | 0 | 0 | 0 | 0 | | | Scholar | -| Lawyer | Townhouse | Legal services | n/a | Ariston, Merchant, Banker | No | 4 | 6 | 2 | 3 | 1 | 2 | | | Scholar | -| Magus | Townhouse | Magic | n/a | Tyrranos, General | No | 3 | 4 | 1 | 2 | 0.25 | 0.5 | | | Scholar | +A craftsman starts as an apprentice to a master of the chosen crafts. Most crafts recruit from vagrants, A character must be a journeyman merchant before becoming an apprentice banker, while various intellectual crafts recruit from journeyman scholars. +It's assumed that a journeyman scholar, presented with the opportunity, would prefer to become an apprentice magus than a master scholar. - A craftsman starts as an apprentice to a master of the chosen crafts. Most crafts recruit from vagrants, A character must be a journeyman merchant before becoming an apprentice banker, while various intellectual crafts recruit from journeyman scholars. +### Related crafts - It's assumed that a journeyman scholar, presented with the opportunity, would prefer to become an apprentice magus than a master scholar. +There are groups of crafts which should probably be seen as related crafts, where apprenticeship in one should serve as qualification to serve as journeyman in another. For example, there is a family of woodworking crafts, whose base is probably `Joiner`. - A journeyman settles and becomes a master when he finds a location with at least the solo/min number of appropriate customer type who are not serviced by another master craftsman of the same craft; he also (obviously) needs to find enough free land to set up his dwelling. The radius within which his serviced customers must live may be a fixed 10Km or it may be variable dependent on craft. If there are unserviced customers within his service radius, the master craftsman may take on apprentices and journeymen to service the additional customers up to a fixed limit – perhaps a maximum of four of each, perhaps variable by craft. If the number of customers falls, the master craftsman will first dismiss journeymen, and only in desperate circumstances dismiss apprentices. Every apprentice becomes a journeyman after three years service. +Crafts within this family include - The list of crafts given here is illustrative, not necessarily exhaustive. +* Boatwright +* Cabinetmaker +* Cartwright +* Cooper +* Lutanist +* Military Artificer +* Millwright +* Turner + +So although I think these are separate crafts, all are Joiners; all can undertake construction joinery work; and a journeyman who has served as apprentice to any can serve as journeyman to any other. Since journeymen will typically serve under more than one master before settling down, it will be possible for one person to have served under masters in two different related trades and therefore be qualified to set up as a master of either. + +A journeyman settles and becomes a master when he finds a location with at least the solo/min number of appropriate customer type who are not serviced by another master craftsman of the same craft; he also (obviously) needs to find enough free land to set up his dwelling. The radius within which his serviced customers must live may be a fixed 10Km or it may be variable dependent on craft. If there are unserviced customers within his service radius, the master craftsman may take on apprentices and journeymen to service the additional customers up to a fixed limit – perhaps a maximum of four of each, perhaps variable by craft. If the number of customers falls, the master craftsman will first dismiss journeymen, and only in desperate circumstances dismiss apprentices. Every apprentice becomes a journeyman after three years service. + +The list of crafts given here is illustrative, not necessarily exhaustive. ## Aristocracy - As in the real world, aristocracy is essentially a protection racket, and all nobles are originally outlaw leaders who found an area with rich pickings and settled down. +As in the real world, aristocracy is essentially a protection racket, and all nobles are originally outlaw leaders who found an area with rich pickings and settled down. + +
Rank Follower rank Client type Clients protected Trade in market Followers per client +
Min Max Min Max Min Max +
Bonnet Laird Private Farmer 6 20 0 100 0.25 0.5 +
Ariston Captain Bonnet Laird 10 30 25 1000 0.5 1 +
Tyrranos General Ariston 10 unlimited 250 unlimited 0.1 0.5 +
-| Rank | Follower rank | Client type | Clients protected | Trade in market | Followers per client | -| --- | --- | --- | --- | --- | --- | -| | | | Min | Max | Min | Max | Min | Max | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | -| Bonnet Laird | Private | Farmer | 6 | 20 | 0 | 100 | 0.25 | 0.5 | -| Ariston | Captain | Bonnet Laird | 10 | 30 | 25 | 1000 | 0.5 | 1 | -| Tyrranos | General | Ariston | 10 | unlimited | 250 | unlimited | 0.1 | 0.5 | +Every noble establishes a market and, if he employs a chancellor, taxes trade in it. Crafts which 'need a market' can only be established in the vicinity of a market, irrespective of whether there are sufficient customers elsewhere. All non-perishable goods are traded through the markets, and merchants will transfer surpluses between markets if they can make a profit from it. +My world has essentially three ranks of nobility. The title of the lowest rank will probably change to something vaguely italianate. An aristocrat advances to the next rank when either the requisite number of clients become available in the locality to support the next rank, or the trade in his market becomes sufficient to support the next rank. - Every noble establishes a market and, if he employs a chancellor, taxes trade in it. Crafts which 'need a market' can only be established in the vicinity of a market, irrespective of whether there are sufficient customers elsewhere. All non-perishable goods are traded through the markets, and merchants will transfer surpluses between markets if they can make a profit from it. - - My world has essentially three ranks of nobility. The title of the lowest rank will probably change to something vaguely italianate. An aristocrat advances to the next rank when either the requisite number of clients become available in the locality to support the next rank, or the trade in his market becomes sufficient to support the next rank. - - Obviously when a province has eleven unprotected bonnet lairds, under the rules given above any of them may become the ariston, and essentially it will be the next one to move after the condition becomes true. If the number of available clients drops below the minimum and the market trade also drops below the minimum, the noble sinks to a lower level – in the case of the bonnet laird, to outlaw leader. +Obviously when a province has eleven unprotected bonnet lairds, under the rules given above any of them may become the ariston, and essentially it will be the next one to move after the condition becomes true. If the number of available clients drops below the minimum and the market trade also drops below the minimum, the noble sinks to a lower level – in the case of the bonnet laird, to outlaw leader. ## Military - The aristocracy is supported by the military. An outlaw becomes a soldier when his leader becomes a noble. Otherwise, vagrants are recruited as soldiers by bonnet lairds or sergeants who have vacancies. Captains are recruited similarly by aristons or generals, and generals are recruited by tyrranos. If the conditions for employment no longer exist, a soldier is allowed a period of unemployment while he lives off savings and finds another employer, but if no employer is found he will eventually become an outlaw (or, if an officer, an outlaw leader). A private is employed by his sergeant or bonnet laird, a sergeant by his captain, a captain by his arison or general, a general by his tyrranos. +The aristocracy is supported by the military. An outlaw becomes a soldier when his leader becomes a noble. Otherwise, vagrants are recruited as soldiers by bonnet lairds or sergeants who have vacancies. Captains are recruited similarly by aristons or generals, and generals are recruited by tyrranos. If the conditions for employment no longer exist, a soldier is allowed a period of unemployment while he lives off savings and finds another employer, but if no employer is found he will eventually become an outlaw (or, if an officer, an outlaw leader). A private is employed by his sergeant or bonnet laird, a sergeant by his captain, a captain by his arison or general, a general by his tyrranos. + +
Rank Follower rank Followers Condition New rank +
Min Max +
Private None 0 0 Battle hardened, unled privates Sergeant +
Sergeant Private 5 15 More battle hardened, unled sergeantts Captain +
Captain Sergeant 5 15 More battle hardened, unled captains General +
General Captain 5 unlimited +
-| Rank | Follower rank | Followers | | Condition | New rank | -| --- | --- | --- | --- | --- | --- | -| | | Min | Max | | | -| --- | --- | --- | --- | --- | --- | -| Private | None | 0 | 0 | Battle hardened, unled privates | Sergeant | -| Sergeant | Private | 5 | 15 | More battle hardened, unled sergeantts | Captain | -| Captain | Sergeant | 5 | 15 | More battle hardened, unled captains | General | -| General | Captain | 5 | unlimited | | | - - - Soldiers have no loyalty to their employer's employer. +Soldiers have no loyalty to their employer's employer. diff --git a/doc/Roadmap.md b/doc/Roadmap.md new file mode 100644 index 0000000..8a2ed57 --- /dev/null +++ b/doc/Roadmap.md @@ -0,0 +1,30 @@ +# Roadmap (obsolete) + +This document outlines a plan to move forward from where I am in June 2021. + +**NOTE**: this document has been [superceded](MVP-Roadmap.html). + +# JMonkeyEngine + +[JMonkeyEngine](https://jmonkeyengine.org/) is not, at this time, an AAA game engine. But at the same time I'm never, really, going to build an AAA game. It is a working game engine which can display characters on screen in scenery and have them move around, and, actually, they can be fairly sophisticated. It will be resaonably easy to integrate Clojure code with JMonkeyEngine - easier than it would be to integrate either Clojure or Common Lisp with [Unreal Engine](https://www.unrealengine.com/) or [Unity 3D](https://unity.com/). As a significant added bonus, JMonkeyEngine is open source. + +Consequently I plan to stop agonising about what game engine to use, and seriously focus on getting something working in JMonkeyEngine. + +# Not Reinventing Wheels + +JMonkeyEngine already has working code for walking animated characters, which is entirely adequate to proof-of-concept what I want to do. Rather than try to implement them myself, I just intend to use existing JMonkeyEngine code as far as possible. + +# The 1Km World + +I propose to build a 1Km square world, containing one settlement, as a proof of concept for + +1. Procedural (genetic) buildings; +2. Procedural settlement planning; +3. Procedural characters, probably based on [MakeHuman 'Mass Produce' plugin](https://youtu.be/jRHnJX-TdT4), using walk animation based on [TestWalkingChar](https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java); +4. Characters with their own hierarchy of needs, and their own means of planning to fulfil these; +5. Characters with individualised knowledge about the world; +6. Characters who can parse typed questions, and produce either a textual or audio response; +7. Characters with procedurally generated accents (very stretch goal)! +8. Characters who can listen to spoken questions, and produce audio responses. + +At that stage, I have a technology demonstrator that will be interesting. It still leaves the big procedural world builder still to do, but it would be enough technology to get other people interested in the project. \ No newline at end of file diff --git a/doc/sandbox.md b/doc/Sandbox.md similarity index 52% rename from doc/sandbox.md rename to doc/Sandbox.md index 82098d6..5d2410a 100644 --- a/doc/sandbox.md +++ b/doc/Sandbox.md @@ -35,7 +35,7 @@ The next tier of playable roles rotates around issues arising from the mercantil ### Aristocracy -Aristocrats are basically settled outlaws who seek to establish a monopoly on extracting taxes from inhabitants and travellers in a particular region by driving out all other outlaws. Within the comain of an aristocrat, you have to pay tax but you're reasonably safe from being attacked by other outlaws and losing everything. Aristocrats may also maintain and improve roads and bridges and do other things to boost the economy of their territory, may expant into adjoining territory with no current aristocratic control, and may wage war on other aristocrats. +Aristocrats are basically settled outlaws who seek to establish a monopoly on extracting taxes from inhabitants and travellers in a particular region by driving out all other outlaws. Within the domain of an aristocrat, you have to pay tax but you're reasonably safe from being attacked by other outlaws and losing everything. Aristocrats may also maintain and improve roads and bridges and do other things to boost the economy of their territory, may expand into adjoining territory with no current aristocratic control, and may wage war on other aristocrats. An outlaw ought to be able to become an aristocrat, by dominating an ungoverned area or by defeating an existing aristocrat. @@ -45,22 +45,24 @@ Soldiers, like aristocrats, are basically on the same spectrum as outlaws. Outla ## Routine, Discretion and Playability -There's a term that's used in criticism of many computer games which is worth thinking about hard here: that term is 'farming'. 'Farming', in this sense, is doing something repetitive and dull to earn credits in a game. Generally this is not fun. What makes roles in a game-world fun is having individual discretion - the ability to choose between actions and strategies - and a lack of routine. +There's a term that's used in criticism of many computer games which is worth thinking about hard here: that term is 'farming'. 'Farming', in this sense, is doing something repetitive and dull to earn credits in a game. Generally this is not fun. What makes roles in a game-world fun is having individual discretion — the ability to choose between actions and strategies — and a lack of routine. -Most craft skills - especially in the learning phase - are not like this, and crafts which are sophisticated enough to be actually engaging are very hard to model in a game. Learning a craft is essentially, inherently, repetitive and dull, and if you take that repetition out of it you probably don't have enough left to yield the feeling of mastery which would reward success; so it doesn't seem to me that making craft roles playable should be a priority. +Most craft skills — especially in the learning phase — are not like this, and crafts which are sophisticated enough to be actually engaging are very hard to model in a game. Learning a craft is essentially, inherently, repetitive and dull, and if you take that repetition out of it you probably don't have enough left to yield the feeling of mastery which would reward success; so it doesn't seem to me that making craft roles playable should be a priority. ## Cruise control -One of the most enjoyable aspects of The Witcher 3 - still my go-to game for ideas I want to improve on - is simply travelling through the world. Although fast travel is possible I find I rarely use it, and a journey which takes fifteen minutes of real world wall clock time can be enjoyable in and of itself. This is, of course, a credit to the beautiful way the world is realised. +One of the most enjoyable aspects of The Witcher 3 — still my go-to game for ideas I want to improve on — is simply travelling through the world. Although fast travel is possible I find I rarely use it, and a journey which takes fifteen minutes of real world wall clock time can be enjoyable in and of itself. This is, of course, a credit to the beautiful way the world is realised. -But nevertheless, in The Witcher 3, a decision was made to pack incident fairly densely - because players would find just travelling boring. This leads to a situation where peaceful villages exist two minutes travel from dangerous monsters or bandit camps, and the suspension of disbelief gets a little strained. Building a world big enough that a market simulation is believable means that for the individual, the travel time to a market where a particular desired good is likely to be cheaper becomes costly in itself. Otherwise, there's no arbitrage between markets and no ecological niche for a merchant to fill. The journey time from market to market has to be several in-game days. +(It's worth noting that [Kenshi](https://lofigames.com/), a game I'm coming to greatly admire, does not allow fast travel at all, but has an equivalent of 'cruise control' — you can set a destination and then accelerate time and simply watch as your characters journey). -An in-game day doesn't have to be as long as a wall clock day, and, indeed, typically isn't. But nevertheless, doing several game days of incident-free travel, even in beautiful scenery, is not going to be engaging - which implies a fast-travel mechanic. +But nevertheless, in The Witcher 3, a decision was made to pack incident fairly densely — because players would find just travelling boring. This leads to a situation where peaceful villages exist two minutes travel from dangerous monsters or bandit camps, and the suspension of disbelief gets a little strained. Building a world big enough that a market simulation is believable means that for the individual, the travel time to a market where a particular desired good is likely to be cheaper becomes costly in itself. Otherwise, there's no arbitrage between markets and no ecological niche for a merchant to fill. The journey time from market to market has to be several in-game days. -I don't like fast travel, I find it a too-obvious breaking of immersion. Also, of course, one of the interesting things about a game in a merchant/outlaw ecosystem is the risk of interception on a journey. The Dragon Age series handled interrupted travel in 'fast travel' by randomly interrupting the loading screen you get when moving from location to location in Dragon Age's patchwork worlds by dumping you into a tiny arena with enemies. That's really, really bad - there's no other way to say this. Everything about it shouts artifice. +An in-game day doesn't have to be as long as a wall clock day, and, indeed, typically isn't. But nevertheless, doing several game days of incident-free travel, even in beautiful scenery, is not going to be engaging — which implies a fast-travel mechanic. + +I don't like fast travel, I find it a too-obvious breaking of immersion. Also, of course, one of the interesting things about a game in a merchant/outlaw ecosystem is the risk of interception on a journey. The Dragon Age series handled interrupted travel in 'fast travel' by randomly interrupting the loading screen you get when moving from location to location in Dragon Age's patchwork worlds by dumping you into a tiny arena with enemies. That's really, really bad — there's no other way to say this. Everything about it shouts artifice. So I'm thinking of a different mechanism: one I'm calling cruise control. -You set out on a task which will take a long time - such as a journey, but also such as any routine task. You're shown either a 'fast forward' of your character carrying out this task, or a series of cinematic 'shots along the way'. This depends, of course, on there being continuous renderable landscape between your departure and your destination, but there will be. This fast-forward proceeds at a substantially higher time gearing than normal game time - ten times as fast perhaps; we need it to, because as well as doing backgound scenery loading to move from one location to another, we're also simulating lots of non-player agents' actions in parts of the world where the player currently isn't. So a 'jump cut' from one location to another isn't going to work anyway. +You set out on a task which will take a long time — such as a journey, but also such as any routine task. You're shown either a 'fast forward' of your character carrying out this task, or a series of cinematic 'shots along the way'. This depends, of course, on there being continuous renderable landscape between your departure and your destination, but there will be. This fast-forward proceeds at a substantially higher time gearing than normal game time — ten times as fast perhaps; we need it to, because as well as doing backgound scenery loading to move from one location to another, we're also simulating lots of non-player agents' actions in parts of the world where the player currently isn't. So a 'jump cut' from one location to another isn't going to work anyway. -The player can interrupt 'fast forward' at any time. But also, the game itself may bring you out of fast forward when it anticipates that there may be action which requires decision - for example, when there are outlaws in the vicinity. And it will do this **before** the player's party is under immediate attack - the player will have time to take stock of the situation and prepare appropriately. Finally, this will take place in the full open world; the player will have the option to choose *not* to enter the narrow defile, for example, to ask local people (if there are any) for any news of outlaw activity, or, if they are available, to send forward scouts. +The player can interrupt 'fast forward' at any time. But also, the game itself may bring you out of fast forward when it anticipates that there may be action which requires decision — for example, when there are outlaws in the vicinity. And it will do this **before** the player's party is under immediate attack — the player will have time to take stock of the situation and prepare appropriately. Finally, this will take place in the full open world; the player will have the option to choose *not* to enter the narrow defile, for example, to ask local people (if there are any) for any news of outlaw activity, or, if they are available, to send forward scouts. diff --git a/doc/Selecting_Character.md b/doc/Selecting_Character.md new file mode 100644 index 0000000..43b6086 --- /dev/null +++ b/doc/Selecting_Character.md @@ -0,0 +1,70 @@ +# Selecting the Player Character + +## Background + +Many computer role playing games, particularly older ones such as Neverwinter Nights, allow you to 'design' your player character from a fairly broad canvas. Race, class, attributes, gender and appearance are all selectable. + +Choice has eroded over time. For example the Dragon Age series, where you can chose between three races, two genders, and a small number of classes. In the Mass Effect trilogy, you play as Shepard, who is human and essentially a Fighter, but can be either male or female and whose appearance you can customise. You can play as either lawful good or chaotic neutral. In Cyberpunk 2077, you play as V, who is human, either male or female, essentially a Fighter, and chaotic neutral. + +In more recent games, there has been a trend towards more limited choice. In the games of The Witcher series, you get no choice at all, but play as Geralt of Rivia, who in the categorisation of Dungeons and Dragons, is a Fighter/Ranger, male, human, and somewhere between chaotic good and chaotic neutral depending on how you play him. In the Horizon series, you play as Aloy, again a Fighter/Ranger, female, human, and essentially chaotic good. + +As I've argued elsewhere, part of the reason for limiting choice is voice acting. + +Limiting choice of player character, especially in games with increasingly highly scripted stories, limits replayability; after two or three playthroughs, there are very few interesting surprises left. + +## The Self-voiced Player + +If we have voice interaction sufficiently sophisticated that we can allow the player character to say more or less whatever they want to say — [and my argument here is that we can do this](Gossip_scripted_plot_and_Johnny_Silverhand.md) — then we don't need voice acting for the player character, and that gives us a lot of freedom. There's then really no reason why the player can't inhabit any character in the game world and play as that character. + +## Tinder as a Character Selector + +Tinder is a dating app. It shows you pictures (with brief profiles) of potential partners, and you choose from them by swiping left to reject them, or right to express interest in them. That's a kernel of an idea for how to select from among a large selection of people. + +So how about: + +1. The game developer selects a large subset of characters in the game as potentially playable. This might be as large as all characters who are not plot characters, as small as only soldiers, or most plausibly, any adult who is not yet in a long term romantic relationship. This forms the candidate set. +2. In the character selector, the game shows a character chosen at random from the set, and, each time the player rejects the character shown, shows another until the player accepts a character. + +That works, but we can do better. + +## Refining the Selection + +Suppose, below the image of the character on the selection screen, we have a short text caption with name, age, home, occupation, gender, and below that, we have a row of icons showing attributes, with some representation of the character's relative measurement of that attribute. Clicking one of these attribute icons would be interpreted as meaning 'show me a character quite like the current character, but having a higher score on this particular attribute'. + +### Refinable Attributes + +In lots of games which present the player with dialogue options, there are some options which can't be selected unless the player character passes a 'skill check'. Very often, for example, a player won't be able to issue a particular threat unless they have a specific value of strength, or to say something flirtatious unless they have a specific value of charm. + +It makes no sense in a game in which the player gets to freely choose what to say for an attribute like 'charm' to be a refinable attribute. Instead, responding to 'charming' or flirtatious or threatening or funny or sexually suggestive speech is a matter for the programming of a particular non-player character (although the interpretation of the speech and the tagging of it as charming or flirtatious or threatening or funny or suggestive would be a function of the top level speech input processor). + +So, sensibly refinable attributes might include things like + +1. Strength; +2. Agility; +3. Dexterity; +4. Endurance. + +I did think that 'intelligence' or 'learning' might be on that list but the more I think of it, the harder I find it to understand how low intelligence might be represented in a game in which the player speaks freely. + +There's another attribute icon with slightly different semantics which might sensibly be added, and that's gender. Selecting this icon would be interpreted as meaning 'show me a character quite like the current character, but having a different gender'. + +### Summary design + +So the character selecter now looks like + +1. A main area in which a rendering of the proposed character is shown; this rendering can be zoomed and rotated, so that the player can look at the face and body from different angles; +2. A description panel, normally hidden but when displayed replacing the character rendering in the main area, giving fuller biographical information about the character; +3. Below the main area, a caption, giving name, age, gender, occupation, home; +4. To the right hand side, a vertical column of attribute icons. + +To interact with the screen, the player can + +1. Zoom in and out on the rendered image, for example with a mouse scroll wheel or the left and right trigger buttons of a game controller; +2. Rotate the rendered image, for example by dragging with the right mouse button held down or with the right joystick of a game controller; +3. Toggle between the character render and the description panel; +4. When the description panel is displayed, scroll it; +5. Select any attribute icon to refine the choice of character; +6. 'Swipe left' (or other action) to reject the current choice of character and choose another, without refining in any specific way; +7. 'Swipe right' to select the current character and procede into the game. + + diff --git a/doc/Settling-a-game-world.md b/doc/Settling-a-game-world.md index e391a3c..8c374eb 100644 --- a/doc/Settling-a-game-world.md +++ b/doc/Settling-a-game-world.md @@ -2,7 +2,7 @@ #### Wednesday, 30 December 2009 - *This essay is part of a series with '[Worlds and Flats](Worlds-and-flats.html)' and '[The spread of knowledge in a large game world](The-spread-of-knowledge-in-a-large-game-world.html)'; if you haven't read those you may want to read them before reading this. This essay describes how a large world can come into being and can evolve. I've written again on this subject since - see '[Populating a game world](Populating-a-game-world.html)')* + *This essay is part of a series with '[Worlds and Flats](https://www.journeyman.cc/blog/posts-output/2008-04-04-worlds-and-flats/)' and '[The spread of knowledge in a large game world](The-spread-of-knowledge-in-a-large-game-world.html)'; if you haven't read those you may want to read them before reading this. This essay describes how a large world can come into being and can evolve. I've written again on this subject since - see '[Populating a game world](Populating-a-game-world.html)')* ### Microworld @@ -34,7 +34,7 @@ ### Microworld Two - The objective of this essay is to outline an angorithm for creating inhabited landscapes in which games can be set, which are satisfyingly believable when rendered in three dimensions. The objective of creating landscapes 'procedurally' – that is, with algorithms – is that they can be very much larger than designed landscapes for the same richness of local detail. This does not mean that every aspect of the final landscape must be 'procedural'. It would be possible to use the techniques outlined here to create landscapes which were different every time the game was played, but it would be equally possible to create a landscape which was frozen at a particular point and then hand edited to add features useful to the game's plot. And while I'm principally thinking in this about role playing games, this sort of landscape would be applicable to many other sorts of games – strategy games, god games, first person shooters... + The objective of this essay is to outline an algorithm for creating inhabited landscapes in which games can be set, which are satisfyingly believable when rendered in three dimensions. The objective of creating landscapes 'procedurally' – that is, with algorithms – is that they can be very much larger than designed landscapes for the same richness of local detail. This does not mean that every aspect of the final landscape must be 'procedural'. It would be possible to use the techniques outlined here to create landscapes which were different every time the game was played, but it would be equally possible to create a landscape which was frozen at a particular point and then hand edited to add features useful to the game's plot. And while I'm principally thinking in this about role playing games, this sort of landscape would be applicable to many other sorts of games – strategy games, god games, first person shooters... ### The physical geography diff --git a/doc/sexual-dimorphism.md b/doc/Sexual-dimorphism.md similarity index 78% rename from doc/sexual-dimorphism.md rename to doc/Sexual-dimorphism.md index 724864e..e9fe588 100644 --- a/doc/sexual-dimorphism.md +++ b/doc/Sexual-dimorphism.md @@ -8,7 +8,7 @@ OK? Let's start. When a man and a woman have sex, there's a non-zero chance that the woman will get pregnant. There's a zero chance that the male will get pregnant. -A woman can typically give birth to of the order of twelve children in the course of her life, and each childbirth involves a non-zero risk of death. If modelling the sort of bronze-age-to-late-medieval cultures I'm generally considering, there are no available reliable methods of contraception, although their may be, for example, known spermicidal or abortifacient spells or potions. If it's abortifacient, that's pretty unpleasant for the woman, too. +A woman can typically give birth to of the order of twelve children in the course of her life, and each childbirth involves a non-zero risk of death. If modelling the sort of bronze-age-to-late-medieval cultures I'm generally considering, there are no available reliable methods of contraception, although there may be, for example, known spermicidal or abortifacient spells or potions. If it's abortifacient, that's pretty unpleasant for the woman, too. Children, especially when young, are very vulnerable and need protection. Children with good protection are much more likely to survive to adulthood. Raising children involves a fair amount of work. @@ -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**](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. +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,13 @@ 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. -## +## Women and warrior/adventurer lifestyles + +Generally speaking, people do not want to take their children onto a battlefield. If you're going to have a game world in which women significantly take on warrior or adventurer roles, then you must either have + +* A culture which expects female warriors to be celibate; or +* A culture with access to and acceptance of safe and reliable contraception or abortion; or +* An acceptance of leaving infant children with grandparents, other relatives or foster carers for long periods; +* A system of long term creches; +* Any combination of the above. + diff --git a/doc/Simulation-layers.md b/doc/Simulation-layers.md index ccd842b..250ac9f 100644 --- a/doc/Simulation-layers.md +++ b/doc/Simulation-layers.md @@ -14,7 +14,7 @@ This is mainly a land game. Broadly, caravans take the place of ships in Elite o ## A political simulation -Broadly, aristons claim territories in an essentiallu feudal arrangement, drive out outlaws, and levy taxes. +Broadly, aristons claim territories in an essentially 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. diff --git a/doc/The-spread-of-knowledge-in-a-large-game-world.md b/doc/The-spread-of-knowledge-in-a-large-game-world.md index 937da44..1e89eb6 100644 --- a/doc/The-spread-of-knowledge-in-a-large-game-world.md +++ b/doc/The-spread-of-knowledge-in-a-large-game-world.md @@ -2,18 +2,17 @@ #### Saturday, 26 April 2008 -![part of the role of Dandelion, in The Witcher games, is to provide the player with news](https://4.bp.blogspot.com/-F2gxx0dRM8o/UlfSsRe8ybI/AAAAAAAAYIA/I1I9D5Yk7to/s1600/Tw2_full_Dandelion.png) - - ### Note -_This version of this essay has been adapted to use the code in `the-great-game.gossip.news-items`, [q.v.](the-great-game.gossip.news-items.html). The original version of the essay is [still available on my blog](https://blog.journeyman.cc/2008/04/the-spread-of-knowledge-in-large-game.html)._ +*This version of this essay has been adapted to use the code in `the-great-game.gossip.news-items`, [q.v.](the-great-game.gossip.news-items.html). The original version of the essay is [still available on my blog](https://www.journeyman.cc/blog/posts-output/2008-04-26-the-spread-of-knowledge-in-a-large-game-world/).* + +----- These days we have television, and news. But in a late bronze age world there are no broadcast media. News spreads by word of mouth. If non-player characters are to respond effectively to events in the world, knowledge has to spread. How to model this? - Some non-player characters - doesn't need to be many - are news-spreaders. News-spreaders need to travel. They have to travel even when there are no player characters in the vicinity. But, they don't have to travel very often - once or twice every game day. When a news-spreader is in the immediate vicinity of another character, the pair may (with some degree of randomness) exchange news. There needs to be a hierarchy in the exchange of news, so that 'I-saw' events need to be more likely to be passed on than 'I-heard' events; there needs to be a counter which counts the number of times a knowledge item has been passed on, and also an age counter so that knowledge items are less likely to be passed on as they get older. + Some non-player characters — doesn't need to be many — are news-spreaders. News-spreaders need to travel. They have to travel even when there are no player characters in the vicinity. But, they don't have to travel very often — once or twice every game day. When a news-spreader is in the immediate vicinity of another character, the pair may (with some degree of randomness) exchange news. There needs to be a hierarchy in the exchange of news, so that 'I-saw' events need to be more likely to be passed on than 'I-heard' events; there needs to be a counter which counts the number of times a knowledge item has been passed on, and also an age counter so that knowledge items are less likely to be passed on as they get older. One obvious class of news-spreader is a merchant. Merchant agents can either shuttle mechanically between a fixed group of markets or else possibly respond intelligently to supply and demand. Provided that there is a mesh of merchant routes covering the markets of the game world, and that a useful subset of non-merchant characters are required to visit a market every few game days, this should give a reasonably realistic framework for news spreading. @@ -65,11 +64,11 @@ But also, the added knowledge is *degraded*. If the recipient isn't from Hans'hu :nth-hand 4, :time-stamp 17946463} -The timestamp could also be degraded, or lost altother - although how exactly this is represnted I'm not certain. Someone interested in the incident may remember 'it was exactly 17 days ago', whereas someone else may remember that it was 'this month, I think'. +The timestamp could also be degraded, or lost altother — although how exactly this is represnted I'm not certain. Someone interested in the incident may remember 'it was exactly 17 days ago', whereas someone else may remember that it was 'this month, I think'. Obviously the rate of decay, and the degree of randomness, of the news-passing algorithm would need to be tuned, but this schema seems to me to describe a system with the following features: -* Non-player characters can respond to questions about significant things which happen in the world - without it all having to be scripted +* Non-player characters can respond to questions about significant things which happen in the world — without it all having to be scripted * If you travel fast enough, you can keep ahead of your notoriety * Characters on major trade routes will know more about what is happening in the world than characters in backwaters @@ -79,8 +78,8 @@ The timestamp could also be degraded, or lost altother - although how exactly th Let's work around the idea that a 'game day' equates to about two hours of wall clock time. Let's work around the idea that there are of the order of fifty markets in the game world, and that for each market there are two or three merchants whose 'home base' it is. - Obviously non-player characters who are within the vicinity of a player character have to be 'awake', in order that the player can see them interacting with their world and can interact with them. Those characters have to be in working memory and have to be in the action polling loop in any case. So there's no extra cost to their gossiping away between each other - around the player there's a moving bubble of gossip, allowing each character the player interacts with to have a high probability of having some recent news. + Obviously non-player characters who are within the vicinity of a player character have to be 'awake', in order that the player can see them interacting with their world and can interact with them. Those characters have to be in working memory and have to be in the action polling loop in any case. So there's no extra cost to their gossiping away between each other — around the player there's a moving bubble of gossip, allowing each character the player interacts with to have a high probability of having some recent news. - But the merchants who aren't in the vicinity of a player don't have to be in working memory all the time. Each merchant simply requires to be 'woken up' - loaded into memory - once per game day, move a day's journey in one hop, and then, if arriving at an inn or at a market, wake and exchange news with one resident character - an innkeeper or a gossip. So the cost of this algorithm in a fifty-market game is at worst the cost of loading and unloading two non-player characters from memory every minute, and copying two or three statements from the knowledge set of one to the knowledge set of the other. If you're dynamically modifying significance scores, of course, you'd need to also load the characters about whom news was being passed on; but this still doesn't seem unduly onerous. + But the merchants who aren't in the vicinity of a player don't have to be in working memory all the time. Each merchant simply requires to be 'woken up' — loaded into memory — once per game day, move a day's journey in one hop, and then, if arriving at an inn or at a market, wake and exchange news with one resident character — an innkeeper or a gossip. So the cost of this algorithm in a fifty-market game is at worst the cost of loading and unloading two non-player characters from memory every minute, and copying two or three statements from the knowledge set of one to the knowledge set of the other. If you're dynamically modifying significance scores, of course, you'd need to also load the characters about whom news was being passed on; but this still doesn't seem unduly onerous. Obviously, if memory is not too constrained it may be possible to maintain all the merchants, all the innkeepers and all the characters currently being talked about in memory all the time, further reducing the cost. diff --git a/doc/Things_Voice_Interaction_Enables.md b/doc/Things_Voice_Interaction_Enables.md new file mode 100644 index 0000000..d2476b9 --- /dev/null +++ b/doc/Things_Voice_Interaction_Enables.md @@ -0,0 +1,56 @@ +# Things Voice Interaction Enables + +## Organic quest routing + +In a world in which you can talk to non-player characters, and in which non-player characters know the directions to things which are local to their homes (and some, travellers, will be able to give you routes to things further away), when you need to get to your next waypoint you can just ask for directions. That much is easy. + +But something much richer occurred to me. + +Suppose you're entering a village, and you meet a random character. That character knows any local quest giver, and what it is that quest giver needs –– and, indeed, they know this whether the quest is scripted or organic. + +So the random character could say + +> Hello, I'm Tobias, and that my mill over there. Who might you be, stranger? + +At which point you can either tell him, or not. Suppose you tell him, he could say + +> Oh! I've heard of you. It's said you're very handy with a sword. + +And you can reply however you like, acknowledging, or being modest, or perhaps even denying (although from this line of dialogue if you deny he'll think you're being modest, for reasons see later). He can then say, taking our example from the 'abducted child' quest in [the Introduction](intro.html#dynamic-quests), + +> Thing is, old granny Grizzel's granddaughter Esmerelda has been abducted by bandits, and we've done a whip-around for a reward for someone who can rescue the girl. + +At which point you may reply that you'll do it, or be non-committal, or say you won't. If you say you will, he can say, + +> Well, you should talk to granny Grizzel, she lives in the white house by the crossroads, half a mile that-a-way (pointing). + +If you say you won't, he can say, + +> It would be a virtuous act, the old lady is fair desperate. If you should change your mind, you should talk to her; she lives in the white house by the crossroads, half a mile that-a-way (pointing). + +OK, but what if, in the game world, the player character is not good with a sword? Well, the 'abducted child' quest can be resolved by violence; but it can also be resolved by persuasion, or by sneakiness, or by bribery. So suppose the player isn't (in the game) good with a sword, but is good at negotiation. Then in the initial approach, Tobias could say + +> Oh! I've heard of you. It's said you're very handy at persuasion... Thing is, old granny Grizzel's granddaughter Esmerelda has been abducted by bandits, and we've done a whip-around for a ransom, but she's lacking someone who can negotiate for her. + +It's the same quest, and, whatever Tobias has said, the player can still use either violence or persuasion or trickery to complete the quest (and gain appropriate reputation thereby), but it's flexible enough to adapt to the player's in-game persona, and it means we can direct the player to quest-givers without having to stick a bloody great icon on the quest giver's head. + +So, to repeat for clarity: the idea is, if there is a quest in the vicinity, whether organic or scripted, many of the quest giver's neighbours may know about it, and will bring it up in conversation, introducing it and directing the player to the quest giver. And I believe that this can be done reasonably naturally. + +Obviously there are some sorts of quests where for narrative reasons he quest giver will **not** want their neighbours to know of it, and those quests need to be signposted differently; but I think that effective ways need to be found of signposting those quests to the player without resorting to noticeboards or quest icons. + +## Command in Battles + +Player characters in role playing games are often narratively great heroic leaders — see any of the Dragon Age games but particularly Inquisition for examples of this — but when it comes to a pitched battle all they can do is follow a scripted battle plan and fight individual actions, because in current generation role-playing games there is no effective user interface to allow strategic and tactical control of a battle. + +So how would a real-world, before modern communications technology, war leader command a battle? Why, by observing the battle and talking to people, and those are both things that in our game the player can do. + +So, there are two stages to battle communication: the first is the council of war, before the battle, in which the battle plan is agreed. For the non-player characters to have any significant input into this, we'd need a really good knowledge base of appropriate battle strategies with heuristics for which plan fits which sort of geography and which sort of enemy, but that could be quite fun to develop; but in principle it's sufficient for the player character to be able to say to each of the divisional captains "I want you to do this," and for each captain to say first "yes, I understand" (or "please clarify"), and then "yes, I will do it" (or "yes, I will try"). + +No battle plan, of course, survives first contact with the enemy. It must be possible to update the plan during the battle, and messengers were used to carry new orders from the commander to subordinates. That, of course, we can also do. + +So, ideally (and in describing this I'll try to give 'less than ideal' alternatives where I see them), you can gather your captains to a council of war, either by speaking to them directly or by sending messengers round. At the council of war, non-player-character captains can suggest possible battle plans drawn from a common knowledge base, but can have individual levels of boldness or caution. However, if you've been appointed battle leader, then provided they're individually still loyal to you then they will ultimately agree to what you order. + +When battle is joined you can either join in the fighting in the front line in which case your strategic overview is going to be very limited and you'll just have to hope your initial plan was good enough; or else you can sit on a hilltop overlooking the battlefield with your trumpeter and your messengers, and send messages to control the fight, but not actually take part much yourself (unless everything really goes to shit and your position is overrun). + +In real world battles orders were often misunderstood; I don't think I should do anything special to model that. But orders (other than trumpet calls) will necessarily take finite time, and if the battlefront is really messed up messengers may fail to get through. + diff --git a/doc/Voice-acting-considered-harmful.md b/doc/Voice-acting-considered-harmful.md index 9abf923..49b9559 100644 --- a/doc/Voice-acting-considered-harmful.md +++ b/doc/Voice-acting-considered-harmful.md @@ -5,9 +5,18 @@ ![The Witcher: Conversation with Kalkstein](https://3.bp.blogspot.com/-ZI90HLjEcuo/VO4f-yXP3sI/AAAAAAAAZt4/C0hQ7hScWyM/s1600/witcher_conversation.jpg) Long, long, time ago, I can still remember when... we played (and wrote) adventure games where the user typed at a command line, and the system printed back at them. A Read-Eval-Print loop in the classic Lisp sense, and I wrote my adventure games in Lisp. I used the same opportunistic parser whether the developer was building the game - Create a new room north of here called dungeon-3 the player was playing the game - Pick up the rusty sword and go north or the player was talking to a non-player character - Say to the wizard 'can you tell me the way to the castle' Of course, the parser didn't 'understand' English. It worked on trees of words, in which terminal nodes were actions and branching nodes were key words, and it had the property that any word it didn't recognise at that point in sentence was a noise word and could be ignored. A few special hacks (such as 'the', 'a', or 'an' was an indicator that what came next was probably a noun phrase, and thus that if there was more than one sword in the player's immediate environment the one that was wanted was the one tagged with the adjective 'rusty'), and you ended up with a parser that most of the time convincingly interpreted most of what the player threw at it. + +> Create a new room north of here called dungeon-3 + +the player was playing the game + +> Pick up the rusty sword and go north + +or the player was talking to a non-player character + +> Say to the wizard 'can you tell me the way to the castle' + +Of course, the parser didn't 'understand' English. It worked on trees of words, in which terminal nodes were actions and branching nodes were key words, and it had the property that any word it didn't recognise at that point in sentence was a noise word and could be ignored. A few special hacks (such as 'the', 'a', or 'an' was an indicator that what came next was probably a noun phrase, and thus that if there was more than one sword in the player's immediate environment the one that was wanted was the one tagged with the adjective 'rusty'), and you ended up with a parser that most of the time convincingly interpreted most of what the player threw at it. Text adventures fell into desuetude partly because they weren't graphic, but mainly because people didn't find typing natural, or became dissatisfied with the repertoire of their parsers. Trying to find exactly the right combination tokens to persuade the game to carry out some simple action is not 'fun', it's just frustrating, and it turned people off. Which is a shame because just at the time when people were abandoning text adventures we were beginning to have command parsers which were actually pretty good. Mine, I think, were good - you could have a pretty natural conversation with them, and in 'building' mode, when it hit a 'sorry I don't understand' point, it allowed you to input a path of keywords and a Lisp function so that in future it would understand. diff --git a/doc/intro.md b/doc/intro.md index 3ae3526..f5c0abb 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -33,21 +33,21 @@ repertoire of speech. ## Previous essays that are relevant * [The spread of knowledge in a large game world](The-spread-of-knowledge-in-a-large-game-world.html) (2008) discusses what individual non-player characters know, and how to model dynamic updates to their knowledge; -* [Settling a game world](https://blog.journeyman.cc/2009/12/settling-game-world.html) (2009) gives rough outline of ideas about creating the environment, including modelling things like soil fertility, local building materials, and consequently local architecture; -* [Tessellated multi-layer height map](https://blog.journeyman.cc/2013/07/tessellated-multi-layer-height-map.html) (2013) gives ideas for how a designed geography for a very large world could be stored relatively economically; -* [Genetic Buildings](https://blog.journeyman.cc/2013/07/genetic-buildings.html) (2013) sketches algorithms which would allow procedurally-generated buildings to be site-appropriate, broadly variable and reproducable; +* [Settling a game world](Settling-a-game-world.html) (2009) gives rough outline of ideas about creating the environment, including modelling things like soil fertility, local building materials, and consequently local architecture; +* [Tessellated multi-layer height map](https://www.journeyman.cc/blog/posts-output/2013-07-04-tessellated-multilayer-height-map/) (2013) gives ideas for how a designed geography for a very large world could be stored relatively economically; +* [Genetic Buildings](Genetic-buildings.html) (2013) sketches algorithms which would allow procedurally-generated buildings to be site-appropriate, broadly variable and reproducable; * [Populating a game world](Populating-a-game-world.html) (2013) provides outline algorithms for how a world can be populated, and how organic mixes of trades and crafts can be modelled; -* [Modelling the change from rural to urban](https://blog.journeyman.cc/2013/07/modelling-change-from-rural-to-urban.html) (2013) describes the idea of procedurally modelling settlements, but it is grid-based and not particularly satisfactory and has largely been superceded in my thinking; -* [Of pigeons, and long distance messaging in a game world](https://blog.journeyman.cc/2013/10/of-pigeons-and-long-distance-messaging.html) (2013) builds on ideas about flows of information; -* [Modelling rural to urban, take two](https://blog.journeyman.cc/2013/10/modelling-rural-to-urban-take-two.html) (2013) revisited the idea of modelling organic settlement structures, trying to find algorithms which would naturally produce more persuasive settlement models, including further ideas on the procedural generation of buildings; -* [More on modelling rivers](https://blog.journeyman.cc/2014/09/more-on-modelling-rivers.html) (2014) talks about modelling hydrology, with implications for soil fertility; -* [Modelling settlement with cellular automata](https://blog.journeyman.cc/2014/08/modelling-settlement-with-cellular.html) (2014) talks about successful implementation of algorithms to model vegetative environment, human settlement and the impact of human settlement on the environment; -* [Voice acting considered harmful](https://blog.journeyman.cc/2015/02/voice-acting-considered-harmful.html) (2015) outlines the ideas behind full speech interaction with non-player characters, and modelling what those non-player characters should be able to speak about; +* [Modelling the change from rural to urban](https://www.journeyman.cc/blog/posts-output/2013-07-17-modelling-the-change-from-rural-to-urban/) (2013) describes the idea of procedurally modelling settlements, but it is grid-based and not particularly satisfactory and has largely been superceded in my thinking; +* [Of pigeons, and long distance messaging in a game world](https://www.journeyman.cc/blog/posts-output/2013-10-01-of-pigeons-and-long-distance-messaging-in-a-game-world/) (2013) builds on ideas about flows of information; +* [Modelling rural to urban, take two](https://www.journeyman.cc/blog/posts-output/2013-10-14-modelling-rural-to-urban-take-two/) (2013) revisited the idea of modelling organic settlement structures, trying to find algorithms which would naturally produce more persuasive settlement models, including further ideas on the procedural generation of buildings; +* [More on modelling rivers](https://www.journeyman.cc/blog/posts-output/2014-09-28-more-on-modelling-rivers/) (2014) talks about modelling hydrology, with implications for soil fertility; +* [Modelling settlement with cellular automata](https://www.journeyman.cc/blog/posts-output/2014-08-26-modelling-settlement-with-a-cellular-automaton/) (2014) talks about successful implementation of algorithms to model vegetative environment, human settlement and the impact of human settlement on the environment; +* [Voice acting considered harmful](Voice-acting-considered-harmful.html) (2015) outlines the ideas behind full speech interaction with non-player characters, and modelling what those non-player characters should be able to speak about; * [Baking the world](Baking-the-world.html) (2019) an outline of the overall process of creating a world. ## Organic and emergent game-play -If a world is [dynamically populated](https://blog.journeyman.cc/2014/08/modelling-settlement-with-cellular.html), with [dynamic allocation of livelihoods](https://blog.journeyman.cc/2013/07/populating-game-world.html) then several +If a world is [dynamically populated](https://www.journeyman.cc/blog/posts-output/2014-08-26-modelling-settlement-with-a-cellular-automaton/), with [dynamic allocation of livelihoods](Populating-a-game-world.html) then several aspects of gameplay will emerge organically. First, of course, is just exploring; in a dynamically changing world there will always be more to explore, and it will be different in each restart of the game. @@ -119,7 +119,7 @@ To make dynamic quests work, of course, you need a dynamic world; a world in which conflicts can arise. A world in which traders trade, robbers rob, lovers love, haters hate, scandal-mongers make scandal, organically and dynamically whether the player is there or not, and where news of these events will filter -through to the player through the [gossip network](https://blog.journeyman.cc/2008/04/the-spread-of-knowledge-in-large-game.html) also organically and dynamically. +through to the player through the [gossip network](The-spread-of-knowledge-in-a-large-game-world.html) also organically and dynamically. ## Extending the story @@ -177,7 +177,7 @@ easy: 2. **Master**: what is the sum of (or average of) the esteem held for this agent by other agents of the same craft? 3. **Explorer**: (e.g.) what is the sum of the distance between the most northerly and most southerly, and the most easterly and most westerly, locations this agent has visited? 4. **Climber**: how many 'promotions' has this agent had in the game? -6. **Conqueror**: how many total vassales, recursively, has this agent? +5. **Conqueror**: how many total vassals, recursively, has this agent? 6. **Citizen**: really, really tricky. Probably what is the average esteem for this agent among all agents within a specified radius? - although this will score more highly for agents who have taken part in notable events, and what I'm really thinking of for my ideal 'good citizen' is someone who really hasn't. So each agent is assigned - by the dreaded random number generator - one top @@ -321,7 +321,10 @@ maybe around 10%. A caravan or ship costs so much per day to run, irrespective of whether full or empty. So the base cost of a journey is a function of the time taken, which -is essentially a function of the distance. +is essentially a function of the distance. + +Obviously, on top of the base cost of movement there are tolls, which are imposed +by the aristons through whose territory the journey passes (and therefore predictable, and can be used in route planning), and also the risk of having to bribe or fight outlaws, and the possible need to hire mercenaries to defend against outlaws, which is not predictable but can be estimated and thus also used in route planning. ### Outlawry and merchants @@ -329,7 +332,7 @@ Outside the domains of aristons, outlaws may intercept caravans; when this happens the following outcomes are possible: 1. The merchant (together with any mercenaries the merchant has hired to protect the caravan) successfully fights off the outlaws; -2. The outlaws steal the entire cargo (and may kill the merchant); +2. The outlaws steal the entire cargo (and may kill the merchant and others); 3. The merchant pays protection money to the outlaws, typically around 5%-10% of the value of cargo carried; 4. The merchant employs the outlaws as caravan guards (see below); 5. The outlaws allow the caravan to pass unmolested; @@ -362,7 +365,7 @@ Generally, if a merchant buys goods in an ariston's market, or sells goods in the ariston's market, then the economy benefits and the ariston benefits from that; so the 'tax' element is part of the market markup. But if a caravan passes through an ariston's territory without stopping at a market, -there's probably a tax of about 5% of value. +there's probably a toll of about 5% of value. Generally, an ariston's army will control outlawry within the ariston's domain, so outlaw encounters within a domain are unlikely. Soldiers could diff --git a/docs/cloverage/cc/journeyman/the_great_game/agent/agent.clj.html b/docs/cloverage/cc/journeyman/the_great_game/agent/agent.clj.html new file mode 100644 index 0000000..cafc39e --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/agent/agent.clj.html @@ -0,0 +1,143 @@ + + + + cc/journeyman/the_great_game/agent/agent.clj + + + + 001  (ns cc.journeyman.the-great-game.agent.agent +
+ + 002    "Anything in the game world with agency; primarily but not exclusively +
+ + 003     characters." +
+ + 004    (:require [cc.journeyman.the-great-game.objects.game-object :refer [ProtoObject]] +
+ + 005              [cc.journeyman.the-great-game.objects.container :refer [ProtoContainer]])) +
+ + 006   +
+ + 007  ;;;  hierarchy of needs probably gets implemented here +
+ + 008  ;;;  I'm probably going to want to defprotocol stuff, to define the hierarchy +
+ + 009  ;;;  of things in the gameworld; either that or drop to Java, wich I'd rather not do. +
+ + 010   +
+ + 011  (defprotocol ProtoAgent +
+ + 012    "An object which can act in the world" +
+ + 013    (act +
+ + 014      [actor world circle] +
+ + 015         "Allow `actor` to do something in this `world`, in the context of this +
+ + 016         `circle`; return the new state of the actor if something was done, `nil` +
+ + 017         if nothing was done. Circle is expected to be one of +
+ + 018   +
+ + 019         * `:active` - actors within visual/audible range of the player +
+ + 020           character; +
+ + 021         * `:pending` - actors not in the active circle, but sufficiently close +
+ + 022           to it that they may enter the active circle within a short period; +
+ + 023         * `:background` - actors who are active in the background in order to +
+ + 024           handle trade, news, et cetera; +
+ + 025         * `other` - actors who are not members of any other circle, although +
+ + 026           I'm not clear whether it would ever be appropriate to invoke an +
+ + 027           `act` method on them. +
+ + 028   +
+ + 029         The `act` method *must not* have side effects; it must *only* return a +
+ + 030         new state. If the actor's intention is to seek to change the state of +
+ + 031         something else in the game world, it must add a representation of that +
+ + 032         intention to the sequence which will be returned by its +
+ + 033         `pending-intentions` method.") +
+ + 034    (pending-intentions +
+ + 035      [actor] +
+ + 036      "Returns a sequence of effects an actor intends, as a consequence of +
+ + 037      acting. The encoding of these is not yet defined.")) +
+ + 038   +
+ + 039  (defrecord Agent +
+ + 040    ;; "A default agent." +
+ + 041    [name craft home culture] +
+ + 042    ProtoObject +
+ + 043    ProtoContainer +
+ + 044    ProtoAgent +
+ + 045  ) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/buildings/module.clj.html b/docs/cloverage/cc/journeyman/the_great_game/buildings/module.clj.html new file mode 100644 index 0000000..55ed3f9 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/buildings/module.clj.html @@ -0,0 +1,251 @@ + + + + cc/journeyman/the_great_game/buildings/module.clj + + + + 001  (ns cc.journeyman.the-great-game.buildings.module +
+ + 002   +
+ + 003    "A module of a building; essentially something like a portacabin, which can be +
+ + 004     assembled together with other modules to make a complete building. +
+ + 005    +
+ + 006     Modules need to include +
+ + 007   +
+ + 008     1. Ground floor modules, having external doors; +
+ + 009     2. Craft modules -- workshops -- which will normally be ground floor (except +
+ + 010        weavers) and may have the constraint that no upper floor module can cover them; +
+ + 011     3. Upper floor modules, having NO external doors (but linking internal doors); +
+ + 012     4. Roof modules +
+ + 013      +
+ + 014     **Role** must be one of: +
+ + 015      +
+ + 016     1. `:primary` a ground floor main entrance module +
+ + 017     2. `:secondary` a module which can be upper or ground floor +
+ + 018     3. `:upper` a module which can only be on an upper floor, for example one +
+ + 019        with a projecting gallery, balcony or overhang. +
+ + 020      +
+ + 021     Other values for `role` will emerge. +
+ + 022      +
+ + 023     **Exits** must be a sequence of keywords taken from the following list: +
+ + 024      +
+ + 025     1. `:left` an exit in the centre of the left wall +
+ + 026     2. `:left-front` an exit in the centre of the left half of the front wall +
+ + 027     3. `:front` an exit in the centre of the front wall +
+ + 028     4. `:right-front` an exit in the centre of the right half of the front wall +
+ + 029     5. `:right` an exit in the centre of the right wall +
+ + 030     6. `:right-back` an exit in the centre of the right half of the back wall +
+ + 031     7. `:left-back` an exit in the centre of the back wall +
+ + 032         +
+ + 033     A module placed on an upper floor must have no exit which opens beyond the  +
+ + 034     footprint of the floor below - no doors into mid air! However, it is allowable  +
+ + 035     (and indeed is necessary) to allow doors into roof spaces if the adjacent +
+ + 036     module on the same floor does not yet exist, since otherwise it would be  +
+ + 037     impossible to access a new room which might later be built there. +
+ + 038      +
+ + 039     **Load** must be a small integer indicating both the weight of the module and  +
+ + 040     the total amount of weight it can support. So for example a stone-built module +
+ + 041     might have a `load` value of 4, a brick built one of 3, and a half-timbered one  +
+ + 042     of 2, and a tent of 0. This means a stone ground floor module could support one  +
+ + 043     further floor of stone or brick, or two further floors of half timbered  +
+ + 044     construction; while a brick built ground floor could support a single brick or  +
+ + 045     half-timbered upper floor but not a stone one, and a half-timbered ground floor +
+ + 046     could only support a half timbered upper floor. +
+ + 047      +
+ + 048     There also needs to be an undercroft or platform module, such that the area of  +
+ + 049     the top of the platform is identical with the footprint of the building, and  +
+ + 050     the altitude of the top of the platform is equal to the altitude of the  +
+ + 051     terrain at the heighest corner of the building; so that the actual  +
+ + 052     building doesn't float in the air, and also so that none of the doors or windows +
+ + 053     are partly underground. +
+ + 054   +
+ + 055     Each module needs to wrap an actual 3d model created in Blender or whatever,  +
+ + 056     and have a list of optional **textures** with which that model can be rendered.  +
+ + 057     So an upper floor bedroom module might have the following renders: +
+ + 058   +
+ + 059     1. Bare masonry - constrained to upland or plateau terrain, and to coastal culture +
+ + 060     2. Painted masonry - constrained to upland or plateau terrain, and to coastal culture +
+ + 061     3. Half-timbered - not available on plateau terrain +
+ + 062     4. Weatherboarded - constrained to forest terrain +
+ + 063     5. Brick - constrained to arable or arid terrain +
+ + 064   +
+ + 065     of course these are only examples, and also, it's entirely possible to have +
+ + 066     for example multiple different weatherboard renders for the same module.  +
+ + 067     There needs to be a way of rendering what can be built above what: for +
+ + 068     example, you can't have a masonry clad module over a half timbered one,  +
+ + 069     but you can have a half-timbered one over a masonry one.") +
+ + 070   +
+ + 071  (defrecord BuildingModule +
+ + 072    [model +
+ + 073     ^Double length +
+ + 074     ^Double width +
+ + 075     ^Double height +
+ + 076     ^Integer load  +
+ + 077     ^clojure.lang.Keyword role +
+ + 078     ^clojure.lang.IPersistentCollection textures +
+ + 079     ^clojure.lang.IPersistentCollection exits +
+ + 080     ] +
+ + 081    ) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/buildings/rectangular.clj.html b/docs/cloverage/cc/journeyman/the_great_game/buildings/rectangular.clj.html new file mode 100644 index 0000000..3ffd266 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/buildings/rectangular.clj.html @@ -0,0 +1,458 @@ + + + + cc/journeyman/the_great_game/buildings/rectangular.clj + + + + 001  (ns cc.journeyman.the-great-game.buildings.rectangular +
+ + 002    "Build buildings with a generally rectangular floow plan. +
+ + 003      +
+ + 004     ## Motivations +
+ + 005      +
+ + 006     Right, the idea behind this namespace is many fold. +
+ + 007   +
+ + 008     1. To establish the broad principle of genetic buildings, by creating a +
+ + 009        function which reproducibly creates reproducible buildings at specified +
+ + 010        locations, such that different buildings are credibly varied but a +
+ + 011        building at a specified location is always (modulo economic change) the +
+ + 012        same. +
+ + 013     2. Create good rectangular buildings, and investigate whether a single  +
+ + 014        function can be used to create buildings of more than one family (e.g. +
+ + 015        can it produce flat roofed, north African style, mud brick houses as +
+ + 016        well as pitch roofed, half timbered northern European houses?) +
+ + 017     3. Establish whether, in my current state of fairly severe mental illness, +
+ + 018        I can actually produce any usable code at all. +
+ + 019   +
+ + 020     ## Key factors in the creation of a building +
+ + 021   +
+ + 022     ### Holding +
+ + 023   +
+ + 024     Every building is on a holding, and, indeed, what I mean by 'building' here +
+ + 025     may well turn out to be 'the collection of all the permanent structures on +
+ + 026     a holding. A holding is a polygonal area of the map which does not  +
+ + 027     intersect with any other holding, but for the time being we'll make the  +
+ + 028     simplifying assumption that every holding is a rectangular strip, and that +
+ + 029     'urban' holdings are of a reasonably standard width (see Viking-period  +
+ + 030     York) and length. Rural holdings (farms, ?wood lots) may be much larger. +
+ + 031   +
+ + 032     ### Terrain +
+ + 033   +
+ + 034     A building is made of the stuff of the place. In a forest, buildings will  +
+ + 035     tend to be wooden; in a terrain with rocky outcrops -- normally found on  +
+ + 036     steep slopes -- stone. On the flat lands where there's river mud, of brick, +
+ + 037     cob, or wattle and daub. So to build a building we need to know the  +
+ + 038     terrain. Terrain can be inferred from location but in practice this will  +
+ + 039     be computationally expensive, so we'll pass terrain in as an argument to +
+ + 040     the build function. +
+ + 041   +
+ + 042     For the time being we'll pass it in simply as a keyword from a defined set +
+ + 043     of keywords; later it may be a more sophisticated data structure. +
+ + 044   +
+ + 045     ### Culture +
+ + 046   +
+ + 047     People of different cultures build distinctively different buildings, even +
+ + 048     when using the same materials. So, in our world, a Japanese wooden house  +
+ + 049     looks quite different from an Anglo Saxon stave house which looks quite  +
+ + 050     different from a Canadian log cabin, even though the materials are much the +
+ + 051     same and the tools available to build with are not much different. +
+ + 052   +
+ + 053     Culture can affect not just the overall shape of a building but also its  +
+ + 054     finish and surface detail. For example, in many places in England, stone +
+ + 055     buildings are typically left bare; in rural Scotland, typically painted  +
+ + 056     white or in pastel shades; in Ireland, often quite vivid colours. +
+ + 057   +
+ + 058     People may also show religious or cultural symbols on their buildings. +
+ + 059    +
+ + 060     For all these reasons, we need to know the culture of the occupant when +
+ + 061     creating a building. Again, this will initially be passed in as a keyword. +
+ + 062   +
+ + 063     ### Craft +
+ + 064   +
+ + 065     People in the game world have a craft, and some crafts will require  +
+ + 066     different features in the building. In the broadly late-bronze-age-to +
+ + 067     medieval period within which the game is set, residence and  workplace +
+ + 068     are for most people pretty much the same. +
+ + 069   +
+ + 070     So a baker needs an oven, a smith a forge, and so on. All crafts who do +
+ + 071     some degree retail trade will want a shop front as part of the ground  +
+ + 072     floor of their dwelling. Merchants and bankers will probably have houses +
+ + 073     that are a bit more showy than others. +
+ + 074   +
+ + 075     Whether the 'genetic buildings' idea will ever really produce suitable +
+ + 076     buildings for aristons I don't know; it seems more likely that significant +
+ + 077     strongholds (of which there will be relatively few) should all be hand +
+ + 078     modelled rather than procedurally generated." +
+ + 079    (:require [cc.journeyman.the-great-game.holdings.holding :refer [ProtoHolding]] +
+ + 080              [cc.journeyman.the-great-game.location.location :refer [ProtoLocation]]) +
+ + 081    (:import [org.apache.commons.math3.random MersenneTwister])) +
+ + 082   +
+ + 083    +
+ + 084  (def ^:dynamic *terrain-types*  +
+ + 085    "Types of terrain which affect building families. TODO: This is a placeholder; +
+ + 086     a more sophisticated model will be needed." +
+ + 087    #{:arable :arid :forest :plateau :upland}) +
+ + 088   +
+ + 089  (def ^:dynamic *cultures* +
+ + 090    "Cultures which affect building families. TODO: placeholder" +
+ + 091    #{:ariston :coastal :steppe-clans :western-clans :wild-herd}) +
+ + 092   +
+ + 093  (def ^:dynamic *crafts* +
+ + 094    "Crafts which affect building types in the game. See  +
+ + 095     `Populating a game world`. TODO: placeholder" +
+ + 096    #{:baker :banker :butcher :chancellor :innkeeper :lawyer :magus :merchant :miller :priest :scholar :smith :weaver}) +
+ + 097   +
+ + 098  (def ^:dynamic *building-families*  +
+ + 099    "Families of buildings. +
+ + 100      +
+ + 101     Each family has +
+ + 102      +
+ + 103     * terrain types to which it is appropriate; +
+ + 104     * crafts to which it is appropriate; +
+ + 105     * cultures to which it is appropriate.  +
+ + 106      +
+ + 107     Each generated building will be of one family, and will comprise modules  +
+ + 108     taken only from that family." +
+ + 109    {:pitched-rectangular {:terrains #{:arable :forest :upland} +
+ + 110                           :crafts *crafts* +
+ + 111                           :cultures #{:coastal :western-clans} +
+ + 112                           :modules []} +
+ + 113     :flatroof-rectangular {:terrains #{:arid :plateau} +
+ + 114                            :crafts *crafts* +
+ + 115                            :cultures #{:coastal} +
+ + 116                            :modules []}}) +
+ + 117   +
+ + 118   +
+ + 119  (defn building-family +
+ + 120    "A building family is essentially a collection of models of building modules +
+ + 121     which can be assembled to create buildings of a particular structural and +
+ + 122     architectural style." +
+ + 123    [terrain culture craft gene] +
+ + 124    (let [candidates (filter #(and +
+ + 125                               ((:terrains %) terrain) +
+ + 126                               ((:crafts %) craft) +
+ + 127                               ((:cultures %) culture)) +
+ + 128                             (vals *building-families*))] +
+ + 129      (nth candidates (mod (Math/abs (.nextInt gene)) (count candidates))))) +
+ + 130   +
+ + 131  (building-family :arable :coastal :baker (MersenneTwister. 5)) +
+ + 132   +
+ + 133  (defn build!  +
+ + 134    "Builds a building, and returns a data structure which represents it. In  +
+ + 135     building the building, it adds a model of the building to the representation +
+ + 136     of the world, so it does have a side effect." +
+ + 137    [holding terrain culture craft size] +
+ + 138    (if (satisfies? ProtoHolding holding) +
+ + 139    (let [location (.building-origin holding) +
+ + 140          gene (MersenneTwister. (int (+ (* (.easting location) 1000000) (.northing location)))) +
+ + 141          family (building-family terrain culture craft gene)] +
+ + 142    (if  +
+ + 143     (and (instance? ProtoLocation location) (:orientation location)) +
+ + 144      :stuff +
+ + 145      :nonsense +
+ + 146      )) +
+ + 147      :froboz)) +
+ + 148   +
+ + 149  ;; (def ol (cc.journeyman.the-great-game.location.location/OrientedLocation. 123.45 543.76 12.34 0.00 {})) +
+ + 150   +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/gossip/gossip.clj.html b/docs/cloverage/cc/journeyman/the_great_game/gossip/gossip.clj.html new file mode 100644 index 0000000..cf48455 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/gossip/gossip.clj.html @@ -0,0 +1,227 @@ + + + + cc/journeyman/the_great_game/gossip/gossip.clj + + + + 001  (ns cc.journeyman.the-great-game.gossip.gossip +
+ + 002    "Interchange of news events between gossip agents. +
+ + 003      +
+ + 004     Note that habitual travellers are all gossip agents; specifically, at this +
+ + 005     stage, that means merchants. When merchants are moved we also need to +
+ + 006     update the location of the gossip with the same key. +
+ + 007      +
+ + 008     Innkeepers are also gossip agents but do not typically move." +
+ + 009    (:require [cc.journeyman.the-great-game.utils :refer [deep-merge]] +
+ + 010              [cc.journeyman.the-great-game.gossip.news-items :refer [learn-news-item]] +
+ + 011              )) +
+ + 012   +
+ + 013   +
+ + 014  (defn dialogue +
+ + 015    "Dialogue between an `enquirer` and an `agent` in this `world`; returns a +
+ + 016    map identical to `enquirer` except that its `:gossip` collection may have +
+ + 017    additional entries." +
+ + 018    ;; TODO: not yet written, this is a stub. +
+ + 019    [enquirer respondent world] +
+ + 020    enquirer) +
+ + 021   +
+ + 022  (defn gather-news +
+ + 023    "Gather news for the specified `gossip` in this `world`." +
+ + 024    [world gossip] +
+ + 025    (let [g (cond (keyword? gossip) +
+ + 026                  (-> world :gossips gossip) +
+ + 027                  (map? gossip) +
+ + 028                  gossip)] +
+ + 029      (if g +
+ + 030        {:gossips +
+ + 031         {(:id g) +
+ + 032          (reduce +
+ + 033           deep-merge +
+ + 034           {} +
+ + 035           (map +
+ + 036            #(dialogue g % world) +
+ + 037            (remove +
+ + 038             #(= g %) +
+ + 039             (filter +
+ + 040              #(= (:location %) (:location g)) +
+ + 041              (vals (:gossips world))))))}} +
+ + 042        {}))) +
+ + 043   +
+ + 044  (defn move-gossip +
+ + 045    "Return a world like this `world` but with this `gossip` moved to this +
+ + 046    `new-location`. Many gossips are essentially shadow-records of agents of +
+ + 047    other types, and the movement of the gossip should be controlled by the +
+ + 048    run function of the type of the record they shadow. The [[#run]] function +
+ + 049    below does NOT call this function." +
+ + 050    [gossip world new-location] +
+ + 051    (let [id (cond +
+ + 052              (map? gossip) +
+ + 053              (-> world :gossips gossip :id) +
+ + 054              (keyword? gossip) +
+ + 055              gossip)] +
+ + 056    (deep-merge +
+ + 057      world +
+ + 058      {:gossips +
+ + 059       {id +
+ + 060        {:location new-location}}}))) +
+ + 061   +
+ + 062  (defn run +
+ + 063    "Return a world like this `world`, with news items exchanged between gossip +
+ + 064    agents." +
+ + 065    [world] +
+ + 066    (reduce +
+ + 067     deep-merge +
+ + 068     world +
+ + 069     (map +
+ + 070      #(gather-news world %) +
+ + 071      (keys (:gossips world))))) +
+ + 072   +
+ + 073   +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/gossip/news_items.clj.html b/docs/cloverage/cc/journeyman/the_great_game/gossip/news_items.clj.html new file mode 100644 index 0000000..30f677a --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/gossip/news_items.clj.html @@ -0,0 +1,1043 @@ + + + + cc/journeyman/the_great_game/gossip/news_items.clj + + + + 001  (ns cc.journeyman.the-great-game.gossip.news-items +
+ + 002    "Using news items (propositions) to transfer knowledge between gossip agents. +
+ + 003      +
+ + 004     ## Status +
+ + 005      +
+ + 006     What is here is essentially working. It's not, however, working with the  +
+ + 007     rich data objects which will be needed, and it's not yet nearly efficient  +
+ + 008     enough, but it allows knowledge to propagate through the world procedurally, +
+ + 009     at a rate limited by the speed of movement of the gossip agents. +
+ + 010   +
+ + 011     ## Discussion +
+ + 012      +
+ + 013     The ideas here are based on the essay [The spread of knowledge in a large +
+ + 014     game world](The-spread-of-knowledge-in-a-large-game-world.html), q.v.;  +
+ + 015     they've advanced a little beyond that and will doubtless +
+ + 016     advance further in the course of writing and debugging this namespace. +
+ + 017   +
+ + 018     A news item is a map with the keys: +
+ + 019    +
+ + 020     * `date` - the date on which the reported event is claimed to have happened; +
+ + 021     * `nth-hand` - the number of agents the news item has passed through; +
+ + 022     * `verb` - what it is that happened (key into `news-topics`); +
+ + 023   +
+ + 024     plus other keys taken from the `keys` value associated with the verb in +
+ + 025     `news-topics`. +
+ + 026      +
+ + 027     ## Notes: +
+ + 028      +
+ + 029     *TODO*    +
+ + 030     This namespace at present considers the `:knowledge` of a gossip to be a flat +
+ + 031     list of propositions, each of which must be checked every time any new +
+ + 032     proposition is offered. This is woefully inefficient. " +
+ + 033    (:require [cc.journeyman.the-great-game.world.location :refer [distance-between]] +
+ + 034              [cc.journeyman.the-great-game.time :refer [game-time]] +
+ + 035              [cc.journeyman.the-great-game.utils :refer [inc-or-one truthy?]] +
+ + 036              [taoensso.timbre :as l])) +
+ + 037   +
+ + 038  (def news-topics +
+ + 039    "Topics of interest to gossip agents. Topics are keyed in this map by +
+ + 040    their `verbs`. The `keys` associated with each topic are the extra pieces +
+ + 041    of information required to give context to a gossip item. Generally: +
+ + 042   +
+ + 043    * `actor` is the id of the character who it is reported performed the +
+ + 044    action; +
+ + 045    * `other` is the id of the character on whom it is reported the action +
+ + 046    was performed; +
+ + 047    * `location` is the place at which the action was performed; +
+ + 048    * `object` is an object (or possibly list of objects?) relevant to the +
+ + 049    action; +
+ + 050    * `price` is special to buy/sell, but of significant interest to merchants. +
+ + 051   +
+ + 052    ## Characters +
+ + 053   +
+ + 054    *TODO* but note that at most all the receiver can learn about a character +
+ + 055    from a news item is what the giver knows about that character, degraded by +
+ + 056    what the receiver finds interesting about them. If we just pass the id here, +
+ + 057    then either the receiver knows everything in the database about the +
+ + 058    character, or else the receiver knows nothing at all about the character. +
+ + 059    Neither is desirable. Further thought needed. +
+ + 060   +
+ + 061    By implication, the character values passed should include *all* the +
+ + 062    information the giver knows about the character; that can then be degraded +
+ + 063    as the receiver stores only that segment which the receiver finds +
+ + 064    interesting. +
+ + 065   +
+ + 066    ## Locations +
+ + 067   +
+ + 068    A 'location' value is a list comprising at most the x/y coordinate location +
+ + 069    and the ids of the settlement and region (possibly hierarchically) that contain +
+ + 070    the location. If the x/y is not local to the home of the receiving agent, they +
+ + 071    won't remember it and won't pass it on; if any of the ids are not interesting +
+ + 072    So location information will degrade progressively as the item is passed along. +
+ + 073   +
+ + 074    It is assumed that the `:home` of a character is a location in this sense. +
+ + 075   +
+ + 076    ## Inferences +
+ + 077   +
+ + 078    If an agent learns that Adam has married Betty, they can infer that Betty has +
+ + 079    married Adam; if they learn that Charles killed Dorothy, that Dorothy has died. +
+ + 080    I'm not convinced that my representation of inferences here is ideal." +
+ + 081    {;; A significant attack is interesting whether or not it leads to deaths +
+ + 082     :attack {:verb :attack :keys [:actor :other :location]} +
+ + 083      ;; Deaths of characters may be interesting +
+ + 084     :die {:verb :die :keys [:actor :location]} +
+ + 085      ;; Deliberate killings are interesting. +
+ + 086     :kill {:verb :kill :keys [:actor :other :location] +
+ + 087            :inferences [{:verb :die :actor :other :other :nil}]} +
+ + 088      ;; Marriages may be interesting +
+ + 089     :marry {:verb :marry :keys [:actor :other :location] +
+ + 090             :inferences [{:verb :marry :actor :other :other :actor}]} +
+ + 091      ;; The end of ongoing open conflict between to characters may be interesting +
+ + 092     :peace {:verb :peace :keys [:actor :other :location] +
+ + 093             :inferences [{:verb :peace :actor :other :other :actor}]} +
+ + 094      ;; Things related to the plot are interesting, but will require special +
+ + 095      ;; handling. Extra keys may be required by particular plot events. +
+ + 096     :plot {:verb :plot :keys [:actor :other :object :location]} +
+ + 097      ;; Rapes are interesting. +
+ + 098     :rape {:verb :rape :keys [:actor :other :location] +
+ + 099             ;; Should you also infer from rape that actor is male and adult? +
+ + 100            :inferences [{:verb :attack} +
+ + 101                         {:verb :sex} +
+ + 102                         {:verb :sex :actor :other :other :actor}]} +
+ + 103      ;; Merchants, especially, are interested in prices in other markets +
+ + 104     :sell {:verb :sell :keys [:actor :other :object :location :quantity :price]} +
+ + 105      ;; Sex can juicy gossip, although not normally if the participants are in an +
+ + 106      ;; established sexual relationship. +
+ + 107     :sex {:verb :sex :keys [:actor :other :location] +
+ + 108           :inferences [{:verb :sex :actor :other :other :actor}]} +
+ + 109      ;; Thefts are interesting. +
+ + 110     :steal {:verb :steal :keys [:actor :other :object :location]} +
+ + 111      ;; The succession of rulers is interesting; of respected craftsmen, +
+ + 112      ;; potentially also interesting. +
+ + 113     :succession {:verb :succession :keys [:actor :other :location :rank]} +
+ + 114      ;; The start of ongoing open conflict between two characters may be interesting. +
+ + 115     :war {:verb :war :keys [:actor :other :location] +
+ + 116           :inferences [{:verb :war :actor :other :other :actor}]}}) +
+ + 117   +
+ + 118   +
+ + 119  (def all-known-verbs  +
+ + 120    "All verbs currently known to the gossip system." +
+ + 121    (set (keys news-topics))) +
+ + 122   +
+ + 123   +
+ + 124  (defn interest-in-character +
+ + 125    "Integer representation of how interesting this `character` is to this +
+ + 126    `gossip`. +
+ + 127    *TODO:* this assumes that characters are passed as keywords, but, as +
+ + 128    documented above, they probably have to be maps, to allow for degradation." +
+ + 129    [gossip character] +
+ + 130    (count +
+ + 131     (concat +
+ + 132      ;; TODO: we ought also check the relationships of the gossip. +
+ + 133      ;; Are relationships just propositions in the knowledge base? +
+ + 134      (filter #(= (:actor %) character) (:knowledge gossip)) +
+ + 135      (filter #(= (:other %) character) (:knowledge gossip))))) +
+ + 136   +
+ + 137   +
+ + 138  (defn interesting-character? +
+ + 139    "Boolean representation of whether this `character` is interesting to this +
+ + 140    `gossip`." +
+ + 141    [gossip character] +
+ + 142    (> (interest-in-character gossip character) 0)) +
+ + 143   +
+ + 144  (defn interest-in-location +
+ + 145    "Integer representation of how interesting this `location` is to this +
+ + 146    `gossip`." +
+ + 147    [gossip location] +
+ + 148    (cond +
+ + 149      (and (map? location) (number? (:x location)) (number? (:y location))) +
+ + 150      (if-let [home (:home gossip)] +
+ + 151        (let [d (distance-between location home) +
+ + 152              i (if +
+ + 153                 (zero? d) 1 +
+ + 154                 (/ 10000 d)) +
+ + 155              ;; 10000 at metre scale is 10km; interest should +
+ + 156              ;;fall off with distance from home, but possibly on a log scale +
+ + 157              ] +
+ + 158          (if (>= i 1) i 0)) +
+ + 159        0) +
+ + 160      (coll? location) +
+ + 161      (reduce +
+ + 162       + +
+ + 163       (map +
+ + 164        #(interest-in-location gossip %) +
+ + 165        location)) +
+ + 166      :else +
+ + 167      (count +
+ + 168       (filter +
+ + 169        #(some (fn [x] (= x location)) (:location %)) +
+ + 170        (cons {:location (:home gossip)} (:knowledge gossip)))))) +
+ + 171   +
+ + 172  ;; (distance-between {:x 25 :y 37} {:x 25 :y 37}) +
+ + 173  ;; (interest-in-location {:home [{0, 0} :test-home] :knowledge []} [:test-home]) +
+ + 174   +
+ + 175  (defn interesting-location? +
+ + 176    "True if the location of this news `item` is interesting to this `gossip`." +
+ + 177    [gossip location] +
+ + 178    (> (interest-in-location gossip location) 0)) +
+ + 179   +
+ + 180  (defn interesting-object? +
+ + 181    [gossip object] +
+ + 182    ;; TODO: Not yet (really) implemented +
+ + 183    true) +
+ + 184   +
+ + 185  (defn interesting-topic? +
+ + 186    [gossip topic] +
+ + 187    ;; TODO: Not yet (really) implemented +
+ + 188    true) +
+ + 189   +
+ + 190  (defn interesting-verb? +
+ + 191    "Is this `verb` interesting to this `gossip`?" +
+ + 192    [gossip verb] +
+ + 193    (let [vs (:interesting-verbs gossip)] +
+ + 194      (truthy? +
+ + 195       (if (set? vs) +
+ + 196         (vs verb) +
+ + 197         false)))) +
+ + 198   +
+ + 199  ;; (interesting-verb? {:interesting-verbs #{:kill :sell}} :sell) +
+ + 200   +
+ + 201  (defn compatible-value? +
+ + 202    "True if `known-value` is the same as `new-value`, or, for each key present +
+ + 203     in `new-value`, has the same value for that key.  +
+ + 204      +
+ + 205     The rationale here is that if `new-value` contains new or different  +
+ + 206     information, it's worth learning; otherwise, not." +
+ + 207    [new-value known-value] +
+ + 208    (or +
+ + 209     (= new-value known-value) +
+ + 210     ;; TODO: some handwaving here about being a slightly better descriptor -- +
+ + 211     ;; having more keys than might  +
+ + 212     (when (and (map? new-value) (map? known-value)) +
+ + 213       (every? true? (map #(= (new-value %) (known-value %)) +
+ + 214                          (keys new-value)))))) +
+ + 215   +
+ + 216  (defn compatible-item? +
+ + 217    "True if `new-item` is identical with, or less specific than, `known-item`. +
+ + 218      +
+ + 219     If we already know 'Bad Joe killed Sweet Daisy', there's no point in  +
+ + 220     learning that 'someone killed Sweet Daisy', but there is point in learning +
+ + 221     'someone killed Sweet Daisy _with poison_'." +
+ + 222    [new-item known-item] +
+ + 223    (truthy? +
+ + 224     (reduce +
+ + 225      #(and %1 %2) +
+ + 226      (map #(if +
+ + 227             (known-item %) ;; if known-item has this key +
+ + 228              (compatible-value? (new-item %) (known-item %)) +
+ + 229              true) +
+ + 230           (remove #{:nth-hand :confidence :learned-from} (keys new-item)))))) +
+ + 231   +
+ + 232  (defn known-item? +
+ + 233    "True if this news `item` is already known to this `gossip`. +
+ + 234      +
+ + 235     This means that the `gossip` already knows an item which identifiably has +
+ + 236     the same _or more specific_ values for all the keys of this `item` except +
+ + 237     `:nth-hand`, `:confidence` and `:learned-from`." +
+ + 238    [gossip item] +
+ + 239    (truthy? +
+ + 240     (reduce +
+ + 241      #(or %1 %2) +
+ + 242      false +
+ + 243      (filter true? (map #(compatible-item? item %) (:knowledge gossip)))))) +
+ + 244   +
+ + 245  (defn interesting-item? +
+ + 246    "True if anything about this news `item` is interesting to this `gossip`." +
+ + 247    [gossip item] +
+ + 248    (and (not (known-item? gossip item)) +
+ + 249         (interesting-verb? gossip item) ;; news is only interesting if the topic is. +
+ + 250         (or +
+ + 251          (interesting-character? gossip (:actor item)) +
+ + 252          (interesting-character? gossip (:other item)) +
+ + 253          (interesting-location? gossip (:location item)) +
+ + 254          (interesting-object? gossip (:object item)) +
+ + 255          (interesting-topic? gossip (:verb item))))) +
+ + 256   +
+ + 257  (defn infer +
+ + 258    "Infer a new knowledge item from this `item`, following this `rule`." +
+ + 259    [item rule] +
+ + 260  ;;  (l/info "Applying rule '" rule "' to item '" item "'") +
+ + 261    (reduce merge +
+ + 262            item +
+ + 263            (cons +
+ + 264             {:verb (:verb rule) +
+ + 265              :nth-hand (inc-or-one (:nth-hand item))} +
+ + 266             (map (fn [k] {k (item (rule k))}) +
+ + 267                  (remove +
+ + 268                   #{:verb :nth-hand} +
+ + 269                   (keys rule)))))) +
+ + 270   +
+ + 271  (declare learn-news-item) +
+ + 272   +
+ + 273  (defn make-all-inferences +
+ + 274    "Return a set of knowledge entries that can be inferred from this news +
+ + 275    `item`." +
+ + 276    [item] +
+ + 277    (set +
+ + 278      (map +
+ + 279       #(infer item %) +
+ + 280       (:inferences (news-topics (:verb item)))))) +
+ + 281   +
+ + 282  (defn degrade-character +
+ + 283    "Return a character specification like this `character`, but comprising +
+ + 284    only those properties this `gossip` is interested in." +
+ + 285    [gossip character] +
+ + 286    ;; TODO: Not yet (really) implemented +
+ + 287    character) +
+ + 288   +
+ + 289  (defn degrade-location +
+ + 290    "Return a location specification like this `location`, but comprising +
+ + 291    only those elements this `gossip` is interested in. If none, return +
+ + 292    `nil`." +
+ + 293    [gossip location] +
+ + 294    (let [l (when +
+ + 295             (coll? location) +
+ + 296              (filter +
+ + 297               #(when (interesting-location? gossip %) %) +
+ + 298               location))] +
+ + 299      (when-not (empty? l) l))) +
+ + 300   +
+ + 301  (defn degrade-news-item +
+ + 302    [gossip item] +
+ + 303    (assoc +
+ + 304     item +
+ + 305     :nth-hand (inc-or-one (:nth-hand item)) +
+ + 306     :time-stamp (if +
+ + 307                  (number? (:time-stamp item)) +
+ + 308                   (:time-stamp item) +
+ + 309                   (game-time)) +
+ + 310     :location (degrade-location gossip (:location item)) +
+ + 311     :actor (degrade-character gossip (:actor item)) +
+ + 312     :other (degrade-character gossip (:other item)) +
+ + 313                    ;; TODO: do something to degrade confidence in the item, +
+ + 314                    ;; probably as a function of the provider's confidence in +
+ + 315                    ;; the item and the gossip's trust in the provider +
+ + 316     )) +
+ + 317   +
+ + 318  ;; (degrade-news-item {:home [{:x 25 :y 37} :auchencairn :scotland]} +
+ + 319  ;;                   {:verb :marry :actor :adam :other :belinda :location [{:x 25 :y 37} :auchencairn :scotland]}) +
+ + 320   +
+ + 321  (defn learn-news-item +
+ + 322    "Return a gossip like this `gossip`, which has learned this news `item` if +
+ + 323    it is of interest to them." +
+ + 324    ([gossip item] +
+ + 325     (learn-news-item gossip item true)) +
+ + 326    ([gossip item follow-inferences?] +
+ + 327     (if +
+ + 328      (interesting-item? gossip item) +
+ + 329       (let [item' (degrade-news-item gossip item) +
+ + 330             g (assoc +
+ + 331                gossip +
+ + 332                :knowledge +
+ + 333                (cons +
+ + 334                 item' +
+ + 335                 (:knowledge gossip)))] +
+ + 336         (if follow-inferences? +
+ + 337           (assoc +
+ + 338            g +
+ + 339            :knowledge +
+ + 340            (concat (:knowledge g) (make-all-inferences item'))) +
+ + 341           g))) +
+ + 342     gossip)) +
+ + 343   +
+ + 344   +
+ + 345   +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/holdings/holding.clj.html b/docs/cloverage/cc/journeyman/the_great_game/holdings/holding.clj.html new file mode 100644 index 0000000..1ed2918 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/holdings/holding.clj.html @@ -0,0 +1,146 @@ + + + + cc/journeyman/the_great_game/holdings/holding.clj + + + + 001  (ns cc.journeyman.the-great-game.holdings.holding +
+ + 002    (:require [cc.journeyman.the-great-game.agent.agent :refer [ProtoAgent]] +
+ + 003              [cc.journeyman.the-great-game.objects.container :refer [ProtoContainer]] +
+ + 004              [cc.journeyman.the-great-game.objects.game-object :refer [ProtoObject]] +
+ + 005  ;;            [cc.journeyman.the-great-game.location.location :refer [OrientedLocation]] +
+ + 006              [cc.journeyman.the-great-game.world.routes :refer []])) +
+ + 007   +
+ + 008  ;;; A holding is a polygonal area of the map which does not +
+ + 009  ;;; intersect with any other holding, or with any road or water feature. For  +
+ + 010  ;;; the time being we'll make the  +
+ + 011  ;;; simplifying assumption that every holding is a rectangular strip, and that +
+ + 012  ;;; 'urban' holdings are of a reasonably standard width (see Viking-period  +
+ + 013  ;;; York) and length. Rural holdings (farms, ?wood lots) may be much larger. +
+ + 014   +
+ + 015  (defprotocol ProtoHolding +
+ + 016    (frontage +
+ + 017      [holding] +
+ + 018      "Returns a sequence of two locations representing the edge of the polygon +
+ + 019      which defines this holding which is considered to be the front.") +
+ + 020    (building-origin +
+ + 021      [holding] +
+ + 022      "Returns an oriented location - normally the right hand end of the  +
+ + 023      frontage, for an urban holding - from which buildings on the holding +
+ + 024      should be built.")) +
+ + 025   +
+ + 026  (defrecord Holding [perimeter holder] +
+ + 027    ;; Perimeter should be a list of locations in exactly the same sense as a +
+ + 028    ;; route in `cc.journeyman.the-great-game.world.routes`. Some sanity checking +
+ + 029    ;; is needed to ensure this! +
+ + 030    ProtoContainer +
+ + 031    ProtoHolding +
+ + 032    (frontage  +
+ + 033      [holding] +
+ + 034     "TODO: this is WRONG, but will work for now. The frontage should +
+ + 035      be the side of the perimeter nearest to the nearest existing  +
+ + 036      route." +
+ + 037      [(first (perimeter holding)) (nth (perimeter holding) 1)]) +
+ + 038    (building-origin  +
+ + 039     [holding] +
+ + 040     "TODO: again this is WRONG. The default building origin for rectangular  +
+ + 041      buildings should be the right hand end of the frontage when viewed +
+ + 042      from outside the holding. But that's not general; celtic-style circular +
+ + 043      buildings should normally be in the centre of their holdings. So probably +
+ + 044      building-origin becomes a method of building-family rather than of holding." +
+ + 045     (first (frontage holding))) +
+ + 046    ProtoObject) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/location/location.clj.html b/docs/cloverage/cc/journeyman/the_great_game/location/location.clj.html new file mode 100644 index 0000000..ec74b4d --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/location/location.clj.html @@ -0,0 +1,143 @@ + + + + cc/journeyman/the_great_game/location/location.clj + + + + 001  (ns cc.journeyman.the-great-game.location.location) +
+ + 002   +
+ + 003  ;;; There's probably conflict between this sense of a reified location and +
+ + 004  ;;; the simpler sense of a location described in  +
+ + 005  ;;; `cc.journeyman.the-great-game.world.location`, q.v. This needs to +
+ + 006  ;;; be resolved! +
+ + 007   +
+ + 008  (defprotocol ProtoLocation +
+ + 009    (easting [location] +
+ + 010     "Return the easting of this location") +
+ + 011    (northing [location] "Return the northing of this location") +
+ + 012    (altitude [location] +
+ + 013              "Return the absolute altitude of this location, which may be +
+ + 014               different from the terrain height at this location, if, for +
+ + 015               example, the location is underground or on an upper floor.") +
+ + 016    (terrain-altitude [location] +
+ + 017                      "Return the 'ground level' (altitude of the terrain) +
+ + 018                       at this location given this world. TODO: possibly +
+ + 019                       terrain-altitude should be a method of the world.") +
+ + 020    (settlement [location] +
+ + 021                "Return the settlement record of the settlement in this world +
+ + 022                 within whose parish polygon this location exists, or if none +
+ + 023                 whose centre (inn location) is closest to this location")) +
+ + 024   +
+ + 025   +
+ + 026  (defrecord Location [^Double easting ^Double northing ^Double altitude world] +
+ + 027    ProtoLocation +
+ + 028    (easting [l] (:easting l)) +
+ + 029    (northing [l] (:northing l)) +
+ + 030    (altitude [l] (:altitude l)) +
+ + 031    (terrain-altitude [l] 0.0) ;; TODO +
+ + 032    (settlement [l] :tchahua)) +
+ + 033   +
+ + 034  (defrecord OrientedLocation +
+ + 035    ;; "Identical to a Location except having, additionally, an orientation" +
+ + 036             [^Double easting ^Double northing ^Double altitude ^Double orientation world] +
+ + 037    ProtoLocation +
+ + 038    (easting [l] (:easting l)) +
+ + 039    (northing [l] (:northing l)) +
+ + 040    (altitude [l] (:altitude l)) +
+ + 041    (terrain-altitude [l] 0.0) ;; TODO +
+ + 042    (settlement [l] :tchahua)) ;; TODO +
+ + 043   +
+ + 044   ;; (.settlement (OrientedLocation. 123.45 543.76 12.34 0.00 {})) +
+ + 045   +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/merchants/markets.clj.html b/docs/cloverage/cc/journeyman/the_great_game/merchants/markets.clj.html new file mode 100644 index 0000000..ad08ec1 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/merchants/markets.clj.html @@ -0,0 +1,260 @@ + + + + cc/journeyman/the_great_game/merchants/markets.clj + + + + 001  (ns cc.journeyman.the-great-game.merchants.markets +
+ + 002    "Adjusting quantities and prices in markets." +
+ + 003    (:require [taoensso.timbre :as l :refer [info error]] +
+ + 004              [cc.journeyman.the-great-game.utils :refer [deep-merge]])) +
+ + 005   +
+ + 006  (defn new-price +
+ + 007    "If `stock` is greater than the maximum of `supply` and `demand`, then +
+ + 008    there is surplus and `old` price is too high, so shold be reduced. If +
+ + 009    lower, then it is too low and should be increased." +
+ + 010    [old stock supply demand] +
+ + 011    (let +
+ + 012      [delta (dec' (/ (max supply demand 1) (max stock 1))) +
+ + 013       scaled (/ delta 100)] +
+ + 014      (+ old scaled))) +
+ + 015   +
+ + 016   +
+ + 017  (defn adjust-quantity-and-price +
+ + 018    "Adjust the quantity of this `commodity` currently in stock in this `city` +
+ + 019    of this `world`. Return a fragmentary world which can be deep-merged into +
+ + 020    this world." +
+ + 021    [world city commodity] +
+ + 022    (let [c (cond +
+ + 023              (keyword? city) (-> world :cities city) +
+ + 024              (map? city) city) +
+ + 025          id (:id c) +
+ + 026          p (or (-> c :prices commodity) 0) +
+ + 027          d (or (-> c :demands commodity) 0) +
+ + 028          st (or (-> c :stock commodity) 0) +
+ + 029          su (or (-> c :supplies commodity) 0) +
+ + 030          decrement (min st d) +
+ + 031          increment (cond +
+ + 032                      ;; if we've two turns' production of this commodity in +
+ + 033                      ;; stock, halt production +
+ + 034                      (> st (* su 2)) +
+ + 035                      0 +
+ + 036                      ;; if it is profitable to produce this commodity, the +
+ + 037                      ;; craftspeople of the city will do so. +
+ + 038                      (> p 1) su +
+ + 039                      ;; otherwise, if there isn't a turn's production in +
+ + 040                      ;; stock, top up the stock, so that there's something for +
+ + 041                      ;; incoming merchants to buy +
+ + 042                      (> su st) +
+ + 043                      (- su st) +
+ + 044                      :else +
+ + 045                      0) +
+ + 046          n (new-price p st su d)] +
+ + 047      (if +
+ + 048        (not= p n) +
+ + 049        (l/info "Price of" commodity "at" id "has changed from" (float p) "to" (float n))) +
+ + 050      {:cities {id +
+ + 051                {:stock +
+ + 052                 {commodity (+ (- st decrement) increment)} +
+ + 053                 :prices +
+ + 054                 {commodity n}}}})) +
+ + 055   +
+ + 056   +
+ + 057  (defn update-markets +
+ + 058    "Return a world like this `world`, with quantities and prices in markets +
+ + 059    updated to reflect supply and demand. If `city` or `city` and `commodity` +
+ + 060    are specified, return a fragmentary world with only the changes for that +
+ + 061    `city` (and `commodity` if specified) populated." +
+ + 062    ([world] +
+ + 063     (reduce +
+ + 064       deep-merge +
+ + 065       world +
+ + 066       (map +
+ + 067         #(update-markets world %) +
+ + 068         (keys (:cities world))))) +
+ + 069    ([world city] +
+ + 070     (reduce +
+ + 071       deep-merge +
+ + 072       {} +
+ + 073       (map #(update-markets world city %) +
+ + 074            (keys (:commodities world))))) +
+ + 075    ([world city commodity] +
+ + 076      (adjust-quantity-and-price world city commodity))) +
+ + 077   +
+ + 078   +
+ + 079  (defn run +
+ + 080    "Return a world like this `world`, with quantities and prices in markets +
+ + 081    updated to reflect supply and demand." +
+ + 082    [world] +
+ + 083    (update-markets world)) +
+ + 084   +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/merchants/merchant_utils.clj.html b/docs/cloverage/cc/journeyman/the_great_game/merchants/merchant_utils.clj.html new file mode 100644 index 0000000..377f27a --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/merchants/merchant_utils.clj.html @@ -0,0 +1,326 @@ + + + + cc/journeyman/the_great_game/merchants/merchant_utils.clj + + + + 001  (ns cc.journeyman.the-great-game.merchants.merchant-utils +
+ + 002    "Useful functions for doing low-level things with merchants.") +
+ + 003   +
+ + 004  (defn expected-price +
+ + 005    "Find the price anticipated, given this `world`, by this `merchant` for +
+ + 006    this `commodity` in this `city`. If no information, assume 1. +
+ + 007    `merchant` should be passed as a map, `commodity` and `city` should be passed as keywords." +
+ + 008    [merchant commodity city] +
+ + 009    (or +
+ + 010      (:price +
+ + 011        (last +
+ + 012          (sort-by +
+ + 013            :date +
+ + 014            (-> merchant :known-prices city commodity)))) +
+ + 015      1)) +
+ + 016   +
+ + 017  (defn burden +
+ + 018    "The total weight of the current cargo carried by this `merchant` in this +
+ + 019    `world`." +
+ + 020    [merchant world] +
+ + 021    (let [m (cond +
+ + 022              (keyword? merchant) +
+ + 023              (-> world :merchants merchant) +
+ + 024              (map? merchant) +
+ + 025              merchant) +
+ + 026          cargo (or (:stock m) {})] +
+ + 027      (reduce +
+ + 028        + +
+ + 029        0 +
+ + 030        (map +
+ + 031          #(* (cargo %) (-> world :commodities % :weight)) +
+ + 032          (keys cargo))))) +
+ + 033   +
+ + 034   +
+ + 035  (defn can-carry +
+ + 036    "Return the number of units of this `commodity` which this `merchant` +
+ + 037    can carry in this `world`, given their current burden." +
+ + 038    [merchant world commodity] +
+ + 039    (let [m (cond +
+ + 040              (keyword? merchant) +
+ + 041              (-> world :merchants merchant) +
+ + 042              (map? merchant) +
+ + 043              merchant)] +
+ + 044      (max +
+ + 045        0 +
+ + 046        (quot +
+ + 047          (- (or (:capacity m) 0) (burden m world)) +
+ + 048          (-> world :commodities commodity :weight))))) +
+ + 049   +
+ + 050  (defn can-afford +
+ + 051    "Return the number of units of this `commodity` which this `merchant` +
+ + 052    can afford to buy in this `world`." +
+ + 053    [merchant world commodity] +
+ + 054    (let [m (cond +
+ + 055              (keyword? merchant) +
+ + 056              (-> world :merchants merchant) +
+ + 057              (map? merchant) +
+ + 058              merchant) +
+ + 059          l (:location m)] +
+ + 060      (cond +
+ + 061        (nil? m) +
+ + 062        (throw (Exception. "No merchant?")) +
+ + 063        (or (nil? l) (nil? (-> world :cities l))) +
+ + 064        (throw (Exception. (str "No known location for merchant " m))) +
+ + 065        :else +
+ + 066        (quot +
+ + 067          (:cash m) +
+ + 068          (-> world :cities l :prices commodity))))) +
+ + 069   +
+ + 070  (defn add-stock +
+ + 071    "Where `a` and `b` are both maps all of whose values are numbers, return +
+ + 072    a map whose keys are a union of the keys of `a` and `b` and whose values +
+ + 073    are the sums of their respective values." +
+ + 074    [a b] +
+ + 075    (reduce +
+ + 076      merge +
+ + 077      a +
+ + 078      (map +
+ + 079        #(hash-map % (+ (or (a %) 0) (or (b %) 0))) +
+ + 080        (keys b)))) +
+ + 081   +
+ + 082  (defn add-known-prices +
+ + 083    "Add the current prices at this `merchant`'s location in the `world` +
+ + 084    to a new cache of known prices, and return it." +
+ + 085    [merchant world] +
+ + 086    (let [m (cond +
+ + 087              (keyword? merchant) +
+ + 088              (-> world :merchants merchant) +
+ + 089              (map? merchant) +
+ + 090              merchant) +
+ + 091          k (or (:known-prices m) {}) +
+ + 092          l (:location m) +
+ + 093          d (or (:date world) 0) +
+ + 094          p (-> world :cities l :prices)] +
+ + 095      (cond +
+ + 096        (nil? m) +
+ + 097        (throw (Exception. "No merchant?")) +
+ + 098        (or (nil? l) (nil? (-> world :cities l))) +
+ + 099        (throw (Exception. (str "No known location for merchant " m))) +
+ + 100        :else +
+ + 101        (reduce +
+ + 102          merge +
+ + 103          k +
+ + 104          (map +
+ + 105            #(hash-map % (apply vector cons {:price (p %) :date d} (k %))) +
+ + 106            (-> world :commodities keys)))))) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/merchants/merchants.clj.html b/docs/cloverage/cc/journeyman/the_great_game/merchants/merchants.clj.html new file mode 100644 index 0000000..94daa96 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/merchants/merchants.clj.html @@ -0,0 +1,92 @@ + + + + cc/journeyman/the_great_game/merchants/merchants.clj + + + + 001  (ns cc.journeyman.the-great-game.merchants.merchants +
+ + 002    "Trade planning for merchants, primarily." +
+ + 003    (:require [cc.journeyman.the-great-game.utils :refer [deep-merge]] +
+ + 004              [cc.journeyman.the-great-game.merchants.strategies.simple :refer [move-merchant]] +
+ + 005              [taoensso.timbre :as l])) +
+ + 006   +
+ + 007   +
+ + 008  (defn run +
+ + 009    "Return a partial world based on this `world`, but with each merchant moved." +
+ + 010    [world] +
+ + 011    (try +
+ + 012      (reduce +
+ + 013       deep-merge +
+ + 014       world +
+ + 015       (map +
+ + 016        #(try +
+ + 017           (let [move-fn (or +
+ + 018                          (-> world :merchants % :move-fn) +
+ + 019                          move-merchant)] +
+ + 020             (apply move-fn (list % world))) +
+ + 021           (catch Exception any +
+ + 022             (l/error any "Failure while moving merchant " %) +
+ + 023             {})) +
+ + 024        (keys (:merchants world)))) +
+ + 025      (catch Exception any +
+ + 026        (l/error any "Failure while moving merchants") +
+ + 027        world))) +
+ + 028   +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/merchants/planning.clj.html b/docs/cloverage/cc/journeyman/the_great_game/merchants/planning.clj.html new file mode 100644 index 0000000..ee3243d --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/merchants/planning.clj.html @@ -0,0 +1,485 @@ + + + + cc/journeyman/the_great_game/merchants/planning.clj + + + + 001  (ns cc.journeyman.the-great-game.merchants.planning +
+ + 002    "Trade planning for merchants, primarily. This follows a simple-minded +
+ + 003    generate-and-test strategy and currently generates plans for all possible +
+ + 004    routes from the current location. This may not scale. Also, routes do not +
+ + 005    currently have cost or risk associated with them." +
+ + 006    (:require [cc.journeyman.the-great-game.utils :refer [deep-merge make-target-filter]] +
+ + 007              [cc.journeyman.the-great-game.merchants.merchant-utils :refer [can-afford can-carry expected-price]] +
+ + 008              [cc.journeyman.the-great-game.world.routes :refer [find-route]] +
+ + 009              [cc.journeyman.the-great-game.world.world :refer [actual-price default-world]])) +
+ + 010   +
+ + 011  (defn generate-trade-plans +
+ + 012    "Generate all possible trade plans for this `merchant` and this `commodity` +
+ + 013    in this `world`. +
+ + 014   +
+ + 015    Returned plans are maps with keys: +
+ + 016   +
+ + 017    * :merchant - the id of the `merchant` for whom the plan was created; +
+ + 018    * :origin - the city from which the trade starts; +
+ + 019    * :destination - the city to which the trade is planned; +
+ + 020    * :commodity - the `commodity` to be carried; +
+ + 021    * :buy-price - the price at which that `commodity` can be bought; +
+ + 022    * :expected-price - the price at which the `merchant` anticipates +
+ + 023    that `commodity` can be sold; +
+ + 024    * :distance - the number of stages in the planned journey +
+ + 025    * :dist-to-home - the distance from `destination` to the `merchant`'s +
+ + 026    home city." +
+ + 027    [merchant world commodity] +
+ + 028    (let [m (cond +
+ + 029              (keyword? merchant) +
+ + 030              (-> world :merchants merchant) +
+ + 031              (map? merchant) +
+ + 032              merchant) +
+ + 033          origin (:location m)] +
+ + 034      (map +
+ + 035        #(hash-map +
+ + 036           :merchant (:id m) +
+ + 037           :origin origin +
+ + 038           :destination % +
+ + 039           :commodity commodity +
+ + 040           :buy-price (actual-price world commodity origin) +
+ + 041           :expected-price (expected-price +
+ + 042                             m +
+ + 043                             commodity +
+ + 044                             %) +
+ + 045           :distance (count +
+ + 046                       (find-route world origin %)) +
+ + 047           :dist-to-home (count +
+ + 048                           (find-route +
+ + 049                             world +
+ + 050                             (:home m) +
+ + 051                             %))) +
+ + 052        (remove #(= % origin) (-> world :cities keys))))) +
+ + 053   +
+ + 054  (defn nearest-with-targets +
+ + 055    "Return the distance to the nearest destination among those of these +
+ + 056    `plans` which match these `targets`. Plans are expected to be plans +
+ + 057    as returned by `generate-trade-plans`, q.v.; `targets` are expected to be +
+ + 058    as accepted by `make-target-filter`, q.v." +
+ + 059    [plans targets] +
+ + 060    (apply +
+ + 061      min +
+ + 062      (map +
+ + 063        :distance +
+ + 064        (filter +
+ + 065          (make-target-filter targets) +
+ + 066          plans)))) +
+ + 067   +
+ + 068  (defn plan-trade +
+ + 069    "Find the best destination in this `world` for this `commodity` given this +
+ + 070    `merchant` and this `origin`. If two cities are anticipated to offer the +
+ + 071    same price, the nearer should be preferred; if two are equally distant, the +
+ + 072    ones nearer to the merchant's home should be preferred. +
+ + 073    `merchant` may be passed as a map or a keyword; `commodity` should  be +
+ + 074    passed as a keyword. +
+ + 075   +
+ + 076    The returned plan is a map with keys: +
+ + 077   +
+ + 078    * :merchant - the id of the `merchant` for whom the plan was created; +
+ + 079    * :origin - the city from which the trade starts; +
+ + 080    * :destination - the city to which the trade is planned; +
+ + 081    * :commodity - the `commodity` to be carried; +
+ + 082    * :buy-price - the price at which that `commodity` can be bought; +
+ + 083    * :expected-price - the price at which the `merchant` anticipates +
+ + 084    that `commodity` can be sold; +
+ + 085    * :distance - the number of stages in the planned journey +
+ + 086    * :dist-to-home - the distance from `destination` to the `merchant`'s +
+ + 087    home city." +
+ + 088    [merchant world commodity] +
+ + 089    (let [plans (generate-trade-plans merchant world commodity) +
+ + 090          best-prices (filter +
+ + 091                        (make-target-filter +
+ + 092                          [[:expected-price +
+ + 093                            (apply +
+ + 094                              max +
+ + 095                              (filter number? (map :expected-price plans)))]]) +
+ + 096                        plans)] +
+ + 097      (first +
+ + 098        (sort-by +
+ + 099          ;; all other things being equal, a merchant would prefer to end closer +
+ + 100          ;; to home. +
+ + 101          #(- 0 (:dist-to-home %)) +
+ + 102          ;; a merchant will seek the best price, but won't go further than +
+ + 103          ;; needed to get it. +
+ + 104          (filter +
+ + 105            (make-target-filter +
+ + 106              [[:distance +
+ + 107                (apply min (filter number? (map :distance best-prices)))]]) +
+ + 108            best-prices))))) +
+ + 109   +
+ + 110  (defn augment-plan +
+ + 111    "Augment this `plan` constructed in this `world` for this `merchant` with +
+ + 112    the `:quantity` of goods which should be bought and the `:expected-profit` +
+ + 113    of the trade. +
+ + 114   +
+ + 115    Returns the augmented plan." +
+ + 116    [merchant world plan] +
+ + 117    (let [c (:commodity plan) +
+ + 118          o (:origin plan) +
+ + 119          q (min +
+ + 120              (or +
+ + 121                (-> world :cities o :stock c) +
+ + 122                0) +
+ + 123              (can-carry merchant world c) +
+ + 124              (can-afford merchant world c)) +
+ + 125          p (* q (- (:expected-price plan) (:buy-price plan)))] +
+ + 126      (assoc plan :quantity q :expected-profit p))) +
+ + 127   +
+ + 128  (defn select-cargo +
+ + 129    "A `merchant`, in a given location in a `world`, will choose to buy a cargo +
+ + 130    within the limit they are capable of carrying, which they can anticipate +
+ + 131    selling for a profit at a destination." +
+ + 132    [merchant world] +
+ + 133    (let [m (cond +
+ + 134              (keyword? merchant) +
+ + 135              (-> world :merchants merchant) +
+ + 136              (map? merchant) +
+ + 137              merchant) +
+ + 138          origin (:location m) +
+ + 139          available (-> world :cities origin :stock) +
+ + 140          plans (map +
+ + 141                  #(augment-plan +
+ + 142                     m +
+ + 143                     world +
+ + 144                     (plan-trade m world %)) +
+ + 145                  (filter +
+ + 146                    #(let [q (-> world :cities origin :stock %)] +
+ + 147                       (and (number? q) (pos? q))) +
+ + 148                    (keys available)))] +
+ + 149      (if +
+ + 150        (not (empty? plans)) +
+ + 151        (first +
+ + 152          (sort-by +
+ + 153            #(- 0 (:dist-to-home %)) +
+ + 154            (filter +
+ + 155              (make-target-filter +
+ + 156                [[:expected-profit +
+ + 157                  (apply max (filter number? (map :expected-profit plans)))]]) +
+ + 158              plans)))))) +
+ + 159   +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/merchants/strategies/simple.clj.html b/docs/cloverage/cc/journeyman/the_great_game/merchants/strategies/simple.clj.html new file mode 100644 index 0000000..48b73c0 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/merchants/strategies/simple.clj.html @@ -0,0 +1,527 @@ + + + + cc/journeyman/the_great_game/merchants/strategies/simple.clj + + + + 001  (ns cc.journeyman.the-great-game.merchants.strategies.simple +
+ + 002    "Default trading strategy for merchants. +
+ + 003   +
+ + 004    The simple strategy buys a single product in the local market if there is +
+ + 005    one which can be traded profitably, trades it to the chosen target market, +
+ + 006    and sells it there. If there is no commodity locally which can be traded +
+ + 007    profitably, moves towards home with no cargo. If at home and no commodity +
+ + 008    can be traded profitably, does not move." +
+ + 009    (:require [taoensso.timbre :as l :refer [info error spy]] +
+ + 010              [cc.journeyman.the-great-game.utils :refer [deep-merge]] +
+ + 011              [cc.journeyman.the-great-game.gossip.gossip :refer [move-gossip]] +
+ + 012              [cc.journeyman.the-great-game.merchants.planning :refer [augment-plan plan-trade select-cargo]] +
+ + 013              [cc.journeyman.the-great-game.merchants.merchant-utils :refer +
+ + 014               [add-stock add-known-prices]] +
+ + 015              [cc.journeyman.the-great-game.world.routes :refer [find-route]])) +
+ + 016   +
+ + 017  (defn plan-and-buy +
+ + 018    "Return a world like this `world`, in which this `merchant` has planned +
+ + 019    a new trade, and bought appropriate stock for it. If no profitable trade +
+ + 020    can be planned, the merchant is simply moved towards their home." +
+ + 021    [merchant world] +
+ + 022    (let [m (cond +
+ + 023              (keyword? merchant) +
+ + 024              (-> world :merchants merchant) +
+ + 025              (map? merchant) +
+ + 026              merchant) +
+ + 027          id (:id m) +
+ + 028          location (:location m) +
+ + 029          market (-> world :cities location) +
+ + 030          plan (select-cargo merchant world)] +
+ + 031      (l/debug "plan-and-buy: merchant" id) +
+ + 032      (cond +
+ + 033        (seq? plan) +
+ + 034        (let +
+ + 035          [c (:commodity plan) +
+ + 036           p (* (:quantity plan) (:buy-price plan)) +
+ + 037           q (:quantity plan)] +
+ + 038          (l/info "Merchant" id "bought" q "units of" c "at" location "for" p plan) +
+ + 039          {:merchants +
+ + 040           {id +
+ + 041            {:stock (add-stock (:stock m) {c q}) +
+ + 042             :cash (- (:cash m) p) +
+ + 043             :known-prices (add-known-prices m world) +
+ + 044             :plan plan}} +
+ + 045           :cities +
+ + 046           {location +
+ + 047            {:stock (assoc (:stock market) c (- (-> market :stock c) q)) +
+ + 048             :cash (+ (:cash market) p)}}}) +
+ + 049        ;; if no plan, then if at home stay put +
+ + 050        (= (:location m) (:home m)) +
+ + 051        (do +
+ + 052          (l/info "Merchant" id "remains at home in" location) +
+ + 053          {}) +
+ + 054        ;; else move towards home +
+ + 055        :else +
+ + 056        (let [route (find-route world location (:home m)) +
+ + 057              next-location (nth route 1)] +
+ + 058          (l/info "No trade possible at" location "; merchant" id "moves to" next-location) +
+ + 059          (merge +
+ + 060            {:merchants +
+ + 061             {id +
+ + 062              {:location next-location}}} +
+ + 063            (move-gossip id world next-location)))))) +
+ + 064   +
+ + 065  (defn re-plan +
+ + 066    "Having failed to sell a cargo at current location, re-plan a route to +
+ + 067    sell the current cargo. Returns a revised world." +
+ + 068    [merchant world] +
+ + 069    (let [m (cond +
+ + 070              (keyword? merchant) +
+ + 071              (-> world :merchants merchant) +
+ + 072              (map? merchant) +
+ + 073              merchant) +
+ + 074          id (:id m) +
+ + 075          location (:location m) +
+ + 076          plan (augment-plan m world (plan-trade m world (-> m :plan :commodity)))] +
+ + 077      (l/debug "re-plan: merchant" id) +
+ + 078      (deep-merge +
+ + 079        world +
+ + 080        {:merchants +
+ + 081         {id +
+ + 082          {:plan plan}}}))) +
+ + 083   +
+ + 084  (defn sell-and-buy +
+ + 085    "Return a new world like this `world`, in which this `merchant` has sold +
+ + 086    their current stock in their current location, and planned a new trade, and +
+ + 087    bought appropriate stock for it." +
+ + 088    ;; TODO: this either sells the entire cargo, or, if the market can't afford +
+ + 089    ;; it, none of it. And it does not cope with selling different commodities +
+ + 090    ;; in different markets. +
+ + 091    [merchant world] +
+ + 092    (let [m (cond +
+ + 093              (keyword? merchant) +
+ + 094              (-> world :merchants merchant) +
+ + 095              (map? merchant) +
+ + 096              merchant) +
+ + 097          id (:id m) +
+ + 098          location (:location m) +
+ + 099          market (-> world :cities location) +
+ + 100          stock-value (reduce +
+ + 101                        + +
+ + 102                        (map +
+ + 103                          #(* (-> m :stock %) (-> market :prices m)) +
+ + 104                          (keys (:stock m))))] +
+ + 105      (l/debug "sell-and-buy: merchant" id) +
+ + 106      (if +
+ + 107        (>= (:cash market) stock-value) +
+ + 108        (do +
+ + 109          (l/info "Merchant" id "sells" (:stock m) "at" location "for" stock-value) +
+ + 110          (plan-and-buy +
+ + 111            merchant +
+ + 112            (deep-merge +
+ + 113              world +
+ + 114              {:merchants +
+ + 115               {id +
+ + 116                {:stock {} +
+ + 117                 :cash (+ (:cash m) stock-value) +
+ + 118                 :known-prices (add-known-prices m world)}} +
+ + 119               :cities +
+ + 120               {location +
+ + 121                {:stock (add-stock (:stock m) (:stock market)) +
+ + 122                 :cash (- (:cash market) stock-value)}}}))) +
+ + 123        ;; else +
+ + 124        (re-plan merchant world)))) +
+ + 125   +
+ + 126  (defn move-merchant +
+ + 127    "Handle general en route movement of this `merchant` in this `world`; +
+ + 128    return a (partial or full) world like this `world` but in which the +
+ + 129    merchant may have been moved ot updated." +
+ + 130    [merchant world] +
+ + 131    (let [m (cond +
+ + 132              (keyword? merchant) +
+ + 133              (-> world :merchants merchant) +
+ + 134              (map? merchant) +
+ + 135              merchant) +
+ + 136          id (:id m) +
+ + 137          at-destination? (and (:plan m) (= (:location m) (-> m :plan :destination))) +
+ + 138          plan (:plan m) +
+ + 139          next-location (if plan +
+ + 140                          (nth +
+ + 141                            (find-route +
+ + 142                              world +
+ + 143                              (:location m) +
+ + 144                              (:destination plan)) +
+ + 145                            1) +
+ + 146                          (:location m))] +
+ + 147      (l/debug "move-merchant: merchant" id "at" (:location m) +
+ + 148               "destination" (-> m :plan :destination) "next" next-location +
+ + 149               "at destination" at-destination?) +
+ + 150      (cond +
+ + 151        ;; if the merchant is at the destination of their current plan +
+ + 152        ;; sell all cargo and repurchase. +
+ + 153        at-destination? +
+ + 154        (sell-and-buy merchant world) +
+ + 155        ;; if they don't have a plan, seek to create one +
+ + 156        (nil? plan) +
+ + 157        (plan-and-buy merchant world) +
+ + 158        ;; otherwise, move one step towards their destination +
+ + 159        (and next-location (not= next-location (:location m))) +
+ + 160        (do +
+ + 161          (l/info "Merchant " id " moving from " (:location m) " to " next-location) +
+ + 162          (deep-merge +
+ + 163            {:merchants +
+ + 164             {id +
+ + 165              {:location next-location +
+ + 166               :known-prices (add-known-prices m world)}}} +
+ + 167            (move-gossip id world next-location))) +
+ + 168        :else +
+ + 169        (do +
+ + 170          (l/info "Merchant" id "has plan but no next-location; currently at" +
+ + 171                  (:location m) ", destination is" (:destination plan)) +
+ + 172          world)))) +
+ + 173   +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/objects/container.clj.html b/docs/cloverage/cc/journeyman/the_great_game/objects/container.clj.html new file mode 100644 index 0000000..0140330 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/objects/container.clj.html @@ -0,0 +1,41 @@ + + + + cc/journeyman/the_great_game/objects/container.clj + + + + 001  (ns cc.journeyman.the-great-game.objects.container +
+ + 002    (:require +
+ + 003      [cc.journeyman.the-great-game.objects.game-object :refer :all])) +
+ + 004   +
+ + 005  (defprotocol ProtoContainer +
+ + 006    (contents +
+ + 007      [container] +
+ + 008              "Return a sequence of the contents of this `container`, or `nil` if empty.") +
+ + 009    (is-empty? +
+ + 010      [container] +
+ + 011      "Return `true` if this `container` is empty, else `false`.")) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/objects/game_object.clj.html b/docs/cloverage/cc/journeyman/the_great_game/objects/game_object.clj.html new file mode 100644 index 0000000..32e0483 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/objects/game_object.clj.html @@ -0,0 +1,71 @@ + + + + cc/journeyman/the_great_game/objects/game_object.clj + + + + 001  (ns cc.journeyman.the-great-game.objects.game-object +
+ + 002    "Anything at all in the game world") +
+ + 003   +
+ + 004  (defprotocol ProtoObject +
+ + 005    "An object in the world" +
+ + 006    (id [object] "Returns the unique id of this object.") +
+ + 007    (reify-object +
+ + 008      [object] +
+ + 009      "Adds this `object` to the global object list. If the `object` has a +
+ + 010      non-nil value for its `id` method, keys it to that id - **but** if the +
+ + 011      id value is already in use, throws a hard exception. Returns the id to +
+ + 012      which the object is keyed in the global object list.")) +
+ + 013   +
+ + 014  (defrecord GameObject +
+ + 015             [id] +
+ + 016    ;; "An object in the world" +
+ + 017    ProtoObject +
+ + 018    (id [_] id) +
+ + 019    (reify-object [object] +
+ + 020      "TODO: doesn't work yet" +
+ + 021      object)) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/playroom.clj.html b/docs/cloverage/cc/journeyman/the_great_game/playroom.clj.html new file mode 100644 index 0000000..8c3f407 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/playroom.clj.html @@ -0,0 +1,224 @@ + + + + cc/journeyman/the_great_game/playroom.clj + + + + 001  (ns cc.journeyman.the-great-game.playroom +
+ + 002    (:require [jme-clj.core :refer [add add-to-root box defsimpleapp fly-cam geo  +
+ + 003                                    get* get-state load-texture rotate run set*  +
+ + 004                                    setc set-state start unshaded-mat]]) +
+ + 005    (:import [com.jme3.math ColorRGBA])) +
+ + 006   +
+ + 007  ;; At present this file is just somewhere to play around with jme-clj examples +
+ + 008   +
+ + 009  (declare app) +
+ + 010   +
+ + 011  (defn init [] +
+ + 012    (let [cube (geo "jMonkey cube" (box 1 1 1)) +
+ + 013          mat  (unshaded-mat)] +
+ + 014      (set* mat :texture "ColorMap" (load-texture "textures/Monkey.jpg")) +
+ + 015      (set* cube :material mat) +
+ + 016      (add-to-root cube) +
+ + 017      {:cube cube})) +
+ + 018   +
+ + 019  ;; Let's create simple-update fn with no body for now. +
+ + 020   (defn simple-update [tpf] +
+ + 021     (let [{:keys [cube]} (get-state)] +
+ + 022       (rotate cube 0 (* 2 tpf) 0))) +
+ + 023   +
+ + 024   +
+ + 025  ;; Kills the running app var and closes its window. +
+ + 026  ;; (unbind-app #'app) +
+ + 027   +
+ + 028  ;; We define the `app` var. +
+ + 029  (defsimpleapp app +
+ + 030                 :opts {:show-settings?       false +
+ + 031                        :pause-on-lost-focus? false +
+ + 032                        :settings             {:title          "My JME Game" +
+ + 033                                               :load-defaults? true +
+ + 034                                               :frame-rate     60 +
+ + 035                                               :width          800 +
+ + 036                                               :height         600}} +
+ + 037                 :init init +
+ + 038                 :update simple-update) +
+ + 039   +
+ + 040  ;; (start app) +
+ + 041   +
+ + 042  ;; Reinitialises the running app +
+ + 043  ;;(run app +
+ + 044  ;;     (re-init init)) +
+ + 045    +
+ + 046   ;; By default, there is a Fly Camera attached to the app that you can control with W, A, S and D keys. +
+ + 047   ;; Let's increase its movement speed. Now, you fly faster :) +
+ + 048   ;; (run app +
+ + 049   ;;      (set* (fly-cam) :move-speed 15)) +
+ + 050   +
+ + 051   +
+ + 052   ;; Updates the app  +
+ + 053  ;; (run app +
+ + 054  ;;      (let [{:keys [cube]} (get-state)] +
+ + 055  ;;        (set* cube :local-translation (add (get* cube :local-translation) 1 1 1)))) +
+ + 056   +
+ + 057    ;; Updates the app adding a second cube +
+ + 058  ;; (run app +
+ + 059  ;;       (let [cube (geo "jMonkey cube" (box 1 1 1)) +
+ + 060  ;;             mat  (unshaded-mat)] +
+ + 061  ;;         (set* mat :texture "ColorMap" (load-texture "textures/Monkey.jpg")) +
+ + 062  ;;         (setc cube +
+ + 063  ;;               :material mat +
+ + 064  ;;               :local-translation [-3 0 0]) +
+ + 065  ;;         (add-to-root cube) +
+ + 066  ;;         (set-state :cube2 cube))) +
+ + 067    +
+ + 068   ;; We added the new cube, but it's not rotating. We need to update the simple-update fn. +
+ + 069   ;; (defn simple-update [tpf] +
+ + 070   ;;   (let [{:keys [cube cube2]} (get-state)] +
+ + 071   ;;     (rotate cube 0 (* 2 tpf) 0) +
+ + 072   ;;     (rotate cube2 0 (* 2 tpf) 0))) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/time.clj.html b/docs/cloverage/cc/journeyman/the_great_game/time.clj.html new file mode 100644 index 0000000..f869045 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/time.clj.html @@ -0,0 +1,440 @@ + + + + cc/journeyman/the_great_game/time.clj + + + + 001  (ns cc.journeyman.the-great-game.time +
+ + 002    (:require [clojure.string :as s])) +
+ + 003   +
+ + 004  (def game-start-time +
+ + 005    "The start time of this run." +
+ + 006    (System/currentTimeMillis)) +
+ + 007   +
+ + 008  (def ^:const game-day-length +
+ + 009    "The Java clock advances in milliseconds, which is fine. +
+ + 010    But we need game-days to be shorter than real world days. +
+ + 011    A Witcher 3 game day is 1 hour 36 minutes, or 96 minutes, which is +
+ + 012    presumably researched. Round it up to 100 minutes for easier +
+ + 013    calculation." +
+ + 014    (* 100          ;; minutes per game day +
+ + 015       60           ;; seconds per minute +
+ + 016       1000))       ;; milliseconds per second +
+ + 017   +
+ + 018  (defn now +
+ + 019    "For now, we'll use Java timestamp for time; ultimately, we need a +
+ + 020    concept of game-time which allows us to drive day/night cycle, seasons, +
+ + 021    et cetera, but what matters about time is that it is a value which +
+ + 022    increases." +
+ + 023    [] +
+ + 024    (System/currentTimeMillis)) +
+ + 025   +
+ + 026  (def ^:const canonical-ordering-of-houses +
+ + 027    "The canonical ordering of religious houses." +
+ + 028    [:eye +
+ + 029     :foot +
+ + 030     :nose +
+ + 031     :hand +
+ + 032     :ear +
+ + 033     :mouth +
+ + 034     :stomach +
+ + 035     :furrow +
+ + 036     :plough]) +
+ + 037   +
+ + 038  (def ^:const days-of-week +
+ + 039    "The eight-day week of the game world. This differs from the canonical +
+ + 040    ordering of houses in that it omits the eye." +
+ + 041    (rest canonical-ordering-of-houses)) +
+ + 042   +
+ + 043  (def ^:const days-in-week +
+ + 044    "This world has an eight day week." +
+ + 045    (count days-of-week)) +
+ + 046   +
+ + 047  (def ^:const seasons-of-year +
+ + 048    "The ordering of seasons in the year is different from the canonical +
+ + 049    ordering of the houses, for reasons of the agricultural cycle." +
+ + 050    [:foot +
+ + 051     :nose +
+ + 052     :hand +
+ + 053     :ear +
+ + 054     :mouth +
+ + 055     :stomach +
+ + 056     :plough +
+ + 057     :furrow +
+ + 058     :eye]) +
+ + 059   +
+ + 060  (def ^:const seasons-in-year +
+ + 061    "Nine seasons in a year, one for each house (although the order is +
+ + 062    different." +
+ + 063    (count seasons-of-year)) +
+ + 064   +
+ + 065  (def ^:const weeks-of-season +
+ + 066    "To fit nine seasons of eight day weeks into 365 days, each must be of +
+ + 067    five weeks." +
+ + 068    [:first :second :third :fourth :fifth]) +
+ + 069   +
+ + 070  (def ^:const weeks-in-season +
+ + 071    "To fit nine seasons of eight day weeks into 365 days, each must be of +
+ + 072    five weeks." +
+ + 073    (count weeks-of-season)) +
+ + 074   +
+ + 075  (def ^:const days-in-season +
+ + 076    (* weeks-in-season days-in-week)) +
+ + 077   +
+ + 078  (defn game-time +
+ + 079    "With no arguments, the current game time. If a Java `timestamp` value is +
+ + 080    passed (as a `long`), the game time represented by that value." +
+ + 081    ([] (game-time (now))) +
+ + 082    ([timestamp] +
+ + 083     (- timestamp game-start-time))) +
+ + 084   +
+ + 085  (defmacro day-of-year +
+ + 086    "The day of the year represented by this `game-time`, ignoring leap years." +
+ + 087    [game-time] +
+ + 088    `(mod (long (/ ~game-time game-day-length)) 365)) +
+ + 089   +
+ + 090  (def waiting-day? +
+ + 091    "Does this `game-time` represent a waiting day?" +
+ + 092    (memoize +
+ + 093      ;; we're likely to call this several times in quick succession on the +
+ + 094      ;; same timestamp +
+ + 095      (fn [game-time] +
+ + 096          (>= +
+ + 097            (day-of-year game-time) +
+ + 098            (* seasons-in-year weeks-in-season days-in-week))))) +
+ + 099   +
+ + 100  (defn day +
+ + 101    "Day of the eight-day week represented by this `game-time`." +
+ + 102    [game-time] +
+ + 103    (let [day-of-week (mod (day-of-year game-time) days-in-week)] +
+ + 104      (if (waiting-day? game-time) +
+ + 105        (nth weeks-of-season day-of-week) +
+ + 106        (nth days-of-week day-of-week)))) +
+ + 107   +
+ + 108  (defn week +
+ + 109    "Week of season represented by this `game-time`." +
+ + 110    [game-time] +
+ + 111    (let [day-of-season (mod (day-of-year game-time) days-in-season) +
+ + 112          week (/ day-of-season days-in-week)] +
+ + 113      (if (waiting-day? game-time) +
+ + 114        :waiting +
+ + 115        (nth weeks-of-season week)))) +
+ + 116   +
+ + 117  (defn season +
+ + 118    [game-time] +
+ + 119    (let [season (int (/ (day-of-year game-time) days-in-season))] +
+ + 120      (if (waiting-day? game-time) +
+ + 121        :waiting +
+ + 122        (nth seasons-of-year season)))) +
+ + 123   +
+ + 124  (defn date-string +
+ + 125    "Return a correctly formatted date for this `game-time` in the calendar of +
+ + 126    the Great Place." +
+ + 127    [game-time] +
+ + 128    (s/join +
+ + 129      " " +
+ + 130      (if +
+ + 131        (waiting-day? game-time) +
+ + 132        [(s/capitalize +
+ + 133           (name +
+ + 134             (nth +
+ + 135               weeks-of-season +
+ + 136               (mod (day-of-year game-time) days-in-week)))) +
+ + 137         "waiting day"] +
+ + 138        [(s/capitalize (name (week game-time))) +
+ + 139         (s/capitalize (name (day game-time))) +
+ + 140         "of the" +
+ + 141         (s/capitalize (name (season game-time)))]))) +
+ + 142   +
+ + 143   +
+ + 144   +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/utils.clj.html b/docs/cloverage/cc/journeyman/the_great_game/utils.clj.html new file mode 100644 index 0000000..d8c0be8 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/utils.clj.html @@ -0,0 +1,191 @@ + + + + cc/journeyman/the_great_game/utils.clj + + + + 001  (ns cc.journeyman.the-great-game.utils) +
+ + 002   +
+ + 003  (defn cyclic? +
+ + 004    "True if two or more elements of `route` are identical" +
+ + 005    [route] +
+ + 006    (not= (count route)(count (set route)))) +
+ + 007   +
+ + 008  (defn deep-merge +
+ + 009    "Recursively merges maps. Stolen from +
+ + 010    https://dnaeon.github.io/recursively-merging-maps-in-clojure/" +
+ + 011    [& maps] +
+ + 012    (letfn [(m [& xs] +
+ + 013               (if (some #(and (map? %) (not (record? %))) xs) +
+ + 014                 (apply merge-with m xs) +
+ + 015                 (last xs)))] +
+ + 016      (reduce m maps))) +
+ + 017   +
+ + 018  (defn make-target-filter +
+ + 019    "Construct a filter which, when applied to a list of maps, +
+ + 020    will pass those which match these `targets`, where each target +
+ + 021    is a tuple [key value]." +
+ + 022    ;; TODO: this would probably be more elegant as a macro +
+ + 023    [targets] +
+ + 024    (eval +
+ + 025      (list +
+ + 026        'fn +
+ + 027        (vector 'm) +
+ + 028        (cons +
+ + 029          'and +
+ + 030          (map +
+ + 031            #(list +
+ + 032               '= +
+ + 033               (list (first %) 'm) +
+ + 034               (nth % 1)) +
+ + 035            targets))))) +
+ + 036   +
+ + 037  (defn value-or-default +
+ + 038    "Return the value of this key `k` in this map `m`, or this `dflt` value if +
+ + 039    there is none." +
+ + 040    [m k dflt] +
+ + 041    (or (when (map? m) (m k)) dflt)) +
+ + 042   +
+ + 043  ;; (value-or-default {:x 0 :y 0 :altitude 7} :altitude 8) +
+ + 044  ;; (value-or-default {:x 0 :y 0 :altitude 7} :alt 8) +
+ + 045  ;; (value-or-default nil :altitude 8) +
+ + 046   +
+ + 047  (defn truthy?  +
+ + 048    "Returns `true` unless `val` is `nil`, `false` or an empty sequence. +
+ + 049     Otherwise always 'false'; never any other value." +
+ + 050    [val] +
+ + 051    (and (or val false) true)) +
+ + 052   +
+ + 053   +
+ + 054  (defn inc-or-one +
+ + 055    "If this `val` is a number, return that number incremented by one; otherwise, +
+ + 056     return 1. TODO: should probably be in `utils`." +
+ + 057    [val] +
+ + 058    (if +
+ + 059     (number? val) +
+ + 060      (inc val) +
+ + 061      1)) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/world/heightmap.clj.html b/docs/cloverage/cc/journeyman/the_great_game/world/heightmap.clj.html new file mode 100644 index 0000000..4ca6508 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/world/heightmap.clj.html @@ -0,0 +1,485 @@ + + + + cc/journeyman/the_great_game/world/heightmap.clj + + + + 001  (ns cc.journeyman.the-great-game.world.heightmap +
+ + 002    "Functions dealing with the tessellated multi-layer heightmap." +
+ + 003      (:require [clojure.math.numeric-tower :refer [expt sqrt]] +
+ + 004                [mw-engine.core :refer []] +
+ + 005                [mw-engine.heightmap :refer [apply-heightmap]] +
+ + 006                [mw-engine.utils :refer [get-cell in-bounds? map-world]] +
+ + 007                [cc.journeyman.the-great-game.utils :refer [value-or-default]])) +
+ + 008   +
+ + 009  ;; It's not at all clear to me yet what the workflow for getting a MicroWorld +
+ + 010  ;; map into The Great Game, and whether it passes through Walkmap to get here. +
+ + 011  ;; This file as currently written assumes it doesn't. +
+ + 012   +
+ + 013  ;; It's utterly impossible to hold a whole continent at one metre scale in +
+ + 014  ;; memory at one time. So we have to be able to regenerate high resolution +
+ + 015  ;; surfaces from much lower resolution heightmaps. +
+ + 016  ;; +
+ + 017  ;; Thus to reproduce a segment of surface at a particular level of detail, +
+ + 018  ;; we: +
+ + 019  ;; 1. load the base heightmap into a grid (see +
+ + 020  ;;    `mw-engine.heightmap/apply-heightmap`); +
+ + 021  ;; 2. scale the base hightmap to kilometre scale (see `scale-grid`); +
+ + 022  ;; 3. exerpt the portion of that that we want to reproduce (see `exerpt-grid`); +
+ + 023  ;; 4. interpolate that grid to get the resolution we require (see +
+ + 024  ;;    `interpolate-grid`); +
+ + 025  ;; 5. create an appropriate purturbation grid from the noise map(s) for the +
+ + 026  ;;    same coordinates to break up the smooth interpolation; +
+ + 027  ;; 6. sum the altitudes of the two grids. +
+ + 028  ;; +
+ + 029  ;; In production this will have to be done **very** fast! +
+ + 030   +
+ + 031  (def ^:dynamic *base-map* "resources/maps/heightmap.png") +
+ + 032  (def ^:dynamic *noise-map* "resources/maps/noise.png") +
+ + 033   +
+ + 034  (defn scale-grid +
+ + 035    "multiply all `:x` and `:y` values in this `grid` by this `n`." +
+ + 036    [grid n] +
+ + 037    (map-world grid (fn [w c x] (assoc c :x (* (:x c) n) :y (* (:y c) n))))) +
+ + 038   +
+ + 039   +
+ + 040   +
+ + 041  ;; Each of the east-west curve and the north-south curve are of course two +
+ + 042  ;; dimensional curves; the east-west curve is in the :x/:z plane and the +
+ + 043  ;; north-south curve is in the :y/:z plane (except, perhaps unwisely, +
+ + 044  ;; we've been using :altitude to label the :z plane). We have a library +
+ + 045  ;; function `walkmap.edge/intersection2d`, but as currently written it +
+ + 046  ;; can only find intersections in :x/:y plane. +
+ + 047  ;; +
+ + 048  ;; TODO: rewrite the function so that it can use arbitrary coordinates. +
+ + 049  ;; AFTER TRYING: OK, there are too many assumptions about the way that +
+ + 050  ;; function is written to allow for easy rotation. TODO: think! +
+ + 051   +
+ + 052  (defn interpolate-altitude +
+ + 053    "Return the altitude of the point at `x-offset`, `y-offset` within this +
+ + 054    `cell` having this `src-width`, taken from this `grid`." +
+ + 055    [cell grid src-width x-offset y-offset ] +
+ + 056    (let [c-alt (:altitude cell) +
+ + 057          n-alt (or (:altitude (get-cell grid (:x cell) (dec (:y cell)))) c-alt) +
+ + 058          w-alt (or (:altitude (get-cell grid (inc (:x cell)) (:y cell))) c-alt) +
+ + 059          s-alt (or (:altitude (get-cell grid (:x cell) (inc (:y cell)))) c-alt) +
+ + 060          e-alt (or (:altitude (get-cell grid (dec (:x cell)) (:y cell))) c-alt)] +
+ + 061      ;; TODO: construct two curves (arcs of circles good enough for now) +
+ + 062      ;; n-alt...c-alt...s-alt and e-alt...c-alt...w-alt; +
+ + 063      ;; then interpolate x-offset along e-alt...c-alt...w-alt and y-offset +
+ + 064      ;; along n-alt...c-alt...s-alt; +
+ + 065      ;; then return the average of the two +
+ + 066   +
+ + 067      0)) +
+ + 068   +
+ + 069  (defn interpolate-cell +
+ + 070    "Construct a grid (array of arrays) of cells each of width `target-width` +
+ + 071    from this `cell`, of width `src-width`, taken from this `grid`" +
+ + 072    [cell grid src-width target-width] +
+ + 073    (let [offsets (map #(* target-width %) (range (/ src-width target-width)))] +
+ + 074      (into +
+ + 075        [] +
+ + 076        (map +
+ + 077          (fn [r] +
+ + 078            (into +
+ + 079              [] +
+ + 080              (map +
+ + 081                (fn [c] +
+ + 082                  (assoc cell +
+ + 083                    :x (+ (:x cell) c) +
+ + 084                    :y (+ (:y cell) r) +
+ + 085                    :altitude (interpolate-altitude cell grid src-width c r))) +
+ + 086                offsets))) +
+ + 087          offsets)))) +
+ + 088   +
+ + 089  (defn interpolate-grid +
+ + 090    "Return a grid interpolated from this `grid` of rows, cols given scaling +
+ + 091    from this `src-width` to this `target-width`" +
+ + 092    [grid src-width target-width] +
+ + 093    (reduce +
+ + 094      concat +
+ + 095      (into +
+ + 096        [] +
+ + 097        (map +
+ + 098          (fn [row] +
+ + 099            (reduce +
+ + 100              (fn [g1 g2] +
+ + 101                (into [] (map #(into [] (concat %1 %2)) g1 g2))) +
+ + 102              (into [] (map #(interpolate-cell % grid src-width target-width) row)))) +
+ + 103          grid)))) +
+ + 104   +
+ + 105  (defn excerpt-grid +
+ + 106    "Return that section of this `grid` where the `:x` co-ordinate of each cell +
+ + 107    is greater than or equal to this `x-offset`, the `:y` co-ordinate is greater +
+ + 108    than or equal to this `y-offset`, whose width is not greater than this +
+ + 109    `width`, and whose height is not greater than this `height`." +
+ + 110    [grid x-offset y-offset width height] +
+ + 111    (into +
+ + 112      [] +
+ + 113      (remove +
+ + 114        nil? +
+ + 115        (map +
+ + 116          (fn [row] +
+ + 117            (when +
+ + 118              (and +
+ + 119                (>= (:y (first row)) y-offset) +
+ + 120                (< (:y (first row)) (+ y-offset height))) +
+ + 121              (into +
+ + 122                [] +
+ + 123                (remove +
+ + 124                  nil? +
+ + 125                  (map +
+ + 126                    (fn [cell] +
+ + 127                      (when +
+ + 128                        (and +
+ + 129                          (>= (:x cell) x-offset) +
+ + 130                          (< (:x cell) (+ x-offset width))) +
+ + 131                        cell)) +
+ + 132                    row))))) +
+ + 133         grid)))) +
+ + 134   +
+ + 135  (defn get-surface +
+ + 136    "Return, as a vector of vectors of cells represented as Clojure maps, a +
+ + 137    segment of surface from this `base-map` as modified by this +
+ + 138    `noise-map` at this `cell-size` starting at this `x-offset` and `y-offset` +
+ + 139    and having this `width` and `height`. +
+ + 140   +
+ + 141    If `base-map` and `noise-map` are not supplied, the bindings of `*base-map*` +
+ + 142    and `*noise-map*` will be used, respectively. +
+ + 143   +
+ + 144    `base-map` and `noise-map` may be passed either as strings, assumed to be +
+ + 145    file paths of PNG files, or as MicroWorld style world arrays. It is assumed +
+ + 146    that one pixel in `base-map` represents one square kilometre in the game +
+ + 147    world. It is assumed that `cell-size`, `x-offset`, `y-offset`, `width` and +
+ + 148    `height` are integer numbers of metres." +
+ + 149    ([cell-size x-offset y-offset width height] +
+ + 150     (get-surface *base-map* *noise-map* cell-size x-offset y-offset width height)) +
+ + 151    ([base-map noise-map cell-size x-offset y-offset width height] +
+ + 152     (let [b (if (seq? base-map) base-map (scale-grid (apply-heightmap base-map) 1000)) +
+ + 153           n (if (seq? noise-map) noise-map (apply-heightmap noise-map))] +
+ + 154       (if (and (in-bounds? b x-offset y-offset) +
+ + 155                (in-bounds? b (+ x-offset width) (+ y-offset height))) +
+ + 156         b ;; actually do stuff +
+ + 157         (throw (Exception. "Surface out of bounds for map."))) +
+ + 158       ))) +
+ + 159   +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/world/location.clj.html b/docs/cloverage/cc/journeyman/the_great_game/world/location.clj.html new file mode 100644 index 0000000..d8fdc31 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/world/location.clj.html @@ -0,0 +1,119 @@ + + + + cc/journeyman/the_great_game/world/location.clj + + + + 001  (ns cc.journeyman.the-great-game.world.location +
+ + 002    "Functions dealing with location in the world." +
+ + 003    (:require [clojure.math.numeric-tower :refer [expt sqrt]])) +
+ + 004   +
+ + 005  ;;   A 'location' value is a list comprising at most the x/y coordinate location +
+ + 006  ;;   and the ids of the settlement and region (possibly hierarchically) that contain +
+ + 007  ;;   the location. If the x/y is not local to the home of the receiving agent, they +
+ + 008  ;;   won't remember it and won't pass it on; if any of the ids are not interesting +
+ + 009  ;;   So location information will degrade progressively as the item is passed along. +
+ + 010   +
+ + 011  ;;   It is assumed that the `:home` of a character is a location in this sense. +
+ + 012   +
+ + 013  (defn get-coords +
+ + 014    "Return the coordinates in the game world of `location`, which may be +
+ + 015    1. A coordinate pair in the format {:x 5 :y 32}; +
+ + 016    2. A location, as discussed above; +
+ + 017    3. Any other gameworld object, having a `:location` property whose value +
+ + 018      is one of the above." +
+ + 019    [location] +
+ + 020    (cond +
+ + 021      (empty? location) nil +
+ + 022      (map? location) +
+ + 023      (cond +
+ + 024        (and (number? (:x location)) (number? (:y location))) +
+ + 025        location +
+ + 026        (:location location) +
+ + 027        (:location location)) +
+ + 028      :else +
+ + 029      (get-coords (first (remove keyword? location))))) +
+ + 030   +
+ + 031  (defn distance-between +
+ + 032    [location-1 location-2] +
+ + 033    (let [c1 (get-coords location-1) +
+ + 034          c2 (get-coords location-2)] +
+ + 035      (when +
+ + 036        (and c1 c2) +
+ + 037        (sqrt (+ (expt (- (:x c1) (:x c2)) 2) (expt (- (:y c1) (:y c2)) 2)))))) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/world/mw.clj.html b/docs/cloverage/cc/journeyman/the_great_game/world/mw.clj.html new file mode 100644 index 0000000..80194bc --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/world/mw.clj.html @@ -0,0 +1,29 @@ + + + + cc/journeyman/the_great_game/world/mw.clj + + + + 001  (ns cc.journeyman.the-great-game.world.mw +
+ + 002    "Functions dealing with building a great game world from a MicroWorld world." +
+ + 003      (:require [clojure.math.numeric-tower :refer [expt sqrt]] +
+ + 004                [mw-engine.core :refer []] +
+ + 005                [mw-engine.world :refer []])) +
+ + 006   +
+ + 007  ;; It's not at all clear to me yet what the workflow for getting a MicroWorld map into The Great Game, and whether it passes through Walkmap to get here. This file as currently written assumes it doesn't. +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/world/routes.clj.html b/docs/cloverage/cc/journeyman/the_great_game/world/routes.clj.html new file mode 100644 index 0000000..5d5ee4e --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/world/routes.clj.html @@ -0,0 +1,173 @@ + + + + cc/journeyman/the_great_game/world/routes.clj + + + + 001  (ns cc.journeyman.the-great-game.world.routes +
+ + 002    "Conceptual (plan level) routes, represented as tuples of location ids." +
+ + 003    (:require [cc.journeyman.the-great-game.utils :refer [cyclic?]])) +
+ + 004   +
+ + 005  (defn find-routes +
+ + 006    "Find routes from among these `routes` from `from`; if `to` is supplied, +
+ + 007    to `to`, by breadth-first search." +
+ + 008    ([routes from] +
+ + 009     (map +
+ + 010       (fn [to] (cons from to)) +
+ + 011       (remove +
+ + 012         empty? +
+ + 013         (map +
+ + 014           (fn [route] +
+ + 015             (remove +
+ + 016               #(= from %) +
+ + 017               (if (some #(= % from) route) route))) +
+ + 018           routes)))) +
+ + 019    ([routes from to] +
+ + 020     (let [steps (find-routes routes from) +
+ + 021           found (filter +
+ + 022                   (fn [step] (if (some #(= to %) step) step)) +
+ + 023                   steps)] +
+ + 024       (if +
+ + 025         (empty? found) +
+ + 026         (find-routes routes from to steps) +
+ + 027         found))) +
+ + 028    ([routes from to steps] +
+ + 029     (if +
+ + 030       (not (empty? steps)) +
+ + 031       (let [paths (remove +
+ + 032                     cyclic? +
+ + 033                     (mapcat +
+ + 034                         (fn [path] +
+ + 035                           (map +
+ + 036                             (fn [x] (concat path (rest x))) +
+ + 037                             (find-routes routes (last path)))) +
+ + 038                         steps)) +
+ + 039             found (filter +
+ + 040                     #(= (last %) to) paths)] +
+ + 041         (if +
+ + 042           (empty? found) +
+ + 043           (find-routes routes from to paths) +
+ + 044           found))))) +
+ + 045   +
+ + 046  (defn find-route +
+ + 047    "Find a single route from `from` to `to` in this `world-or-routes`, which +
+ + 048    may be either a world as defined in [[the-great-game.world.world]] or else +
+ + 049    a sequence of tuples of keywords." +
+ + 050    [world-or-routes from to] +
+ + 051    (first +
+ + 052      (find-routes +
+ + 053        (or (:routes world-or-routes) world-or-routes) +
+ + 054        from +
+ + 055        to))) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/world/run.clj.html b/docs/cloverage/cc/journeyman/the_great_game/world/run.clj.html new file mode 100644 index 0000000..f161313 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/world/run.clj.html @@ -0,0 +1,125 @@ + + + + cc/journeyman/the_great_game/world/run.clj + + + + 001  (ns cc.journeyman.the-great-game.world.run +
+ + 002    "Run the whole simulation" +
+ + 003    (:require [environ.core :refer [env]] +
+ + 004              [taoensso.timbre :as timbre] +
+ + 005              [taoensso.timbre.appenders.3rd-party.rotor :as rotor] +
+ + 006              [cc.journeyman.the-great-game.gossip.gossip :as g] +
+ + 007              [cc.journeyman.the-great-game.merchants.merchants :as m] +
+ + 008              [cc.journeyman.the-great-game.merchants.markets :as k] +
+ + 009              [cc.journeyman.the-great-game.world.world :as w])) +
+ + 010   +
+ + 011  (defn init +
+ + 012    ([] +
+ + 013     (init {})) +
+ + 014    ([config] +
+ + 015     (timbre/merge-config! +
+ + 016       {:appenders +
+ + 017        {:rotor (rotor/rotor-appender +
+ + 018                  {:path "the-great-game.log" +
+ + 019                   :max-size (* 512 1024) +
+ + 020                   :backlog 10})} +
+ + 021        :level (or +
+ + 022                 (:log-level config) +
+ + 023                 (if (env :dev) :debug) +
+ + 024                 :info)}))) +
+ + 025   +
+ + 026  (defn run +
+ + 027    "The pipeline to run the simulation each game day. Returns a world like +
+ + 028    this world, with all the various active elements updated. The optional +
+ + 029    `date` argument, if supplied, is set as the `:date` of the returned world." +
+ + 030    ([world] +
+ + 031    (g/run +
+ + 032      (m/run +
+ + 033        (k/run +
+ + 034          (w/run world))))) +
+ + 035    ([world date] +
+ + 036    (g/run +
+ + 037      (m/run +
+ + 038        (k/run +
+ + 039          (w/run world date)))))) +
+ + diff --git a/docs/cloverage/cc/journeyman/the_great_game/world/world.clj.html b/docs/cloverage/cc/journeyman/the_great_game/world/world.clj.html new file mode 100644 index 0000000..7170770 --- /dev/null +++ b/docs/cloverage/cc/journeyman/the_great_game/world/world.clj.html @@ -0,0 +1,584 @@ + + + + cc/journeyman/the_great_game/world/world.clj + + + + 001  (ns cc.journeyman.the-great-game.world.world +
+ + 002    "Access to data about the world") +
+ + 003   +
+ + 004  ;;; The world has to work either as map or a database. Initially, and for +
+ + 005  ;;; unit tests, I'll use a map; later, there will be a database. But the +
+ + 006  ;;; API needs to be agnostic, so that heirarchies which interact with +
+ + 007  ;;; `world` don't have to know which they've got - as far as they're concerned +
+ + 008  ;;; it's just a handle. +
+ + 009   +
+ + 010  (def default-world +
+ + 011    "A basic world for testing concepts" +
+ + 012    {:date 0 ;; the age of this world in game days +
+ + 013     :cities +
+ + 014     {:aberdeen +
+ + 015      {:id :aberdeen +
+ + 016       :supplies +
+ + 017       ;; `supplies` is the quantity of each commodity added to the stock +
+ + 018       ;; each game day. If the price in the market is lower than 1 (the +
+ + 019       ;; cost of production of a unit) no goods will be added. +
+ + 020       {:fish 10 +
+ + 021        :leather 5} +
+ + 022       :demands +
+ + 023       ;; `stock` is the quantity of each commodity in the market at any +
+ + 024       ;; given time. It is adjusted for production and consumption at +
+ + 025       ;; the end of each game day. +
+ + 026       {:iron 1 +
+ + 027        :cloth 10 +
+ + 028        :whisky 10} +
+ + 029       :port true +
+ + 030       :prices +
+ + 031       ;; `prices`: the current price (both buying and selling, for simplicity) +
+ + 032       ;; of each commodity in the market. Updated each game day based on current +
+ + 033       ;; stock. +
+ + 034       {:cloth 1 +
+ + 035        :fish 1 +
+ + 036        :leather 1 +
+ + 037        :iron 1 +
+ + 038        :whisky 1} +
+ + 039       :stock +
+ + 040       ;; `stock` is the quantity of each commodity in the market at any +
+ + 041       ;; given time. It is adjusted for production and consumption at +
+ + 042       ;; the end of each game day. +
+ + 043       {:cloth 0 +
+ + 044        :fish 0 +
+ + 045        :leather 0 +
+ + 046        :iron 0 +
+ + 047        :whisky 0} +
+ + 048       :cash 100} +
+ + 049      :buckie +
+ + 050      {:id :buckie +
+ + 051       :supplies +
+ + 052       {:fish 20} +
+ + 053       :demands +
+ + 054       {:cloth 5 +
+ + 055        :leather 3 +
+ + 056        :whisky 5 +
+ + 057        :iron 1} +
+ + 058       :port true +
+ + 059       :prices {:cloth 1 +
+ + 060                :fish 1 +
+ + 061                :leather 1 +
+ + 062                :iron 1 +
+ + 063                :whisky 1} +
+ + 064       :stock {:cloth 0 +
+ + 065               :fish 0 +
+ + 066               :leather 0 +
+ + 067               :iron 0 +
+ + 068               :whisky 0} +
+ + 069       :cash 100} +
+ + 070      :callander +
+ + 071      {:id :callander +
+ + 072       :supplies {:leather 20} +
+ + 073       :demands +
+ + 074       {:cloth 5 +
+ + 075        :fish 3 +
+ + 076        :whisky 5 +
+ + 077        :iron 1} +
+ + 078       :prices {:cloth 1 +
+ + 079                :fish 1 +
+ + 080                :leather 1 +
+ + 081                :iron 1 +
+ + 082                :whisky 1} +
+ + 083       :stock {:cloth 0 +
+ + 084               :fish 0 +
+ + 085               :leather 0 +
+ + 086               :iron 0 +
+ + 087               :whisky 0} +
+ + 088       :cash 100} +
+ + 089      :dundee {:id :dundee} +
+ + 090      :edinburgh {:id :dundee} +
+ + 091      :falkirk +
+ + 092      {:id :falkirk +
+ + 093       :supplies {:iron 10} +
+ + 094       :demands +
+ + 095       {:cloth 5 +
+ + 096        :leather 3 +
+ + 097        :whisky 5 +
+ + 098        :fish 10} +
+ + 099       :port true +
+ + 100       :prices {:cloth 1 +
+ + 101                :fish 1 +
+ + 102                :leather 1 +
+ + 103                :iron 1 +
+ + 104                :whisky 1} +
+ + 105       :stock {:cloth 0 +
+ + 106               :fish 0 +
+ + 107               :leather 0 +
+ + 108               :iron 0 +
+ + 109               :whisky 0} +
+ + 110       :cash 100} +
+ + 111      :glasgow +
+ + 112      {:id :glasgow +
+ + 113       :supplies {:whisky 10} +
+ + 114       :demands +
+ + 115       {:cloth 5 +
+ + 116        :leather 3 +
+ + 117        :iron 5 +
+ + 118        :fish 10} +
+ + 119       :port true +
+ + 120       :prices {:cloth 1 +
+ + 121                :fish 1 +
+ + 122                :leather 1 +
+ + 123                :iron 1 +
+ + 124                :whisky 1} +
+ + 125       :stock {:cloth 0 +
+ + 126               :fish 0 +
+ + 127               :leather 0 +
+ + 128               :iron 0 +
+ + 129               :whisky 0} +
+ + 130       :cash 100}} +
+ + 131     :merchants +
+ + 132     {:archie {:id :archie +
+ + 133               :home :aberdeen :location :aberdeen :cash 100 :capacity 10 +
+ + 134               :known-prices {} +
+ + 135               :stock {}} +
+ + 136      :belinda {:id :belinda +
+ + 137                :home :buckie :location :buckie :cash 100 :capacity 10 +
+ + 138                :known-prices {} +
+ + 139                :stock {}} +
+ + 140      :callum {:id :callum +
+ + 141               :home :callander :location :calander :cash 100 :capacity 10 +
+ + 142               :known-prices {} +
+ + 143               :stock {}} +
+ + 144      :deirdre {:id :deidre +
+ + 145                :home :dundee :location :dundee :cash 100 :capacity 10 +
+ + 146                :known-prices {} +
+ + 147                :stock {}} +
+ + 148      :euan {:id :euan +
+ + 149             :home :edinbirgh :location :edinburgh :cash 100 :capacity 10 +
+ + 150               :known-prices {} +
+ + 151               :stock {}} +
+ + 152      :fiona {:id :fiona +
+ + 153              :home :falkirk :location :falkirk :cash 100 :capacity 10 +
+ + 154              :known-prices {} +
+ + 155              :stock {}}} +
+ + 156     :routes +
+ + 157     ;; all routes can be traversed in either direction and are assumed to +
+ + 158     ;; take the same amount of time. +
+ + 159     [[:aberdeen :buckie] +
+ + 160      [:aberdeen :dundee] +
+ + 161      [:callander :glasgow] +
+ + 162      [:dundee :callander] +
+ + 163      [:dundee :edinburgh] +
+ + 164      [:dundee :falkirk] +
+ + 165      [:edinburgh :falkirk] +
+ + 166      [:falkirk :glasgow]] +
+ + 167     :commodities +
+ + 168     ;; cost of commodities is expressed in person/days; +
+ + 169     ;; weight in packhorse loads. Transport in this model +
+ + 170     ;; is all overland; you don't take bulk cargoes overland +
+ + 171     ;; in this period, it's too expensive. +
+ + 172     {:cloth {:id :cloth :cost 1 :weight 0.25} +
+ + 173      :fish {:id :fish :cost 1 :weight 1} +
+ + 174      :leather {:id :leather :cost 1 :weight 0.5} +
+ + 175      :whisky {:id :whisky :cost 1 :weight 0.1} +
+ + 176      :iron {:id :iron :cost 1 :weight 10}}}) +
+ + 177   +
+ + 178  (defn actual-price +
+ + 179    "Find the actual current price of this `commodity` in this `city` given +
+ + 180    this `world`. **NOTE** that merchants can only know the actual prices in +
+ + 181    the city in which they are currently located." +
+ + 182    [world commodity city] +
+ + 183    (-> world :cities city :prices commodity)) +
+ + 184   +
+ + 185  (defn run +
+ + 186    "Return a world like this `world` with only the `:date` to this `date` +
+ + 187    (or id `date` not supplied, the current value incremented by one). For +
+ + 188    running other aspects of the simulation, see [[the-great-game.world.run]]." +
+ + 189    ([world] +
+ + 190     (run world (inc (or (:date world) 0)))) +
+ + 191    ([world date] +
+ + 192     (assoc world :date date))) +
+ + diff --git a/docs/cloverage/index.html b/docs/cloverage/index.html index 6901d4d..25f95c7 100644 --- a/docs/cloverage/index.html +++ b/docs/cloverage/index.html @@ -15,44 +15,113 @@ TotalBlankInstrumented - the-great-game.gossip.gossip
cc.journeyman.the-great-game.agent.agent
3
+100.00 % +
3
+100.00 % +4553 + + + cc.journeyman.the-great-game.buildings.module
2
+100.00 % +
2
+100.00 % +8162 + + + cc.journeyman.the-great-game.buildings.rectangular
106
36
+74.65 % +
24
1
6
+80.65 % +1502531 + + + cc.journeyman.the-great-game.gossip.gossip
5
103
4.63 %
5
34
-12.82 % -66539 + style="width:87.5%; + float:left;"> 35
+12.50 % +73740 - the-great-game.gossip.news-items
477
37
-92.80 % + cc.journeyman.the-great-game.gossip.news-items
510
151
+77.16 %
96
101
8
5
-95.41 % -25631109 + style="width:21.58273381294964%; + float:left;"> 30 +78.42 % +34541139 - the-great-game.merchants.markets
191
cc.journeyman.the-great-game.holdings.holding
3
18
+14.29 % +
3
4
+42.86 % +4637 + + + cc.journeyman.the-great-game.location.location
4
22
+15.38 % +
4
10
+28.57 % +45714 + + + cc.journeyman.the-great-game.merchants.markets
192
7
-96.46 % +96.48 %
41
84844 - the-great-game.merchants.merchant-utils
cc.journeyman.the-great-game.merchants.merchant-utils
197
106772 - the-great-game.merchants.merchants
cc.journeyman.the-great-game.merchants.merchants
2
69
-2.82 % + style="width:97.26027397260275%; + float:left;"> 71
+2.74 %
2
28316 - the-great-game.merchants.planning
cc.journeyman.the-great-game.merchants.planning
258
1591185 - the-great-game.merchants.strategies.simple
cc.journeyman.the-great-game.merchants.strategies.simple
5
600
-0.83 % + style="width:99.18433931484502%; + float:left;"> 608
+0.82 %
5
1736124 - the-great-game.objects.container
cc.journeyman.the-great-game.objects.container
2
100.00 % @@ -139,48 +208,86 @@ 1112 - the-great-game.objects.game-object
cc.journeyman.the-great-game.objects.game-object
3
2
-60.00 % + style="width:50.0%; + float:left;"> 3
+50.00 %
3
2
-60.00 % -1925 + style="width:50.0%; + float:left;"> 3
+50.00 % +2126 - the-great-game.time
240
1
-99.59 % + cc.journeyman.the-great-game.playroom
222
168
+56.92 %
59
4
3
10
+41.18 % +721217 + + + cc.journeyman.the-great-game.time
236
5
+97.93 % +
58
1
1
-100.00 % +98.33 % 1442160 - the-great-game.utils
69
-100.00 % + cc.journeyman.the-great-game.utils
88
15
+85.44 %
19
-100.00 % -35319 + style="width:92.5925925925926%; + float:left;"> 25
2
+92.59 % +61827 - the-great-game.world.location
cc.journeyman.the-great-game.world.heightmap
11
295
+3.59 % +
9
62
+12.68 % +1591671 + + + cc.journeyman.the-great-game.world.location
73
37417 - the-great-game.world.routes
cc.journeyman.the-great-game.world.mw
1
+100.00 % +
1
+100.00 % +711 + + + cc.journeyman.the-great-game.world.routes
123
55242 - the-great-game.world.run
cc.journeyman.the-great-game.world.run
3
39220 - the-great-game.world.world
cc.journeyman.the-great-game.world.world
420
-66.55 % +58.91 % -68.63 % +61.63 % diff --git a/docs/codox/A-generic-planning-algorithm-for-craftworker-npcs.html b/docs/codox/A-generic-planning-algorithm-for-craftworker-npcs.html new file mode 100644 index 0000000..b5e93fa --- /dev/null +++ b/docs/codox/A-generic-planning-algorithm-for-craftworker-npcs.html @@ -0,0 +1,70 @@ + +A Generic Planning Algorithm for craftworker NPCs

A Generic Planning Algorithm for craftworker NPCs

+

Preamble

+

The Great Game requires a number of different crafts to be performed, both because the economy depends on the products of those crafts and to provide verisimilitude and set dressing. Some of those crafts, the relations between them, and the progression within them are set out in Populating a game world.

+

For the purposes of planning work, only Master craftspeople are considered.

+

A Master craftsperson has

+
    +
  1. a house and appropriate workshop, within a settlement;
  2. +
  3. zero or more apprentices;
  4. +
  5. zero or more journeyman;
  6. +
  7. a spouse, who is usually of lower status;
  8. +
  9. zero of more coresident children;
  10. +
  11. zero or more coresident non-working parents/elders.
  12. +
+

There are limits to the number of apprentices and journeymen a master may take on, essentially based on demand in the local market. The master is responsible for housing and feeding all of the household including apprentices and journeymen, and for obtaining sufficient craft supplies. All craft work done in the household belongs to the master.

+

Apprentices are definitely not paid. Journeymen should be paid, but this is a detail to ignore until we have other things working.

+

Journeymen will move on from master to master from time to time — infrequently, but it will happen; and may be dismissed by masters when markets are tight. Journeymen probably learn their craft recipes — which is to say, the items and qualities of item they are able to craft — from the masters they work with. Consequently, journeymen will seek out masters with higher reputation; masters will prefer journeymen with more experience.

+

Apprentices do not move on until the end of their period of apprenticeship (16th birthday?) when they become journeymen.

+

The master will plan work in four hour sessions - essentially, a morning session and an afternoon session each day.

+

All craftspeople have regular schedules covering mealtimes, sleep, and festivals. A lower status person within the household will have regular schedules covering each of fetching water, fetching fuel wood, taking out night soil, feeding chickens, washing dishes and laundry, and so on.

+

When the master works in the workshop, all the apprentices and journeymen will also work in the workshop; when the master is engaging in recreation, they’re also engaging in recreation. What they do when the master is e.g. going to market, I haven’t yet decided.

+

Commodity items and special commissions

+

In principle all craftspeople may make both commodity items and special commission items, but in practice many crafts will be mostly commodity and a few will be almost entirely special commission (for example a diplomat doesn’t produce peace treaties prèt-à-porter); but I don’t yet have a good model of how I’m going to handle special commissions, so I’m just doing some hand waving here to say they will exist and must be handled.

+

The algorithm

+

A master craftsperson needs to keep stock of a number of things

+
    +
  1. Sufficient food for the household;
  2. +
  3. Sufficient craft materials for immediate production;
  4. +
  5. Sufficient funds to buy more food/craft materials when needed;
  6. +
  7. Commodity craft items produced;
  8. +
  9. Craft items work in progress.
  10. +
+

Choosing tasks

+

So in planning a period of work, the master has to decide:

+
    +
  1. Do I need to go to market? +
      +
    1. Is there news of a travelling merchant who buys what I produce arriving at my nearest market? -> go to market;
    2. +
    3. Is the household running low on food? -> go to market;
    4. +
    5. Is the household running low on craft materials? -> go to market;
    6. +
    +
  2. +
  3. Do I have any commissioned items to produce? -> produce commissioned items;
  4. +
  5. Should I work on commodities or take the day off? This is a throw-of-the-dice decision, influenced by +
      +
    1. Cash on hand (if there’s little, greater incentive to work);
    2. +
    3. Weather (if it’s especially good, less incentive to work);
    4. +
    5. Gossip (if there’s interesting news, less incentive to work)
    6. +
    +
  6. +
+

Commodity production

+

If the decision is to work on commodities, the next decision is what commodity item to produce.

+

For each craft recipe the master knows there will be

+
    +
  1. A list of quantities of different craft materials needed per item, for example a sword might need two kilograms of steel of a particular quality, ten kilograms of charcoal, one kilogram of timber, half a square metre of leather;
  2. +
  3. An amount of craftsperson time - for example, a standard infantry sword might take ten hours;
  4. +
  5. Memory of prices achieved by item to that recipe in the local market.
  6. +
+

The master will choose a recipe for which there are sufficient materials on hand, and which is profitable to make — the more profitable, the more likely to be selected (but I think there’s probably some furtive dice rolling under the table here too; you don’t want all the smiths in town producing infantry swords at the same time, because that would swamp the market and drive prices down).

+

When an item is started, the materials for it are removed from stock and assigned to the item, which is added to the work in progress list. The number of items that can be produced in a work session is

+
    (/ (* hours-in-session people-in-team) 
+        hours-to-produce-one-item)
+
+

At the end of the session, the integer number of items produced is removed from the work in progress queue and added to stock, and the modulus is added as :work-done to the remaining item, which is left in the work in progress queue.

+

Obviously items in the work in progress queue may need to be completed at the start of the next commodity work session.

+

Obviously, none planned at sufficient granularity to be animated unless the workplace is in the :active circle, and none of it gets actually animated unless it’s actually on camera, but the book-keeping in terms of food and craft materials consumed and of items produced must be done.

+

This implies that at least many master craftspeople must be in the :background circle, i.e. woken up once every game day to plan a work session, no matter how far away the player character is.

+
\ No newline at end of file diff --git a/docs/codox/API_Spec.html b/docs/codox/API_Spec.html new file mode 100644 index 0000000..8f32fc1 --- /dev/null +++ b/docs/codox/API_Spec.html @@ -0,0 +1,20 @@ + +API Spec (unfinished)

API Spec (unfinished)

+

If the Gossip system is ever to be deployed in practice at all, it will need to be deployed as a library add-on to someone else’s game, since in practice The Great Game will never be even nearly finished. The game engine already knows many of the things the Gossip system needs to know; that we need to define is an interface which allows Gossip, considered as a subsystem, to query the game engine.

+

My preference is still that Gossip should be written in a Lisp-like language - and, for now, in Clojure - simply because that is most comfortable to me. It needs bidirectional socket communication with the game engine, over which it sends either extensible data notation or JavaScript Object Notation, with a preference for the former.

+

Tracking what happens in the world

+

Existing game engines don’t tend to track in convenient form things which have happened off-camera - indeed, mostly, things don’t happen at all when the player isn’t present. They don’t even track much that happens when the player is present, and they usually track what they do track in fairly ad-hoc ways. So generally Gossip-as-library will have to maintain its own history of what has happened, and who knows what about what has happened; and will have to model the major life events of non-player characters happening off-camera (if this is done at all) itself.

+

Interrogating lore

+

Many games have a great deal of lore and many lore texts. It’s reasonable to expect each non-player character to know a certain amount of lore, certainly lore which is local to their home location, or relevant to their trade. In order to make that available to Gossip, you probably need to construct a searchable corpus of all the lore, which can be simply queried.

+

That obviously then needs to be filtered by what the respondent can be expected to know, but that’s a problem Gossip has to handle anyway.

+

Interrogating the map

+

get-character-location id

+

Returns the player location in the world of the character with the specified id, as at minimum a three dimensional coordinate tuple, with heading; optionally with hierarchical region ids.

+

get-potential-auditors id

+

get-potential-auditors id, volume

+

Return an ordered list of ids of characters spatially close to the character with the specified id, ordered by their likelihood of being the character addressed (i.e. preferring characters in front of the character with the specified id to those off to the side or behind, on a sort of cardioid pattern). The set is bounded by the distance at which speech is deemed to be intelligible, which may be a constant, or maybe modified by some modelling of ambient noise, or the volume of the character’s speech act.

+

get-potentially-aware id

+

get-potentially-aware id, volume

+

As above, but return a list of ids of characters within a distance in which speech may be heard but not intelligibly.

+
\ No newline at end of file diff --git a/docs/codox/Appraisal.html b/docs/codox/Appraisal.html new file mode 100644 index 0000000..e6ead9b --- /dev/null +++ b/docs/codox/Appraisal.html @@ -0,0 +1,29 @@ + +Appraisal (unfinished)

Appraisal (unfinished)

+

What is Appraisal

+

There’s an thing that all non player characters can do, which varies greatly from person to person, and which is of particular importance to merchants, and that is appraisal.

+

Each category of goods has different dimensions of quality. A sword may be evaluated, for example, on

+ + + + + + + + + + + + + +
Dimension Better is Ease of appraisal
Hardness More Difficult
Toughness More Difficult
Wear Less Intermediate
Weight There’s a sweet spot, but it’s low Easy
Length Judgement call Easy
Decoration/Showiness Judgement call Intermediate
Workmanship Better Intermediate
+

A person learns to appraise the qualities of a sword by having direct experience of swords with a range of values for the particular quality. A person who’s only ever handled one sword does not know whether that sword heavy or light, pristine or worn. However, once a person has handled a dozen swords of different weights, they’ll have some idea of what weight an average sword is, even if their idea may actually be a little off. Weight and length are easy to assess.

+

Similarly, once someone has handled a few dozen swords with different degrees of wear, will have an idea of how many chips, how much corrosion or pitting, is normal. Wear is harder to assess, but it doesn’t need particular techniques or skills to assess, just observation. To assess hardness, you really need to have sharpened the blade and then used it to the extent that it needs sharpening again, but if you’ve handled a lot of blades of varying qualities you may associate patterns in the steel, such as pattern welding, damascus steel, or a hamun, or particular markers’ marks, with varying hardnesses. Toughness is even harder to assess (without actually chipping or breaking the blade) and is really going to come down to recognising either high quality steels or particular makers’ marks.

+

Developing appraisal skill

+

So: how does one gain experience? I’m going to assume that anyone who’s bought a sword has handled it before making the choice. That anyone who’s survived on the winning side f a battle unwounded will also have handled eight of each type of weapon used, for each such battle (the victors will have the pick of the spoils on the battlefield). That a weapon smith has handled sixteen for each year they’ve been working. And possibly that a master weapon smith will at least examine more weapons in a year than a journeyman, who will at least examing more than an apprentice. But, essentially, appraisal skill develops with exposure to items in the particular category. The exact mechanism for tracking this I’m unsure of, because there is a tradeoff between richness of records and data compactness, and this game looks like getting rather big.

+

Of course, some people may be more observant than others, so it’s possible that some people may gain appraisal skill on the basis of less exposure than others. But at this moment that’s not a thing I’m planning to model.

+

What does appraisal skill buy you?

+

In any category of goods, some individual items are better than others, and this difference may be significant. A person with good appraisal skill will recognise this difference. So a person with good skills, offered two items at the same price, will be able to select the better one; if bargaining for an item, will be prepared to offer a higher price for the better one; if selling items, will be prepared to sell the better one only for a higher price.

+

Price arbitrage is how a static merchant makes money.

+
\ No newline at end of file diff --git a/docs/codox/Baking-the-world.html b/docs/codox/Baking-the-world.html index bd493e8..1e215e7 100644 --- a/docs/codox/Baking-the-world.html +++ b/docs/codox/Baking-the-world.html @@ -1,40 +1,41 @@ -Baking the world

Baking the world

-

Wednesday, 8 May 2019

-

Devogilla’s Bridge in Dumfries, early foourteenth century

+Baking the world

Baking the world

+

Wednesday, 8 May 2019

+

Devorgilla's Bridge in Dumfries, early fourteenth century

+

Devorgilla’s Bridge in Dumfries, early fourteenth century. This clearly shows how a genetic buildings approach to bridges can be made to work: a single element is repeated to span the necessary distance. That element can be stretched vertically and laterally to match the location, and can be rendered in different stone finishes to match local geology.

In previous posts, I’ve described algorithms for dynamically populating and dynamically settling a game world. But at kilometre scale (and I think we need a higher resolution than that - something closer to hectare scale), settling the British Isles using my existing algorithms takes about 24 hours of continuous compute on an eight core, 3GHz machine. You cannot do that every time you launch a new game.

So the game development has to run in four phases: the first three phases happen during development, to create a satisfactory, already populated and settled, initial world for the game to start from. This is particularly necessary if hand-crafted buildings and environments are going to be added to the world; the designers of those buildings and environments have to be able to see the context into which their models must fit.

-

Phase one: proving - the procedural world

+

Phase one: proving - the procedural world

I’m going to call the initial phase of the game run - the phase which takes place before the quest team write their quests and the art department adds their hand-crafted models - ‘proving’, as when dough has been been made and set aside to rise.

Then, when the landscape has developed - the areas of forest, scrub, open meadow, moorland, savanah and desert are determined, the rivers plotted, the settlers moved in, their trades determined and their settlements allocated, the roadways which link settlements routed, river crossings and ports defined - the proving process ends, and the world is turned over to the plot-writers, quest builders and designers, for a process we can see as analogous to kneading.

But, before going there, to summarise the proving stage. The inputs are:

    -
  1. A raster height map (although this could be randomly generated using any one of many fractal algorithms) - this probably uses ideas from tessellated multi-layer height map;
  2. -
  3. Optionally, a raster rainfall map at 1km resolution (although my personal preference is that this should be generated procedurally from the height map).
  4. +
  5. A raster height map (although this could be randomly generated using any one of many fractal algorithms) - this probably uses ideas from tessellated multi-layer height map;
  6. +
  7. Optionally, a raster rainfall map at 1km resolution (although my personal preference is that this should be generated procedurally from the height map).

The outputs are

    -
  1. A vector drainage map (rivers);
  2. -
  3. A raster biome map at roughly 1 km resolution (it might be anything between hectare resolution and 1Km resolution,  but obviously higher resolution takes more storage);
  4. -
  5. A database of settlers and their settlements, such that the settlements have x,y co-ordinates;
  6. -
  7. A vector road map.
  8. +
  9. A vector drainage map (rivers);
  10. +
  11. A raster biome map at roughly 1 km resolution (it might be anything between hectare resolution and 1Km resolution,  but obviously higher resolution takes more storage);
  12. +
  13. A database of settlers and their settlements, such that the settlements have x,y co-ordinates;
  14. +
  15. A vector road map.

In this sense, the ‘biome map’ is just the end state of a Microworld run. The ‘biomes’ include things like ‘forest’, ‘scrub’, ‘heath’, ‘pasture’, but they may also include human settlement, and even settlement by different cultural groups.

This gives us all we need to vegetate and furnish the world. When rendering each square metre we have

    -
  1. The x,y coordinates, obviously;
  2. -
  3. The altitude, taken from the height map;
  4. -
  5. The biome, taken from the biome map;
  6. -
  7. The biomes of adjacent cells in the biome map;
  8. -
  9. The proximity of the nearest watercourse;
  10. -
  11. The proximity of the nearest road or pathway;
  12. -
  13. Whether we are inside, or outside, a settlement (where for these purposes, ‘settlement’ includes enclosed field), and if inside, what type of settlement it is.
  14. +
  15. The x,y coordinates, obviously;
  16. +
  17. The altitude, taken from the height map;
  18. +
  19. The biome, taken from the biome map;
  20. +
  21. The biomes of adjacent cells in the biome map;
  22. +
  23. The proximity of the nearest watercourse;
  24. +
  25. The proximity of the nearest road or pathway;
  26. +
  27. Whether we are inside, or outside, a settlement (where for these purposes, ‘settlement’ includes enclosed field), and if inside, what type of settlement it is.

Given these parameters, and using the x, y coordinates as seed of a deterministic pseudo-random number generator, we can generate appropriate vegetation and buildings to render a believable world. The reason for pulling adjacent biomes into the renderer is that sharp transitions from one biome to another - especially ones which align to a rectangular grid - rarely exist in nature, and that consequently most transitions from one biome to another should be gradual.

Note that proving, although extremely compute intensive, is not necessarily a one-time job. If the designers aren’t satisfied with the first world to emerge from this process, they can run it again, and again, to generate a world with which they are satisfied. It’s also possible to hand-edit the output of proving, if needed.

But now, designers and story-writers can see the world in which their creations will be set.

-

Phase two: kneading - making the world fit our needs

+

Phase two: kneading - making the world fit our needs

Enough of proving, let’s get on to kneading.

Hand-designed buildings and environments are likely to be needed, or at least useful, for plot; also, particularly, very high status buildings are probably better hand designed. I’m inclined to think that less is more here, for two reasons:

You cannot hand design a very large world, it’s just impossible. How CD Project Red managed with Witcher 3 I don’t know, since I understand that is largely hand designed; but that was a very large team, and even so it isn’t a world on the scale I’m envisaging.

@@ -45,10 +46,11 @@

However, in some places the designers and story writers will want, for plot reasons and to create iconic environments, to add models. I’m inclined not to over do this, both for reasons of development effort and for reasons of storage cost, but they will. Very high status buildings may need to be unique and distinctive, for example. These need to be designed and their locations and spatial dimensions added to the database, so that the models can be rendered in the right positions (and, critically, procedurally generated models can be omitted in those positions!)

Story and quest writers will also want characters for their plots. While there’s no reason why writers cannot add entirely new characters to the database, there’s no reason why they cannot incorporate characters generated in the settlement phase into the story; for this reason, characters need to be able to be tagged in the database as plot characters, and with what quests/elements of the plot they’re associated.

This allows a mechanism to prevent a plot character from being killed by another non-player character, or dying of disease or starvation, before the plot elements in which they feature have been completed.

-

Phase three: baking - making it delicious

+

Phase three: baking - making it delicious

Once the world has been populated, settled, vegetated, the story has been written, the models built, the quests designed, there is probably a process of optimisation - stripping out things which aren’t needed at play time, streamlining things that are - before you have a game ready to ship; but really I haven’t yet given that much thought.

-

Phase four: eating!

-

At the end, though, you have a game, and a player plays it. How much of the dynamic, organic life that brought the game through proving continues on into the playing phase? If the gossip ideas are to work, if unscripted, non-plot-related events (as well as scripted, plot related events) are to happen while the player plays, if news of these events is to percolate through the world and reach the player in organic, unscripted ways, if a lot of the emergent gameplay I’m imagining is to work, then quite a lot of the dynamic things must be happening.

+

Phase four: eating!

+

At the end, though, you have a game, and a player plays it. How much of the dynamic, organic life that brought the game through proving continues on into the playing phase? If the gossip ideas are to work, if unscripted, non-plot-related events (as well as scripted, plot related events) are to happen while the player plays, if news of these events is to percolate through the world and reach the player in organic, unscripted ways, if a lot of the emergent gameplay I’m imagining is to work, then quite a lot of the dynamic things must be happening.

Of course, part of this depends on the length of ‘game world time’ is expected to elapse in the course of one play through of the game. If it’s less than a year, then you don’t need children dynamically being born, and characters dynamically growing older; but if more, then you do. Similarly, you don’t need a real simulation of trading to dynamically drive prices in markets, but for a fun trading sub-game to emerge, you probably do, and if you are using merchants as news spreading agents the additional compute cost is not high.

And I understand that many game writers will shudder at the thought that a war might (or might not) start in the middle of their plot, that a battle might, one time in a thousand, take place right where they’ve plotted some significant encounter. Most modern video games are essentially just very complicated state machines: if you make this sequence of choices, this outcome will happen, guaranteed. Or else they’re puddles of random soup, where everything that happens is more or less driven by a random number generator. What I’m envisaging is something quite different: a world in which traders gonna trade, robbers gonna rob, lovers gonna love, scandal-mongers gonna make scandal, organically and dynamically whether the player is there or not, and news of these events will filter through to the player through the gossip network also organically and dynamically.

-

A world, in short, through which no two runs will ever be the same, in which interesting bits of story will happen with no-one directing or scripting them. And for that to work, some of the same dynamic processes that drove the proving phase have to continue into the eating phase.

\ No newline at end of file +

A world, in short, through which no two runs will ever be the same, in which interesting bits of story will happen with no-one directing or scripting them. And for that to work, some of the same dynamic processes that drove the proving phase have to continue into the eating phase.

+
\ No newline at end of file diff --git a/docs/codox/Biomes_and_ecology.html b/docs/codox/Biomes_and_ecology.html new file mode 100644 index 0000000..f0bd159 --- /dev/null +++ b/docs/codox/Biomes_and_ecology.html @@ -0,0 +1,66 @@ + +Biomes and ecology (unfinished)

Biomes and ecology (unfinished)

+

The motivation for this document was to explain the mulberry trees in the Tcha valley, and think about why Tchahua is especially a centre for the silk trade

+

Broader geography

+

The broader geography of the world is not a matter for this document, but TODO: there isn’t yet a document which usefully describes it, and there needs to be.

+

Biomes relevant at this stage

+

1. Steppe

+

The centre of the continent is the steppe; it is generally too arid for forest growth, and is therefore scrub and grassland. There is one principal river system, which feeds into a marshland in the south, from which the water then goes underground beneath the limestone plateau to become the Tcha and Sind rivers. In late summer there’s little water in the river, and few other waterholes. Antelope, camels, horses, goats, possibly sheep are native to the steppe, and there are probably something like leopards which predate on them, but I haven’t fleshed it out.

+

Big dragons don’t hunt on the steppe because they can’t take off from flat ground, but smaller dragons may do so.

+

Settled by the steppe tribes, who are nomadic herders, extremely warlike but not technically highly developed. They are the game world’s principle horse breeders. Basically in the game as I’m working on it at present, the player cannot go north across the steppe because the steppe tribes are too hostile.

+

A single major road, the Caravan Road, runs north to south across the steppe. There were in the past fortified caravanserrais along the length of the road, established and protected by Hans’hua, but they have been progressively overrun and destroyed by the steppe tribes and are now ruinous. Only one remains: the North Inn, just below the northern slope of the plateau. There is some limited horticulture on land close to the South Inn, supplying markets in Hans’hua.

+

2. Plateau

+

The limestone plateau runs along the whole of the southern edge of the steppe, from the western massif to the rim of the crater which forms The Great Place. It is a landscape of clints and grykes, on which nothing grows, and on which there is no water. It is about four day’s journey by fast horse from north to south. The caravan road crosses the plateau from the North Inn to another caravanserrai, the South Inn, located in the north end of the Tcha valley. Because of the dense chaotic pattern of clints and grykes and the lack of accessible water, it is effectively impossible to cross the plateau other than by the caravan road, or by another path to the extreme east of the plateau, where it abuts the mountains of the Rim.

+

2.1 Hans’hua

+

There is one city, Hans’hua, on the caravan road about half way across the plateau, where wind-pumps lift water from the underground river. Apart from this one city, nothing lives on the plateau. Migrating birds cross it, and that is all.

+

The city is small, walled, and run as an extreme neoliberal oligarchy; the city’s main industry is maintaining the wind pumps, and its entire income is from tolls on caravans passing along the caravan road. This has been, and is still, extremely lucrative, but it is obvious both to the long distance merchants and to the oligarchs that the new ships are going to make the caravans too slow, too risky and too expensive to compete, and that as more ships are built, traffic on the caravan road will dwindle.

+

3. Massif

+

There’s a granite intrusion which forms the entire western coast of the continent. It’s geologically old and consequently the hills, though high, are rounded rather than jagged; at the southern end of the range (which is the only part that’s in the least fleshed out yet) they’re not snow covered in summer. As the prevailing winds are westerly, this massif intercepts most of the rain, which is why the steppe is arid.

+

Consequently it’s pretty thoroughly forested, and the southern parts of it are mainly broadleaf forests including high quality hardwoods and many fruiting trees. Understory typical of mediterranean littoral forests, about which I don’t really know enough.

+

Deer, cattle, pigs, wolves, leopards, badgers, squirrels… masses of birds of all appropriate types.

+

Because it’s an old granite intrusion, the soil in the valleys is largely clay. There are mineral rich veins with a considerable range of minerals, but, obviously, not all in the same place.

+

Settled by the Western Clans, a negroid people living mainly in small isolated villages in the forest, with mostly limited agriculture.

+

3.1 Northern massif

+

I haven’t yet fleshed this out, but there are probably permanent snows and the forests are probably coniferous. It’s my current working assumption that the new great ships are built from old growth conifers, taken from forests in the northern massif; but as I say this is not yet fleshed out.

+

The northern culture have developed very high quality ceramics using clay from the massif, including stonewares and porcelaines. I think the same clays also exist in the south of the massif, but the technology for producing high quality ceramics does not exist there. The northerners are also making high quality steels from magnetite and haematite from the massif. Whether these ores exist in the south I don’t yet know.

+

3.2 Dor

+

The northernmost of the western clans, the Dor, live in the central massif north of Andale, but apart from the fact that they exist and they’re there, I don’t yet really know much.

+

3.3 Andale

+

The river An rises in the east of the massif near the south-west corner of the steppe, west of where the village and market of Dawnhold now stand, and flows more or less due westward. There are two major drops in the river’s course, the upper a day’s travel east of Silverhold, which is an actual fall of at least six metres, and the lower at Anghold. Between Anghold and Silverhold the river is navigable by small shallow draught boats; west of Anghold it is navigable down to the sea at Anmouth.

+

There are freshwater and migratory fish in the river, and fishing is a source of protein and livelihood the whole length of the valley.

+

The valley is largely forested. Apart from wild animals, domestic cattle and pigs are herded in the forest. Trees include alder, almond, apple, apricot, ash, beech, birch, cherry, chestnut, hazel, holly, lime, maple, mulberry, oak, orange, pear, walnut, yew.

+
3.3.1 Dawnhold
+

Dawnhold isn’t strictly geographically in Andale — it’s east of, on the steppe side of, the watershead, but it marks the eastern border of the lands settled by clan An. There’s an annual market, a village, and a garrisoned fortification to deter raids by the steppe tribes.

+
3.3.2 Silverhold
+

Small town serving the only significant silver mine in the world. A tributary flows in from the north here, but I know nothing about it yet. There is a major fortification/refinery/treasury. All around Silverhold, right up to the headwaters of the An and right down to Anghold, the valley is forested with only small clearings round villages, which are mainly close to the river.

+

Many other metals — certainly inluding lead, tin, and small quantities of gold, probably not copper — come out of the mines at Silverhold.

+

The An produce enough ferrous metals for their own tools and weapons, but their iron smelting technology is not advanced and they don’t export iron or iron products. They produce eathernware ceramics for domestic consumption. They produce leather and linen, and textiles from nettle fibres. They produce timber, which is their principal building material, but they don’t export it. In practice their major export is silver coinage.

+
3.3.3 Longwater
+

Longwater is a long, narrow lake, like Loch Lomond, on a tributary which flows into the An from the south, joining upstream from Anghold. There is no major nucleated settlement on Longwater, but there are sufficient small villages and hamlets on its banks to form an identifiable settlement cluster. Small boats can make it downstream from Longwater from the An and back, probably with some degree of portage around rapids. There’s a pass over from the south of the Longwater valley to Gor territory, but it’s high, difficult, and not much used. The whole of the Longwater valley is broadleaf forest.

+
3.3.4 Anghold
+

There’s a small town, market and fortification — Anghold — on the south bank of the An, just above first cataract, where boats are portaged up from the lower river to the middle reach. Downstream from Anghold the river is wider, slower and more meandering, with marshy banks. The valley west of Anghold, especially on the southern side, is also more populated, with more of the forest cleared and more arable agriculture.

+
3.3.5 Anmouth
+

The An meets the sea at Anmouth, where there is a deep harbour at a bend in the river just east of a long estuary, There is a bar, making it dangerous to enter the harbour in bad weather, and the whole estuary is pretty exposed to western storms, although there may be some islands providing some shelter for emergency anchorages — I don’t have that level of detail yet. Certainly the big new ships do not yet call in here, but could.

+

There are farming and sea-fishing villages down both sides of the estuary. There is no tradition of ship building, however.

+

3.4 Gor

+

Clan Gor occupy the south-western peninsula of the continent, and the south slope of the massif, east almost as far as the Tcha valley. Their land is forested with a similar mix of trees to Andale. They have no major rivers, but several minor ones. They live mainly in coastal villages, and sea fishing is a major economic activity. They have no deep water ports.

+

In addition they do mine iron, and they have exported swords, but the market for their swords is being undercut by better crucible steel swords from the north now being imported into the Cities of the Coast by the new ships. Similarly, the Gor used to export earthenware, but that too is now being undercut by stonewares and porcelaines from the north.

+

Because of a history of being victims of raiding from the Cities of the Coast, the Gor maintain a fortified eastern border along the line of hills to the west of the Tcha valley. Nevertheless they have mostly good trading relationships with Tchahua. In particular they export large quantities of raw and spun silk, and some woven silk cloth, to Tchahua.

+

I don’t yet have nearly a clear enough picture of the organisation and layout of the Gor lands, but their major stronghold and administrative centre must be to the east. While they traditionally had the communist and democratic culture of the other Western Clans, one family have become dominant and have become effectively hereditary leaders, influenced by the cultures to their east. However the leading family do not self-identify as aristons.

+

4. Coast

+

“The Coast” is the name given to the southern littoral of the continent, west of the Great Place and east of the Massif. It’s limestone, with deeply cut, steep sided valleys separated by high, arid uplands, with scrubby vegetation, grazed by domestic sheep and both domestic and wild goats.

+

The native culture were peaceable, communistic agriculturalists, not greatly different from the Western Clans. However some several hundred years ago they were invaded by a warrior group from the steppe tribes, who established themselves as a military aristocracy — the Aristae — and started to build cities — and impose taxes onto the peasantry, forcing them into a more or less cash oriented economy.

+

The valleys were once forested, but the central valleys, which were in any case rather dryer and where the Aristae first settled and established cities, are now mostly cleared, and are a mix of pastoral and arable, with considerable viticulture.

+

4.1 Tcha valley

+

The Tcha is the westernmost — and largest — river of the coast. It emerges from under the plateau at a pool under the South Tower marking the southern limit of Hans’hua territory and runs south more or less along the divide between the granite to the west and the limestone to the east. It is still largely forested, partly because it is relatively recently occupied by the Aristae, but partly because of the growth of the silk industry. This has led to some forested areas, especially near the navigable reaches of the river, being converted into mulberry orchards. However, there’s still a great deal of mixed forest, and the majority of mulberry leaves for feeding to silk worms are gathered from natural forest.

+

A road branches off from the main Caravan Road at the South Inn and runs down the eastern side of the valley, to a ferry across the Sind river, where it joins the Tcha as a tributary, at the village helpfully known as Sind Ferry, and thence to Tchahua.

+

Mulberries, by-products of the silk industry, are used in the production of brandy. Mulberry wine is produced in villages in the forest, and transported down river to a distillery at Sind Ferry, where it is distilled. Some mulberry wine may be sold in Tchahua for drinking as wine (and it is certainly drunk in the villages), but it is generally considered inferior to grape wine.

+

There is some arable and mixed agriculture, mainly towards the southern end of the valley on the western (less steep) side, although this side is also largely forested.

+
4.1.1 Tchahua
+

The city of Tchahua lies on the east bank of the river at the head of its estuary, and has deep water — the only really usable deep water port on the coast, being not only the largest river but also the least silted. Until quite recently it had been a small provincial silk weaving city, nominally independent but in fact paying tribute to both Sinhua to its east and the Gor to its west, in order to avoid being formally conquered by either.

+

There’s a multi-span bridge here — I think a pontoon bridge — of which the eastern most span is a drawbridge which can be lifted into a fortified gateway on the eastern (Tchahua) shore. There is a fishing industry, but as the eastern side

+

Industries are silk weaving and dying, and fishing. Very recently, a new deep water quay has been constructed and the first large ships have begun to call. It is obvious that the city is going to become much more important as a strategic market and transport hub, but that has only just begun to have effect.

+

4.2 Sind valley

+

4.2.1 Sinhua

+
\ No newline at end of file diff --git a/docs/codox/Building_on_microworld.html b/docs/codox/Building_on_microworld.html new file mode 100644 index 0000000..0f886ee --- /dev/null +++ b/docs/codox/Building_on_microworld.html @@ -0,0 +1,8 @@ + +Building on Microworld

Building on Microworld

+

In Settling a Game World I intended that a world should be populated by setting agents - settlers - to explore the map and select places to settle according to particular rules. In the meantime, I’ve built MicroWorld, a rule driven cellular automaton which makes a reasonably good job of modelling human settlement. It works, and I now plan to use it, as detailed in this note; but there are issues.

+

First and foremost, it’s slow, and both processor and memory hungry. That means that at continent scale, a cell of one kilometre square is the minimum size which is really possible, which isn’t small enough to create a settlement map of the density that a game will need. Even with 1 km cells, even on the most powerful machines I have access to, a continent-size map will take many days to run.

+

Of course it would be possible to do a run at one km scale top identify areas which would support settlement, and then to do a run on a ten metre grid on each of those areas to more precisely plot settlement. That’s an idea which I haven’t yet explored, which might prove fruitful.

+

Secondly, being a cellular automaton, MicroWorld works on a grid. This means that everything is grid aligned, which is absolutely not what I want! So I think the way to leverage this is to use MicroWorld to establish which kilometre square cells om the grid should be populated (and roughly with what), and then switch to ad hoc code to populate those cells.

+
\ No newline at end of file diff --git a/docs/codox/Canonical-dictionary.html b/docs/codox/Canonical-dictionary.html new file mode 100644 index 0000000..b0896f1 --- /dev/null +++ b/docs/codox/Canonical-dictionary.html @@ -0,0 +1,36 @@ + +Canonical dictionary for this documentation

Canonical dictionary for this documentation

+

Where a word is used in the documentation for The Great Game and its related projects, this file describes the canonical meaning of that word. This is because a lot of the concepts in play are messy and ambiguous, so that at times even I am confused by what I mean. The presence of this file is an acknowledment of this difficulty, and an implicit admission that not all the documentation is, at this stage anyway, consistent.

+

Actor

+

An actor is a thing which performs actions within the game world. Thus a tree is (almost certainly) not an actor, and things like sheep and rabbits that run about are probably not actors, but an animal which may pro-actively interact with the player character (such as a predator, or a beast of burden, or even a prey species which may flee) is an actor. In god mode, if implemented, the player can inhabit any actor within the game world.

+

Agent

+

Agent is probably just a synonym for actor. If it is different in any way, that way has not yet been determined.

+

Gossip

+

A gossip is an actor who exchanges news with other actors, even when the player character is not nearby. Thus gossips are the mechanism by which news propagates through the game world, and also the mechanism by which information degrades. Broadly:

+
    +
  1. innkeepers (and possibly some others) are gossips who do not move; rather, they gather information from gossips who do move, and all non-player characters local to the are deemed to know everything that their local innkeeper knows;
  2. +
  3. merchants (and possibly some others) are gossips who do move from place to place, and thus transfer news.
  4. +
+

See the spread of knowledge in a large game world.

+

Heightmap

+

A heightmap is a raster image of the world, such that the intensity in which an area is coloured represents the value of some variable, by default height, of that area.

+

Holding

+

A holding is a polygon ‘owned’ by an actor on which are built appropriate building units representing the actors craft and status.

+

Location

+

A location value is a sequence comprising at most the x/y coordinate location and the ids of the settlement and region (possibly hierarchically) that contain the location. If the x/y is not local to the home of the receiving agent, they won’t remember it and won’t pass it on; if any of the ids are not interesting, they won’t be passed on. So location information will degrade progressively as the item is passed along.

+

It is assumed that the :home of a character is a location in this sense.

+

Examples

+
    +
  1. [{:x 5445678 :y 9684351}]
  2. +
  3. [{:x 5445678 :y 9684351} :karalin-palace :hanshua]
  4. +
+

Merchant

+

A merchant is an actor and gossip who trades goods, and incidentally conveys news, between markets.

+

Non-player character

+

A non-player character is, for our purposes, an actor capable of engaging in conversation with the player character. Note, however, that, from a software point of view, the player character is just a special case of a non-player character.

+

Player character

+

The player character is the unique actor within the game currently controlled and inhabited by the player.

+

Route

+

A route is a pre-prepared path through the game world that an actor may take. Most actors are not constrained to follow routes, but in general routes have lower traversal cost than other terrain.

+
\ No newline at end of file diff --git a/docs/codox/Division_of_tasks_between_server_and_client.html b/docs/codox/Division_of_tasks_between_server_and_client.html new file mode 100644 index 0000000..9bedb72 --- /dev/null +++ b/docs/codox/Division_of_tasks_between_server_and_client.html @@ -0,0 +1,19 @@ + +Division of tasks between server and client

Division of tasks between server and client

+

An alternative nomentclature I may use for this dichotomy would be planner and performer; it would be the same dichotomy. ‘Planner’ and ‘server’ are synonyms; ‘performer’ and ‘client’ are synonyms.

+

What do I mean by the ‘server’?

+

There is something which manages game state and things like the gossip network, merchant network, and major world events. This something is almost certainly written in some form of Lisp; I’d prefer Clojure but I don’t think it’s performant enough so probably Common Lisp. This means that it has inevitable pauses for garbage collection. Underneath this is a database which handles persistent storage of game state, which is probably an SQL database and quite likely SQLite.

+

The initial idea of The Great Game is that it is a single player game, but it actually doesn’t need to be and it would be quite possible for one server to support multiple clients, each being used by a different player.

+

The server/planner decides what each actor does, models what each character knows, plans and records all actions and transactions. It plans speech acts, and handles conversations which happen off screen, but hands speech texts over to the client/performer layer for actual performance. It also plans journeys as described in Pathmaking, but it doesn’t deal with movement within a polygon or with collision avoidance. It deals with fights which happen off screen, but not those that happen on screen.

+

What do I mean by the client?

+

There is something that renders an interesting and lively display of the part of the game world that the player can see from their current position. This display has to run without significant pauses — it’s not OK, for example, for all conversation to stop suddenly in a market place just because the server is garbage collecting.

+

The client is written in some high level game engine system, possibly Unreal Engine (although for ideological reasons I’d prefer an open source one).

+

The client/performer renders and animates everything the player character can see, and performs every sound the player character can hear. In doing this it is responsible for

+
    +
  1. The rendering of landscape, vegetation, buildings, furniture, and everything else that is fixed within the visible scene;
  2. +
  3. The animation of everything which moves within the visible scene, and, to facilitate this, detailed route planning and collision avoidance;
  4. +
  5. The performance of all speech acts and gestures, all musical performance, and the playing of all foley sounds;
  6. +
  7. Combat which happens in the field of view, including specifically all combat (including sparring) involving the player character. This means that the client/performer is the bit of the system which decides what blows are struck and whether they hit their targets, and consequently which character wins each fight. It reports this information back to the server.
  8. +
+
\ No newline at end of file diff --git a/docs/codox/Dynamic-consequences.html b/docs/codox/Dynamic-consequences.html new file mode 100644 index 0000000..7955991 --- /dev/null +++ b/docs/codox/Dynamic-consequences.html @@ -0,0 +1,45 @@ + +On the consequences of a dynamic game environment for storytelling

On the consequences of a dynamic game environment for storytelling

+

First, a framing disclaimer: in Racundra’s First Cruise, Arthur Ransome describes coming across a half built — and by the time he saw it, already obsolete — wooden sailing ship, in a Baltic forest. An old man was building it, by himself. He had been building it since he had been a young man. It’s clear that Ransome believed the ship would never be finished. It’s not clear whether the old man believed that it would, but nevertheless he was building it.

+

I will never build a complete version of The Great Game; it will probably never even be a playable prototype. It is a minor side-project of someone who

+
    +
  1. Is old and ill, and consequently has inconsistent levels of energy and concentration;
  2. +
  3. Has other things to do in the real world which necessarily take precedence.
  4. +
+

Nevertheless, in making design choices I want to specify something which could be built, which could, except for the technical innovations I’m trying myself to build, be built with the existing state of the art, and which if built, would be engaging and interesting to play.

+

The defining characteristic of Role Playing Games — the subcategory of games in which I am interested — is that the actions, decisions and choices of the player make a significant difference to the outcome of the plot, significantly affect change in the world. This already raises challenges for the cinematic elements in telling the game story, and those cinematic elements are one of the key rewards to the player, one of the elements of the game’s presentation which most build, and hold, player engagement. These challenges are clearly expressed in two very good videos I’ve watched recently: Who’s Commanding Shepard in Mass Effect?, which discusses how much control the player actually has/should have over the decisions of the character they play as; and What Happened with Mass Effect Andromeda’s Animation?, which discusses how the more control the player has, the bigger the task of authoring animation of all conversations and plot events becomes.

+

There are two key innovations I want to make in The Great Game which set it apart from existing Role Playing Games, both of which make the production of engaging cinematic presentation of conversation more difficult, and I’ll handle each in turn. But before I do, there’s something I need to make clear about the nature of video games themselves: what they are for. Video games are a vehicle to tell stories, to convey narrative. They’re a rich vehicle, because the narrative is not fixed: it is at least to some degree mutable, responsive to the input of the audience: the player.

+

Clear? Let’s move on.

+

The innovations I am interested in are

+

Unconstrained natural speech input/output

+

I want the player to be able to interact with non-player characters (and, indeed, potentially with other player characters, in a multi-player context) simply by speaking to them. This means that the things the player character says cannot be scripted: there is no way for the game designer to predict the full repertoire of the player’s input. It also means that the game must construct, and put into the mouth of the non-player character being addressed, an appropriate response, given

+
    +
  1. The speech interpretation engine’s interpretation of what it is the player said;
  2. +
  3. The immediate game and plot context;
  4. +
  5. The particular non-player character addressed’s knowledge of the game world;
  6. +
  7. The particular non-player character’s attitude towards the player;
  8. +
  9. The particular non-player character’s speech idiosyncracies, dialect, and voice
  10. +
+

and it must be pretty clear that the full range of potential responses is extremely large. Consequently, it’s impossible that all non-player character speech acts can be voice acted; rather, this sort of generated speech must be synthesised. But a consequence of this is that the non-player character’s facial animation during the conversation also cannot be motion captured from a human actor; rather, it, too, must be synthesized.

+

This doesn’t mean that speech acts by non-player characters which make plot points or advance the narrative can’t be voice acted, but it does mean that the voice acting must be consistent with the simulated voice used for that non-player character — which is to say, probably, that the non-player character must use a synthetic voice derived from the voice performance of that particular voice actor in that role.

+

Note that this has interesting consequences for social equity with regard to those whose current profession is voice acting video games. Automating work people do generally has the consequence of putting those people out of work, or at least of making their work less valuable and consequently less remunerative. Almost everyone who has worked in software has to some extent done this. I’m not avoiding or ignoring the ethical issue here. I would argue in mitigation that because games of the type I am suggesting can never be voice acted, I’m not replacing work any real actors will ever do, but that is tendentious since if games of this sort are built and are successful they will compete for audience attention with games which are voice acted.

+

Dynamic game environment

+

Modern Role Playing Games are, in effect, extremely complex state machines: if you do the same things in the same sequence, the same outcomes will always occur. In a world full of monsters, bandits, warring armies and other dangers, the same quest givers will be in the same places at the same times. They are clockwork worlds, filled with clockwork automata. Of course, this has the advantage that is makes testing easier — and in a game with a complex branching narrative and many quests, testing is inevitably hard.

+

Interestingly, Kenshi — a game I’m increasingly impressed and influenced by — is not quite clockwork in this sense. As the player upsets the equilibrium of the game’s political economy, factions not impacted negatively will move against competing factions which are impacted negatively, in a way which may be scripted, but it’s so well done it’s hard to tell.

+

My vision for The Great Game is different. It is that the economy — and with it, the day to day choices of non-player characters — should be modelled. This means, non-player characters may unexpectedly die. Of course, you could implement a tag for plot-relevant characters which prevents them being killed (except when required by the plot).

+

Plot follows player

+

As Role Playing Games have moved towards open worlds — where the player’s movement in the environment is relatively unconstrained — the clockwork has become strained. The player has to get to particular locations where particular events happen, and so the player has to be very heavily signposted. Sometimes the mark you have to hit to trigger the next advance of the plot can be extremely awkward; an example from Cyberpunk 2077 is finding the right spot, in the quest ‘They Won’t Go When I Go’, to trigger the button which raises the cross.

+

Another solution — which I’d like to explore — is ‘plot follows character’. The player is free to wander at will in the world, and plot relevant events will happen on their path. And by that I don’t mean that we associate a set of non-player characters which each quest — as current Role Playing Games do — and then uproot the whole set from wherever they normally live in the world and dump them down in the player’s path; but rather, for each role in a quest or plot event, we define a set of characteristics required to fulfil that role, and then, when the player comes to a place where there are a set of characters who have those characteristics, the quest or plot event will happen.

+

Cut scenes, cinematics and rewarding the player

+

There’s no doubt at all that ‘cut scenes’ — in effect, short movies spliced into game play during which the player has no decisions to make but can simply watch the scene unroll — are elements of modern games which players enjoy, and see to some extent as ‘rewards’. And in many games, these are beautifully constructed works. It is a very widely held view that the quality of cutscenes depends to a large degree on human authorship. The choices I’ve made above:

+
    +
  1. We can’t always know exactly what non-player characters will say (although perhaps we can in the context of cut scenes where the player has no input);
  2. +
  3. We can’t always know exactly which non-player characters will speak the lines;
  4. +
  5. We can’t predict what a non-player character will say in response to a question, or how long that will take;
  6. +
  7. We can’t always know where any particular plot event will take place;
  8. +
+

each make the task of authoring an animation harder. The general summary of what I’m saying here is that, although in animating a conversation or cutscene what the animator is essentially animating is the skeletons of the characters, and, provided that all character models are rigged on essentially similar skeletons, substituting one character model for another in an animated scene isn’t a huge issue, with so much unknowable it is impossible that hand-authoring will be practicable, and so a lot will depend on the quality of the conversation system not merely to to produce convincingly enunciated and emoted sound, but also appropriate character animation and attractive cinematography. As you will have learned from the Mass Effect analysis videos I linked to above, that’s a big ask.

+

Essentially the gamble here is that players will find the much richer conversations, and consequent emergent gameplay, possible with non-player charcaters who have dynamic knowledge about their world sufficiently engaging to compensate for a less compelling cinematic experience. I believe that they would; but really the only way to find out would be to try.

+

Interestingly, an early preview of CD Project Red’s Cyberpunk 2077 has relatively few cutscenes, suggesting that these very experienced storytellers don’t feel they need cutscenes either to tell their story or maintain player engagement.

+
\ No newline at end of file diff --git a/docs/codox/Economy.html b/docs/codox/Economy.html new file mode 100644 index 0000000..bef0905 --- /dev/null +++ b/docs/codox/Economy.html @@ -0,0 +1,36 @@ + +Game world economy

Game world economy

+

Broadly this essay extends ideas presented in Populating a game world, q.v.

+

Primary producers

+

Herdsfolk

+

Herdsfolk are nomadic; it’s reasonable to think they’ll bring their herds to market, rather than selling at lots of tiny markets. So in the spring, shepherds will visit specific towns at the edge of open land, to hold a shearing festival/carnevale; and that both shepherds and cattle herders will visit towns on the edge of open land to sell fatstock in the autumn.

+

Miners

+

Miners mine. They’re settled, but they’re settled usually in specialist settlements at the location where the ore body is accessible, usually in mountenous territory. They’ll consume a lot of food, so there will be a local market for foodstuffs encouraging local farming. Different mines obviously mine different ores, but, for example, lead and silver are frequently found together.

+

Foresters

+

Foresters are more or less settled at the edge of forests, at locations from which timber can be moved by navigable water; again in specialist settlements. In addition to timber, foresters hunt and produce both meat and furs, so have less need for other food producers locally.

+

Farmers

+

Farmers are settled. Farmers occupy standard runrig plots, but because they don’t employ journeymen or apprentices, and don’t have workshops, the plots are mostly open with little building. Most farmers are ‘mixed farmers’, producing cereals, meat, eggs and milk. Some will be more specialist. Farm produce, taken broadly to include orchardsfolk, include:

+
    +
  • meat
  • +
  • milk and milk products
  • +
  • hides
  • +
  • eggs
  • +
  • cereals
  • +
  • root vegetables, onions, etc
  • +
  • peas and beans
  • +
  • leaf vegetables
  • +
  • fruits
  • +
  • fibres: linen, hemp and silk (from silk-moths in mulberry orchards)
  • +
  • possibly other stuff I’ve forgotten.
  • +
+

Farmers are all primarily subsistence farmers, farming first to feed their own household and selling only surplus in the market.

+

Crafts

+

Crafts generally process primary goods into secondary goods — whether intermediate stages or final consumer items. Some elite ‘crafts’ deal with abstract primary goods like law and knowledge, and they may be seen as somewhat separate.

+

A master craftsperson may occupy a standard runrig plot, much like a farmer’s plot. Like a farmer, a poor master crafter household will cultivate part of the plot to produce food for the house — at least grow vegetables and keep hens. However, as the crafter takes on apprentices and journeymen — and gets richer — more buildings will be required as accommodation, workshop space and materials stores.

+

Also, Tchahua is much more a gold-rush town than an organic, grew over hundreds of years sort of town, so it is not ex-runrig; and additionally the original settlement was probably along the river bank, land which has now been redeveloped as warehouses and as rich merchant residences. Generally, town house plots are small from the get go.

+

Hans’hua is again an exception from normal organic development, as it has no agricultural land close to the city at all.

+

Generally, primary goods aren’t transported over land — because overland transport is expensive, by the time they’ve been transported they’re no longer low cost goods. So often the craftspeople who process primary produce into at least commodity intermediate forms will live close to the source of the primary goods.

+

So, for example, the town(s) where the shepherds hold their shearing fairs will tend to have a lot of weavers. While around mines there will be smelters producing ingots and bar stock to be marketed to smiths all over the place, there will also be smiths close to the mines producing commodity tools and weapons.

+

See the tables in Populating a game world.

+
\ No newline at end of file diff --git a/docs/codox/Further-reading.html b/docs/codox/Further-reading.html new file mode 100644 index 0000000..e2f62a0 --- /dev/null +++ b/docs/codox/Further-reading.html @@ -0,0 +1,13 @@ + +Further Reading (and watching)

Further Reading (and watching)

+

Work by other people which is relevant to what I’m doing, and which I should study.

+

## Modelling the natural environment

+
    +
  1. Synthetic Silviculture: Multi-scale Modeling of Plant Ecosystems — see also this video.
  2. +
+

Systemic games

+
    +
  1. This video is thought provoking with excellent examples.
  2. +
+
\ No newline at end of file diff --git a/docs/codox/Game-engine-integration.html b/docs/codox/Game-engine-integration.html new file mode 100644 index 0000000..340d5e5 --- /dev/null +++ b/docs/codox/Game-engine-integration.html @@ -0,0 +1,7 @@ + +Game-engine integration (unfinished)

Game-engine integration (unfinished)

+

To build a game using these ideas we need a lot of things that are well understood and already implemented: rendering a world, moving models of characters in a world, and so on. This collection of technologies which allow us to realise an interactive realisation of a world is typically called a game engine.

+

It’s my intention that the bits that I add to the mix should be open source in the hard sense of that phrase, fully free software released under GPL. They cannot therfore be directly linked to a proprietary game engine.

+

But the current state of play is that the best and easiest to work with game engines are not open source; and while I could build a demo game using, for example, the Godot engine or jMonkeyEngine the result wouldn’t be as compelling and I believe the effort would be more considerable than if I use Unreal Engine, which is my current plan.

+
\ No newline at end of file diff --git a/docs/codox/Game_Play.html b/docs/codox/Game_Play.html index a1d8141..76118e6 100644 --- a/docs/codox/Game_Play.html +++ b/docs/codox/Game_Play.html @@ -1,31 +1,39 @@ -Game Play

Game Play

+Game Play

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. -
  3. -

    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.

  4. -
  5. -

    Boss fights: some non-player characters have special, and specially strong, combat repertoire, and block progress in the game until you overcome them.

  6. -
  7. -

    Psychokiller: completing the game necessarily involves beating many, many other characters in combat.

  8. -
  9. -

    Slaughterhouse: the main way to interact with other characters is to kill them.

  10. -
  11. -

    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.

  12. -
  13. -

    Dumb and dumber: non-player characters, even important ones, have extremely limited vocal repertoire.

  14. +
  15. +

    Superpower: the player character has some special powers or skills that other characters in the game fo not have.

    +
  16. +
  17. +

    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.

    +
  18. +
  19. +

    Boss fights: some non-player characters have special, and specially strong, combat repertoire, and block progress in the game until you overcome them.

    +
  20. +
  21. +

    Psychokiller: completing the game necessarily involves beating many, many other characters in combat.

    +
  22. +
  23. +

    Slaughterhouse: the main way to interact with other characters is to kill them.

    +
  24. +
  25. +

    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.

    +
  26. +
  27. +

    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’ in which generated speech just sounds uncomfortably off.

+

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 in 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 Dum-Dum

+

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’ 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 which I recomment to you; but is equally true of almost all other games.

+

And as new 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 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 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.

\ No newline at end of file +

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 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.

+
\ No newline at end of file diff --git a/docs/codox/Genetic-buildings.html b/docs/codox/Genetic-buildings.html new file mode 100644 index 0000000..c2bce27 --- /dev/null +++ b/docs/codox/Genetic-buildings.html @@ -0,0 +1,46 @@ + +Genetic Buildings

Genetic Buildings

+

Building selection based on location

+

The objective of this note is to create a landscape with varied and believable buildings, with the minimum possible data storage per instance.

+

Like plants, buildings will ‘grow’ from a seed which has northing and easting attributes. These locate a position on the map. Again, like trees, some aspects of the building type selector are location based. Aspects of the location which are relevant to building type are

+
    +
  • elevation — derived from the map location by interpolation from grid. The actual interpolation algorithm is probably some form of spline, but in any case it’s the same one as for everything else.
  • +
  • orientation of slope — derived by taking altitude at four corners of a 100 metre square centred on the seed point, and then taking the highest and lowest of these. If highest is northwest, lowest is southeast, the slope is considered to be oriented southeast; if highest is northwest and lowest southwest, the orientation is considered to be south, and so on. Eight orientation values are sufficient.
  • +
  • gradient of slope — derived from the difference in altitude across the same 100 metre square
  • +
  • neighbours — number of other buildings in 500 metre square centred on seed point.
  • +
+

The reason orientation is relevant is exactly the same as the reason it’s relevant to trees. West facing slopes are assumed wetter (coriolis winds), so grow trees better, so better availability of better quality timber, so a higher probability of timber as a primary building material. But also, in areas of higher rainfall, rain shedding is an important consideration, so a higher value is placed on pitched roofs.

+

So you have the following general relationships

+
    +
  • west (or southwest or northwest) facing, moderate gradient, moderate altitude: high probability of timber construction; construction techniques involving large timbers (e.g. cruck frame); greater probability of shingled roofs;
  • +
  • west (or southwest or northwest) facing, moderate gradient, higher altitude or northern latitude: high probability of building styles adapted to straight-trunk conifers, e.g. log cabins, stave buildings; greater probability of shingled roofs;
  • +
  • east facing, generally: greater probability of flat roofs;
  • +
  • steeper gradients: greater probability of stone buildings (steeper gradients = shallower topsoil and greater ease of quarrying = access to stone); greater probability of slate roofs;
  • +
  • shallower gradients: greater probability of mud, cobb, brick or wattle-and-daub as building materials; greater probability of thatch or turf roofs;
  • +
  • Higher number of neighbours: higher probability of two or more stories;
  • +
+

These factors allow classes of building to be selected. Having got past that point, we need to consider how classes of genetic building can work.

+

Rectangular genetic buildings

+

Some genetic buildings will have cells with rectangular plan. This doesn’t mean that genetic buildings are required to have rectangular cells, but they provide a starting point for discussion. For a given class of building (for example, timber frame), a number of prototype models of cells exist. These models are fully realised three dimensional models. Possibly all cells belonging to the building class have two open ends, and end walls exist as separate models; equally possibly, some cells have only one extensible end. In any case, a building will not normally comprise a single cell. Normally it will comprise multiple cells. So the cells belonging to a particular building class will be designed to ‘plug together’. Multi story building classes will have some cells which are specifically ground floor only (flat ceiling, no roof), and such cells will always have an upper floor cell added above them. Where an upper floor cell has an outside door, an outside stair will automatically be added.

+

Cell mutability

+

Although cell models are repeatedly reused they don’t have to look the same every time they are reused. Within limits, every cell can be stretched along any of its three axes. Obviously, the degree of stretch on a given axis for every cell in a given building must be the same, otherwise they won’t line up. Another mutable area is skinning — it may be possible to have alternate skins for cells, and even if there are not alternate skins, it will be possible to mutably darken, lighten or otherwise tint the skins used, within ranges which are appropriate to the materials represented. Obviously there are limits to stretching — timber comes in only such a length, stone lintels will only support such a span.

+

Functional cells

+

Some trade functions require cells of particular kinds. Thus a smith needs a working building with one cell which is explicitly a forge. A water mill must have one cell which explicitly houses the mill gear. A forge cell or a waterwheel cell should never appear in weavers workshop. But most cells are not dedicated in this way. A bedroom cell is a bedroom cell, more or less; wealth may alter how it is furnished, but it may appear in any dwelling. Similarly, except for the very wealthy, a living cell is pretty much a living cell. And any building may incorporate a storage cell. If a given building class has twelve distinct ‘generic’ cells’ and half a dozen distinct functional cells, and if buildings in the class average four cells each, then ignoring variance caused by skin mutability, a street of fifty buildings could have every one different.

+

Reproducibility

+

It’s critical that if a player visits a location, leaves it, and then returns, the buildings should not all have changed. So it must be possible to repeatedly reproduce the building at the location (this, of course, applies to other procedural scene dressing, such as trees, roads, boundaries, bridges and so on). This is possible if a deterministic random number generator is used which is seeded from the latitude and longitude attributes of the location. Other attributes which should be cached on the seed even though they are determined procedurally when the building is first instantiated include building class, purpose, and wealth. Using these attributes and the deterministic random number generator, the same building can be reproduced on the same site each time it is visited, with a very small amount of data stored.

+

Buildings will normally be built at the edge of the associated land holding. If an edge of the land holding adjoins a road, then the building will be built with one long side aligned to the road. Otherwise, the building will be built at right angles to the orientation of the slope. The orientation will be ‘frozen’ once the building has been instantiated and will be cached on the seed.

+

So, to build a building, use the following algorithm:

+

Seed the random number generator with latitude and longitude

+
while ( building value is less than wealth) {
+   select a cell selected from the building class using the next number from the random number generator modulo the number of generic cells in the class;
+   if the selected cell is not inappropriate to the building's function {
+       fit the cell to the building at the point determined by a deterministic algorithm
+       furnish cell using the random number generator to determine
+       furnishing types and locations from a selection appropriate to the cell
+       if the selected cell was not a top story cell {
+            add a requirement that the next cell selected must be an upper story cell}
+   }
+}
+
+
\ No newline at end of file diff --git a/docs/codox/Gossip_scripted_plot_and_Johnny_Silverhand.html b/docs/codox/Gossip_scripted_plot_and_Johnny_Silverhand.html index 33918d7..804fd9f 100644 --- a/docs/codox/Gossip_scripted_plot_and_Johnny_Silverhand.html +++ b/docs/codox/Gossip_scripted_plot_and_Johnny_Silverhand.html @@ -1,56 +1,57 @@ -Gossip, scripted plot, and Johnny Silverhand

Gossip, scripted plot, and Johnny Silverhand

-

I’ve been writing literally for years – since Voice acting considered harmful 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,

+Gossip, scripted plot, and Johnny Silverhand

Gossip, scripted plot, and Johnny Silverhand

+

I’ve been writing literally for years — since Voice acting considered harmful 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. -
  3. A decision on whether to co-operate based on the particular NPC’s general demeanor and particular attitude to the player;
  4. -
  5. A search of the game state and lore for relevant information;
  6. -
  7. A filtering of the results based on what the particular NPC can be expected to know;
  8. -
  9. 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;
  10. -
  11. Production of audio using a [Lyrebird]{https://www.descript.com/overdub?lyrebird=true) style generated voice.
  12. +
  13. Alexa/Siri style speech interpretation;
  14. +
  15. A decision on whether to co-operate based on the particular NPC’s general demeanor and particular attitude to the player;
  16. +
  17. A search of the game state and lore for relevant information;
  18. +
  19. A filtering of the results based on what the particular NPC can be expected to know;
  20. +
  21. 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;
  22. +
  23. Production of audio using a Lyrebird 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.

+

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. (Interestingly, since I first wrote this note, CD Projekt Red have used Lyrebird-like technology to resurrect a voice actor in Phantom Liberty, proving that the technology is good enough).

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 – 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.

+

Obviously, my vision — as I’ve set out in Organic Quests — 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, 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.

+

In Cyberpunk 2077, 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.

+

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:

+

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.

+

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?

+

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.

+

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.

+

Johnny:But you didn’t answer my question. Repeats question.

or

-

Johnny: As I said before, Repeats what he said before.

+

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.

\ No newline at end of file +

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.

+
\ No newline at end of file diff --git a/docs/codox/MVP-Roadmap.html b/docs/codox/MVP-Roadmap.html new file mode 100644 index 0000000..b9a73b7 --- /dev/null +++ b/docs/codox/MVP-Roadmap.html @@ -0,0 +1,42 @@ + +Minimum Viable Product, and a road map

Minimum Viable Product, and a road map

+

Right, I’m bogged down thinking about the immensity of what I want to build, so I’m achieving nothing. So the first thing I need to state is what the Minimum Viable Product is, and the second is to outline a rough road map which takes us forwards a few steps from the MVP.

+

The core idea here is to have a game world in which you can just say anything you like to game characters, and they can say sensible things back.

+

But actually, I know that speech to text can be reasonably effectively done; and I believe with a slightly lower degree of confidence that text to convincing speech can also be done.

+

I also know that the movement of a character around a convincing three dimensional representation of a world can be done, but that a great deal of effort is needed to build that world.

+

The minimum viable product does not need to demonstrate features which people have reasonable confidence can be done. What I need to demonstrate is the things which people haven’t seen done, or haven’t seen done well.

+

Prototype one: the minimum viable product

+

The minimum viable product can have just a text adventure style interface:

+
+

You are in the market square. It is mid morning. To the north is the guild hall; to the east there are market stalls; to the south is the residence; to the west is the bridge gate.

+

There is a merchant here; there is a guardsman here.

+
+

To which the user can type (for example)

+
+

Say to the guardsman, “Can you direct me to Master Dalwhiel’s house?”

+
+

Within that interface, you should be able to interact with characters who:

+
    +
  1. have different levels of knowledge of the world, partly driven by their age, trade and personal history;
  2. +
  3. move about and exchange gossip, even when the player is not present to see/hear this;
  4. +
  5. have different attitudes towards the player and other characters, which will be modified by what they learn in gossip;
  6. +
  7. have their own hierarchies of needs, which they make plans to satisfy;
  8. +
  9. have homes and trades;
  10. +
  11. will respond to speech addressed to them by the player depending on their attitude to the player, how busy they are and their knowledge of the world; and
  12. +
  13. as a stretch goal, will have different dialects in which they will express their responses to the player.
  14. +
+

There should be one or two multiple decision point quests in this world which can be resolved by talking to characters.

+

Prototype two: adding organic quests

+

Extends prototype one only by adding organic quests.

+

Prototype three: voice interaction

+

Extends prototype two by adding speech to text, so that the player can directly talk (via a microphone) to characters, and text to speech, so that the system can voice the characters’ responses.

+

Different characters should have different voices.

+

Prototype four: performative speech

+

This one is hard because I’m not absolutely sure how I can do it, but I need characters’ voices to convey emotion; the player needs to know from their voice whether they are angry, or frightened, or impatient, or bored.

+

There is a W3C specification for an XML markup for speech performance, and I can certainly generate that, but I’d need to find a text-to-speech library which could consume it. There’s also a separate specification to associate pronunciations with lexical tokens, which is also potentially useful, especially for names.

+

Google has a ‘Cloud Text-to-Speech’ service which understands SSML and might be good enough for a demo but is more likely just embarrassingly bad.

+

Prototype five traversible world

+

Now, a small section of a three dimensional open world, with at this stage simple block buildings that the player cannot enter, within which the characters act out their lives.

+

Stretch goal, JALI-like lip sync.

+
\ No newline at end of file diff --git a/docs/codox/Modelling_democracy_and_morale.html b/docs/codox/Modelling_democracy_and_morale.html new file mode 100644 index 0000000..18975e1 --- /dev/null +++ b/docs/codox/Modelling_democracy_and_morale.html @@ -0,0 +1,18 @@ + +The Red Company: modelling democracy and morale (unfinished)

The Red Company: modelling democracy and morale (unfinished)

+

Background

+

The Great Game exists as a project on two levels. One one level, it’s a framework for building algorithms to build much more vibrant, and thus enjoyable game worlds; at another level, it’s about building a particular world, in which I want to tell stories.

+

The world in which I want to tell stories is a world which is based roughly on late bronze age to medieval Europe. It’s a world in which the region known as ‘The Coast’ – the southern littoral of the continent – had been a mostly-peaceful matrideic dispersed agrarian tribal society, which had been invaded some hundreds of years past by a warrior tribe with substantially better military technology.

+

These warrior tribesmen have settled down as local tyrants or robber barons, parasitising on the indigenous communities, and have evolved into an aristocratic (‘Ariston’) class. In the meantime, a mercantile class has grown up and established important long distance overland trade routes; and significant towns (called ‘cities’, but of only at most a few tens of thousand inhabitants) have grown up around markets.

+

These mercantile cities have been under the governance of powerful aristons known as tyrranoi, and the cities under their tyrranoi have competed militarily as well as commercially for control of strategic features on trade routes, such as bridges, fords, oases, mountain passes, and so on.

+

In the very earliest days of the warrior invasion, the warriors themselves fought against the indigenous peoples, who had very limited military equipment and tactics. Later, as they settled into Aristons, they fought by leading feudal levies of partially-trained peasants. Over the past hundred years or so, mercenary companies have emerged of specialist, trained warriors, and because these have more fighting experience (and often better equipment) they tend to beat feudal levies. These mercenary companies are base loosely on the condottierri of fourteenth century Italy.

+

So more and more, tyrranoi, rather than leading their own feudal levies, instead tax their peasantry and mercantile class more and hire condottierri to fight their wars.

+

Mercenary companies evolve out of feudal levies, and in the period of The Great Game, are mostly owned and led by aristons who employ their soldiers by paying them a wage.

+

One company, the Red Company, has become essentially a workers’ co-op, after its former ariston leader fled in the course of a battle which looked like an inevitable defeat (but which the company, without him, won). In this company, soldiers are paid a salary, probably lower than salaries in other companies, but also at the end of the year get a share in the profits. The soldiers are organised into squads of eight who elect their own sergeants; squads are organised into companies of eight squads, and the sergeants elect the captain; companies are organised into legions of eight companies, and the captains elect the captain-general.

+

However, while in combat this represents a chain of command, out of combat it is much more a delegate structure; when making significant decisions, the captains general will consult with the captains who will consult with the sergeants who will consult with the soldiers.

+

One of the themes of the stories I want to tell is that this more democratic structure contributes to higher morale and hence to greater military success. I could model this by just making membership of the Red Company a factor in the function which computes morale. However…

+

Modelling democracy

+

If each individual character has a hierarchy of needs, and plans actions based on that hierarchy of needs, then they have the mechanism in place to choose which of two options better conforms to their hierarchy of needs.

+

This implies that soldiers are likely to vote for the people (or ideas presented by the people) they consider most competent and/or most trustworthy. Which comes back to modelling reputation; which comes back to the gossip.

+
\ No newline at end of file diff --git a/docs/codox/Modelling_trading_cost_and_risk.html b/docs/codox/Modelling_trading_cost_and_risk.html new file mode 100644 index 0000000..baedd48 --- /dev/null +++ b/docs/codox/Modelling_trading_cost_and_risk.html @@ -0,0 +1,8 @@ + +Modelling trading cost and risk (unfinished)

Modelling trading cost and risk (unfinished)

+

In a dynamic pre-firearms world with many small states and contested regions, trade is not going to be straightforward. Not only will different routes have different physical characteristics - more or less mountainous, more or fewer unbridged river crossings - they will also have different political characteristics: more of less taxed, more or less effectively policed.

+

Raids by outlaws are expected to be part of the game economy. News of raids are the sort of things which may propagate through the gossip system. So are changes in taxation regime. Obviously, knowledge items can affect merchants’ trading strategy; in existing prototype code, individual merchants already each keep their own cache of known historical prices, and exchange historical price data with one another; and use this price data to select trades to make.

+

So: to what extent is it worth modelling the spread of knowledge of trade cost and risk?

+

Obviously the more we model, the more compute power modelling consumes. If the core objective is a Role Playing Games as currently understood, then there is no need to model very complex trade risk assessment behaviour.

+
\ No newline at end of file diff --git a/docs/codox/My-setting.html b/docs/codox/My-setting.html new file mode 100644 index 0000000..60a7047 --- /dev/null +++ b/docs/codox/My-setting.html @@ -0,0 +1,6 @@ + +My setting for the Great Game

My setting for the Great Game

+

It should be evident that all the key ideas in The Great Game project would be applicable to games set in the historic past of our world, to games set in its present, or to games set in some imagined or forecast future; the ideas are intended to be, and I believe are, largely independent of setting.

+

Nevertheless I feel the need for a concrete setting to ground the development of ideas. I’ve chosen deliberately not to place that setting in the real world; although it’s broadly based on cultures from the late bronze age/early iron age mediterrainian.

+
\ No newline at end of file diff --git a/docs/codox/Naming-of-characters.html b/docs/codox/Naming-of-characters.html new file mode 100644 index 0000000..2342e2e --- /dev/null +++ b/docs/codox/Naming-of-characters.html @@ -0,0 +1,32 @@ + +Naming of Characters

Naming of Characters

+

Generally speaking, in modern RPGs, every character with any impact on the plot has a distinct name. But if we are going to give all non-player characters sufficient agency to impact on the plot, then we must have a way of naming tens or hundreds of thousands of characters, and distinct names will become problematic (even if we’re procedurally generating names, which we shall have to do. So this note is about how characters are named.

+

The full name of each character will be made up as follows:

+

epithet clan personal-name the trade-or-rank of location, son/daughter of parent

+

Based on, roughly, historical name patterns like

+

Archibald (personal-name) the Grim (epithet), Earl (trade-or-rank) of Douglas (location)

+

Where

+
    +
  1. +

    epithet is a prefix based on some notable feature or feat of the character. Most characters won’t have an epithet, unless they have some notable feature or they’ve done something notable. If a character does something notable in the course of the game, they will subsequently gain an epithet; ‘notability’ may be measured by how many times the event is transmitted through the gossip network.

    +
  2. +
  3. +

    clan is special to the Western Clans, although people from the Great Place may possible use the name of their house similarly.

    +
  4. +
  5. +

    personal-name is chosen from one of a limited set of limited sets; different cultural groups will have different (possibly overlapping) sets of names, but within each set there will only be a limited subset

    +
  6. +
  7. +

    trade-or-rank is just that. “Smith”, “Miller”, “Ariston”, “Captain”. Either only master craftsfolk have the trade-or-rank name of their craft, or we distinguish between ‘Calon the Smith’, who may be a journeyman, and ‘Calon the Master Smith’, who is a master.

    +
  8. +
  9. +

    location is the name of a location; a village, town, city or province. The location which forms part of a character’s name is the location where there current home is, not the location where they were born or where their ancestors came from

    +
  10. +
+

Full names will almost never be used - only, perhaps, in extremely formal circumstances. The form of a name used will depend on context, and will generally be just sufficient to disambiguate the character in the context.

+

If the speaker is in Sinhua and referring to someone from Sinhua, they won’t refer to them as ‘of Sinhua’.

+

If everyone present is a bargee and the speaker referring to someone who is also a bargee, they won’t refer to them as ‘the bargee’.

+

The question asked influences the context: in answer to the question ‘who is the best sword smith’, the answer will not be ‘Calon the Smith’ but ‘Calon of Sinhua’.

+

Patronymics/matronymics will not normally be used of adults (although they may be used of apprentices and journeymen.

+
\ No newline at end of file diff --git a/docs/codox/Not_my_problem.html b/docs/codox/Not_my_problem.html new file mode 100644 index 0000000..78e3358 --- /dev/null +++ b/docs/codox/Not_my_problem.html @@ -0,0 +1,21 @@ + + Not my problem

# Not my problem

+

Introduction

+

This document is essentially a catalogue of side-tracks which I do not have to go down when implementing The Great Game. Solved problems; or problems which are common to many other games, so if I don’t solve them someone else will. The object of doing this is to work down to a constrained set of problems which are genuinely things I’m trying to innovate, which I should focus on; which essentially come down to

+
    +
  1. Gossip
  2. +
  3. Reputation
  4. +
  5. Dynamic character motivation and action, and hence
  6. +
  7. Dynamic economy, and
  8. +
  9. Dynamic plot
  10. +
  11. Procedural (‘genetic’) buildings.
  12. +
+

(Note that although procedural vegetation is in principle a solved problem and so I don’t need to solve it, I need repeatable procedural vegetation so I need to be a bit careful about the procedural vegetation library I pick).

+

Animation

+

I envisage a well rendered three dimensional world in which many non-player characters interact with one another and with the player character. All of my characters are either human, quadrupeds, or birds (my dragons animate like very large birds). The humans are all just human; there are infants, children, adolescents, youths, adults, elderly; there are multiple racial types — but they’re all human. Systems for creating varied distinct human models exist; systems for animating them exist; systems for applying and animating clothing exist. Even systems for animating continuous speech exist.

+

Rendering

+

Ideally I’d like a stylised, not-quite-photorealistic render, because such things age, in my opinion, better than things which do seek to be photorealistic. But actually that does not matter very much; the game won’t be made or broken by its rendering. Photorealistic renders are sort of the current default, that most game engines.

+

Continuous Open World

+

I’ve done a great deal of thinking about how to render a continuous open world over the years, and I think at least some of it is reasonably good; but I haven’t actually written any code, and in the same time period other people have written continuous open world libraries which do work, so I’d be much better choosing an existing one.

+
\ No newline at end of file diff --git a/docs/codox/On-dying.html b/docs/codox/On-dying.html new file mode 100644 index 0000000..59e49d6 --- /dev/null +++ b/docs/codox/On-dying.html @@ -0,0 +1,17 @@ + +On Dying, and Injury

On Dying, and Injury

+

Death is the end of your story. One of the tropes in games which, for me, most breaks immersion is when you lose a fight and are presented with a screen that says ‘you are dead. Do you want to reload your last save?’ Life is not like that. We do not have save-states. We die.

+

So how could this be better handled?

+

You lose a fight. Switch to cutscene: the battlefield, after the fight, your body is there. Probably no sound. A party of non-enemies crosses the battlefield and finds your body. We see surprise and concern. They gather around you. Cut to interior scene, you are in a bed, unconcious, being tended; cut to similar interior scene, you are in a bed, conscious, being tended; cut to exterior scene, you are sitting with some of your saviours, and the game restarts.

+

Time has passed; events in the game world have moved on. You can talk to your saviours about it. You have lost a lot of strength, and most of the gear you were carrying. You must do whatever it is you do within the game mechanics to rebuild strength, and to acquire more gear. Significantly you have acquired a debt of honour to your saviours, which they may call on later. You almost certainly have new scars, and might possibly have some lasting effects (although how that interacts with other game mechanics might be tricky).

+

So who are the non-enemies? It depends on context. If you have a party, and some of that party survived the fight, it’s your party. Otherwise, if you’re in a populated place, it’s locals. If it’s on a road or other route, it’s passing merchants. If you’re in the wilderness, a hunting party. It’s a bunch of non-hostiles who might reasonably be expected to be around: that’s what matters. It’s about not breaking immersion.

+

Obviously losing a fight must have weight, it must have meaning, it must have in-game consequences; otherwise it is meaningless.

+

Injury

+

Similarly to death, injury must have meaning. Any injury takes time to recover from. It takes a certain amount of time if you’re able to rest somewhere safe, and considerably longer if you’re not. If you fight while injured, you’ll have less strength, less stramina, and probably also less agility. Depending where you’re injured, there will be certain things you cannot do. If you fight while injured, also, your recovery time will be extended, even if you take no further injury.

+

Some serious injuries will lead to permanent scarring, and permanent loss of agility; you’ll be just slightly slower in fights.

+

It should be said that Kenshi — a game I’ve only recently become aware of and greatly admire — handles all of this extremely well, and is worth studying.

+

Reciprocity

+

If the player is going to depend on good samaritans for rescue after losing a fight, then there must be at least a social convention that people should assist people found injured on the wayside. Consequently, if the player fails to do this, that should in itself become a ‘gossip’ event which will lower the player’s reputation with non-player characters.

+

On the other hand, helping NPCs found injured at the wayside can be another category of organic quest, as a special subcategory of an escort quest.

+
\ No newline at end of file diff --git a/docs/codox/On-sex-and-sexual-violence.html b/docs/codox/On-sex-and-sexual-violence.html new file mode 100644 index 0000000..6883c83 --- /dev/null +++ b/docs/codox/On-sex-and-sexual-violence.html @@ -0,0 +1,45 @@ + +On Sex, and Sexual Violence, in Games

On Sex, and Sexual Violence, in Games

+

For me the purpose of games is to provide worlds in which players can explore moral actions, and the consequences of moral actions. Sexual violence is something that happens in the real world, and which happens, even within the real world, more frequently in areas of poor governance and open conflict; and those are areas in which there are important moral actions, and important moral consequences, so they are areas in which it is interesting to set games.

+

It would be ludicrous to argue ‘sexual violence is wrong, therefore we should not represent it in games.’ Killing people is also wrong, yet it is extremely common in games. However, sexual violence — and in particular the representation of sexual violence — does pose some specific problems that need to be addressed.

+

Firstly, sexual violence is extremely gendered. Yes, male people are sometimes subjected to sexual violence, but nevertheless the overwhelming majority of victims of sexual violence are female. Yes, female people are sometimes — extraordinarily rarely, but sometimes — perpetrators of sexual violence, but nevertheless perpetrators of sexual violence are almost exclusively male.

+

Secondly, it is extremely tricky to represent sexual violence in visual media without eroticising it. There’s a very famous scene in Last Tango in Paris which the director might claim is consented in context, but which appears to me to be a clear case of anal rape, which is nevertheless highly erotic. There’s a scene in High Plains Drifter where no part of the rape is actually represented — it happens off screen — but it is nevertheless perceived by many people (including me) as eroticised. Many people — I suspect more men than women, but certainly including many women — do find the idea of rape erotic. It seems to me highly undesirable that a game should be seen to be rewarding immoral action.

+

(Yes, I know many modern games do quite explicitly reward killing, including of characters whose culpability is at best trivial, but — surely — this is something we should be seeking to move away from.)

+

Subtlety and Nuance

+

A final issue here is that sexual interactions between people are subtle, and are subtle even around issues of consent. A less powerful person (normally a woman) — alone or as a member of a weak party, a party of perhaps older people, other women, children — may submit to sex with more powerful others without protest in order to protect others in their party, or to avoid death or serious injury, or to avoid starvation, or to escape debt. Do any of these things truly count as consent?

+

Again, a less powerful person may submit to sex with more powerful others transactionally in return to protection, or shelter, or food, or other resources. In modern society we might see this as sex work, and we might argue that sex work falls into the same moral category as any other labour entered into transactionally. But, generally, is it moral that people should be put into a position where their survival depends on their ability to sell any sort of unwilling labour?

+

(This is not to deny that some people, who do have secure living conditions or who could choose to do other things in order to gain secure living conditions do choose, willingly and voluntarily, to engage in sex work; and it isn’t to criticise those people in any way).

+

Games are not very good at subtly and nuance. When, while playing a game, the character who is our avatar in the game, who we thought we were controlling, does something which we didn’t intend them to do, it’s very wrenching and immersion-breaking.

+

At the same time, if other characters in the game interpret something the player’s character has done as sexual violence when the player did not intend sexual violence, that’s also undesirable.

+

So, questions:

+

Sex between non-player characters

+

People have sex. If people didn’t have sex, there wouldn’t be people; but more, if people didn’t have sex, there wouldn’t be (many) stories, since most stories are driven at least in part by sex. So pretending that non-player characters don’t have sex is worse than unrealistic.

+

We live in a pathologically repressed society, in which open sex — sex in public places, sex with other people present — is rare, is seen as deviant, is (perhaps in consequence) highly eroticised. Does that mean that all the societies we represent in our games must be similarly repressed?

+

I would argue strongly to the contrary. Games are environments in which we can explore moral possibilities, and a society in which public sexuality was normal is clearly a possibility. Would such a society be a better society? Games are a mechanism through which we can ask that question, and questions of that sort.

+

If we’re going to represent a society in which public sex is normal, then we’re going to have to represent public sex on screen. It can take one of many forms:

+
    +
  1. Sex as normal activity — it’s just going on in the background, and no other non-player characters pay much attention;
  2. +
  3. Sex as conscious performance — sex where the participants intend to be watched, and other non-player characters do pay attention (this may include consciously eroticised performance);
  4. +
  5. Sex as part of a religious or other ritual event — this is related to, and is, sex as conscious performance, but the purpose of the performance is symbolic and/or sacramental. This doesn’t mean it is not eroticised, but it may not be eroticised.
  6. +
+

By ‘eroticised’, I’m meaning deliberately intended to trigger sexual feelings in the audience — which, if the player character is present, includes the player.

+

Sexual violence between non-player characters

+

In a world in which there are characters who are thuggish, who seek to dominate, terrorise and subdue other characters, whether those characters are outlaws or soldiers or aristocrats, to pretend that rape would not be used as a means to dominate, terrorise or subdue is… bowdlerisation. It’s unrealistic, and it’s a morally indefensible choice.

+

So there has to be a mechanism for non-player characters to decide to commit acts of sexual violence towards other non-player characters. The player must at least hear of such events through the gossip network, and should be able to find the specific non-player characters involved, and speak to them. Whether it’s necessary to portray acts of sexual violence on screen is something I’m much less persuaded by, simply because it runs the risk of eroticising them.

+

Mutually consented sexual activity between the player character and non-player characters

+

Mutually consented sexual behaviour between the player character and (certain, scripted) non-player characters has been a feature of video games for some time, and has occasionally been portrayed with real sensitivity and eroticism. Two cases I would point to are

+
    +
  1. The sex scene between Geralt and Shani in The Witcher;
  2. +
  3. The sex scene between V and Judy in Cyberpunk 2077.
  4. +
+

Cyberpunk is a largely non-cutscene game, but the sex scenes is a cutscenes and I completely understand why, from a technical point of view: the player does not have, either with mouse and keyboard or with a game controller, nearly enough control over their character to convey the subtlety and nuance of a good sex scene. Sex scenes in most video games are also pretty rare, and that must be at least partly because of cultural prurience.

+

But if a game allows a player to have a long lasting, narratively sexual relationship with a non-player character, as many games do, then sex is a behaviour which may happen repeatedly, and just playing the same cutscene over and over again is not going to be an adequate way of representing that.

+

The ideal would be to have a moderately large library of brief motion captures of people authentically having sex, and to be able to select performances at random from that library to apply to the body models of the characters who in the game are having sex, whether that be the player character with a non-player character, or two non-player characters. In the case where the player character is involved, this would happen in the location where the player chose to initiate it, so it wouldn’t be a cutscene in the normal sense; but I think that the controller should be disabled for the duration of the performance.

+

Sexual violence by one non-player character towards another

+

This is at least implicitly represented in existing video games, and while caution about eroticising it should be maintained, I think it’s something which should be narratively possible.

+

Sexual violence from the player character towards non-player characters

+

This would be extremely tricky (and controversial!) to handle; I think it ought to be in the narrative toolkit, but I have no specification to offer just now.

+

Sexual violence from a non-player character towards the player character

+

Even trickier!

+
\ No newline at end of file diff --git a/docs/codox/Organic_Quests.html b/docs/codox/Organic_Quests.html index 055e53e..2308755 100644 --- a/docs/codox/Organic_Quests.html +++ b/docs/codox/Organic_Quests.html @@ -1,25 +1,25 @@ -Organic Quests

Organic Quests

-

The structure of a modern Role Playing Came revolves around ‘quests’: tasks that the player character is invited to do, either by the framing narrative of the game or by some non-player character (‘the Quest Giver’). Normally there is one core quest which provides the overarching narrative for the whole game. [Wikipedia](https://en.wikipedia.org/wiki/Quest_(gaming)) offers a typology of quests as follows:

+Organic Quests

Organic Quests

+

The structure of a modern Role Playing Came revolves around ‘quests’: tasks that the player character is invited to do, either by the framing narrative of the game or by some non-player character (‘the Quest Giver’). Normally there is one core quest which provides the overarching narrative for the whole game. Wikipedia offers a typology of quests as follows:

    -
  1. Kill quests
  2. -
  3. Combo quests
  4. -
  5. Delivery quests
  6. -
  7. Gather quests
  8. -
  9. Escort quests
  10. -
  11. Syntax quests
  12. -
  13. Hybrids
  14. +
  15. Kill quests
  16. +
  17. Combo quests
  18. +
  19. Delivery quests
  20. +
  21. Gather quests
  22. +
  23. Escort quests
  24. +
  25. Syntax quests
  26. +
  27. 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. 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 conincident, then a delivery quest and a fetch quest become the same thing. Thus

+

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. -
  3. The location from which the quest object must be collected;
  4. -
  5. The location to which the quest object must be delivered;
  6. -
  7. The location of the quest giver at the end of the quest.
  8. +
  9. The location of the quest giver at the beginning of the quest;
  10. +
  11. The location from which the quest object must be collected;
  12. +
  13. The location to which the quest object must be delivered;
  14. +
  15. 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 at the end of the quest, 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.

+

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.

My understanding is that what Wikipedia means by a ‘syntax quest’ is what one would normally call a puzzle.

@@ -27,19 +27,21 @@

Combo quests are not, in my opinion, particularly relevant to the sorts of game we’re discussing here.

So essentially quests break down into three core types

    -
  1. Fetch and deliver quests
  2. -
  3. Escort quests
  4. -
  5. Puzzles
  6. +
  7. Fetch and deliver quests
  8. +
  9. Escort quests
  10. +
  11. Puzzles

which are combined together into more or less complex chains, where the simplest chain is a single quest.

Given that quests are as simple as this, it’s obvious that narrative sophistication is required to make them interesting; and this point is clearly made by some variants of roguelike games which procedurally generate quests: they’re generally pretty dull. By contrast, the Witcher series is full of fetch-quests which are made to really matter by being wrapped in interesting character interaction and narrative plausibility. Very often this takes the form of tragedy: as one reviewer pointed out, the missing relatives that Geralt is asked to find generally turn out to be (horribly) dead. In other words, creative scripting tends to deliver much more narratively satisfying quests than is usually delivered by procedural generation.

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, 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.

Obviously, this doesn’t stop you doing jobs you get directly paid/rewarded for, but I’d like the web of obligation to be at least potentially much richer than just tit for tat.

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, and Middle Earth: Shadow of War have a procedural story system called Nemesis, which is worth a look.

\ No newline at end of file +

Stuff to consider

+

The games Middle Earth: Shadow of Mordor, and Middle Earth: Shadow of War have a procedural story system called Nemesis, which is worth a look.

+

There’s an interesting critique of Red Dead Redemption 2 which is relevant to what I’m saying here.

+
\ No newline at end of file diff --git a/docs/codox/Pathmaking.html b/docs/codox/Pathmaking.html index 966e6e7..6586e04 100644 --- a/docs/codox/Pathmaking.html +++ b/docs/codox/Pathmaking.html @@ -1,79 +1,98 @@ -Pathmaking

Pathmaking

+Pathmaking

Pathmaking

NOTE: this file is called ‘pathmaking’, not ‘pathfinding’, because ‘pathfinding’ has a very specific meaning/usage in game design which is only part of what I want to talk about here.

-

Stages in creating routes between locations

-

The ‘procedural’ phase

-

see also Baking-the-world

+

NOTE: Work on this is being carried on in a separate library, Walkmap, q.v.

+

Stages in creating routes between locations

+

see also Baking the world

Towards the end of the procedural phase of the build process, every agent within the game world must move through the complete range of their needs-driven repertoire. Merchants must traverse their trading routes; soldiers must patrol routes within their employers domain; primary producers and craftspeople must visit the craftspeople who supply them; every character must visit their local inn, and must move daily between their dwelling and their workplace if different; and so on. They must do this over a considerable period - say 365 simulated days.

At the start of the baking phase, routes - roads, tracks and paths - designed by the game designers already exist.

The algorithmic part of choosing a route is the same during this baking phase as in actual game play except that during the baking phase the routemap is being dynamically updated, creating a new path or augmenting an existing path wherever any agent goes.

Thus the ‘weight’ of any section of route is a function of the total number of times that route segment has been traversed by an agent during this baking phase. At the end of the baking phase, routes travelled more than R times are rendered as roads, T times as tracks, and P times as footpaths, where R, T and P are all chosen by the game designer but generally R > T > P.

-

Algorithmic rules

+

Routing

+

Routing is fundamentally by A*, I think.

+

Algorithmic rules

    -
  1. No route may pass through any part of a reserved holding, except the holding which is its origin, if any, and the holding which is its destination (and in any case we won’t render paths or roads within holdings, although traversal information may be used to determine whether a holding, or part of it, is paved/cobbled;
  2. -
  3. No route may pass through any building, with the exception of a city gate;
  4. -
  5. We don’t have bicycles: going uphill costs work, and you don’t get that cost back on the down hill. Indeed, downhills are at least as expensive to traverse as flat ground;
  6. -
  7. Any existing route segment costs only a third as much to traverse as open ground having the same gradient;
  8. -
  9. A more used route costs less to traverse than a less used route.
  10. +
  11. No route may pass through any part of a reserved holding, except the holding which is its origin, if any, and the holding which is its destination, if any (and in any case we won’t render paths or roads within holdings, although traversal information may be used to determine whether a holding, or part of it, is paved/cobbled;
  12. +
  13. No route may pass through any building, with the exception of a city gate;
  14. +
  15. We don’t have bicycles: going uphill costs work, and you don’t get that cost back on the down hill. Indeed, downhills are at least as expensive to traverse as flat ground;
  16. +
  17. Any existing route segment costs only a third as much to traverse as open ground having the same gradient;
  18. +
  19. A more used route costs less to traverse than a less used route.
-

River crossings

-

Crossing rivers is expensive - say five times as expensive as level open ground (but this will probably need tuning). Where a river is shallow enough, (i.e. where the amount of water passing is below some threshold) then a path crossing will be rendered as stepping stones and a track crossing as a ford. Where it’s deeper than that, a path crossing either isn’t rendered at all or is rendered as a light footbridge. A track or road crossing is rendered as a bridge. However, the maximum length of a bridge varies with the amount of traffic on the route segment, and if the crossing exceeds that length then a ferry is used. Road bridges will be more substantial than track bridges, for example in a biome with both timber and stone available road bridges might be rendered as stone bridges while track bridges were rendered as timber. If the watercourse is marked as navigable, the bridge must have a lifting section. It is assumed here that bridges are genetic buildings like most other in-game buildings, and so don’t need to be individually designed.

-

Representation

+

Step costing:

+

Step cost is something like:

+
(/
+  (-
+    (+ distance
+      (expt height-gained height-gain-exponent)
+      (reduce + (map crossing-penalty watercourses-crossed)))
+    (reduce + (map bridge-bonus bridges-crossed)))
+  (or road-bonus 1))
+
+

Where

+
    +
  • distance traversed is in metres;
  • +
  • height-gained is in metres;
  • +
  • height-gain-exponent is tunable;
  • +
  • river crossing-penalty varies with a (tunable) exponent of the flow;
  • +
  • bridge-bonus works as follows: bridge bonus for a bridge entirely cancels the river crossing penalty for the watercourse the bridge crosses; bridge bonus for a ferry cancels a (tunable) fraction the river crossing penalty.
  • +
  • road-bonus for a road is substantial - probably about 8; for a track is less than road but greater than footpath, say 5; for a footpath has to be at least 3, to provide an incentive to stick to paths. All these values are tunable. Road bonus ought also to increase a small amount with each traversal of the path segment, but that’s still to be worked on.
  • +
+

A lot of this is subject to tuning once we have prototype code running.

+

Somewhere into all this I need to factor tolls charged by local aristons, especially for bridges/ferries, and risk factors of hostile action, whether by outlaws or by hostile factions. But actually, that is at a per actor level, rather than at a pathmaking level: richer actors are less deterred by tolls, better armed actors less deterred by threat of hostile action.

+

River crossings

+

River crossings appear automatically when the number of traversals of a particular route across a watercourse passes some threshhold. The threshold probably varies with an exponent of the flow; the threshold at which a ferry will appear is lower (by half?) than the threshold for a bridge. Of course river crossings, like roads, can also be pre-designed by game designers.

+

Where a river is shallow enough, (i.e. where the flow is below some threshold) then a path crossing will be rendered as stepping stones and a track crossing as a ford. Where it’s deeper than that, a path crossing either isn’t rendered at all or is rendered as a light footbridge. A track or road crossing is rendered as a bridge. However, the maximum length of a bridge varies with the amount of traffic on the route segment, and if the crossing exceeds that length then a ferry is used. Road bridges will be more substantial than track bridges, for example in a biome with both timber and stone available road bridges might be rendered as stone bridges while track bridges were rendered as timber. If the watercourse is marked as navigable, the bridge must have a lifting section. It is assumed here that bridges are genetic buildings like most other in-game buildings, and so don’t need to be individually designed.

+

Representation

At some stage in the future I’ll have actual game models to work with and $DEITY knows what the representation of those will be like, but to get this started I need two inputs: a heightmap, from which gradients can be derived, and a route map. The heightmap can conventionally be a monochrome raster image, and that’s easy. The route map needs to be a vector representation, and SVG will be as convenient as any. So from the point of view of routing during the baking phase, a route map shall be an SVG with the following classes:

    -
  • exclusion used on polygons representing e.g. buildings, or impassable terrain which may not be traversed at all;
  • -
  • openwater used on polygons representing oceans and lakes, which may be traversed only by boat (or possibly swimming, for limited distances);
  • -
  • watercourse used on paths representing rivers or streams, with some additional attribute giving rate of flow;
  • -
  • navigable may be an additional class on a path also marked watercourse indicating that it is navigable by cargo vessels;
  • -
  • route used on paths representing a path, track or road whose final representation will be dynamically assigned at the end of baking, with some additional attribute giving total traversals to date;
  • -
  • path used on paths representing a path designed by the designers, which will certainly be rendered as a path no matter how frequently it is traversed;
  • -
  • track used on paths representing a track designed by the designers, which will certainly be rendered as a track no matter how frequently it is traversed;
  • -
  • road used on paths representing a road designed by the designers, which will certainly be rendered as a road no matter how (in)frequently it is traversed.
  • +
  • exclusion used on polygons representing e.g. buildings, or impassable terrain which may not be traversed at all;
  • +
  • openwater used on polygons representing oceans and lakes, which may be traversed only by boat (or possibly swimming, for limited distances);
  • +
  • watercourse used on paths representing rivers or streams, with some additional attribute giving rate of flow;
  • +
  • navigable may be an additional class on a path also marked watercourse indicating that it is navigable by cargo vessels;
  • +
  • route used on paths representing a path, track or road whose final representation will be dynamically assigned at the end of baking, with some additional attribute giving total traversals to date;
  • +
  • path used on paths representing a path designed by the designers, which will certainly be rendered as a path no matter how frequently it is traversed;
  • +
  • track used on paths representing a track designed by the designers, which will certainly be rendered as a track no matter how frequently it is traversed;
  • +
  • road used on paths representing a road designed by the designers, which will certainly be rendered as a road no matter how (in)frequently it is traversed.

At the end of the baking process the routing engine should be able to write out an updated SVG. New routes should be splined curves, so that they have natural bends not sharp angles.

-

The ‘Walkmap’

+

The ‘Walkmap’

Conventional game pathfinding practice is to divide the traversable area into a mesh of ‘convex polygons’, where a ‘convex polygon’ in this sense is, essentially, a polygon having no bays. Routes traverse from a starting point to the centre of a polygon ajacent to the polygon in which the starting point is located. I have reservations as to whether this will do what I need since I’m not convinced it will produce naturalistic paths; however, it’s worth at least experimenting with.

-

There are existing utilities (such as hmm) which convert heightmaps into suitable geometry files; however all I’ve found so far convert to [binary STL](https://en.wikipedia.org/wiki/STL_(file_format)). This isn’t a format I find very useful; I’d prefer an XML dialect, and SVG is good enough for me.

+

There are existing utilities (such as hmm) which convert heightmaps into suitable geometry files; however all I’ve found so far convert to binary STL. This isn’t a format I find very useful; I’d prefer an XML dialect, and SVG is good enough for me.

hmm converts the heightmap into a tesselation of triangles, which are necessarily convex in the sense given above. Utilities (such as binary-stl-toASCII) exist to convert binary STL to an ASCII encoded equivalent, which may be easier to parse.

So the pipeline seems to be

    -
  1. heightmap to binary STL
  2. -
  3. (optional) binary STL to ASCII STL
  4. -
  5. STL to SVG (where ‘SVG’ here is shorthand for a convenient vector format)
  6. -
  7. Exclude holdings, buildings, open water, and other exclusions
  8. -
  9. Where we have excluded exclusions, ensure that any non-convex polygons we’ve created are divided into new convex polygons.
  10. +
  11. heightmap to binary STL
  12. +
  13. (optional) binary STL to ASCII STL
  14. +
  15. STL to SVG (where ‘SVG’ here is shorthand for a convenient vector format)
  16. +
  17. Exclude holdings, buildings, open water, and other exclusions
  18. +
  19. Where we have excluded exclusions, ensure that any non-convex polygons we’ve created are divided into new convex polygons.

I shall have to write custom code for 4 and 5 above, and, looking at what’s available, probably 3 as well.

I’m working on a separate library, walkmap, which will attempt to implement this pipeline.

-

Pathmaking and scale

-

Dealing with large heightmaps - doing anything at all with them - is extremely compute intensive. Just converting a 1000x1000 heightmap from STL to SVG is currently taking 8 hours and 15 minutes; and it ends up with a 46 megabyte SVG file! However, most of the time cost is in writing. Reading the STL file takes four and a quarter seconds; converting that STL to SVG in memory takes less than five seconds. So the huge cost is writing the file with Dali.

-
walkmap.core=> (time (def stl (decode-binary-stl "../the-great-game/resources/maps/heightmap.stl")))
-"Elapsed time: 4285.231513 msecs"
-#'walkmap.core/stl
-walkmap.core=> (time (def svg (stl-to-svg stl)))
-"Elapsed time: 4865.798059 msecs"
-#'walkmap.core/svg
-
-

“Elapsed time: 2.969569560662E7 msecs”

+

Pathmaking and scale

+

Dealing with large heightmaps - doing anything at all with them - is extremely compute intensive.

We cannot effectively do routing at metre scale - which is what we ultimately need in settlements - across the entire thousand kilometre square map in one pass. But also we don’t need to because much of the continent is by design relatively unpeopled and relatively untracked. The basic concept of the Steppe is that there are two north/south routes, the one over the Midnight Pass into the Great Place and the one via Hans’hua down to the Cities of the Coast, and those can be part of the ‘designed roads’ map. So we can basically exclude most of the Steppe from routing altogether. We can also - for equally obvious reasons exclude the ocean. The ocean makes up roughly half of the 1000x1000 kilometre map, the steppe and plateau take up half of what’s left, mountain massifs eat into the remainder and my feeling is that much of the eastern part of the continent is probably too arid to be settled. So we probably end up only having to dynamically route about 20% of the entire map.

However, this doesn’t get round the main problem with scale, and pathmaking. If we pathmake at kilometre scale, then curves will be necessarily very long and sweeping - because each path segment will be at least a kilometre long. And, actually, that’s fine for very long distance roads in unpopulated fairly flat territory. It’s not so good for long distance roads in rugged terrain, but…

-

Phase one: hand-designed routes

+

Phase one: hand-designed routes

While, given the bottlenecks of the few mountain passes and the one possible pass over the plateau, the caravan routes we want would almost certainly emerge organically out of dynamic routing. But, actually, I know more or less where they need to be and it’s probably easiest to hand design them. It will certainly save an enormous amount of brute-force compute time.

I think I have to accept that if I want Alpe d’Huez-style switchbacks up the Sunset and Midnight passes, they’re going to have to be hand designed. The same applies to where the Hans’hua caravan road ascends the plateau.

-

Phase two: route segments ‘for free’ out of settlement activity

+

Phase two: route segments ‘for free’ out of settlement activity

If we start by pathmaking around settlements, we can make a first start by giving the template for a holding a segment of track parallel to and just in front of its frontage, and a segment of path along its left hand and rear edges. That, actually, is going to provide 90% of all routing within a settlement, and it’s done for us within the Settling-a-game-world phase.

-

Phase three: metre scale routing around settlements

+

Phase three: metre scale routing around settlements

So if we then collect groups of contiguous 100x100 metre zones each of which has at least one settled holding, we can route at one metre scale over that and what it will essentially do is join up and augment the route segments generated by settlement. Areas of dense settlement do not make up a great deal of the map. Note that experience may show that the metre scale routing is superflous.

-

Phases four, five and six: increasing granularity

+

Phases four, five and six: increasing granularity

Taking the augmented route map comprised of

    -
  1. The hand-designed, mainly long distance or plot-important routes;
  2. -
  3. The route segments bordering holdings;
  4. -
  5. The metre scale routing
  6. +
  7. The hand-designed, mainly long distance or plot-important routes;
  8. +
  9. The route segments bordering holdings;
  10. +
  11. The metre scale routing

we can then collect contiguous groups of zones each having at least one holding, where in phase four each zone is a kilometre square and divided into 100x100 grid so that we route at ten metre scale; in phase five we use ten kilometre by ten kilometre zones and we route at 100 metre scale; in phase six, 100 km by 100 km zones and we route at kilometre scale. This process should automatically link up all settlements on the south and west coasts, all those on the north coast, and all in the Great Place; and seeing that the posited pre-designed caravan roads already join the south coast to the north, the north to the Great Place and the Great Place to the south coast, we’re done.

At least one of phases three, four, five and six is probably redundant; but without trying I’m not sure which.

-

Tidying up

+

Relevant actor classes by phase

+

Craftspeople and primary producers do travel between settlements, but only exceptionally. They mainly travel within at most a few kilometres of home; so they are primarily relevant in phases four and five, and need not be activated during phase six. Similarly, merchants primarily travel between settlements, and rarely within settlements; therefore, they need not be activated in phase four, and probably not even in phase five; but they must do a lot of journeys - substantially their full repertoire - in phase six.

+

Tidying up

After the full set of increasing-scale passes is complete, we should automatically cull any route segments generated in the settlement phase which have never actually been traversed.

-

Following that, there may be scope for some final manual tweaking, if desired; I think this is most likely to happen where roads routed at kilometre scale cross rugged terrain.

\ No newline at end of file +

Following that, there may be scope for some final manual tweaking, if desired; I think this is most likely to happen where roads routed at kilometre scale cross rugged terrain.

+
\ No newline at end of file diff --git a/docs/codox/Populating-a-game-world.html b/docs/codox/Populating-a-game-world.html index c02a951..46fc6cd 100644 --- a/docs/codox/Populating-a-game-world.html +++ b/docs/codox/Populating-a-game-world.html @@ -1,297 +1,98 @@ -Populating a game world

Populating a game world

-

Saturday, 6 July 2013

-

(You might want to read this essay in conjunction with my older essay, Settling a game world, which covers similar ground but which this hopefully advances on)

+Populating a game world

Populating a game world

+

Saturday, 6 July 2013

+

(You might want to read this essay in conjunction with my older essay, Settling a game world, which covers similar ground but which this hopefully advances on)

For an economy to work people have to be able to move between occupations to fill economic niches. In steady state, non player character (NPC) males become adult as ‘vagrants’, and then move through the state transitions described in this document. The pattern for females is different.

-

Basic occupations

+

Basic occupations

The following are ‘unskilled’ occupations which form the base of the occupation system. Generally a male character at maturity becomes a ‘Vagrant’ and wanders though the world until he encounters a condition which allows him to advance up the occupation graph. If an occupation wholly fails, the character can revert to being a ‘Vagrant’ and start again.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + +
Occupation Dwelling condition New trade Notes
Vagrant None land available and animals available Herdsman
Vagrant None arable land available Farmer See crops
Vagrant None has weapons Outlaw
Herdsman None Insufficient food Vagrant
Farmer Farm Insufficient food Vagrant
Outlaw None loses weapons Vagrant
Vagrant None craftsman willing to take on apprentice Apprentice
Herdsman None arable land available Farmer
Outlaw None Battle hardened OutlawLeader
Apprentice (craftsman’s) Qualified Journeyman
Journeyman None Unserviced customers available Craftsman See crafts
Craftsman See crafts Too few customers Journeyman
Journeyman None arable land available Farmer
Vagrant None Lord with vacancies available Soldier See military
OutlawLeader None Unprotected farms available Laird See nobility
Occupation Dwelling Condition New trade Notes
Vagrant None land available and animals available Herdsman
Vagrant None arable land available Farmer See crops
Vagrant None has weapons Outlaw
Herdsman None Insufficient food Vagrant
Farmer Farm Insufficient food Vagrant
Outlaw None loses weapons Vagrant
Vagrant None craftsman willing to take on apprentice Apprentice
Herdsman None arable land available Farmer
Outlaw None Battle hardened OutlawLeader
Apprentice (craftsman’s) Qualified Journeyman
Journeyman None Unserviced customers available Craftsman See crafts
Craftsman See crafts Too few customers Journeyman
Journeyman None arable land available Farmer
Vagrant None Lord with vacancies available Soldier See military
OutlawLeader None Unprotected farms available Laird See nobility
-

Gender dimorphism

+

Gender dimorphism

In the paragraph above I said ‘a male character’. It may seem unfair to create a game world in which the sexual inequality of the real world is carried over, and for that reason it seems sensible that female children should have the same opportunities as male children. But games work on conflicts and injustices, and so it seems reasonable to me to have a completely different occupation graph for women. I haven’t yet drawn that up.

-

Wandering

+

Wandering

Vagrants wander in a fairly random way. While vagrants are wandering they are assumed to live off the land and require no resources. Solitary outlaws similarly wander until they find a leader, although they will avoid the areas protected by nobles. Herdsmen also wander but only over unenclosed pasture. They visit markets, if available, periodically; otherwise, they live off their herds. Journeymen wander from market to market, but are assumed to trade skills with farmers along the way.

-

Crafts

+

Crafts

Crafts are occupations which require acquired skills. In the initial seeding of the game world there are probably ‘pioneers’, who are special vagrants who, on encountering the conditions for a particular craft to thrive, instantly become masters of that craft.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Craft Dwelling Supplies Perishable? Customer types Needs market? Customers Supplier Suppliers Recruits
Solo Per journeyman Per apprentice
-

| | | | | | | — | — | — | | | | | | | | | | | Min | Max | Min | Max | Min | Max | | | | | — | | | | | | — | — | — | — | — | — | | | | | Smith | Forge | Metal Items | no | Farmer, Soldier | No | 6 | 10 | 4 | 6 | 1 | 3 | Miner | 1 | Vagrant | | Baker | Bakery | Bread | yes | All NPCs | No | 20 | 30 | 12 | 18 | 6 | 10 | Miller | 1 | Vagrant | | Miller | Mill | Flour, meal | no | Baker, Innkeeper | No | 2 | 3 | 1 | 2 | 1 | 1 | Farmer | 6 | Vagrant | | Weaver | Weaver’s house | Cloth | no | All NPCs | Yes | 6 | 10 | 4 | 6 | 1 | 3 | Herdsman | 2 | Vagrant | | Innkeeper | Inn | Food, hospitality | yes | Merhant, Soldier, Farmer, Lord | No | 10 | 20 | 5 | 10 | 2 | 4 | Farmer,Herdsman | 2 | Vagrant | | Miner | Mine | Ores | no | Smith | Yes | 2 | 3 | 1 | 2 | 1 | 1 | Farmer | 1 | Vagrant | | Butcher | Butchery | Meat | yes | All NPCs | No | 10 | 20 | 4 | 8 | 2 | 4 | Farmer, Herdsman | 2 | Vagrant | | Merchant | Townhouse | Transport, logistics | n/a | Craftsmen, nobility | Yes | 10 | 20 | 4 | 8 | 2 | 4 | n/a | n/a | Vagrant | | Banker | Bank | Financial services | yes | Merchant | Yes | 10 | 20 | 4 | 8 | 2 | 4 | n/a | n/a | Merchant | | Scholar | Academy | Knowledge | n/a | Ariston, Tyrranos, General, Banker | No | 1 | 4 | 1 | 2 | 0.25 | 0.5 | n/a | n/a | Vagrant | | Priest | Temple | Religion | n/a | All NPCs | No | 50 | 100 | | | | | | | Scholar | | Chancellor | Chancellory | Administration | n/a | Ariston, Tyrranos | No | 1 | 1 | 0 | 0 | 0 | 0 | | | Scholar | | Lawyer | Townhouse | Legal services | n/a | Ariston, Merchant, Banker | No | 4 | 6 | 2 | 3 | 1 | 2 | | | Scholar | | Magus | Townhouse | Magic | n/a | Tyrranos, General | No | 3 | 4 | 1 | 2 | 0.25 | 0.5 | | | Scholar |

+ + Craft Dwelling Supplies Perishable? Customer types Needs market? Customers Supplier Suppliers Recruits + Solo Per journeyman Per apprentice + Min Max Min Max Min Max +Smith Forge Metal Items no Farmer, Soldier No 6 10 4 6 1 3 Miner 1 Vagrant +Baker Bakery Bread yes All NPCs No 20 30 12 18 6 10 Miller 1 Vagrant +Miller Mill Flour, meal no Baker, Innkeeper No 2 3 1 2 1 1 Farmer 6 Vagrant +Weaver Weaver's house Cloth no All NPCs Yes 6 10 4 6 1 3 Herdsman 2 Vagrant +Innkeeper Inn Food, hospitality yes Merhant, Soldier, Farmer, Lord No 10 20 5 10 2 4 Farmer,Herdsman 2 Vagrant +Miner Mine Ores no Smith Yes 2 3 1 2 1 1 Farmer 1 Vagrant +Butcher Butchery Meat yes All NPCs No 10 20 4 8 2 4 Farmer, Herdsman 2 Vagrant +Merchant Townhouse Transport, logistics n/a Craftsmen, nobility Yes 10 20 4 8 2 4 n/a n/a Vagrant +Banker Bank Financial services yes Merchant Yes 10 20 4 8 2 4 n/a n/a Merchant +Scholar Academy Knowledge n/a Ariston, Tyrranos, General, Banker No 1 4 1 2 0.25 0.5 n/a n/a Vagrant +Priest Temple Religion n/a All NPCs No 50 100 Scholar +Chancellor Chancellory Administration n/a Ariston, Tyrranos No 1 1 0 0 0 0 Scholar +Lawyer Townhouse Legal services n/a Ariston, Merchant, Banker No 4 6 2 3 1 2 Scholar +Magus Townhouse Magic n/a Tyrranos, General No 3 4 1 2 0.25 0.5 Scholar +

A craftsman starts as an apprentice to a master of the chosen crafts. Most crafts recruit from vagrants, A character must be a journeyman merchant before becoming an apprentice banker, while various intellectual crafts recruit from journeyman scholars.

It’s assumed that a journeyman scholar, presented with the opportunity, would prefer to become an apprentice magus than a master scholar.

+

Related crafts

+

There are groups of crafts which should probably be seen as related crafts, where apprenticeship in one should serve as qualification to serve as journeyman in another. For example, there is a family of woodworking crafts, whose base is probably Joiner.

+

Crafts within this family include

+
    +
  • Boatwright
  • +
  • Cabinetmaker
  • +
  • Cartwright
  • +
  • Cooper
  • +
  • Lutanist
  • +
  • Military Artificer
  • +
  • Millwright
  • +
  • Turner
  • +
+

So although I think these are separate crafts, all are Joiners; all can undertake construction joinery work; and a journeyman who has served as apprentice to any can serve as journeyman to any other. Since journeymen will typically serve under more than one master before settling down, it will be possible for one person to have served under masters in two different related trades and therefore be qualified to set up as a master of either.

A journeyman settles and becomes a master when he finds a location with at least the solo/min number of appropriate customer type who are not serviced by another master craftsman of the same craft; he also (obviously) needs to find enough free land to set up his dwelling. The radius within which his serviced customers must live may be a fixed 10Km or it may be variable dependent on craft. If there are unserviced customers within his service radius, the master craftsman may take on apprentices and journeymen to service the additional customers up to a fixed limit – perhaps a maximum of four of each, perhaps variable by craft. If the number of customers falls, the master craftsman will first dismiss journeymen, and only in desperate circumstances dismiss apprentices. Every apprentice becomes a journeyman after three years service.

The list of crafts given here is illustrative, not necessarily exhaustive.

-

Aristocracy

+

Aristocracy

As in the real world, aristocracy is essentially a protection racket, and all nobles are originally outlaw leaders who found an area with rich pickings and settled down.

- - - - - - - - - - - - - - - - - - - - - - - -
Rank Follower rank Client type Clients protected Trade in market Followers per client
Min Max Min Max Min Max
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bonnet Laird Private Farmer 6 20 0 100 0.25 0.5
Ariston Captain Bonnet Laird 10 30 25 1000 0.5 1
Tyrranos General Ariston 10 unlimited 250 unlimited 0.1 0.5
+ Rank Follower rank Client type Clients protected Trade in market Followers per client + Min Max Min Max Min Max +Bonnet Laird Private Farmer 6 20 0 100 0.25 0.5 +Ariston Captain Bonnet Laird 10 30 25 1000 0.5 1 +Tyrranos General Ariston 10 unlimited 250 unlimited 0.1 0.5 +

Every noble establishes a market and, if he employs a chancellor, taxes trade in it. Crafts which ‘need a market’ can only be established in the vicinity of a market, irrespective of whether there are sufficient customers elsewhere. All non-perishable goods are traded through the markets, and merchants will transfer surpluses between markets if they can make a profit from it.

My world has essentially three ranks of nobility. The title of the lowest rank will probably change to something vaguely italianate. An aristocrat advances to the next rank when either the requisite number of clients become available in the locality to support the next rank, or the trade in his market becomes sufficient to support the next rank.

Obviously when a province has eleven unprotected bonnet lairds, under the rules given above any of them may become the ariston, and essentially it will be the next one to move after the condition becomes true. If the number of available clients drops below the minimum and the market trade also drops below the minimum, the noble sinks to a lower level – in the case of the bonnet laird, to outlaw leader.

-

Military

+

Military

The aristocracy is supported by the military. An outlaw becomes a soldier when his leader becomes a noble. Otherwise, vagrants are recruited as soldiers by bonnet lairds or sergeants who have vacancies. Captains are recruited similarly by aristons or generals, and generals are recruited by tyrranos. If the conditions for employment no longer exist, a soldier is allowed a period of unemployment while he lives off savings and finds another employer, but if no employer is found he will eventually become an outlaw (or, if an officer, an outlaw leader). A private is employed by his sergeant or bonnet laird, a sergeant by his captain, a captain by his arison or general, a general by his tyrranos.

- - - - - - - - - - - - - - - - - - - - -
Rank Follower rank Followers Condition New rank
Min Max
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Private None 0 0 Battle hardened, unled privates Sergeant
Sergeant Private 5 15 More battle hardened, unled sergeantts Captain
Captain Sergeant 5 15 More battle hardened, unled captains General
General Captain 5 unlimited
-

Soldiers have no loyalty to their employer’s employer.

\ No newline at end of file + Rank Follower rank Followers Condition New rank + Min Max +Private None 0 0 Battle hardened, unled privates Sergeant +Sergeant Private 5 15 More battle hardened, unled sergeantts Captain +Captain Sergeant 5 15 More battle hardened, unled captains General +General Captain 5 unlimited + +

Soldiers have no loyalty to their employer’s employer.

+
\ No newline at end of file diff --git a/docs/codox/Roadmap.html b/docs/codox/Roadmap.html new file mode 100644 index 0000000..a322cec --- /dev/null +++ b/docs/codox/Roadmap.html @@ -0,0 +1,24 @@ + +Roadmap (obsolete)

Roadmap (obsolete)

+

This document outlines a plan to move forward from where I am in June 2021.

+

NOTE: this document has been superceded.

+

JMonkeyEngine

+

JMonkeyEngine is not, at this time, an AAA game engine. But at the same time I’m never, really, going to build an AAA game. It is a working game engine which can display characters on screen in scenery and have them move around, and, actually, they can be fairly sophisticated. It will be resaonably easy to integrate Clojure code with JMonkeyEngine - easier than it would be to integrate either Clojure or Common Lisp with Unreal Engine or Unity 3D. As a significant added bonus, JMonkeyEngine is open source.

+

Consequently I plan to stop agonising about what game engine to use, and seriously focus on getting something working in JMonkeyEngine.

+

Not Reinventing Wheels

+

JMonkeyEngine already has working code for walking animated characters, which is entirely adequate to proof-of-concept what I want to do. Rather than try to implement them myself, I just intend to use existing JMonkeyEngine code as far as possible.

+

The 1Km World

+

I propose to build a 1Km square world, containing one settlement, as a proof of concept for

+
    +
  1. Procedural (genetic) buildings;
  2. +
  3. Procedural settlement planning;
  4. +
  5. Procedural characters, probably based on MakeHuman ‘Mass Produce’ plugin, using walk animation based on TestWalkingChar;
  6. +
  7. Characters with their own hierarchy of needs, and their own means of planning to fulfil these;
  8. +
  9. Characters with individualised knowledge about the world;
  10. +
  11. Characters who can parse typed questions, and produce either a textual or audio response;
  12. +
  13. Characters with procedurally generated accents (very stretch goal)!
  14. +
  15. Characters who can listen to spoken questions, and produce audio responses.
  16. +
+

At that stage, I have a technology demonstrator that will be interesting. It still leaves the big procedural world builder still to do, but it would be enough technology to get other people interested in the project.

+
\ No newline at end of file diff --git a/docs/codox/Sandbox.html b/docs/codox/Sandbox.html new file mode 100644 index 0000000..5e8679b --- /dev/null +++ b/docs/codox/Sandbox.html @@ -0,0 +1,41 @@ + +Sandbox

Sandbox

+

Up to now I’ve been thinking of the Great Game as essentially an RPG with some sandbox-like elements; but I think it may be better to think of it as a sandbox game with some RPG like elements.

+

Why?

+

The core of the game is a world in which non-player characters have enough individual knowledge of the world and their immediate surroundings that they can sensibly answer questions like

+
    +
  • Where is the nearest craftsman of this craft?
  • +
  • What price can I expect to get for this item in the local market?
  • +
  • What news have you heard recently?
  • +
  • Where does this person from your village live?
  • +
+

and where there’s a sufficiently sophisticated and robust economy simulation that buying goods in one market and selling them in another is viable.

+

The original BBC Micro space trading game Elite had very little more in terms of game mechanics than a sandbox with a means to navigate it and an economy simulation, which wasn’t even nearly as sophisticated as the one I have working now. Yet that combination resulted in engaging game play.

+

Main sandbox roles

+

The idea of a sandbox is that the player character should be able to do pretty much anything they like within the mechanics of the game. From that, it seems to me reasonable that the player ought to be able to do more or less everything a non-player character can do. But creating the game mechanics to make each additional task doable takes time and investment, so there’s a need to prioritise.

+

So, as Elite did, I propose to make the first available sandbox roles

+

Merchant

+

Someone who travels from city to city, buying goods cheap in one and selling them for more in another; and

+

Outlaw

+

Someone who intercepts and steals from merchants (and may also attack outlying farms and villages)

+

Second tier playable roles

+

The next tier of playable roles rotates around issues arising from the mercantile ecosystem.

+

Aristocracy

+

Aristocrats are basically settled outlaws who seek to establish a monopoly on extracting taxes from inhabitants and travellers in a particular region by driving out all other outlaws. Within the domain of an aristocrat, you have to pay tax but you’re reasonably safe from being attacked by other outlaws and losing everything. Aristocrats may also maintain and improve roads and bridges and do other things to boost the economy of their territory, may expand into adjoining territory with no current aristocratic control, and may wage war on other aristocrats.

+

An outlaw ought to be able to become an aristocrat, by dominating an ungoverned area or by defeating an existing aristocrat.

+

Soldiery

+

Soldiers, like aristocrats, are basically on the same spectrum as outlaws. Outlaws may hire themselves out to merchants as caravan guards, or to aristocrats as soldiers. Soldiers or guards, falling on bad times, may revert to outlawry.

+

Routine, Discretion and Playability

+

There’s a term that’s used in criticism of many computer games which is worth thinking about hard here: that term is ‘farming’. ‘Farming’, in this sense, is doing something repetitive and dull to earn credits in a game. Generally this is not fun. What makes roles in a game-world fun is having individual discretion — the ability to choose between actions and strategies — and a lack of routine.

+

Most craft skills — especially in the learning phase — are not like this, and crafts which are sophisticated enough to be actually engaging are very hard to model in a game. Learning a craft is essentially, inherently, repetitive and dull, and if you take that repetition out of it you probably don’t have enough left to yield the feeling of mastery which would reward success; so it doesn’t seem to me that making craft roles playable should be a priority.

+

Cruise control

+

One of the most enjoyable aspects of The Witcher 3 — still my go-to game for ideas I want to improve on — is simply travelling through the world. Although fast travel is possible I find I rarely use it, and a journey which takes fifteen minutes of real world wall clock time can be enjoyable in and of itself. This is, of course, a credit to the beautiful way the world is realised.

+

(It’s worth noting that Kenshi, a game I’m coming to greatly admire, does not allow fast travel at all, but has an equivalent of ‘cruise control’ — you can set a destination and then accelerate time and simply watch as your characters journey).

+

But nevertheless, in The Witcher 3, a decision was made to pack incident fairly densely — because players would find just travelling boring. This leads to a situation where peaceful villages exist two minutes travel from dangerous monsters or bandit camps, and the suspension of disbelief gets a little strained. Building a world big enough that a market simulation is believable means that for the individual, the travel time to a market where a particular desired good is likely to be cheaper becomes costly in itself. Otherwise, there’s no arbitrage between markets and no ecological niche for a merchant to fill. The journey time from market to market has to be several in-game days.

+

An in-game day doesn’t have to be as long as a wall clock day, and, indeed, typically isn’t. But nevertheless, doing several game days of incident-free travel, even in beautiful scenery, is not going to be engaging — which implies a fast-travel mechanic.

+

I don’t like fast travel, I find it a too-obvious breaking of immersion. Also, of course, one of the interesting things about a game in a merchant/outlaw ecosystem is the risk of interception on a journey. The Dragon Age series handled interrupted travel in ‘fast travel’ by randomly interrupting the loading screen you get when moving from location to location in Dragon Age’s patchwork worlds by dumping you into a tiny arena with enemies. That’s really, really bad — there’s no other way to say this. Everything about it shouts artifice.

+

So I’m thinking of a different mechanism: one I’m calling cruise control.

+

You set out on a task which will take a long time — such as a journey, but also such as any routine task. You’re shown either a ‘fast forward’ of your character carrying out this task, or a series of cinematic ‘shots along the way’. This depends, of course, on there being continuous renderable landscape between your departure and your destination, but there will be. This fast-forward proceeds at a substantially higher time gearing than normal game time — ten times as fast perhaps; we need it to, because as well as doing backgound scenery loading to move from one location to another, we’re also simulating lots of non-player agents’ actions in parts of the world where the player currently isn’t. So a ‘jump cut’ from one location to another isn’t going to work anyway.

+

The player can interrupt ‘fast forward’ at any time. But also, the game itself may bring you out of fast forward when it anticipates that there may be action which requires decision — for example, when there are outlaws in the vicinity. And it will do this before the player’s party is under immediate attack — the player will have time to take stock of the situation and prepare appropriately. Finally, this will take place in the full open world; the player will have the option to choose not to enter the narrow defile, for example, to ask local people (if there are any) for any news of outlaw activity, or, if they are available, to send forward scouts.

+
\ No newline at end of file diff --git a/docs/codox/Selecting_Character.html b/docs/codox/Selecting_Character.html new file mode 100644 index 0000000..4d13d95 --- /dev/null +++ b/docs/codox/Selecting_Character.html @@ -0,0 +1,52 @@ + +Selecting the Player Character

Selecting the Player Character

+

Background

+

Many computer role playing games, particularly older ones such as Neverwinter Nights, allow you to ‘design’ your player character from a fairly broad canvas. Race, class, attributes, gender and appearance are all selectable.

+

Choice has eroded over time. For example the Dragon Age series, where you can chose between three races, two genders, and a small number of classes. In the Mass Effect trilogy, you play as Shepard, who is human and essentially a Fighter, but can be either male or female and whose appearance you can customise. You can play as either lawful good or chaotic neutral. In Cyberpunk 2077, you play as V, who is human, either male or female, essentially a Fighter, and chaotic neutral.

+

In more recent games, there has been a trend towards more limited choice. In the games of The Witcher series, you get no choice at all, but play as Geralt of Rivia, who in the categorisation of Dungeons and Dragons, is a Fighter/Ranger, male, human, and somewhere between chaotic good and chaotic neutral depending on how you play him. In the Horizon series, you play as Aloy, again a Fighter/Ranger, female, human, and essentially chaotic good.

+

As I’ve argued elsewhere, part of the reason for limiting choice is voice acting.

+

Limiting choice of player character, especially in games with increasingly highly scripted stories, limits replayability; after two or three playthroughs, there are very few interesting surprises left.

+

The Self-voiced Player

+

If we have voice interaction sufficiently sophisticated that we can allow the player character to say more or less whatever they want to say — and my argument here is that we can do this — then we don’t need voice acting for the player character, and that gives us a lot of freedom. There’s then really no reason why the player can’t inhabit any character in the game world and play as that character.

+

Tinder as a Character Selector

+

Tinder is a dating app. It shows you pictures (with brief profiles) of potential partners, and you choose from them by swiping left to reject them, or right to express interest in them. That’s a kernel of an idea for how to select from among a large selection of people.

+

So how about:

+
    +
  1. The game developer selects a large subset of characters in the game as potentially playable. This might be as large as all characters who are not plot characters, as small as only soldiers, or most plausibly, any adult who is not yet in a long term romantic relationship. This forms the candidate set.
  2. +
  3. In the character selector, the game shows a character chosen at random from the set, and, each time the player rejects the character shown, shows another until the player accepts a character.
  4. +
+

That works, but we can do better.

+

Refining the Selection

+

Suppose, below the image of the character on the selection screen, we have a short text caption with name, age, home, occupation, gender, and below that, we have a row of icons showing attributes, with some representation of the character’s relative measurement of that attribute. Clicking one of these attribute icons would be interpreted as meaning ‘show me a character quite like the current character, but having a higher score on this particular attribute’.

+

Refinable Attributes

+

In lots of games which present the player with dialogue options, there are some options which can’t be selected unless the player character passes a ‘skill check’. Very often, for example, a player won’t be able to issue a particular threat unless they have a specific value of strength, or to say something flirtatious unless they have a specific value of charm.

+

It makes no sense in a game in which the player gets to freely choose what to say for an attribute like ‘charm’ to be a refinable attribute. Instead, responding to ‘charming’ or flirtatious or threatening or funny or sexually suggestive speech is a matter for the programming of a particular non-player character (although the interpretation of the speech and the tagging of it as charming or flirtatious or threatening or funny or suggestive would be a function of the top level speech input processor).

+

So, sensibly refinable attributes might include things like

+
    +
  1. Strength;
  2. +
  3. Agility;
  4. +
  5. Dexterity;
  6. +
  7. Endurance.
  8. +
+

I did think that ‘intelligence’ or ‘learning’ might be on that list but the more I think of it, the harder I find it to understand how low intelligence might be represented in a game in which the player speaks freely.

+

There’s another attribute icon with slightly different semantics which might sensibly be added, and that’s gender. Selecting this icon would be interpreted as meaning ‘show me a character quite like the current character, but having a different gender’.

+

Summary design

+

So the character selecter now looks like

+
    +
  1. A main area in which a rendering of the proposed character is shown; this rendering can be zoomed and rotated, so that the player can look at the face and body from different angles;
  2. +
  3. A description panel, normally hidden but when displayed replacing the character rendering in the main area, giving fuller biographical information about the character;
  4. +
  5. Below the main area, a caption, giving name, age, gender, occupation, home;
  6. +
  7. To the right hand side, a vertical column of attribute icons.
  8. +
+

To interact with the screen, the player can

+
    +
  1. Zoom in and out on the rendered image, for example with a mouse scroll wheel or the left and right trigger buttons of a game controller;
  2. +
  3. Rotate the rendered image, for example by dragging with the right mouse button held down or with the right joystick of a game controller;
  4. +
  5. Toggle between the character render and the description panel;
  6. +
  7. When the description panel is displayed, scroll it;
  8. +
  9. Select any attribute icon to refine the choice of character;
  10. +
  11. ‘Swipe left’ (or other action) to reject the current choice of character and choose another, without refining in any specific way;
  12. +
  13. ‘Swipe right’ to select the current character and procede into the game.
  14. +
+
\ No newline at end of file diff --git a/docs/codox/Settling-a-game-world.html b/docs/codox/Settling-a-game-world.html index cbf569e..5d90dc9 100644 --- a/docs/codox/Settling-a-game-world.html +++ b/docs/codox/Settling-a-game-world.html @@ -1,68 +1,69 @@ -Settling a game world

Settling a game world

-

Wednesday, 30 December 2009

-

This essay is part of a series with ‘Worlds and Flats’ and ‘The spread of knowledge in a large game world’; if you haven’t read those you may want to read them before reading this. This essay describes how a large world can come into being and can evolve. I’ve written again on this subject since - see ‘Populating a game world’)

-

Microworld

+Settling a game world

Settling a game world

+

Wednesday, 30 December 2009

+

This essay is part of a series with ‘Worlds and Flats’ and ‘The spread of knowledge in a large game world’; if you haven’t read those you may want to read them before reading this. This essay describes how a large world can come into being and can evolve. I’ve written again on this subject since - see ‘Populating a game world’)

+

Microworld

Some twenty years ago I wrote a rather sophisticated cellular automaton which I called ‘Microworld’ which modelled the spread of human population over a landscape. It did this by first fractally folding a grid to assign elevations to cells. Then, cells below a critical elevation – the tree line – were assigned as forest. For each cycle – ‘year’ – a cell remained forest, its soil fertility would increase. Random events – ‘lightning strikes’ could change a cell from forest to clearing. Then the following transitions might take place, each with a probability, where each cell is considered to have eight neighbours:

    -
  • A forest cell with a lightning strike as a neighbour may catch fire and burn
  • -
  • A forest cell with a fire as a neighbour may catch fire and burn
  • -
  • A burning cell become a clearing cell
  • -
  • A clearing cell with forest or scrub as a neighbour may become scrub
  • -
  • A scrub cell may become forest
  • +
  • A forest cell with a lightning strike as a neighbour may catch fire and burn
  • +
  • A forest cell with a fire as a neighbour may catch fire and burn
  • +
  • A burning cell become a clearing cell
  • +
  • A clearing cell with forest or scrub as a neighbour may become scrub
  • +
  • A scrub cell may become forest

This more or less completes the ‘natural’ cycle… then we get to settlement. Pastoral and agrarian 1 cells gradually degrade soil fertility (erosion, etc). Agrarian 2 cells do not degrade fertility.

    -
  • A clearing cell (including cells above the treeline) may become a pastoral cell (pastoral 1, no settlement)
  • -
  • A pastoral 1 cell whose soil fertility falls below a threshhold becomes waste
  • -
  • A pastoral 1 cell with no pastoral neighbours may become waste
  • -
  • A waste cell below the treeline may become scrub
  • -
  • A waste cell may become clearing
  • -
  • A pastoral 1 cell with two or more pastoral neighbours may become a pastoral 2 cell (settlement)
  • -
  • A forest cell with two or more pastoral neighbours may become clearing
  • -
  • A pastoral 2 cell with two or more pastoral 2 neighbours may become agrarian 1
  • -
  • An agrarian 1 cell which falls below a critical fertility becomes pastoral 1
  • -
  • An agrarian 1 cell with three or more agrarian 1 neighbours becomes agrarian 2 (smith, mill)
  • -
  • A cell with three or more agrarian 2 neighbours becomes market
  • -
  • A market cell with no agrarian 2, market or urban neighbours becomes waste
  • -
  • A cell with two or more market neighbours becomes urban
  • +
  • A clearing cell (including cells above the treeline) may become a pastoral cell (pastoral 1, no settlement)
  • +
  • A pastoral 1 cell whose soil fertility falls below a threshhold becomes waste
  • +
  • A pastoral 1 cell with no pastoral neighbours may become waste
  • +
  • A waste cell below the treeline may become scrub
  • +
  • A waste cell may become clearing
  • +
  • A pastoral 1 cell with two or more pastoral neighbours may become a pastoral 2 cell (settlement)
  • +
  • A forest cell with two or more pastoral neighbours may become clearing
  • +
  • A pastoral 2 cell with two or more pastoral 2 neighbours may become agrarian 1
  • +
  • An agrarian 1 cell which falls below a critical fertility becomes pastoral 1
  • +
  • An agrarian 1 cell with three or more agrarian 1 neighbours becomes agrarian 2 (smith, mill)
  • +
  • A cell with three or more agrarian 2 neighbours becomes market
  • +
  • A market cell with no agrarian 2, market or urban neighbours becomes waste
  • +
  • A cell with two or more market neighbours becomes urban

That’s simple, but it provides a remarkable good model of population spread. however, it is essentially a grid and so doesn’t make for natural-seeming landscapes when considered as a three dimensional rendered world. How can we do better?

-

Microworld Two

-

The objective of this essay is to outline an angorithm for creating inhabited landscapes in which games can be set, which are satisfyingly believable when rendered in three dimensions. The objective of creating landscapes ‘procedurally’ – that is, with algorithms – is that they can be very much larger than designed landscapes for the same richness of local detail. This does not mean that every aspect of the final landscape must be ‘procedural’. It would be possible to use the techniques outlined here to create landscapes which were different every time the game was played, but it would be equally possible to create a landscape which was frozen at a particular point and then hand edited to add features useful to the game’s plot. And while I’m principally thinking in this about role playing games, this sort of landscape would be applicable to many other sorts of games – strategy games, god games, first person shooters…

-

The physical geography

+

Microworld Two

+

The objective of this essay is to outline an algorithm for creating inhabited landscapes in which games can be set, which are satisfyingly believable when rendered in three dimensions. The objective of creating landscapes ‘procedurally’ – that is, with algorithms – is that they can be very much larger than designed landscapes for the same richness of local detail. This does not mean that every aspect of the final landscape must be ‘procedural’. It would be possible to use the techniques outlined here to create landscapes which were different every time the game was played, but it would be equally possible to create a landscape which was frozen at a particular point and then hand edited to add features useful to the game’s plot. And while I’m principally thinking in this about role playing games, this sort of landscape would be applicable to many other sorts of games – strategy games, god games, first person shooters…

+

The physical geography

Consider our landscape as, once again, a fractally folded sheet on which any given point has characteristics based on its elevation and orientation. There are two critical levels – water level and treeline. The water level is, overall, sea level, but in the case of a localised depression it is equal to the lowest land height between the depression and the sea (lakes form in depressions). Computing the fractal sheet forms stage one in computing the landscape. Next, we need functions which, for any given point on the landscape, compute two different dimensions of soil fertility: water and warmth. We’ll assume a coriolis prevailing wind blowing from the west, bringing in damp air from an ocean in that direction. Western slopes are wetter than eastern slopes. In principle, also, there’s likely to be a rain shadow to the east of high ground leading to considerable aridity, but that may be too expensive to compute. Rain runs swiftly off steeper slopes, more slowly on flatter ground, so flatter ground is wetter than steeper ground. Water flows down hill, so lower ground is on the whole wetter than higher ground. This isn’t a precise model of soil hydrology, but I think it’s good enough. From each lake a watercourse follows the lowest possible path to the sea. Watercourses modify the land overwhich they flow, carving out a route at least sufficient to carry the amount of water collected in the watershed above each point. Where watercourses flow down steeper gradients, they carve out gullies, possibly with waterfalls. Where they cross shallower gradients or level ground, they become broader. Computing the watercourses becomes the second stage of computing the lanscape.

-

Vegetation

+

Vegetation

Now sprinkle seeds randomly across the landscape at a density of roughly one every ten square metres. Seeds which fall in water, ignore (? or make into water plants?). The position of the plant is taken from the random sprinkling. The species and size of the plant that grows from the plant are a function of the water and warmth functions described above, with latitude and longitude as seeds for pseudo-random functions delivering aspects like branching and so on – enough to make individual plants distinct and not carbon copies even of other plants of the same species, but nevertheless recreatable from just the latitude and longitude. So for each plant only two integers need to be stored, yet every time a player passes he will see an identically recreated world. Of course there is a trade-off between storage space and rendering time, and it may be more efficient to build and cache a detailed model of each plant. Like a lot of other things it depends on the game being designed and the processing power of the platform on which that game is delivered. As to how the functions which select the vegetation type work, obviously trees grow better in wetter places, grassland plants in dryer places; within the wetter places, coniferous trees are more prevalent where it is cooler, broadleaves where it is warmer. In the very wettest places, willows, alders and marshland plants. These plants – the seeded plants – are the feature plants of the landscape. When rendering the landscape the renderer would first apply a suitable local surface texture, for example, in grassland areas, grass.

-

Settling the world

+

Settling the world

So now we need to make this an inhabited landscape. My proposal for this is to introduce proto-actors, which may be the same software agents as the non-player characters the user will interact with (see my essay on the spread of knowledge). At this stage in their lifecycle, the proto-actors are fairly simple state transition machines. Generally, their algorithm is as follows: Starting from one or two seed points, proto-agents will initially move across the landscape travelling at most 20Km in a day, preferring to stop at inns or else at existing settlements; and will maintain a history of the places they have been, never revisiting a place until they have settled. Whenever moving, whether before they have settled or after, proto-actors will plan their route across the landscape, avoiding trees, buildings, and steep gradients, and will prefer to cross rivers at a bridge (if available) or else a ferry (if available), or failing that at the narrowest convenient point. When proto-actors settle, they will claim an area of territory appropriate to their trade – more below; the system must build up a database of land holdings. In particular a land holding will never cross a watercourse, an existing road or overlap another land holding (although roads may develop across existing holdings). This is key because I don’t want holdings normally to have regular shapes. A settled proto-agent will build a building to live in, and possibly an additional one for his trade. When building buildings, proto-actors will prefer to build at the edge of their land holding, as close as possible to existing buildings and ideally at the side of an existing road. The richer an existing building is, the more attractive it will be to new buildings. Buildings will be built with their long edge aligned with the edge of the owner’s hoding.

    -
  • A proto-actor is initially, as described above, an itinerant. Itinerants are introduced into the world at a small number of geographical locations, and gradually, not all at once. Itinerants travel as described above. As they move they will leave breadcrumb trails with a roughly ten metre resolution. If they cross an existing track which goes in roughly the right direction they will prefer to follow it. Once a track has been followed by a certain number of proto-actors, it becomes a road.
  • -
  • An itinerant who finds an area of unsettled grassland of ten hectares with low soil fertility and not more than one hundred trees settles and becomes a pastoralist. He builds a cottage.
  • -
  • An itinerant who finds an area of unsettled grassland of ten hectares with medium or high soil fertility becomes an agrarian. He builds a homestead. Depending on the fertility of his land he can support between zero and ten labourers, 10% of a smith, 10% of a miller and 10% of a bonnet laird.
  • -
  • An itinerant who finds an area of unsettled land of 100 square metres within five hundred metres of a homestead with unfulfilled labourer demand becomes a labourer. He builds a cottage.
  • -
  • An itinerant who finds an area of unsettled land of 100 square metres within five kilometres of ten farmers with unfilled smithing slots becomes a smith. He builds a cottage and a forge.
  • -
  • An itinerant who finds an area of unsettled land either at the side of a water course or at the top of a hill, and within 5 kilometers of ten farmers with unfilled milling slots becomes a miller. He builds a mill – water or wind, appropriate to location.
  • -
  • Any settler who plays host to more than a certain number of travellers becomes an innkeeper. He claims 400 square metres of unclaimed land as close as possible to his existing settlement and buids an inn and stableyard.
  • -
  • An itinerant who finds 400 square metres of unclaimed land within a certain distance of an inn and a smith will become a merchant, provided that there are three smiths within a 5Km radius who have unfilled market slots. The merchant builds a marketplace and a counting house.
  • -
  • An itinerant who finds 200 square metres of unclaimed land within a specified distance of a market with an unfilled chapel slot becomes a priest and builds a chapel and manse, and possibly a school.
  • -
  • An itinerant who finds 100 square metres of unclaimed land adjacent to where a road crosses a river becomes a ferryman.
  • -
  • A ferryman who carries more than a certain number of passengers in a given period becomes a tollkeeper and builds a bridge.
  • +
  • A proto-actor is initially, as described above, an itinerant. Itinerants are introduced into the world at a small number of geographical locations, and gradually, not all at once. Itinerants travel as described above. As they move they will leave breadcrumb trails with a roughly ten metre resolution. If they cross an existing track which goes in roughly the right direction they will prefer to follow it. Once a track has been followed by a certain number of proto-actors, it becomes a road.
  • +
  • An itinerant who finds an area of unsettled grassland of ten hectares with low soil fertility and not more than one hundred trees settles and becomes a pastoralist. He builds a cottage.
  • +
  • An itinerant who finds an area of unsettled grassland of ten hectares with medium or high soil fertility becomes an agrarian. He builds a homestead. Depending on the fertility of his land he can support between zero and ten labourers, 10% of a smith, 10% of a miller and 10% of a bonnet laird.
  • +
  • An itinerant who finds an area of unsettled land of 100 square metres within five hundred metres of a homestead with unfulfilled labourer demand becomes a labourer. He builds a cottage.
  • +
  • An itinerant who finds an area of unsettled land of 100 square metres within five kilometres of ten farmers with unfilled smithing slots becomes a smith. He builds a cottage and a forge.
  • +
  • An itinerant who finds an area of unsettled land either at the side of a water course or at the top of a hill, and within 5 kilometers of ten farmers with unfilled milling slots becomes a miller. He builds a mill – water or wind, appropriate to location.
  • +
  • Any settler who plays host to more than a certain number of travellers becomes an innkeeper. He claims 400 square metres of unclaimed land as close as possible to his existing settlement and buids an inn and stableyard.
  • +
  • An itinerant who finds 400 square metres of unclaimed land within a certain distance of an inn and a smith will become a merchant, provided that there are three smiths within a 5Km radius who have unfilled market slots. The merchant builds a marketplace and a counting house.
  • +
  • An itinerant who finds 200 square metres of unclaimed land within a specified distance of a market with an unfilled chapel slot becomes a priest and builds a chapel and manse, and possibly a school.
  • +
  • An itinerant who finds 100 square metres of unclaimed land adjacent to where a road crosses a river becomes a ferryman.
  • +
  • A ferryman who carries more than a certain number of passengers in a given period becomes a tollkeeper and builds a bridge.

This set of rules – and possibly others like them (woodcutters, fishermen, hunters…) provide the first wave of settlement. Once the landscape is sufficiently settled by this first wave, there needs to be a period of establishing trading routes. First, every settler will visit his nearest market, leaving a permanent track if there is not already a road. Where several of these tracks overlay one another, once again a road is created. Each merchant then visits each of the ten markets nearest his own, following existing tracks and roads where available. Wherever the merchants do not find roads, new roads are created. This completes the roads network. Each market is now assigned a value which is a function of

    -
  • the number of people for whom it is the nearest market
  • -
  • the sum of the wealth (soil fertility) of the homesteads for which it is the nearest market
  • -
  • the wealth of other markets within a day’s travel
  • +
  • the number of people for whom it is the nearest market
  • +
  • the sum of the wealth (soil fertility) of the homesteads for which it is the nearest market
  • +
  • the wealth of other markets within a day’s travel

Depending on its wealth a market may support up to twenty stallholders, including bakers, butchers, tanners, weavers, cobblers, chandlers and so on. So a second wave of itinerants sets off. These follow the original rules for itinerants, but if they find an unsettled 100 square metres within five hundred metres of a market, will set up as a stallholder, building a town house and appropriate trade building on their own settlement, and a stall in the market. An itinerant finding a hundred square metres within five hundred metres of a market which has all its stallholder slots filled may become a slum landlord, and build a tenement for day-labourers. Finally, aristocracy. In the second wave an itinerant who finds either a hilltop, an island in a lake or river, or a significant river crossing, with one hectare of unclaimed land and within 5Km of ten farms with unfilled bonnet laird slots becomes a bonnet laird (or ‘squire’, if you prefer) and builds a fortified house. At the end of the second wave of settlement the ten percent of bonnet lairds with the richest fiefs (using much the same metric as for the wealth of markets) become barons and build castles.

-

Rendering the buildings

+

Rendering the buildings

This seems to me to provide an algorithmic means of settling a landscape which will generate organic and satisfying patterns of settlement. But it all fails if the buildings are chosen from a limited palette of models. As with the trees I think we need algorithmic mechanisms of building similar-but-different buildings which can be repeatably rendered from relatively small data sets. As an example of what I mean, in damper landscapes where wood is likely to be available, there might be a higher probability of stave buildings, or weatherboarding, with mainly shingle roofs. In slightly less damp areas where timber is still available, cruck frames and half timbered buildings will prevail, with mostly thatched roofs. In the dryest areas, cob and brick buildings will be common, often with tile roofs. On steeper hillsides, stone buildings will be common, perhaps with slate roofs. Within each of these types there are essential cells from which a building is created. These cells can be longer or shorter, taller or lower, wider or narrower. A building may comprise a single cell, or more. If more than three cells they may be arranged in a row or round a courtyard. And they may have one story or two. Which they have can be based – like the details of the plants – on functions which take latitude and longitude as arguments and which, internally use pseudo-randoms seeded from those latitude and longitude values.

-

How vast a world?

+

How vast a world?

OK, so, with this general approach, how big can we go? The answer seems to me to be ‘big enough’. A 32 bit integer gives somewhat over four billion values, so can resolve down to one millimetre precision in a world 4000 kilometres by 4000 kilometres. But we don’t actually need millimetre resolution; centimetre would be quite small enough. And that gives us potential for a world 40000Km square, or 1.6 billion square kilometres, which is three times the surface area of planet Earth.

In practice we can’t go that big for all sorts of space and time reasons. Recording land heights is inevitably an issue. I don’t know of a pseudo random function which will generate satisfying land heights. Anything based on Julia sets, for example, ends up with landforms symmetrical around a central point. Furthermore, the shapes of fractals which can be constructed from simple functions tend to have a noticable and unnatural degree of self-similarity across scales. I’d dearly like to be wrong on this, but I think we need to store at minimum elevation values at ten metre intervals. If we can accept 100mm resolution for elevations, storing 16 bit values gives a range of 6,500 metres - 21,000 feet - from the deepest seabed to the peaks of the highest mountains.

This means that landform information alone requires 20Kbytes per square kilometre - unindexed, but seeing it’s a rigid ten metre grid that isn’t a problem. Which, in turn, means that you can store landform information for a planet the size of Earth in one terrabyte. But we don’t need a planet the size of earth. Scotland is 80,000 square kilometers of land area; allowing for a bit of sea around to the horizon around it, say 100,000 square kilometers. That seems to me more than big enough to be a game space. It amounts to 160Mb of landform data, which is completely manageable.

If we stored plant data for every distinctive plant in Scotland - even at one per ten square metres - that does become an impractically large data set, because quite apart from anything else, the plant locations do have to be indexed. But actually, given that the actual plants that grow are a function of the location at which they grow, no player is going to notice if the pattern of the locations of plants is the same for each square kilometre. So we can manage plant data for a land area the size of Scotland in 400,000 bytes - we could do it in less (if the locations were generated using a pseudo-random function, much less).

Building data is different. We need to store the latitude, longitude and type of every building explicitly, and again they need to be indexed in order that we can recover the buildings in a given area efficiently. We need about 16 bytes per building (four bytes latitude, four longitude, two type; then for each tile a null-terminated vector of pointers to building records). If we assume that our feudal land of 80,000 square kilometers has a population of a million, and that there are on average five occupants of every building, that’s two hundred thousand buildings, implying 3.2Mb of data.

-

Of course, that’s just the backing store size. As tiles are loaded into active memory - see the essay ‘Tiles and Flats’ this raw backing data has to be inflated procedurally into actual models that can be rendered; models which may have thousands of vertices and hundreds of kilobytes of textures. The functions which do that inflating have some finite size, and, significantly, they’ll need to work on prototype models which will in turn take storage space. Finally there are hand-edited models potentially used at particular plot locations; those need to be stored more or less in full. But all this has not become an unmanageable amount of data. It seems to me plausible that you could store a fully populated 100,000 square kilometer game world on one uncompressed 700Mb CD. On a 4Gb DVD, you could do it very easily.

\ No newline at end of file +

Of course, that’s just the backing store size. As tiles are loaded into active memory - see the essay ‘Tiles and Flats’ this raw backing data has to be inflated procedurally into actual models that can be rendered; models which may have thousands of vertices and hundreds of kilobytes of textures. The functions which do that inflating have some finite size, and, significantly, they’ll need to work on prototype models which will in turn take storage space. Finally there are hand-edited models potentially used at particular plot locations; those need to be stored more or less in full. But all this has not become an unmanageable amount of data. It seems to me plausible that you could store a fully populated 100,000 square kilometer game world on one uncompressed 700Mb CD. On a 4Gb DVD, you could do it very easily.

+
\ No newline at end of file diff --git a/docs/codox/Sexual-dimorphism.html b/docs/codox/Sexual-dimorphism.html new file mode 100644 index 0000000..bfd002d --- /dev/null +++ b/docs/codox/Sexual-dimorphism.html @@ -0,0 +1,37 @@ + +Sexual dimorphism

Sexual dimorphism

+

This essay is going to upset a lot of people, so let’s start with a statement of what it is about: it is an attempt to describe the systematically different behaviours of men and women, in sufficient detail that this can be represented by agents in a game world. It’s trying to allow as broad as possible a range of cultures to be represented, so when I’m talking about what I consider to be behaviours of particular cultures, I’ll say that.

+

Of course, I’m writing this from the view point of an old white male. It’s not possible to write about these things from a totally neutral viewpoint, and every one of us will have prejudices.

+

OK? Let’s start.

+

When a man and a woman have sex, there’s a non-zero chance that the woman will get pregnant. There’s a zero chance that the male will get pregnant.

+

A woman can typically give birth to of the order of twelve children in the course of her life, and each childbirth involves a non-zero risk of death. If modelling the sort of bronze-age-to-late-medieval cultures I’m generally considering, there are no available reliable methods of contraception, although there may be, for example, known spermicidal or abortifacient spells or potions. If it’s abortifacient, that’s pretty unpleasant for the woman, too.

+

Children, especially when young, are very vulnerable and need protection. Children with good protection are much more likely to survive to adulthood. Raising children involves a fair amount of work.

+

For all sorts of reasons, some of which are clearly cultural but others of which are fundamental, it’s much easier for men to walk away from responsibility for their children than it is for women. For example, considering a pre-modern world, women would always know for certain which children were theirs, and men would not.

+

For a woman, consequently, the best breeding strategy is to have sex only with men who will be ‘good fathers’, where there are three essential parameters to “good fathers”:

+
    +
  1. Desirable genetic traits;
  2. +
  3. Preparedness to stick around and share the work;
  4. +
  5. Ability to provide and protect.
  6. +
+

The essential trade-off in the traditional western marriage is that the man gets to have sex, and the woman gets to have protection for her progeny.

+

Another significant point is that women’s ability to bear children ceases at a much younger age than men’s ability to father them.

+

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.

+

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.

+

Why have children?

+

In modern Scotland, I have met a lot of women with a strong drive to have children for the sake of having children, where the best explanation they could give is that it’s instinctual; it may be so. But beyond that, in many cultures children provide their (acknowledged) parents with care and security in their old age, may tend their graves and perform belief-related services after they die, and carry on their name and their stories into the future.

+

Not everyone wants to have children; in thinking about the driving aspirations of game characters, I view having children one of six potential key aspirations.

+

Why else have sex?

+

Sex, done right, is an extremely pleasant pastime. Sex can also be used to create and maintain bonds of committment, to demonstrate social status, to defuse tense situations, and transactionally in many ways, both formal and informal.

+

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.

+

Women and warrior/adventurer lifestyles

+

Generally speaking, people do not want to take their children onto a battlefield. If you’re going to have a game world in which women significantly take on warrior or adventurer roles, then you must either have

+
    +
  • A culture which expects female warriors to be celibate; or
  • +
  • A culture with access to and acceptance of safe and reliable contraception or abortion; or
  • +
  • An acceptance of leaving infant children with grandparents, other relatives or foster carers for long periods;
  • +
  • A system of long term creches;
  • +
  • Any combination of the above.
  • +
+
\ No newline at end of file diff --git a/docs/codox/Simulation-layers.html b/docs/codox/Simulation-layers.html index 0e37f3a..0bf1d03 100644 --- a/docs/codox/Simulation-layers.html +++ b/docs/codox/Simulation-layers.html @@ -1,13 +1,14 @@ -Simulation layers

Simulation layers

+Simulation layers

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

+

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.

+

A political simulation

+

Broadly, aristons claim territories in an essentially 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.

\ No newline at end of file +

Aristons who can generate surplus can hire more soldiers, ascend the feudal hierarchy, and wage war against neighbours.

+
\ No newline at end of file diff --git a/docs/codox/The-spread-of-knowledge-in-a-large-game-world.html b/docs/codox/The-spread-of-knowledge-in-a-large-game-world.html index eb95181..8a8728e 100644 --- a/docs/codox/The-spread-of-knowledge-in-a-large-game-world.html +++ b/docs/codox/The-spread-of-knowledge-in-a-large-game-world.html @@ -1,21 +1,21 @@ -The spread of knowledge in a large game world

The spread of knowledge in a large game world

-

Saturday, 26 April 2008

-

part of the role of Dandelion, in The Witcher games, is to provide the player with news

-

Note

-

This version of this essay has been adapted to use the code in the-great-game.gossip.news-items, q.v.. The original version of the essay is still available on my blog.

+The spread of knowledge in a large game world

The spread of knowledge in a large game world

+

Saturday, 26 April 2008

+

Note

+

This version of this essay has been adapted to use the code in the-great-game.gossip.news-items, q.v.. The original version of the essay is still available on my blog.

+

These days we have television, and news. But in a late bronze age world there are no broadcast media. News spreads by word of mouth. If non-player characters are to respond effectively to events in the world, knowledge has to spread.

How to model this?

-

Some non-player characters - doesn’t need to be many - are news-spreaders. News-spreaders need to travel. They have to travel even when there are no player characters in the vicinity. But, they don’t have to travel very often - once or twice every game day. When a news-spreader is in the immediate vicinity of another character, the pair may (with some degree of randomness) exchange news. There needs to be a hierarchy in the exchange of news, so that ‘I-saw’ events need to be more likely to be passed on than ‘I-heard’ events; there needs to be a counter which counts the number of times a knowledge item has been passed on, and also an age counter so that knowledge items are less likely to be passed on as they get older.

+

Some non-player characters — doesn’t need to be many — are news-spreaders. News-spreaders need to travel. They have to travel even when there are no player characters in the vicinity. But, they don’t have to travel very often — once or twice every game day. When a news-spreader is in the immediate vicinity of another character, the pair may (with some degree of randomness) exchange news. There needs to be a hierarchy in the exchange of news, so that ‘I-saw’ events need to be more likely to be passed on than ‘I-heard’ events; there needs to be a counter which counts the number of times a knowledge item has been passed on, and also an age counter so that knowledge items are less likely to be passed on as they get older.

One obvious class of news-spreader is a merchant. Merchant agents can either shuttle mechanically between a fixed group of markets or else possibly respond intelligently to supply and demand. Provided that there is a mesh of merchant routes covering the markets of the game world, and that a useful subset of non-merchant characters are required to visit a market every few game days, this should give a reasonably realistic framework for news spreading.

What else? What things qualify as news items? I think at least the following:

    -
  • Deaths of sentient characters, especially if violent
  • -
  • Commodity prices
  • -
  • Changes of rulers in cities
  • -
  • Marriages of sentient characters
  • -
  • Plot events, flagged as events by the game designer
  • +
  • Deaths of sentient characters, especially if violent
  • +
  • Commodity prices
  • +
  • Changes of rulers in cities
  • +
  • Marriages of sentient characters
  • +
  • Plot events, flagged as events by the game designer

Obviously, news is more valuable if the people involved are important or notorious: the significance of a story is probably the product of the significance of the people concerned.

So a news item becomes a map with keys similar to

@@ -48,16 +48,17 @@ :nth-hand 4, :time-stamp 17946463} -

The timestamp could also be degraded, or lost altother - although how exactly this is represnted I’m not certain. Someone interested in the incident may remember ‘it was exactly 17 days ago’, whereas someone else may remember that it was ‘this month, I think’.

+

The timestamp could also be degraded, or lost altother — although how exactly this is represnted I’m not certain. Someone interested in the incident may remember ‘it was exactly 17 days ago’, whereas someone else may remember that it was ‘this month, I think’.

Obviously the rate of decay, and the degree of randomness, of the news-passing algorithm would need to be tuned, but this schema seems to me to describe a system with the following features:

    -
  • Non-player characters can respond to questions about significant things which happen in the world - without it all having to be scripted
  • -
  • If you travel fast enough, you can keep ahead of your notoriety
  • -
  • Characters on major trade routes will know more about what is happening in the world than characters in backwaters
  • +
  • Non-player characters can respond to questions about significant things which happen in the world — without it all having to be scripted
  • +
  • If you travel fast enough, you can keep ahead of your notoriety
  • +
  • Characters on major trade routes will know more about what is happening in the world than characters in backwaters

This seems to me a reasonably good model of news spread.

-

Scaling of the algorithm

+

Scaling of the algorithm

Let’s work around the idea that a ‘game day’ equates to about two hours of wall clock time. Let’s work around the idea that there are of the order of fifty markets in the game world, and that for each market there are two or three merchants whose ‘home base’ it is.

-

Obviously non-player characters who are within the vicinity of a player character have to be ‘awake’, in order that the player can see them interacting with their world and can interact with them. Those characters have to be in working memory and have to be in the action polling loop in any case. So there’s no extra cost to their gossiping away between each other - around the player there’s a moving bubble of gossip, allowing each character the player interacts with to have a high probability of having some recent news.

-

But the merchants who aren’t in the vicinity of a player don’t have to be in working memory all the time. Each merchant simply requires to be ‘woken up’ - loaded into memory - once per game day, move a day’s journey in one hop, and then, if arriving at an inn or at a market, wake and exchange news with one resident character - an innkeeper or a gossip. So the cost of this algorithm in a fifty-market game is at worst the cost of loading and unloading two non-player characters from memory every minute, and copying two or three statements from the knowledge set of one to the knowledge set of the other. If you’re dynamically modifying significance scores, of course, you’d need to also load the characters about whom news was being passed on; but this still doesn’t seem unduly onerous.

-

Obviously, if memory is not too constrained it may be possible to maintain all the merchants, all the innkeepers and all the characters currently being talked about in memory all the time, further reducing the cost.

\ No newline at end of file +

Obviously non-player characters who are within the vicinity of a player character have to be ‘awake’, in order that the player can see them interacting with their world and can interact with them. Those characters have to be in working memory and have to be in the action polling loop in any case. So there’s no extra cost to their gossiping away between each other — around the player there’s a moving bubble of gossip, allowing each character the player interacts with to have a high probability of having some recent news.

+

But the merchants who aren’t in the vicinity of a player don’t have to be in working memory all the time. Each merchant simply requires to be ‘woken up’ — loaded into memory — once per game day, move a day’s journey in one hop, and then, if arriving at an inn or at a market, wake and exchange news with one resident character — an innkeeper or a gossip. So the cost of this algorithm in a fifty-market game is at worst the cost of loading and unloading two non-player characters from memory every minute, and copying two or three statements from the knowledge set of one to the knowledge set of the other. If you’re dynamically modifying significance scores, of course, you’d need to also load the characters about whom news was being passed on; but this still doesn’t seem unduly onerous.

+

Obviously, if memory is not too constrained it may be possible to maintain all the merchants, all the innkeepers and all the characters currently being talked about in memory all the time, further reducing the cost.

+
\ No newline at end of file diff --git a/docs/codox/Things_Voice_Interaction_Enables.html b/docs/codox/Things_Voice_Interaction_Enables.html new file mode 100644 index 0000000..d7dc60e --- /dev/null +++ b/docs/codox/Things_Voice_Interaction_Enables.html @@ -0,0 +1,43 @@ + +Things Voice Interaction Enables

Things Voice Interaction Enables

+

Organic quest routing

+

In a world in which you can talk to non-player characters, and in which non-player characters know the directions to things which are local to their homes (and some, travellers, will be able to give you routes to things further away), when you need to get to your next waypoint you can just ask for directions. That much is easy.

+

But something much richer occurred to me.

+

Suppose you’re entering a village, and you meet a random character. That character knows any local quest giver, and what it is that quest giver needs –– and, indeed, they know this whether the quest is scripted or organic.

+

So the random character could say

+
+

Hello, I’m Tobias, and that my mill over there. Who might you be, stranger?

+
+

At which point you can either tell him, or not. Suppose you tell him, he could say

+
+

Oh! I’ve heard of you. It’s said you’re very handy with a sword.

+
+

And you can reply however you like, acknowledging, or being modest, or perhaps even denying (although from this line of dialogue if you deny he’ll think you’re being modest, for reasons see later). He can then say, taking our example from the ‘abducted child’ quest in the Introduction,

+
+

Thing is, old granny Grizzel’s granddaughter Esmerelda has been abducted by bandits, and we’ve done a whip-around for a reward for someone who can rescue the girl.

+
+

At which point you may reply that you’ll do it, or be non-committal, or say you won’t. If you say you will, he can say,

+
+

Well, you should talk to granny Grizzel, she lives in the white house by the crossroads, half a mile that-a-way (pointing).

+
+

If you say you won’t, he can say,

+
+

It would be a virtuous act, the old lady is fair desperate. If you should change your mind, you should talk to her; she lives in the white house by the crossroads, half a mile that-a-way (pointing).

+
+

OK, but what if, in the game world, the player character is not good with a sword? Well, the ‘abducted child’ quest can be resolved by violence; but it can also be resolved by persuasion, or by sneakiness, or by bribery. So suppose the player isn’t (in the game) good with a sword, but is good at negotiation. Then in the initial approach, Tobias could say

+
+

Oh! I’ve heard of you. It’s said you’re very handy at persuasion… Thing is, old granny Grizzel’s granddaughter Esmerelda has been abducted by bandits, and we’ve done a whip-around for a ransom, but she’s lacking someone who can negotiate for her.

+
+

It’s the same quest, and, whatever Tobias has said, the player can still use either violence or persuasion or trickery to complete the quest (and gain appropriate reputation thereby), but it’s flexible enough to adapt to the player’s in-game persona, and it means we can direct the player to quest-givers without having to stick a bloody great icon on the quest giver’s head.

+

So, to repeat for clarity: the idea is, if there is a quest in the vicinity, whether organic or scripted, many of the quest giver’s neighbours may know about it, and will bring it up in conversation, introducing it and directing the player to the quest giver. And I believe that this can be done reasonably naturally.

+

Obviously there are some sorts of quests where for narrative reasons he quest giver will not want their neighbours to know of it, and those quests need to be signposted differently; but I think that effective ways need to be found of signposting those quests to the player without resorting to noticeboards or quest icons.

+

Command in Battles

+

Player characters in role playing games are often narratively great heroic leaders — see any of the Dragon Age games but particularly Inquisition for examples of this — but when it comes to a pitched battle all they can do is follow a scripted battle plan and fight individual actions, because in current generation role-playing games there is no effective user interface to allow strategic and tactical control of a battle.

+

So how would a real-world, before modern communications technology, war leader command a battle? Why, by observing the battle and talking to people, and those are both things that in our game the player can do.

+

So, there are two stages to battle communication: the first is the council of war, before the battle, in which the battle plan is agreed. For the non-player characters to have any significant input into this, we’d need a really good knowledge base of appropriate battle strategies with heuristics for which plan fits which sort of geography and which sort of enemy, but that could be quite fun to develop; but in principle it’s sufficient for the player character to be able to say to each of the divisional captains “I want you to do this,” and for each captain to say first “yes, I understand” (or “please clarify”), and then “yes, I will do it” (or “yes, I will try”).

+

No battle plan, of course, survives first contact with the enemy. It must be possible to update the plan during the battle, and messengers were used to carry new orders from the commander to subordinates. That, of course, we can also do.

+

So, ideally (and in describing this I’ll try to give ‘less than ideal’ alternatives where I see them), you can gather your captains to a council of war, either by speaking to them directly or by sending messengers round. At the council of war, non-player-character captains can suggest possible battle plans drawn from a common knowledge base, but can have individual levels of boldness or caution. However, if you’ve been appointed battle leader, then provided they’re individually still loyal to you then they will ultimately agree to what you order.

+

When battle is joined you can either join in the fighting in the front line in which case your strategic overview is going to be very limited and you’ll just have to hope your initial plan was good enough; or else you can sit on a hilltop overlooking the battlefield with your trumpeter and your messengers, and send messages to control the fight, but not actually take part much yourself (unless everything really goes to shit and your position is overrun).

+

In real world battles orders were often misunderstood; I don’t think I should do anything special to model that. But orders (other than trumpet calls) will necessarily take finite time, and if the battlefront is really messed up messengers may fail to get through.

+
\ No newline at end of file diff --git a/docs/codox/Uncanny_dialogue.html b/docs/codox/Uncanny_dialogue.html index e3e619e..231b823 100644 --- a/docs/codox/Uncanny_dialogue.html +++ b/docs/codox/Uncanny_dialogue.html @@ -1,7 +1,8 @@ -The Uncanny Valley, and dynamically generated dialogue

The Uncanny Valley, and dynamically generated dialogue

+The Uncanny Valley, and dynamically generated dialogue

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 and Twitter thread 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.

\ No newline at end of file +

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.

+
\ No newline at end of file diff --git a/docs/codox/Voice-acting-considered-harmful.html b/docs/codox/Voice-acting-considered-harmful.html index 17e9dec..0ec682b 100644 --- a/docs/codox/Voice-acting-considered-harmful.html +++ b/docs/codox/Voice-acting-considered-harmful.html @@ -1,29 +1,41 @@ -Voice acting considered harmful

Voice acting considered harmful

-

Wednesday, 25 February 2015

+Voice acting considered harmful

Voice acting considered harmful

+

Wednesday, 25 February 2015

The Witcher: Conversation with Kalkstein

-

Long, long, time ago, I can still remember when… we played (and wrote) adventure games where the user typed at a command line, and the system printed back at them. A Read-Eval-Print loop in the classic Lisp sense, and I wrote my adventure games in Lisp. I used the same opportunistic parser whether the developer was building the game Create a new room north of here called dungeon-3 the player was playing the game Pick up the rusty sword and go north or the player was talking to a non-player character Say to the wizard ‘can you tell me the way to the castle’ Of course, the parser didn’t ‘understand’ English. It worked on trees of words, in which terminal nodes were actions and branching nodes were key words, and it had the property that any word it didn’t recognise at that point in sentence was a noise word and could be ignored. A few special hacks (such as ‘the’, ‘a’, or ‘an’ was an indicator that what came next was probably a noun phrase, and thus that if there was more than one sword in the player’s immediate environment the one that was wanted was the one tagged with the adjective ‘rusty’), and you ended up with a parser that most of the time convincingly interpreted most of what the player threw at it.

+

Long, long, time ago, I can still remember when… we played (and wrote) adventure games where the user typed at a command line, and the system printed back at them. A Read-Eval-Print loop in the classic Lisp sense, and I wrote my adventure games in Lisp. I used the same opportunistic parser whether the developer was building the game

+
+

Create a new room north of here called dungeon-3

+
+

the player was playing the game

+
+

Pick up the rusty sword and go north

+
+

or the player was talking to a non-player character

+
+

Say to the wizard ‘can you tell me the way to the castle’

+
+

Of course, the parser didn’t ‘understand’ English. It worked on trees of words, in which terminal nodes were actions and branching nodes were key words, and it had the property that any word it didn’t recognise at that point in sentence was a noise word and could be ignored. A few special hacks (such as ‘the’, ‘a’, or ‘an’ was an indicator that what came next was probably a noun phrase, and thus that if there was more than one sword in the player’s immediate environment the one that was wanted was the one tagged with the adjective ‘rusty’), and you ended up with a parser that most of the time convincingly interpreted most of what the player threw at it.

Text adventures fell into desuetude partly because they weren’t graphic, but mainly because people didn’t find typing natural, or became dissatisfied with the repertoire of their parsers. Trying to find exactly the right combination tokens to persuade the game to carry out some simple action is not ‘fun’, it’s just frustrating, and it turned people off. Which is a shame because just at the time when people were abandoning text adventures we were beginning to have command parsers which were actually pretty good. Mine, I think, were good - you could have a pretty natural conversation with them, and in ‘building’ mode, when it hit a ‘sorry I don’t understand’ point, it allowed you to input a path of keywords and a Lisp function so that in future it would understand.

So much, so Eliza.

Modern role-playing games - the evolutionary successors of those high and far off text adventures - don’t have text input. Instead, at each stage in a conversation, the user is offered a choice of three or four canned responses, and can pick one; very often what the player’s character actually says then differs from the text the user has chosen, often with differences of nuance which the user feels (s)he didn’t intend. And the non-player-character’s response is similarly canned. Indeed, the vast majority of non-player characters in most games have a ‘repertoire’, if one may call it that, of only one sentence. Others will have one shallow conversational tree, addressing one minor quest or plot-point.

If you want to talk to them about anything else - well, you just can’t.

Only a very few key non-player characters will have a large repertoire of conversational trees, relevant to all parts of the plot. And even those trees are not deep. You soon exhaust them; the characters’ ability to simulate real agency just isn’t there.

I first wrote about the limiting effects of voice acting in my review of the original Witcher game, back in 2008; things haven’t got better.

-

On phones: speaking

+

On phones: speaking

In my pocket I carry a phone. It’s not big: 127 x 64.9 x 8.6mm. A small thing.

When I first used Android phones for navigation, I used to delight in their pronunciation of Scots placenames - pronouncing them phonetically, as spelled, and as though their spelling were modern English. What’s delightful about Scots placenames is that they are linguistically and orthographically so varied - their components may be Brythonic, Goidaelic, Anglian, Norn, French, English, or even Latin; and very frequently they combine elements of more than one language (Benlaw Hill, anyone? Derrywoodwachy?).

Yes, gentle reader, this does seem a long way from game design; be patient, I’m getting there. But I’m going to digress even further for first…

There have been orthographic changes, and pronunciation changes consequent on orthographic changes. For example, medieval Scots used the letter Yogh (ȝ), which isn’t present in the English alphabet. So when Edinburgh printers in the early modern period bought type for their printing presses from England, there was no Yogh in the font. So they substituted Zed. So we get names like Dalȝiel, Kirkgunȝeon, Menȝies, Cockenȝie. How do you pronounce them?

The letter that looks like a ‘z’ is pronounced rather like a ‘y’; so

    -
  • Deeyell
  • -
  • Kirkgunyeon
  • -
  • Mingis
  • +
  • Deeyell
  • +
  • Kirkgunyeon
  • +
  • Mingis

and… drumroll…

    -
  • Cockenzie.
  • +
  • Cockenzie.

What happened?

Well, Dalȝiel and Menȝies are personal names, and people are protective of their own names. Kirkgunȝeon is a small, unimportant place, and all the locals know how it is pronounced. Scots folk, are, after all, used to Scots orthography and its peculiarities. So those names haven’t changed.

@@ -32,18 +44,19 @@

Another more interesting example of the same thing is ‘Kirkcudbright’. It’s a town built around the kirk (church) of saint Cuthbert. So how does it come to have a ‘d’ in it? And why is it pronounced ‘Kirkoobry’? Well, the venerable Cuthbert pronounced his name in a way which would be represented in modern English as ‘Coothbrecht’, but he spelled it ‘Cuðbrecht’. See that ‘ð’? That’s not a ‘d’, it’s an Eth. Because Cuðbrecht was Anglian, and the Anglian alphabet had Eth; it’s pronounced as a soft ‘th’, and Icelandic still has it (as well as Thorn, þ, a hard ‘th’ sound). Medieval scribes didn’t know about Eth, so in copying out ð they wrote the more familiar d. The local people, however, mostly couldn’t read, so the pronunciation of the name didn’t change with the change in spelling (although the pronunciation, too, has drifted a little with time).

So, in brief, pronouncing Scots placenames is hard, and there are a lot of curious rules, and consequently it’s not surprising that five years ago, listening to Android’s pronunciation of Scots placenames was really funny.

But what’s really curious is that now it isn’t. Now, it rarely makes a mistake. Now, Android can do text to speech on unusual and perverse orthography, and get it right better than 95% of the time - and manage a reasonably natural speaking voice while doing so. On a small, low power machine which fits in my pocket.

-

On phones: listening

+

On phones: listening

But navigation is not all I can do with my phone. I can also dictate. By which I don’t mean I can make a voice recording, play it back later and type what I hear, although, of course, I can. I mean I can dictate, for example, an email, and see it in text on my phone before I send it. It quickly learned my peculiarities of diction, and it now needs very little correction. On a small, low power machine which fits in my pocket.

-

And breathe

+

And breathe

Right, so where am I going with all this? Well, we interact with modern computer role playing games through very restricted, entirely scripted dialogues. Why do we do so? Why, on our modern machines with huge amounts of store, do our non-player characters - and worse still, our player character, our own avatar - have such restricted repertoires?

Because they are voice acted. Don’t get me wrong, voice acting makes a game far more engaging. But for voice acting to work, the people doing the acting have to know not only the full range of sentences that their character is going to speak, but also roughly how they feel (angry? sad? excited?) when they say it. Ten years ago, voice acting was probably the only way you could have got this immediacy into games, because ten years ago, text-to-speech systems were pretty crude - think of Stephen Hawking’s voice synthesiser. But now, Edinburgh University’s open source synthesiser is pretty good, and comes with twenty-four voices (and seeing it’s open source, you can of course add your own). Speech to text was probably better ten years ago - think of Dragon Naturally Speaking - but it was proprietary software, and used a fair proportion of a machine’s horsepower. Now there’s (among others) Carnegie Mellon’s open source Sphinx engine, which can quickly adapt to your voice.

So, we have text-to-speech engines which can generate from samples of many different voices, and speech to text engines which can easily be tuned to your particular voice. There’s even a program called Voice Attack, built on top of Microsoft’s proprietary speech to text engine, which already allows you to control games with speech. Where does that take us?

Well, we already know how to make sophisticated natural language parsers for text, given moderately limited domains - we don’t need full natural language comprehension here.

-

You may think it’s a long way down the road to the chemist

+

You may think it’s a long way down the road to the chemist

There are things one needs to know in a game world. For example: I need a sword, where’s the nearest swordsmith? In a real quasi-medieval world, certainly every soldier would be able to tell you, and everyone from the swordsmith’s town or village. Very celebrated swordsmiths would be known more widely.

And the thing is, the game engine knows where the nearest swordsmith is. It knows what potion will heal what wound, and what herbs and what tincture to use to make it. It knows which meats are good to eat, and which inns have rooms free. It knows good campsites. It knows where there be dragons. It knows where the treasure is hid. It knows - as far as the game and its plot are concerned - everything.

So to make an in-game Siri - an omniscient companion you could ask anything of - would be easy. Trivial. It also wouldn’t add verisimilitude to the game. But to model which non-player characters know what is not that much harder. Local people know what’s where in their locality. Merchants know the prices in nearby markets. They, and minstrels, know the game-world’s news - major events that affect the plot. Apothecaries, alchemists and witches know the properties of herbs and minerals.

And to model which non-player characters are friendly, and willing to answer your every question; which neutral or busy, and liable to answer tersely; and which actively hostile, and likely, if they answer at all, to deliberately mislead - that’s not very much harder.

I’m not arguing that voice acting, and scripted dialogue trees, should be done away with altogether. They still have a use, as cutscenes do, to advance plot. And I’m not suggesting that we use voice to control the player characters movements and actions - I’m not not suggesting that we should say ‘run north; attack the troll with the rusty sword’. Keyboards and mice may be awkward ways to control action, but they’re better than that. Bur I am suggesting that one should be able to talk to any (supposedly sentient) character in the game, and have them talk reasonably sensibly back. As one can already do physically in wandering an open world, a full voice interaction system would allow one to go off piste - to leave the limited, constrained pre-scripted interaction of the voice-acted dialogue tree. And that has got to make our worlds, and our interactions with them, richer, more surprising, more engaging.

A hybrid system needn’t be hard to achieve, needn’t be jarring in use. You can record the phonemes of your voice actor’s voice, so that the same character will have roughly the same voice - the same timbre, the same vowel sounds, the same characteristics of  pronunciation - whether in a voice acted dialogue or in a generated one.

-

We don’t need to let voice acting limit the repertoires of our characters any more. And we shouldn’t.

\ No newline at end of file +

We don’t need to let voice acting limit the repertoires of our characters any more. And we shouldn’t.

+
\ No newline at end of file diff --git a/docs/codox/building_on_microworld.html b/docs/codox/building_on_microworld.html new file mode 100644 index 0000000..6a13727 --- /dev/null +++ b/docs/codox/building_on_microworld.html @@ -0,0 +1,8 @@ + +Building on Microworld

Building on Microworld

+

In Settling a Game World I intended that a world should be populated by setting agents - settlers - to explore the map and select places to settle according to particular rules. In the meantime, I’ve built MicroWorld, a rule driven cellular automaton which makes a reasonably good job of modelling human settlement. It works, and I now plan to use it, as detailed in this note; but there are issues.

+

First and foremost, it’s slow, and both processor and memory hungry. That means that at continent scale, a cell of one kilometre square is the minimum size which is really possible, which isn’t small enough to create a settlement map of the density that a game will need. Even with 1 km cells, even on the most powerful machines I have access to, a continent-size map will take many days to run.

+

Of course it would be possible to do a run at one km scale top identify areas which would support settlement, and then to do a run on a ten metre grid on each of those areas to more precisely plot settlement. That’s an idea which I haven’t yet explored, which might prove fruitful.

+

Secondly, being a cellular automaton, MicroWorld works on a grid. This means that everything is grid aligned, which is absolutely not what I want! So I think the way to leverage this is to use MicroWorld to establish which kilometre square cells om the grid should be populated (and roughly with what), and then switch to ad hoc code to populate those cells.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.agent.agent.html b/docs/codox/cc.journeyman.the-great-game.agent.agent.html new file mode 100644 index 0000000..343bf76 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.agent.agent.html @@ -0,0 +1,24 @@ + +cc.journeyman.the-great-game.agent.agent documentation

cc.journeyman.the-great-game.agent.agent

Anything in the game world with agency; primarily but not exclusively characters.

+

ProtoAgent

protocol

An object which can act in the world

+

members

act

(act actor world circle)

Allow actor to do something in this world, in the context of this circle; return the new state of the actor if something was done, nil if nothing was done. Circle is expected to be one of

+
    +
  • :active - actors within visual/audible range of the player character;
  • +
  • :pending - actors not in the active circle, but sufficiently close to it that they may enter the active circle within a short period;
  • +
  • :background - actors who are active in the background in order to handle trade, news, et cetera;
  • +
  • :other - actors who are not members of any other circle.
  • +
+

The act method must not have side effects; it must only return a new state. If the actor’s intention is to seek to change the state of something else in the game world, it must add a representation of that intention to the sequence which will be returned by its pending-intentions method.

+

hungry?

(hungry? actor world circle)

True if this actor is hungry and has no immediate access to food.

+

pending-intentions

(pending-intentions actor)

Returns a sequence of effects an actor intends, as a consequence of acting.

+

pending-scheduled-action?

(pending-scheduled-action? actor world circle)

True if there is a plan in this actor’s schedule which should be activated now. NOTE THAT plans in the daily schedule are NOT activated when in circles :background or :other

+

plan-fight-or-flight

(plan-fight-or-flight actor world circle)

Return a plan to resolve any active threat to this actor in this world.

+

plan-find-food

(plan-find-food actor workd circle)

Return a plan to find this actor food in this world.

+

plan-find-rest

(plan-find-rest actor workd circle)

Return a plan to find this actor a safe place to rest, or if in one, to actually rest, in this world.

+

plan-goal

(plan-goal actor world circle)

Return a plan to advance this actor towards their personal objective, in this world, or nil for default actors with no objective.

+

plan-scheduled-action

(plan-scheduled-action actor workd circle)

Return a plan taken from the schedule of this actor for the current date and time, if any, else nil.

+

schedule

(schedule actor)

Return a map of scheduled actions for this actor. TODO: work out the detailed format!

+

threatened?

(threatened? actor world circle)

True if this actor is threatened in this world.

+

tired?

(tired? actor world circle)

True if this actor needs rest.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.agent.schedule.html b/docs/codox/cc.journeyman.the-great-game.agent.schedule.html new file mode 100644 index 0000000..4a4ded2 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.agent.schedule.html @@ -0,0 +1,5 @@ + +cc.journeyman.the-great-game.agent.schedule documentation

cc.journeyman.the-great-game.agent.schedule

Schedules of plans for actors in the game, in order that they may have daily and seasonal patterns of behaviour.

+

plan-scheduled-action

(plan-scheduled-action actor world circle)

TODO: write docs

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.buildings.module.html b/docs/codox/cc.journeyman.the-great-game.buildings.module.html new file mode 100644 index 0000000..9a89a99 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.buildings.module.html @@ -0,0 +1,40 @@ + +cc.journeyman.the-great-game.buildings.module documentation

cc.journeyman.the-great-game.buildings.module

A module of a building; essentially something like a portacabin, which can be assembled together with other modules to make a complete building.

+

Modules need to include

+
    +
  1. Ground floor modules, having external doors;
  2. +
  3. Craft modules – workshops – which will normally be ground floor (except weavers) and may have the constraint that no upper floor module can cover them;
  4. +
  5. Upper floor modules, having NO external doors (but linking internal doors);
  6. +
  7. Roof modules
  8. +
+

Role must be one of:

+
    +
  1. :primary a ground floor main entrance module
  2. +
  3. :secondary a module which can be upper or ground floor
  4. +
  5. :upper a module which can only be on an upper floor, for example one with a projecting gallery, balcony or overhang.
  6. +
+

Other values for role will emerge.

+

Exits must be a sequence of keywords taken from the following list:

+
    +
  1. :left an exit in the centre of the left wall
  2. +
  3. :left-front an exit in the centre of the left half of the front wall
  4. +
  5. :front an exit in the centre of the front wall
  6. +
  7. :right-front an exit in the centre of the right half of the front wall
  8. +
  9. :right an exit in the centre of the right wall
  10. +
  11. :right-back an exit in the centre of the right half of the back wall
  12. +
  13. :left-back an exit in the centre of the back wall
  14. +
+

A module placed on an upper floor must have no exit which opens beyond the footprint of the floor below - no doors into mid air! However, it is allowable (and indeed is necessary) to allow doors into roof spaces if the adjacent module on the same floor does not yet exist, since otherwise it would be impossible to access a new room which might later be built there.

+

Load must be a small integer indicating both the weight of the module and the total amount of weight it can support. So for example a stone-built module might have a load value of 4, a brick built one of 3, and a half-timbered one of 2, and a tent of 0. This means a stone ground floor module could support one further floor of stone or brick, or two further floors of half timbered construction; while a brick built ground floor could support a single brick or half-timbered upper floor but not a stone one, and a half-timbered ground floor could only support a half timbered upper floor.

+

There also needs to be an undercroft or platform module, such that the area of the top of the platform is identical with the footprint of the building, and the altitude of the top of the platform is equal to the altitude of the terrain at the heighest corner of the building; so that the actual building doesn’t float in the air, and also so that none of the doors or windows are partly underground.

+

Each module needs to wrap an actual 3d model created in Blender or whatever, and have a list of optional textures with which that model can be rendered. So an upper floor bedroom module might have the following renders:

+
    +
  1. Bare masonry - constrained to upland or plateau terrain, and to coastal culture
  2. +
  3. Painted masonry - constrained to upland or plateau terrain, and to coastal culture
  4. +
  5. Half-timbered - not available on plateau terrain
  6. +
  7. Weatherboarded - constrained to forest terrain
  8. +
  9. Brick - constrained to arable or arid terrain
  10. +
+

of course these are only examples, and also, it’s entirely possible to have for example multiple different weatherboard renders for the same module. There needs to be a way of rendering what can be built above what: for example, you can’t have a masonry clad module over a half timbered one, but you can have a half-timbered one over a masonry one.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.buildings.rectangular.html b/docs/codox/cc.journeyman.the-great-game.buildings.rectangular.html new file mode 100644 index 0000000..7d190c5 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.buildings.rectangular.html @@ -0,0 +1,39 @@ + +cc.journeyman.the-great-game.buildings.rectangular documentation

cc.journeyman.the-great-game.buildings.rectangular

Build buildings with a generally rectangular floow plan.

+

Motivations

+

Right, the idea behind this namespace is many fold.

+
    +
  1. To establish the broad principle of genetic buildings, by creating a function which reproducibly creates reproducible buildings at specified locations, such that different buildings are credibly varied but a building at a specified location is always (modulo economic change) the same.
  2. +
  3. Create good rectangular buildings, and investigate whether a single function can be used to create buildings of more than one family (e.g. can it produce flat roofed, north African style, mud brick houses as well as pitch roofed, half timbered northern European houses?)
  4. +
  5. Establish whether, in my current state of fairly severe mental illness, I can actually produce any usable code at all.
  6. +
+

Key factors in the creation of a building

+

Holding

+

Every building is on a holding, and, indeed, what I mean by ‘building’ here may well turn out to be ’the collection of all the permanent structures on a holding. A holding is a polygonal area of the map which does not intersect with any other holding, but for the time being we’ll make the simplifying assumption that every holding is a rectangular strip, and that ‘urban’ holdings are of a reasonably standard width (see Viking-period York) and length. Rural holdings (farms, ?wood lots) may be much larger.

+

Terrain

+

A building is made of the stuff of the place. In a forest, buildings will tend to be wooden; in a terrain with rocky outcrops – normally found on steep slopes – stone. On the flat lands where there’s river mud, of brick, cob, or wattle and daub. So to build a building we need to know the terrain. Terrain can be inferred from location but in practice this will be computationally expensive, so we’ll pass terrain in as an argument to the build function.

+

For the time being we’ll pass it in simply as a keyword from a defined set of keywords; later it may be a more sophisticated data structure.

+

Culture

+

People of different cultures build distinctively different buildings, even when using the same materials. So, in our world, a Japanese wooden house looks quite different from an Anglo Saxon stave house which looks quite different from a Canadian log cabin, even though the materials are much the same and the tools available to build with are not much different.

+

Culture can affect not just the overall shape of a building but also its finish and surface detail. For example, in many places in England, stone buildings are typically left bare; in rural Scotland, typically painted white or in pastel shades; in Ireland, often quite vivid colours.

+

People may also show religious or cultural symbols on their buildings.

+

For all these reasons, we need to know the culture of the occupant when creating a building. Again, this will initially be passed in as a keyword.

+

Craft

+

People in the game world have a craft, and some crafts will require different features in the building. In the broadly late-bronze-age-to medieval period within which the game is set, residence and workplace are for most people pretty much the same.

+

So a baker needs an oven, a smith a forge, and so on. All crafts who do some degree retail trade will want a shop front as part of the ground floor of their dwelling. Merchants and bankers will probably have houses that are a bit more showy than others.

+

Whether the ‘genetic buildings’ idea will ever really produce suitable buildings for aristons I don’t know; it seems more likely that significant strongholds (of which there will be relatively few) should all be hand modelled rather than procedurally generated.

+

*building-families*

dynamic

Families of buildings.

+

Each family has

+
    +
  • terrain types to which it is appropriate;
  • +
  • crafts to which it is appropriate;
  • +
  • cultures to which it is appropriate.
  • +
+

Each generated building will be of one family, and will comprise modules taken only from that family.

+

*crafts*

dynamic

Crafts which affect building types in the game. See Populating a game world. TODO: placeholder

+

*cultures*

dynamic

Cultures which affect building families. TODO: placeholder

+

*terrain-types*

dynamic

Types of terrain which affect building families. TODO: This is a placeholder; a more sophisticated model will be needed.

+

build!

(build! holding terrain culture craft size)

Builds a building, and returns a data structure which represents it. In building the building, it adds a model of the building to the representation of the world, so it does have a side effect.

+

building-family

(building-family terrain culture craft gene)

A building family is essentially a collection of models of building modules which can be assembled to create buildings of a particular structural and architectural style.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.cloverage.html b/docs/codox/cc.journeyman.the-great-game.cloverage.html new file mode 100644 index 0000000..8f847a4 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.cloverage.html @@ -0,0 +1,6 @@ + +cc.journeyman.the-great-game.cloverage documentation

cc.journeyman.the-great-game.cloverage

TODO: write docs

+

documented-project-dir

TODO: write docs

+

opts

TODO: write docs

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.gossip.gossip.html b/docs/codox/cc.journeyman.the-great-game.gossip.gossip.html new file mode 100644 index 0000000..9ec474a --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.gossip.gossip.html @@ -0,0 +1,10 @@ + +cc.journeyman.the-great-game.gossip.gossip documentation

cc.journeyman.the-great-game.gossip.gossip

Interchange of news events between gossip agents.

+

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.

+

Innkeepers are also gossip agents but do not typically move.

+

dialogue

(dialogue enquirer respondent world)

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.

+

gather-news

(gather-news world gossip)

Gather news for the specified gossip in this world.

+

move-gossip

(move-gossip gossip world new-location)

Return a world like this world but with this gossip moved to this new-location. Many gossips are essentially shadow-records of agents of other types, and the movement of the gossip should be controlled by the run function of the type of the record they shadow. The function below does NOT call this function.

+

run

(run world)

Return a world like this world, with news items exchanged between gossip agents.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.gossip.news-items.html b/docs/codox/cc.journeyman.the-great-game.gossip.news-items.html new file mode 100644 index 0000000..7bf108f --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.gossip.news-items.html @@ -0,0 +1,54 @@ + +cc.journeyman.the-great-game.gossip.news-items documentation

cc.journeyman.the-great-game.gossip.news-items

Using news items (propositions) to transfer knowledge between gossip agents.

+

Status

+

What is here is essentially working. It’s not, however, working with the rich data objects which will be needed, and it’s not yet nearly efficient enough, but it allows knowledge to propagate through the world procedurally, at a rate limited by the speed of movement of the gossip agents.

+

Discussion

+

The ideas here are based on the essay The spread of knowledge in a large game world, q.v.; they’ve advanced a little beyond that and will doubtless advance further in the course of writing and debugging this namespace.

+

A news item is a map with the keys:

+
    +
  • date - the date on which the reported event is claimed to have happened;
  • +
  • nth-hand - the number of agents the news item has passed through;
  • +
  • verb - what it is that happened (key into news-topics);
  • +
+

plus other keys taken from the keys value associated with the verb in news-topics.

+

Notes:

+

TODO
+This namespace at present considers the :knowledge of a gossip to be a flat list of propositions, each of which must be checked every time any new proposition is offered. This is woefully inefficient.

+

all-known-verbs

All verbs currently known to the gossip system.

+

compatible-item?

(compatible-item? new-item known-item)

True if new-item is identical with, or less specific than, known-item.

+

If we already know ‘Bad Joe killed Sweet Daisy’, there’s no point in learning that ‘someone killed Sweet Daisy’, but there is point in learning ‘someone killed Sweet Daisy with poison’.

+

compatible-value?

(compatible-value? new-value known-value)

True if known-value is the same as new-value, or, for each key present in new-value, has the same value for that key.

+

The rationale here is that if new-value contains new or different information, it’s worth learning; otherwise, not.

+

degrade-character

(degrade-character gossip character)

Return a character specification like this character, but comprising only those properties this gossip is interested in.

+

degrade-location

(degrade-location gossip location)

Return a location specification like this location, but comprising only those elements this gossip is interested in. If none, return nil.

+

degrade-news-item

(degrade-news-item gossip item)

TODO: write docs

+

infer

(infer item rule)

Infer a new knowledge item from this item, following this rule.

+

interest-in-character

(interest-in-character gossip character)

Integer representation of how interesting this character is to this gossip. TODO: this assumes that characters are passed as keywords, but, as documented above, they probably have to be maps, to allow for degradation.

+

interest-in-location

(interest-in-location gossip location)

Integer representation of how interesting this location is to this gossip.

+

interesting-character?

(interesting-character? gossip character)

Boolean representation of whether this character is interesting to this gossip.

+

interesting-item?

(interesting-item? gossip item)

True if anything about this news item is interesting to this gossip.

+

interesting-location?

(interesting-location? gossip location)

True if the location of this news item is interesting to this gossip.

+

interesting-object?

(interesting-object? gossip object)

TODO: write docs

+

interesting-verb?

(interesting-verb? gossip verb)

Is this verb interesting to this gossip?

+

known-item?

(known-item? gossip item)

True if this news item is already known to this gossip.

+

This means that the gossip already knows an item which identifiably has the same or more specific values for all the keys of this item except :nth-hand, :confidence and :learned-from.

+

learn-news-item

(learn-news-item gossip item)(learn-news-item gossip item follow-inferences?)

Return a gossip like this gossip, which has learned this news item if it is of interest to them.

+

make-all-inferences

(make-all-inferences item)

Return a set of knowledge entries that can be inferred from this news item.

+

news-topics

Topics of interest to gossip agents. Topics are keyed in this map by their verbs. The keys associated with each topic are the extra pieces of information required to give context to a gossip item. Generally:

+
    +
  • actor is the id of the character who it is reported performed the action;
  • +
  • other is the id of the character on whom it is reported the action was performed;
  • +
  • location is the place at which the action was performed;
  • +
  • object is an object (or possibly list of objects?) relevant to the action;
  • +
  • price is special to buy/sell, but of significant interest to merchants.
  • +
+

Characters

+

TODO but note that at most all the receiver can learn about a character from a news item is what the giver knows about that character, degraded by what the receiver finds interesting about them. If we just pass the id here, then either the receiver knows everything in the database about the character, or else the receiver knows nothing at all about the character. Neither is desirable. Further thought needed.

+

By implication, the character values passed should include all the information the giver knows about the character; that can then be degraded as the receiver stores only that segment which the receiver finds interesting.

+

Locations

+

A ‘location’ value is a list comprising at most the x/y coordinate location and the ids of the settlement and region (possibly hierarchically) that contain the location. If the x/y is not local to the home of the receiving agent, they won’t remember it and won’t pass it on; if any of the ids are not interesting So location information will degrade progressively as the item is passed along.

+

It is assumed that the :home of a character is a location in this sense.

+

Inferences

+

If an agent learns that Adam has married Betty, they can infer that Betty has married Adam; if they learn that Charles killed Dorothy, that Dorothy has died. I’m not convinced that my representation of inferences here is ideal.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.holdings.holding.html b/docs/codox/cc.journeyman.the-great-game.holdings.holding.html new file mode 100644 index 0000000..a55c5f5 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.holdings.holding.html @@ -0,0 +1,6 @@ + +cc.journeyman.the-great-game.holdings.holding documentation

cc.journeyman.the-great-game.holdings.holding

TODO: write docs

+

ProtoHolding

protocol

members

building-origin

(building-origin holding)

Returns an oriented location - normally the right hand end of the frontage, for an urban holding - from which buildings on the holding should be built.

+

frontage

(frontage holding)

Returns a sequence of two locations representing the edge of the polygon which defines this holding which is considered to be the front.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.location.location.html b/docs/codox/cc.journeyman.the-great-game.location.location.html new file mode 100644 index 0000000..3b99969 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.location.location.html @@ -0,0 +1,9 @@ + +cc.journeyman.the-great-game.location.location documentation

cc.journeyman.the-great-game.location.location

TODO: write docs

+

ProtoLocation

protocol

members

altitude

(altitude location)

Return the absolute altitude of this location, which may be different from the terrain height at this location, if, for example, the location is underground or on an upper floor.

+

easting

(easting location)

Return the easting of this location

+

northing

(northing location)

Return the northing of this location

+

settlement

(settlement location)

Return the settlement record of the settlement in this world within whose parish polygon this location exists, or if none whose centre (inn location) is closest to this location

+

terrain-altitude

(terrain-altitude location)

Return the ‘ground level’ (altitude of the terrain) at this location given this world. TODO: possibly terrain-altitude should be a method of the world.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.lore.digester.html b/docs/codox/cc.journeyman.the-great-game.lore.digester.html new file mode 100644 index 0000000..f43a435 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.lore.digester.html @@ -0,0 +1,4 @@ + +cc.journeyman.the-great-game.lore.digester documentation

cc.journeyman.the-great-game.lore.digester

TODO: write docs

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.merchants.markets.html b/docs/codox/cc.journeyman.the-great-game.merchants.markets.html new file mode 100644 index 0000000..7801e86 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.merchants.markets.html @@ -0,0 +1,8 @@ + +cc.journeyman.the-great-game.merchants.markets documentation

cc.journeyman.the-great-game.merchants.markets

Adjusting quantities and prices in markets.

+

adjust-quantity-and-price

(adjust-quantity-and-price world city commodity)

Adjust the quantity of this commodity currently in stock in this city of this world. Return a fragmentary world which can be deep-merged into this world.

+

new-price

(new-price old stock supply demand)

If stock is greater than the maximum of supply and demand, then there is surplus and old price is too high, so shold be reduced. If lower, then it is too low and should be increased.

+

run

(run world)

Return a world like this world, with quantities and prices in markets updated to reflect supply and demand.

+

update-markets

(update-markets world)(update-markets world city)(update-markets world city commodity)

Return a world like this world, with quantities and prices in markets updated to reflect supply and demand. If city or city and commodity are specified, return a fragmentary world with only the changes for that city (and commodity if specified) populated.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.merchants.merchant-utils.html b/docs/codox/cc.journeyman.the-great-game.merchants.merchant-utils.html new file mode 100644 index 0000000..de4820b --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.merchants.merchant-utils.html @@ -0,0 +1,10 @@ + +cc.journeyman.the-great-game.merchants.merchant-utils documentation

cc.journeyman.the-great-game.merchants.merchant-utils

Useful functions for doing low-level things with merchants.

+

add-known-prices

(add-known-prices merchant world)

Add the current prices at this merchant’s location in the world to a new cache of known prices, and return it.

+

add-stock

(add-stock a b)

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.

+

burden

(burden merchant world)

The total weight of the current cargo carried by this merchant in this world.

+

can-afford

(can-afford merchant world commodity)

Return the number of units of this commodity which this merchant can afford to buy in this world.

+

can-carry

(can-carry merchant world commodity)

Return the number of units of this commodity which this merchant can carry in this world, given their current burden.

+

expected-price

(expected-price merchant commodity city)

Find the price anticipated, given this world, by this merchant for this commodity in this city. If no information, assume 1. merchant should be passed as a map, commodity and city should be passed as keywords.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.merchants.merchants.html b/docs/codox/cc.journeyman.the-great-game.merchants.merchants.html new file mode 100644 index 0000000..717d464 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.merchants.merchants.html @@ -0,0 +1,5 @@ + +cc.journeyman.the-great-game.merchants.merchants documentation

cc.journeyman.the-great-game.merchants.merchants

Trade planning for merchants, primarily.

+

run

(run world)

Return a partial world based on this world, but with each merchant moved.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.merchants.planning.html b/docs/codox/cc.journeyman.the-great-game.merchants.planning.html new file mode 100644 index 0000000..187b01e --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.merchants.planning.html @@ -0,0 +1,32 @@ + +cc.journeyman.the-great-game.merchants.planning documentation

cc.journeyman.the-great-game.merchants.planning

Trade planning for merchants, primarily. This follows a simple-minded generate-and-test strategy and currently generates plans for all possible routes from the current location. This may not scale. Also, routes do not currently have cost or risk associated with them.

+

augment-plan

(augment-plan merchant world plan)

Augment this plan constructed in this world for this merchant with the :quantity of goods which should be bought and the :expected-profit of the trade.

+

Returns the augmented plan.

+

generate-trade-plans

(generate-trade-plans merchant world commodity)

Generate all possible trade plans for this merchant and this commodity in this world.

+

Returned plans are maps with keys:

+
    +
  • :merchant - the id of the merchant for whom the plan was created;
  • +
  • :origin - the city from which the trade starts;
  • +
  • :destination - the city to which the trade is planned;
  • +
  • :commodity - the commodity to be carried;
  • +
  • :buy-price - the price at which that commodity can be bought;
  • +
  • :expected-price - the price at which the merchant anticipates that commodity can be sold;
  • +
  • :distance - the number of stages in the planned journey
  • +
  • :dist-to-home - the distance from destination to the merchant’s home city.
  • +
+

nearest-with-targets

(nearest-with-targets plans targets)

Return the distance to the nearest destination among those of these plans which match these targets. Plans are expected to be plans as returned by generate-trade-plans, q.v.; targets are expected to be as accepted by make-target-filter, q.v.

+

plan-trade

(plan-trade merchant world commodity)

Find the best destination in this world for this commodity given this merchant and this origin. If two cities are anticipated to offer the same price, the nearer should be preferred; if two are equally distant, the ones nearer to the merchant’s home should be preferred. merchant may be passed as a map or a keyword; commodity should be passed as a keyword.

+

The returned plan is a map with keys:

+
    +
  • :merchant - the id of the merchant for whom the plan was created;
  • +
  • :origin - the city from which the trade starts;
  • +
  • :destination - the city to which the trade is planned;
  • +
  • :commodity - the commodity to be carried;
  • +
  • :buy-price - the price at which that commodity can be bought;
  • +
  • :expected-price - the price at which the merchant anticipates that commodity can be sold;
  • +
  • :distance - the number of stages in the planned journey
  • +
  • :dist-to-home - the distance from destination to the merchant’s home city.
  • +
+

select-cargo

(select-cargo merchant world)

A merchant, in a given location in a world, will choose to buy a cargo within the limit they are capable of carrying, which they can anticipate selling for a profit at a destination.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.merchants.strategies.simple.html b/docs/codox/cc.journeyman.the-great-game.merchants.strategies.simple.html new file mode 100644 index 0000000..169f900 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.merchants.strategies.simple.html @@ -0,0 +1,9 @@ + +cc.journeyman.the-great-game.merchants.strategies.simple documentation

cc.journeyman.the-great-game.merchants.strategies.simple

Default trading strategy for merchants.

+

The simple strategy buys a single product in the local market if there is one which can be traded profitably, trades it to the chosen target market, and sells it there. If there is no commodity locally which can be traded profitably, moves towards home with no cargo. If at home and no commodity can be traded profitably, does not move.

+

move-merchant

(move-merchant merchant world)

Handle general en route movement of this merchant in this world; return a (partial or full) world like this world but in which the merchant may have been moved ot updated.

+

plan-and-buy

(plan-and-buy merchant world)

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.

+

re-plan

(re-plan merchant world)

Having failed to sell a cargo at current location, re-plan a route to sell the current cargo. Returns a revised world.

+

sell-and-buy

(sell-and-buy merchant world)

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.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.objects.character.html b/docs/codox/cc.journeyman.the-great-game.objects.character.html new file mode 100644 index 0000000..a312edb --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.objects.character.html @@ -0,0 +1,4 @@ + +cc.journeyman.the-great-game.objects.character documentation

cc.journeyman.the-great-game.objects.character

TODO: write docs

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.objects.container.html b/docs/codox/cc.journeyman.the-great-game.objects.container.html new file mode 100644 index 0000000..c20418c --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.objects.container.html @@ -0,0 +1,6 @@ + +cc.journeyman.the-great-game.objects.container documentation

cc.journeyman.the-great-game.objects.container

TODO: write docs

+

ProtoContainer

protocol

members

contents

(contents container)

Return a sequence of the contents of this container, or nil if empty.

+

is-empty?

(is-empty? container)

Return true if this container is empty, else false.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.objects.game-object.html b/docs/codox/cc.journeyman.the-great-game.objects.game-object.html new file mode 100644 index 0000000..9bccbe9 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.objects.game-object.html @@ -0,0 +1,7 @@ + +cc.journeyman.the-great-game.objects.game-object documentation

cc.journeyman.the-great-game.objects.game-object

Anything at all in the game world

+

ProtoObject

protocol

An object in the world

+

members

id

(id object)

Returns the unique id of this object.

+

reify-object

(reify-object object)

Adds this object to the global object list. If the object has a non-nil value for its id method, keys it to that id - but if the id value is already in use, throws a hard exception. Returns the id to which the object is keyed in the global object list.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.playroom.html b/docs/codox/cc.journeyman.the-great-game.playroom.html new file mode 100644 index 0000000..1f2b666 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.playroom.html @@ -0,0 +1,7 @@ + +cc.journeyman.the-great-game.playroom documentation

cc.journeyman.the-great-game.playroom

TODO: write docs

+

app

TODO: write docs

+

init

(init)

TODO: write docs

+

simple-update

(simple-update tpf)

TODO: write docs

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.time.html b/docs/codox/cc.journeyman.the-great-game.time.html new file mode 100644 index 0000000..cad862f --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.time.html @@ -0,0 +1,22 @@ + +cc.journeyman.the-great-game.time documentation

cc.journeyman.the-great-game.time

TODO: write docs

+

canonical-ordering-of-houses

The canonical ordering of religious houses.

+

date-string

(date-string game-time)

Return a correctly formatted date for this game-time in the calendar of the Great Place.

+

day

(day game-time)

Day of the eight-day week represented by this game-time.

+

day-of-year

macro

(day-of-year game-time)

The day of the year represented by this game-time, ignoring leap years.

+

days-in-season

TODO: write docs

+

days-in-week

This world has an eight day week.

+

days-of-week

The eight-day week of the game world. This differs from the canonical ordering of houses in that it omits the eye.

+

game-day-length

The Java clock advances in milliseconds, which is fine. But we need game-days to be shorter than real world days. A Witcher 3 game day is 1 hour 36 minutes, or 96 minutes, which is presumably researched. Round it up to 100 minutes for easier calculation.

+

game-start-time

The start time of this run.

+

game-time

(game-time)(game-time timestamp)

With no arguments, the current game time. If a Java timestamp value is passed (as a long), the game time represented by that value.

+

now

(now)

For now, we’ll use Java timestamp for time; ultimately, we need a concept of game-time which allows us to drive day/night cycle, seasons, et cetera, but what matters about time is that it is a value which increases.

+

season

(season game-time)

TODO: write docs

+

seasons-in-year

Nine seasons in a year, one for each house (although the order is different.

+

seasons-of-year

The ordering of seasons in the year is different from the canonical ordering of the houses, for reasons of the agricultural cycle.

+

waiting-day?

Does this game-time represent a waiting day?

+

week

(week game-time)

Week of season represented by this game-time.

+

weeks-in-season

To fit nine seasons of eight day weeks into 365 days, each must be of five weeks.

+

weeks-of-season

To fit nine seasons of eight day weeks into 365 days, each must be of five weeks.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.utils.html b/docs/codox/cc.journeyman.the-great-game.utils.html new file mode 100644 index 0000000..a219273 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.utils.html @@ -0,0 +1,10 @@ + +cc.journeyman.the-great-game.utils documentation

cc.journeyman.the-great-game.utils

TODO: write docs

+

cyclic?

(cyclic? route)

True if two or more elements of route are identical

+

deep-merge

(deep-merge & maps)

inc-or-one

(inc-or-one val)

If this val is a number, return that number incremented by one; otherwise, return 1. TODO: should probably be in utils.

+

make-target-filter

(make-target-filter targets)

Construct a filter which, when applied to a list of maps, will pass those which match these targets, where each target is a tuple key value.

+

truthy?

(truthy? val)

Returns true unless val is nil, false or an empty sequence. Otherwise always ‘false’; never any other value.

+

value-or-default

(value-or-default m k dflt)

Return the value of this key k in this map m, or this dflt value if there is none.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.world.heightmap.html b/docs/codox/cc.journeyman.the-great-game.world.heightmap.html new file mode 100644 index 0000000..f8c182d --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.world.heightmap.html @@ -0,0 +1,14 @@ + +cc.journeyman.the-great-game.world.heightmap documentation

cc.journeyman.the-great-game.world.heightmap

Functions dealing with the tessellated multi-layer heightmap.

+

*base-map*

dynamic

TODO: write docs

+

*noise-map*

dynamic

TODO: write docs

+

excerpt-grid

(excerpt-grid grid x-offset y-offset width height)

Return that section of this grid where the :x co-ordinate of each cell is greater than or equal to this x-offset, the :y co-ordinate is greater than or equal to this y-offset, whose width is not greater than this width, and whose height is not greater than this height.

+

get-surface

(get-surface cell-size x-offset y-offset width height)(get-surface base-map noise-map cell-size x-offset y-offset width height)

Return, as a vector of vectors of cells represented as Clojure maps, a segment of surface from this base-map as modified by this noise-map at this cell-size starting at this x-offset and y-offset and having this width and height.

+

If base-map and noise-map are not supplied, the bindings of *base-map* and *noise-map* will be used, respectively.

+

base-map and noise-map may be passed either as strings, assumed to be file paths of PNG files, or as MicroWorld style world arrays. It is assumed that one pixel in base-map represents one square kilometre in the game world. It is assumed that cell-size, x-offset, y-offset, width and height are integer numbers of metres.

+

interpolate-altitude

(interpolate-altitude cell grid src-width x-offset y-offset)

Return the altitude of the point at x-offset, y-offset within this cell having this src-width, taken from this grid.

+

interpolate-cell

(interpolate-cell cell grid src-width target-width)

Construct a grid (array of arrays) of cells each of width target-width from this cell, of width src-width, taken from this grid

+

interpolate-grid

(interpolate-grid grid src-width target-width)

Return a grid interpolated from this grid of rows, cols given scaling from this src-width to this target-width

+

scale-grid

(scale-grid grid n)

multiply all :x and :y values in this grid by this n.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.world.location.html b/docs/codox/cc.journeyman.the-great-game.world.location.html new file mode 100644 index 0000000..9d1aa6d --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.world.location.html @@ -0,0 +1,6 @@ + +cc.journeyman.the-great-game.world.location documentation

cc.journeyman.the-great-game.world.location

Functions dealing with location in the world.

+

distance-between

(distance-between location-1 location-2)

TODO: write docs

+

get-coords

(get-coords location)

Return the coordinates in the game world of location, which may be 1. A coordinate pair in the format {:x 5 :y 32}; 2. A location, as discussed above; 3. Any other gameworld object, having a :location property whose value is one of the above.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.world.mw.html b/docs/codox/cc.journeyman.the-great-game.world.mw.html new file mode 100644 index 0000000..20bc9d8 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.world.mw.html @@ -0,0 +1,4 @@ + +cc.journeyman.the-great-game.world.mw documentation

cc.journeyman.the-great-game.world.mw

Functions dealing with building a great game world from a MicroWorld world.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.world.routes.html b/docs/codox/cc.journeyman.the-great-game.world.routes.html new file mode 100644 index 0000000..e414e6b --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.world.routes.html @@ -0,0 +1,6 @@ + +cc.journeyman.the-great-game.world.routes documentation

cc.journeyman.the-great-game.world.routes

Conceptual (plan level) routes, represented as tuples of location ids.

+

find-route

(find-route world-or-routes from to)

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.

+

find-routes

(find-routes routes from)(find-routes routes from to)(find-routes routes from to steps)

Find routes from among these routes from from; if to is supplied, to to, by breadth-first search.

+
\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.world.run.html b/docs/codox/cc.journeyman.the-great-game.world.run.html new file mode 100644 index 0000000..9e6bfe8 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.world.run.html @@ -0,0 +1,3 @@ + +cc.journeyman.the-great-game.world.run documentation

cc.journeyman.the-great-game.world.run

Run the whole simulation

init

(init)(init config)

TODO: write docs

run

(run world)(run world date)

The pipeline to run the simulation each game day. Returns a world like this world, with all the various active elements updated. The optional date argument, if supplied, is set as the :date of the returned world.

\ No newline at end of file diff --git a/docs/codox/cc.journeyman.the-great-game.world.world.html b/docs/codox/cc.journeyman.the-great-game.world.world.html new file mode 100644 index 0000000..2c10680 --- /dev/null +++ b/docs/codox/cc.journeyman.the-great-game.world.world.html @@ -0,0 +1,7 @@ + +cc.journeyman.the-great-game.world.world documentation

cc.journeyman.the-great-game.world.world

Access to data about the world

+

actual-price

(actual-price world commodity city)

Find the actual current price of this commodity in this city given this world. NOTE that merchants can only know the actual prices in the city in which they are currently located.

+

default-world

A basic world for testing concepts

+

run

(run world)(run world date)

Return a world like this world with only the :date to this date (or id date not supplied, the current value incremented by one). For running other aspects of the simulation, see the-great-game.world.run.

+
\ No newline at end of file diff --git a/docs/codox/economy.html b/docs/codox/economy.html index 8e93312..f95ccf8 100644 --- a/docs/codox/economy.html +++ b/docs/codox/economy.html @@ -1,33 +1,36 @@ -Game world economy

Game world economy

+Game world economy

Game world economy

Broadly this essay extends ideas presented in Populating a game world, q.v.

-

Primary producers

-

Herdsfolk

-

Herdsfolk are nomadic; it’s reasonable to think they’ll bring their herds to market, rather than selling it lots of tiny markets. So in the spring, shepherds will visit specific towns at the edge of open land, to hold a shearing festival/carnevale; and that both shepherds and cattle herders will visit towns on the edge of open land to sell fatstock in the autumn.

-

Miners

+

Primary producers

+

Herdsfolk

+

Herdsfolk are nomadic; it’s reasonable to think they’ll bring their herds to market, rather than selling at lots of tiny markets. So in the spring, shepherds will visit specific towns at the edge of open land, to hold a shearing festival/carnevale; and that both shepherds and cattle herders will visit towns on the edge of open land to sell fatstock in the autumn.

+

Miners

Miners mine. They’re settled, but they’re settled usually in specialist settlements at the location where the ore body is accessible, usually in mountenous territory. They’ll consume a lot of food, so there will be a local market for foodstuffs encouraging local farming. Different mines obviously mine different ores, but, for example, lead and silver are frequently found together.

-

Foresters

+

Foresters

Foresters are more or less settled at the edge of forests, at locations from which timber can be moved by navigable water; again in specialist settlements. In addition to timber, foresters hunt and produce both meat and furs, so have less need for other food producers locally.

-

Farmers

+

Farmers

Farmers are settled. Farmers occupy standard runrig plots, but because they don’t employ journeymen or apprentices, and don’t have workshops, the plots are mostly open with little building. Most farmers are ‘mixed farmers’, producing cereals, meat, eggs and milk. Some will be more specialist. Farm produce, taken broadly to include orchardsfolk, include:

    -
  • meat
  • -
  • milk and milk products
  • -
  • hides
  • -
  • eggs
  • -
  • cereals
  • -
  • root vegetables, onions, etc
  • -
  • peas and beans
  • -
  • leaf vegetables
  • -
  • fruits
  • -
  • fibres: linen, hemp and silk (from silk-moths in mulberry orchards)
  • -
  • possibly other stuff I’ve forgotten.
  • +
  • meat
  • +
  • milk and milk products
  • +
  • hides
  • +
  • eggs
  • +
  • cereals
  • +
  • root vegetables, onions, etc
  • +
  • peas and beans
  • +
  • leaf vegetables
  • +
  • fruits
  • +
  • fibres: linen, hemp and silk (from silk-moths in mulberry orchards)
  • +
  • possibly other stuff I’ve forgotten.

Farmers are all basically subsistence farmers, farming first to feed their own household and selling only surplus in the market.

-

Crafts

+

Crafts

Crafts generally process primary goods into secondary goods - whether intermediate stages or final consumer items. Some elite ‘crafts’ deal with abstract primary goods like law and knowledge, and they may be seen as somewhat separate.

-

A master craftsperson occupies a standard runrig plot, much like a farmer’s plot. Like a farmer, a poor master crafter household will cultivate part of the plot to produce food for the house - at least grow vegetables and keep hens. However, as the crafter takes on apprentices and journeymen - and gets richer - more buildings will be required as accommodation, workshop space and materials stores.

+

A master craftsperson may occupy a standard runrig plot, much like a farmer’s plot. Like a farmer, a poor master crafter household will cultivate part of the plot to produce food for the house - at least grow vegetables and keep hens. However, as the crafter takes on apprentices and journeymen - and gets richer - more buildings will be required as accommodation, workshop space and materials stores.

+

Also, Tchahua is much more a gold-rush town than an organic, grew over hundreds of years sort of town, so it is not ex-runrig; and additionally the original settlement was probably along the river bank, land which has now been redeveloped as warehouses and as rich merchant residences. Generally, town house plots are small from the get go.

+

Hans’hua is again an exception from normal organic development, as it has no agricultural land close to the city at all.

Generally, primary goods aren’t transported over land - because overland transport is expensive, by the time they’ve been transported they’re no longer low cost goods. So often the craftspeople who process primary produce into at least commodity intermediate forms will live close to the source of the primary goods.

So, for example, the town(s) where the shepherds hold their shearing fairs will tend to have a lot of weavers. While around mines there will be smelters producing ingots and bar stock to be marketed to smiths all over the place, there will also be smiths close to the mines producing commodity tools and weapons.

-

See the table in Populating a game world.

\ No newline at end of file +

See the table in Populating a game world.

+
\ No newline at end of file diff --git a/docs/codox/genetic-buildings.html b/docs/codox/genetic-buildings.html new file mode 100644 index 0000000..4274e19 --- /dev/null +++ b/docs/codox/genetic-buildings.html @@ -0,0 +1,46 @@ + +Genetic Buildings

Genetic Buildings

+

Building selection based on location

+

The objective of this note is to create a landscape with varied and believable buildings, with the minimum possible data storage per instance.

+

Like plants, buildings will ‘grow’ from a seed which has northing and easting attributes. These locate a position on the map. Again, like trees, some aspects of the building type selector are location based. Aspects of the location which are relevant to building type are

+
    +
  • elevation — derived from the map location by interpolation from grid. The actual interpolation algorithm is probably some form of spline, but in any case it’s the same one as for everything else.
  • +
  • orientation of slope — derived by taking altitude at four corners of a 100 metre square centred on the seed point, and then taking the highest and lowest of these. If highest is northwest, lowest is southeast, the slope is considered to be oriented southeast; if highest is northwest and lowest southwest, the orientation is considered to be south, and so on. Eight orientation values are sufficient.
  • +
  • gradient of slope — derived from the difference in altitude across the same 100 metre square
  • +
  • neighbours — number of other buildings in 500 metre square centred on seed point.
  • +
+

The reason orientation is relevant is exactly the same as the reason it’s relevant to trees. West facing slopes are assumed wetter (coriolis winds), so grow trees better, so better availability of better quality timber, so a higher probability of timber as a primary building material. But also, in areas of higher rainfall, rain shedding is an important consideration, so a higher value is placed on pitched roofs.

+

So you have the following general relationships

+
    +
  • west (or southwest or northwest) facing, moderate gradient, moderate altitude: high probability of timber construction; construction techniques involving large timbers (e.g. cruck frame); greater probability of shingled roofs;
  • +
  • west (or southwest or northwest) facing, moderate gradient, higher altitude or northern latitude: high probability of building styles adapted to straight-trunk conifers, e.g. log cabins, stave buildings; greater probability of shingled roofs;
  • +
  • east facing, generally: greater probability of flat roofs;
  • +
  • steeper gradients: greater probability of stone buildings (steeper gradients = shallower topsoil and greater ease of quarrying = access to stone); greater probability of slate roofs;
  • +
  • shallower gradients: greater probability of mud, cobb, brick or wattle-and-daub as building materials; greater probability of thatch or turf roofs;
  • +
  • Higher number of neighbours: higher probability of two or more stories;
  • +
+

These factors allow classes of building to be selected. Having got past that point, we need to consider how classes of genetic building can work.

+

Rectangular genetic buildings

+

Some genetic buildings will have cells with rectangular plan. This doesn’t mean that genetic buildings are required to have rectangular cells, but they provide a starting point for discussion. For a given class of building (for example, timber frame), a number of prototype models of cells exist. These models are fully realised three dimensional models. Possibly all cells belonging to the building class have two open ends, and end walls exist as separate models; equally possibly, some cells have only one extensible end. In any case, a building will not normally comprise a single cell. Normally it will comprise multiple cells. So the cells belonging to a particular building class will be designed to ‘plug together’. Multi story building classes will have some cells which are specifically ground floor only (flat ceiling, no roof), and such cells will always have an upper floor cell added above them. Where an upper floor cell has an outside door, an outside stair will automatically be added.

+

Cell mutability

+

Although cell models are repeatedly reused they don’t have to look the same every time they are reused. Within limits, every cell can be stretched along any of its three axes. Obviously, the degree of stretch on a given axis for every cell in a given building must be the same, otherwise they won’t line up. Another mutable area is skinning — it may be possible to have alternate skins for cells, and even if there are not alternate skins, it will be possible to mutably darken, lighten or otherwise tint the skins used, within ranges which are appropriate to the materials represented. Obviously there are limits to stretching — timber comes in only such a length, stone lintels will only support such a span.

+

Functional cells

+

Some trade functions require cells of particular kinds. Thus a smith needs a working building with one cell which is explicitly a forge. A water mill must have one cell which explicitly houses the mill gear. A forge cell or a waterwheel cell should never appear in weavers workshop. But most cells are not dedicated in this way. A bedroom cell is a bedroom cell, more or less; wealth may alter how it is furnished, but it may appear in any dwelling. Similarly, except for the very wealthy, a living cell is pretty much a living cell. And any building may incorporate a storage cell. If a given building class has twelve distinct ‘generic’ cells’ and half a dozen distinct functional cells, and if buildings in the class average four cells each, then ignoring variance caused by skin mutability, a street of fifty buildings could have every one different.

+

Reproducibility

+

It’s critical that if a player visits a location, leaves it, and then returns, the buildings should not all have changed. So it must be possible to repeatedly reproduce the building at the location (this, of course, applies to other procedural scene dressing, such as trees, roads, boundaries, bridges and so on). This is possible if a deterministic random number generator is used which is seeded from the latitude and longitude attributes of the location. Other attributes which should be cached on the seed even though they are determined procedurally when the building is first instantiated include building class, purpose, and wealth. Using these attributes and the deterministic random number generator, the same building can be reproduced on the same site each time it is visited, with a very small amount of data stored.

+

Buildings will normally be built at the edge of the associated land holding. If an edge of the land holding adjoins a road, then the building will be built with one long side aligned to the road. Otherwise, the building will be built at right angles to the orientation of the slope. The orientation will be ‘frozen’ once the building has been instantiated and will be cached on the seed.

+

So, to build a building, use the following algorithm:

+

Seed the random number generator with latitude and longitude

+
while ( building value is less than wealth) {
+   select a cell selected from the building class using the next number from the random number generator modulo the number of generic cells in the class;
+   if the selected cell is not inappropriate to the building's function {
+       fit the cell to the building at the point determined by a deterministic algorithm
+       furnish cell using the random number generator to determine
+       furnishing types and locations from a selection appropriate to the cell
+       if the selected cell was not a top story cell {
+            add a requirement that the next cell selected must be an upper story cell}
+   }
+}
+
+
\ No newline at end of file diff --git a/docs/codox/index.html b/docs/codox/index.html index 095c01b..86d8078 100644 --- a/docs/codox/index.html +++ b/docs/codox/index.html @@ -1,3 +1,29 @@ -The-great-game 0.1.1

The-great-game 0.1.1

Released under the GNU General Public License,version 2.0 or (at your option) any later version

Prototype code towards the great game I've been writing about for ten years, and know I will never finish.

Installation

To install, add the following dependency to your project or build file:

[the-great-game "0.1.1"]

Topics

Namespaces

the-great-game.agent.agent

Anything in the game world with agency

Public variables and functions:

    the-great-game.gossip.gossip

    Interchange of news events between gossip agents

    Public variables and functions:

    the-great-game.merchants.markets

    Adjusting quantities and prices in markets.

    Public variables and functions:

    the-great-game.merchants.merchant-utils

    Useful functions for doing low-level things with merchants.

    the-great-game.merchants.merchants

    Trade planning for merchants, primarily.

    Public variables and functions:

    the-great-game.merchants.planning

    Trade planning for merchants, primarily. This follows a simple-minded generate-and-test strategy and currently generates plans for all possible routes from the current location. This may not scale. Also, routes do not currently have cost or risk associated with them.

    the-great-game.merchants.strategies.simple

    Default trading strategy for merchants.

    Public variables and functions:

    the-great-game.utils

    TODO: write docs

    Public variables and functions:

    the-great-game.world.location

    Functions dealing with location in the world.

    Public variables and functions:

    the-great-game.world.routes

    Conceptual (plan level) routes, represented as tuples of location ids.

    Public variables and functions:

    the-great-game.world.run

    Run the whole simulation

    Public variables and functions:

    the-great-game.world.world

    Access to data about the world

    Public variables and functions:

    \ No newline at end of file +The-great-game 0.1.2-SNAPSHOT

    The-great-game 0.1.2-SNAPSHOT

    Released under the GNU General Public License,version 2.0 or (at your option) any later version

    Prototype code towards the great game I've been writing about for ten years, and know I will never finish.

    Installation

    To install, add the following dependency to your project or build file:

    [journeyman-cc/the-great-game "0.1.2-SNAPSHOT"]

    Topics

    Namespaces

    cc.journeyman.the-great-game.agent.agent

    Anything in the game world with agency; primarily but not exclusively characters.

    +

    Public variables and functions:

    cc.journeyman.the-great-game.agent.schedule

    Schedules of plans for actors in the game, in order that they may have daily and seasonal patterns of behaviour.

    +

    Public variables and functions:

    cc.journeyman.the-great-game.buildings.module

    A module of a building; essentially something like a portacabin, which can be assembled together with other modules to make a complete building.

    +

    Public variables and functions:

      cc.journeyman.the-great-game.buildings.rectangular

      Build buildings with a generally rectangular floow plan.

      +

      cc.journeyman.the-great-game.cloverage

      TODO: write docs

      +

      Public variables and functions:

      cc.journeyman.the-great-game.gossip.gossip

      Interchange of news events between gossip agents.

      +

      Public variables and functions:

      cc.journeyman.the-great-game.holdings.holding

      TODO: write docs

      +

      Public variables and functions:

      cc.journeyman.the-great-game.location.location

      TODO: write docs

      +

      Public variables and functions:

      cc.journeyman.the-great-game.lore.digester

      TODO: write docs

      +

      Public variables and functions:

        cc.journeyman.the-great-game.merchants.markets

        Adjusting quantities and prices in markets.

        +

        Public variables and functions:

        cc.journeyman.the-great-game.merchants.merchant-utils

        Useful functions for doing low-level things with merchants.

        +

        cc.journeyman.the-great-game.merchants.merchants

        Trade planning for merchants, primarily.

        +

        Public variables and functions:

        cc.journeyman.the-great-game.merchants.planning

        Trade planning for merchants, primarily. This follows a simple-minded generate-and-test strategy and currently generates plans for all possible routes from the current location. This may not scale. Also, routes do not currently have cost or risk associated with them.

        +

        cc.journeyman.the-great-game.merchants.strategies.simple

        Default trading strategy for merchants.

        +

        Public variables and functions:

        cc.journeyman.the-great-game.objects.character

        TODO: write docs

        +

        Public variables and functions:

          cc.journeyman.the-great-game.objects.container

          TODO: write docs

          +

          Public variables and functions:

          cc.journeyman.the-great-game.objects.game-object

          Anything at all in the game world

          +

          Public variables and functions:

          cc.journeyman.the-great-game.playroom

          TODO: write docs

          +

          Public variables and functions:

          cc.journeyman.the-great-game.world.heightmap

          Functions dealing with the tessellated multi-layer heightmap.

          +

          cc.journeyman.the-great-game.world.location

          Functions dealing with location in the world.

          +

          Public variables and functions:

          cc.journeyman.the-great-game.world.mw

          Functions dealing with building a great game world from a MicroWorld world.

          +

          Public variables and functions:

            cc.journeyman.the-great-game.world.routes

            Conceptual (plan level) routes, represented as tuples of location ids.

            +

            Public variables and functions:

            cc.journeyman.the-great-game.world.world

            Access to data about the world

            +

            Public variables and functions:

            \ No newline at end of file diff --git a/docs/codox/intro.html b/docs/codox/intro.html index f7de5af..71d225c 100644 --- a/docs/codox/intro.html +++ b/docs/codox/intro.html @@ -1,128 +1,130 @@ -Introduction to the-great-game

            Introduction to the-great-game

            -

            The Great Game

            +Introduction to the-great-game

            Introduction to the-great-game

            +

            The Great Game

            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.

            So, firstly, how does one characterise this game?

            It has strong elements of a Role Playing Game, as currently understood; some elements of a Simulation Game; some elements of a God Game. But what I see it as is fundamentally a sandbox in which the player(s) can explore ideas about human conflicts and how to resolve them, without immediate real-world consequences. It’s also a sandbox in which story tellers can tell stories, but that’s essentially a side-effect - a consequence of the fact that I need to be able to use it to tell stories, in order to create initial threads of narrative from which players can start their exploration.

            Note that, by ‘conflict’, here, I explicitly do not mean ‘killing people’, or even ‘killing non-player characters’. I have written extensively about the problem in many current video games that all too often the only way of interacting with non-player characters is to kill them. Killing people should be one of the potential ways of resolving conflicts, because that is reality, but negotiation must be another.

            So this is a game in which rich interaction with non-player characters is possible. The NPCs have individual knowledge and individual agency: they have intentions, aspirations and desires. They also have a wide dynamic repertoire of speech.

            -

            Previous essays that are relevant

            +

            Previous essays that are relevant

              -
            • The spread of knowledge in a large game world (2008) discusses what individual non-player characters know, and how to model dynamic updates to their knowledge;
            • -
            • Settling a game world (2009) gives rough outline of ideas about creating the environment, including modelling things like soil fertility, local building materials, and consequently local architecture;
            • -
            • Tessellated multi-layer height map (2013) gives ideas for how a designed geography for a very large world could be stored relatively economically;
            • -
            • Genetic Buildings (2013) sketches algorithms which would allow procedurally-generated buildings to be site-appropriate, broadly variable and reproducable;
            • -
            • Populating a game world (2013) provides outline algorithms for how a world can be populated, and how organic mixes of trades and crafts can be modelled;
            • -
            • Modelling the change from rural to urban (2013) describes the idea of procedurally modelling settlements, but it is grid-based and not particularly satisfactory and has largely been superceded in my thinking;
            • -
            • Of pigeons, and long distance messaging in a game world (2013) builds on ideas about flows of information;
            • -
            • Modelling rural to urban, take two (2013) revisited the idea of modelling organic settlement structures, trying to find algorithms which would naturally produce more persuasive settlement models, including further ideas on the procedural generation of buildings;
            • -
            • More on modelling rivers (2014) talks about modelling hydrology, with implications for soil fertility;
            • -
            • Modelling settlement with cellular automata (2014) talks about successful implementation of algorithms to model vegetative environment, human settlement and the impact of human settlement on the environment;
            • -
            • Voice acting considered harmful (2015) outlines the ideas behind full speech interaction with non-player characters, and modelling what those non-player characters should be able to speak about;
            • -
            • Baking the world (2019) an outline of the overall process of creating a world.
            • +
            • The spread of knowledge in a large game world (2008) discusses what individual non-player characters know, and how to model dynamic updates to their knowledge;
            • +
            • Settling a game world (2009) gives rough outline of ideas about creating the environment, including modelling things like soil fertility, local building materials, and consequently local architecture;
            • +
            • Tessellated multi-layer height map (2013) gives ideas for how a designed geography for a very large world could be stored relatively economically;
            • +
            • Genetic Buildings (2013) sketches algorithms which would allow procedurally-generated buildings to be site-appropriate, broadly variable and reproducable;
            • +
            • Populating a game world (2013) provides outline algorithms for how a world can be populated, and how organic mixes of trades and crafts can be modelled;
            • +
            • Modelling the change from rural to urban (2013) describes the idea of procedurally modelling settlements, but it is grid-based and not particularly satisfactory and has largely been superceded in my thinking;
            • +
            • Of pigeons, and long distance messaging in a game world (2013) builds on ideas about flows of information;
            • +
            • Modelling rural to urban, take two (2013) revisited the idea of modelling organic settlement structures, trying to find algorithms which would naturally produce more persuasive settlement models, including further ideas on the procedural generation of buildings;
            • +
            • More on modelling rivers (2014) talks about modelling hydrology, with implications for soil fertility;
            • +
            • Modelling settlement with cellular automata (2014) talks about successful implementation of algorithms to model vegetative environment, human settlement and the impact of human settlement on the environment;
            • +
            • Voice acting considered harmful (2015) outlines the ideas behind full speech interaction with non-player characters, and modelling what those non-player characters should be able to speak about;
            • +
            • Baking the world (2019) an outline of the overall process of creating a world.
            -

            Organic and emergent game-play

            -

            If a world is dynamically populated, with dynamic allocation of livelihoods then several aspects of gameplay will emerge organically. First, of course, is just exploring; in a dynamically changing world there will always be more to explore, and it will be different in each restart of the game.

            -

            Trading

            +

            Organic and emergent game-play

            +

            If a world is dynamically populated, with dynamic allocation of livelihoods then several aspects of gameplay will emerge organically. First, of course, is just exploring; in a dynamically changing world there will always be more to explore, and it will be different in each restart of the game.

            +

            Trading

            Second is trading. If there are markets, and merchants moving between them, then the prices in the markets can be modelled dynamically. Markets in out of the way places which produce otherwise scarce primary products will have low prices for those products, and the player can make profit by carrying product to more urban markets where the prices are higher. Yes, that isn’t in itself a satisfying game, but if the player is in any case travelling from place to place it may be a useful side-game.

            -

            Dynamic quests

            +

            Dynamic quests

            Third is aiding. If dynamic events happen in the world, then, for some non-player characters, some of those events will be negative. A merchant who is robbed, a shepherd whose sheep have been driven off by wolves, a family whose child has been abducted, will seek help. These requests for aid can become dynamically generated quests. Dynamic quests have a bad reputation, but with better modelling of NPC behaviour and better repertoire, I think that satisfying dynamic quests shouldn’t be too difficult to do - they are, after all, just another instance of procedural generation.

            So in the ‘abducted child’ quest, for example, there are a range of things which may be going on:

            Did the child go willingly? If so, were they fleeing an abusive home, or seeking a better life, or eloping with a lover, or seduced by a bad actor? Do they want to go back, or do they want to stay away? If they want to stay away, can you force them to go back? Alternatively, can you negotiate a state of peace between the abductor and the family?

            So there are a range of possible outcomes:

              -
            1. The player talks to the child and decides to take no further action;
            2. -
            3. The player abducts/liberates the child from the abductors and returns the child to their parents;
            4. -
            5. The player abducts/liberates the child from the abductors and allows the child to choose which to stay with;
            6. -
            7. The player kills off the abductors and returns the child to their parents;
            8. -
            9. The player kills off the abductors and allows the child to choose where to go;
            10. -
            11. The player negotiates a ransom and returns the child to their parents;
            12. -
            13. The player negotiates a reconcilliation between the parents and the abductor, and the child chooses which to stay with.
            14. +
            15. The player talks to the child and decides to take no further action;
            16. +
            17. The player abducts/liberates the child from the abductors and returns the child to their parents;
            18. +
            19. The player abducts/liberates the child from the abductors and allows the child to choose which to stay with;
            20. +
            21. The player kills off the abductors and returns the child to their parents;
            22. +
            23. The player kills off the abductors and allows the child to choose where to go;
            24. +
            25. The player negotiates a ransom and returns the child to their parents;
            26. +
            27. The player negotiates a reconcilliation between the parents and the abductor, and the child chooses which to stay with.

            Generally, (1) and (2) above will enhance the player’s reputation for getting stuff done, (4) or (5) enhance their reputation as a fighter, and (6) or (7) as a negotiator. However, while (2), (4) and (7) will increase the player’s favour with the parents and consequently with their wider circly, returning an unwilling child to its parents will have a much more uncertain outcome. Allowing the child to choose will increase the player’s favour with the child, but probably decrease it with the parents.

            Thus there is a fairly rich dynamic quest graph for this general quest, and it’s conditioned by many factors. For example, if the player is already viewed favourably by the abductor, then negotiation will be much easier; if negatively, negotiation may be impossible. How favourably the child views the player will affect how willing the child is to go with the player (and, of course, if the abductor was the child’s lover, then killing the abductor will sharply reduce the child’s favour towards the player).

            There’s a similarly rich quest graph regarding goods in contested ownership, e.g. they’ve been stolen from a merchant (or the merchant claims that they have) but are now held by someone who claims that they bought them honestly. And so on: rich abstract quest graphs can be derived for quite a lot of c onflicts which will arise dynamically between non-player characters.

            -

            To make dynamic quests work, of course, you need a dynamic world; a world in which conflicts can arise. A world in which traders trade, robbers rob, lovers love, haters hate, scandal-mongers make scandal, organically and dynamically whether the player is there or not, and where news of these events will filter through to the player through the gossip network also organically and dynamically.

            -

            Extending the story

            +

            To make dynamic quests work, of course, you need a dynamic world; a world in which conflicts can arise. A world in which traders trade, robbers rob, lovers love, haters hate, scandal-mongers make scandal, organically and dynamically whether the player is there or not, and where news of these events will filter through to the player through the gossip network also organically and dynamically.

            +

            Extending the story

            Dynamic quests do not mean that there should not be, or cannot be, scripted quests, and, indeed, I’m sure that there should be; which brings us to the next point.

            In a very large world, writing enough story to have satisfyingly constructed narratives everywhere the player goes is a very large job. But I became excited by role playing games, not so much by the original Neverwinter Nights itself, but by the authoring tools which came free with it. There were thousands of user-contributed add-on ‘mods’, mostly stories and quests, for Neverwinter Nights, of which I wrote several - and I greatly enjoyed doing so.

            Later on, with Carrol Dufault and others (including James Semple who wrote wonderful original music), I went on to write a new story for The Witcher which won CD Project’s prize for best mod.

            For me, writing story is every bit as compelling an activity as playing it, and I know I’m not alone in that. So I feel strongly that if The Great Game were ever released, it wouldn’t be necessary to fully populate the map with scripted story; rather, the release should include authoring tools which would allow players to extend story, and documentation which set the overall framework within which story could be extended. And then there should be a mechanism by which extensions of sufficient quality could be merged into the overall game for all players, and the authors of those stories rewarded with some degree of recognition.

            -

            Aspirations and goals

            +

            Aspirations and goals

            (In what follows I shall use the word ‘agent’ to cover both player characters and - but more particularly - non-player characters) In order to build a dynamic world in which we can play with ideas about human conflict, we need to model those things which give rise to conflict, which means we need to model not merely short term aspirations and goals but also long term aspirations and goals; agents have a hierarchy of needs and to achieve those needs they must have a hierarchy of goals.

            Not everyone has the same ‘top level goal’; different agents should have different top level goals. The following are some plausible top level goals:

              -
            1. Ancestor: To be succeeded by children and grandchildren, to found a dynasty;
            2. -
            3. Master: To become highly esteemed as a master of your craft;
            4. -
            5. Explorer: To be widely travelled, to see the world;
            6. -
            7. Climber: To climb as high as possible in the social hierarchy, to become Tyrranos or Imperator;
            8. -
            9. Conqueror: To build the largest possible realm under your control;
            10. -
            11. Citizen: To build a secure and comfortable home, able to feed and protect those within it;
            12. +
            13. Ancestor: To be succeeded by children and grandchildren, to found a dynasty;
            14. +
            15. Master: To become highly esteemed as a master of your craft;
            16. +
            17. Explorer: To be widely travelled, to see the world;
            18. +
            19. Climber: To climb as high as possible in the social hierarchy, to become Tyrranos or Imperator;
            20. +
            21. Conqueror: To build the largest possible realm under your control;
            22. +
            23. Citizen: To build a secure and comfortable home, able to feed and protect those within it;

            In this typology, a hero is a master soldier, and a sage a master scholar. Each of these types should be capable of being ‘scored’ by a real function which can be written over real parameters which exist in the game. Some are easy:

              -
            1. Ancestor: how many living descendants does this agent have now?
            2. -
            3. Master: what is the sum of (or average of) the esteem held for this agent by other agents of the same craft?
            4. -
            5. Explorer: (e.g.) what is the sum of the distance between the most northerly and most southerly, and the most easterly and most westerly, locations this agent has visited?
            6. -
            7. Climber: how many ‘promotions’ has this agent had in the game?
            8. -
            9. Conqueror: how many total vassales, recursively, has this agent?
            10. -
            11. Citizen: really, really tricky. Probably what is the average esteem for this agent among all agents within a specified radius? - although this will score more highly for agents who have taken part in notable events, and what I’m really thinking of for my ideal ‘good citizen’ is someone who really hasn’t.
            12. +
            13. Ancestor: how many living descendants does this agent have now?
            14. +
            15. Master: what is the sum of (or average of) the esteem held for this agent by other agents of the same craft?
            16. +
            17. Explorer: (e.g.) what is the sum of the distance between the most northerly and most southerly, and the most easterly and most westerly, locations this agent has visited?
            18. +
            19. Climber: how many ‘promotions’ has this agent had in the game?
            20. +
            21. Conqueror: how many total vassals, recursively, has this agent?
            22. +
            23. Citizen: really, really tricky. Probably what is the average esteem for this agent among all agents within a specified radius? - although this will score more highly for agents who have taken part in notable events, and what I’m really thinking of for my ideal ‘good citizen’ is someone who really hasn’t.

            So each agent is assigned - by the dreaded random number generator - one top level goal when they are instantiated. I don’t think it’s necessary to model change of top level goals, although of course that does happen in real life; however, although each agent has one top level goal, they will have lower level ‘stretch goals’ also taken from this list: so at each decision point in an agent’s planning loop, if base level needs are satisfied and progress on the top level goal is blocked, actions should be chosen which progress one of the lower goals. Indeed, it’s possible that all agents could have all goals, but randomly ordered.

            At the lowest level there are immediate needs goals every agent must satisfy: food for tonight, a safe place to stay tonight, food for next year, a safe place to stay next year.

            -

            On screen and off screen

            +

            On screen and off screen

            If we’re going to have a very large world with a very large number of characters (as an order of magnitude number, say 100,000), then obviously we cannot plan in detail every time each character lifts a cup to their lips to drink. When a character is on screen we must represent small actions, and at some level these must be planned for. But when they’re off screen, that’s just wasted computation. The only actions we need to plan are life altering actions, such as:

              -
            • Killings and deaths;
            • -
            • Raids, feuds, abductions and significant thefts;
            • -
            • Marriages, especially among the high status;
            • -
            • Treaties and wars;
            • -
            • Scandalous liaisons.
            • +
            • Killings and deaths;
            • +
            • Raids, feuds, abductions and significant thefts;
            • +
            • Marriages, especially among the high status;
            • +
            • Treaties and wars;
            • +
            • Scandalous liaisons.

            How far away should these actions be planned? Well, that’s driven by gossip. If news of an action is likely to reach the player through the gossip network, then that action needs to be planned; if it’s extremely unlikely, then not so much. So we need to have a moving bubble around the player in which every actor is woken for one iteration of their planning loop each game day; a larger bubble in which only Masters, Captains, Outlaw Leaders and Aristons and above are woken; and an outermost bubble comprising the whole world in which only Tyrannos and Generals are woken.

            Note that, if there’s a ‘fast travel’ mode (which likely there will be), ‘game days’ also happen while fast travelling, so this ‘wake loop’ has to be one of the things which are still computed during fast travel.

            Of course, gossip, markets and merchants are slightly different. For gossip to work, merchants (and other gossip agents) need to be woken every time they arrive at a new location, to exchange news; for trade simulation to work, the buying and selling decisions of merchants at markets need to be modelled, including modelling which markets the merchant will visit next. Also, there needs to be some sort of thing about at the end of each game day, if there’s an Outlaw Leader within a certain distance of a merchant, then that outlaw leader has to be woken for a decision on whether to attack (although this may simply be within the second bubble, in which case the outlaw leaders will be woken anyway).

            -

            Planning

            -

            Esteem and favour

            +

            Planning

            +

            Esteem and favour

            Note that for all this work there need to be several dimensions to reputation, and here I’d like to clearly discriminate between two: esteem, and favour. Suppose, for a moment, that you are a Captain, engaged in a battle with another Captain who wins the battle through what you regard as a sneaky trick. You’re not going to like your opponent much: your favour for them will go down. But you’re going to think they’re pretty effective at their job: your esteem for them will go up.

            In general, an agent will treat more favourably another agent for whom they have more favour, whether that’s sharing more information (gossip), sharing (or offering more favourable prices for) goods, or whatever.

            This isn’t the same thing as esteem. If there are two weapon smiths in town, and you need a high quality sword, you’ll go to the one you esteem more, not the one you favour more. Esteem itself may have multiple dimensions: that weaponsmith whom you esteem as a weaponsmith, you may not esteem as a fighter. Obviously, the more dimensions you give it the harder it is to model, but at least for player characters I’d like several dimensions of esteem, since a player who has been successful in negotiation, for example, should be offered more diplomacy quests, where one who has been more successful in battle should be offered more warlike quests.

            Generally, an agent will not employ another agent for whom they hold negative esteem or negative favour; so losing either esteem or favour with your employer will lead to vagrancy.

            -

            One class of agent

            +

            One class of agent

            But that brings me to a separate point: I feel strongly that every agent in the game world should be essentially the same, in as much as whichever agent the player inhabits, the game will still work. In some games, for example the Witcher series, the player has no choice at all of which character they play; in others, such as for example Dragon Age, you can choose your character within some broad parameters, although this choice won’t greatly affect the story.

            What I envisage is a game in which the player can choose to inhabit any character at all in the game world, and the game will still work. Of course, scripting a narrative with that sort of flexibility is a very big job, but actually everything about this proposal is a very big job; I’m not going to veer away from the view that the toolkit ought to at least support this (it ought also to support the player choosing not to inhabit any character at all, and just watch the stories unfold as with a movie, without taking part at all). Having every agent ‘the same’ also makes the software more orthogonal and thus simpler. Obviously, agents must differ, but that difference should be in parameterisation - data - rather than anything else.

            -

            More about merchants

            +

            More about merchants

            Having said that there’s one class of agent, there is something special about merchants (and also minstrels and diplomats, see below); they are travellers who make aspects of the dynamic game world work, and to do so they have to have some behaviours to a greater degree than other agents.

            A merchant has:

              -
            • A home base at a particular location - in a town with a market;
            • -
            • A caravan of pack animals, or else a ship, in either case of finite capacity;
            • -
            • A line of credit with some banking network, again finite.
            • +
            • A home base at a particular location - in a town with a market;
            • +
            • A caravan of pack animals, or else a ship, in either case of finite capacity;
            • +
            • A line of credit with some banking network, again finite.

            At each market, a merchant must decide

              -
            1. Whether, and what, to sell;
            2. -
            3. Whether, and what, to buy.
            4. +
            5. Whether, and what, to sell;
            6. +
            7. Whether, and what, to buy.

            In any case, the merchant can’t carry more than the capacity of their ship/caravan. The judgements are based on knowledge of likely prices in reachable markets, the likely costs of the routes to those markets, and thus the likely profitability of the trade. When away from their home market, there will be a slight bias in selecting trades which will take them closer to their home market. At each market, when goods are bought, the price of that commodity in that market will rise slightly; when goods are sold, the price of that commodity in that market will fall slightly. For some commodities it may be reasonably possible to fully model price movements; for others, they will probably need to be fudged. More modelling is better, but it costs compute, and thus it may be necessary to fudge. In any given market, the ‘buy’ price of any commodity is higher than the ‘sell’ price, by some markup, which is maybe around 10%.

            -

            Cost of movement

            +

            Cost of movement

            A caravan or ship costs so much per day to run, irrespective of whether full or empty. So the base cost of a journey is a function of the time taken, which is essentially a function of the distance.

            -

            Outlawry and merchants

            +

            Obviously, on top of the base cost of movement there are tolls, which are imposed by the aristons through whose territory the journey passes (and therefore predictable, and can be used in route planning), and also the risk of having to bribe or fight outlaws, and the possible need to hire mercenaries to defend against outlaws, which is not predictable but can be estimated and thus also used in route planning.

            +

            Outlawry and merchants

            Outside the domains of aristons, outlaws may intercept caravans; when this happens the following outcomes are possible:

              -
            1. The merchant (together with any mercenaries the merchant has hired to protect the caravan) successfully fights off the outlaws;
            2. -
            3. The outlaws steal the entire cargo (and may kill the merchant);
            4. -
            5. The merchant pays protection money to the outlaws, typically around 5%-10% of the value of cargo carried;
            6. -
            7. The merchant employs the outlaws as caravan guards (see below);
            8. -
            9. The outlaws allow the caravan to pass unmolested;
            10. -
            11. There is no contact.
            12. +
            13. The merchant (together with any mercenaries the merchant has hired to protect the caravan) successfully fights off the outlaws;
            14. +
            15. The outlaws steal the entire cargo (and may kill the merchant and others);
            16. +
            17. The merchant pays protection money to the outlaws, typically around 5%-10% of the value of cargo carried;
            18. +
            19. The merchant employs the outlaws as caravan guards (see below);
            20. +
            21. The outlaws allow the caravan to pass unmolested;
            22. +
            23. There is no contact.

            Why should a merchant hire outlaws a guards? In this world, all fighter are more or less mercenaries, and there’s a fluidity between outlaws and mercenaries; a fighter is employed by their sergeant, and if their sergeant is employed by an ariston (or a captain employed by an ariston), they’re a soldier, and that’s respectable. If, however, the sergeant isn’t employed, then at some point they become outlaws. At the point they become outlaws, they start to raid unprotected farms, villages and caravans. Every time they raid, the favour in which they are held by all other agents who hear of it through the gossip network will decline.

            A captain or ariston will choose to employ sergeants whom they view with favour over equally esteemable sergeants they don’t, so once you’ve become an outlaw you’re on a downward spiral. However, if you work for a merchant and the merchant is happy with your work (i.e. he completes his journey without being hit up by any other outlaws), then positive favour towards you will propagate through the gossip network, and this is the outlaw’s way out of the downward spiral.

            The fee for being a caravan guard is X per fighter per day, where X varies a bit but is essentially a known rough amount.

            -

            Aristons and merchants

            -

            Generally, if a merchant buys goods in an ariston’s market, or sells goods in the ariston’s market, then the economy benefits and the ariston benefits from that; so the ‘tax’ element is part of the market markup. But if a caravan passes through an ariston’s territory without stopping at a market, there’s probably a tax of about 5% of value.

            +

            Aristons and merchants

            +

            Generally, if a merchant buys goods in an ariston’s market, or sells goods in the ariston’s market, then the economy benefits and the ariston benefits from that; so the ‘tax’ element is part of the market markup. But if a caravan passes through an ariston’s territory without stopping at a market, there’s probably a toll of about 5% of value.

            Generally, an ariston’s army will control outlawry within the ariston’s domain, so outlaw encounters within a domain are unlikely. Soldiers could be able seek bribes, but that would bring a strongly negative impact on favour and I’m not sure it’s work modelling.

            -

            Other habitual travellers: gossipers

            -

            Apart from merchants, the habitual travellers are diplomats (who, in the craft tree, are similar to chancellors) and minstrels (who aren’t on the craft tree but should be); and vagrants. However, vagrants almost certainly don’t have positive favour, so aren’t likely to be useful gossip agents. Each game day, every habitual traveller within the ‘local’ gossip bubble exchanges some items of gossip with the nearest innkeeper to their current location. In the second and third gossip bubbles, it’s probably only more favoured gossip agents who do this. See The spread of knowledge in a large game world

            \ No newline at end of file +

            Other habitual travellers: gossipers

            +

            Apart from merchants, the habitual travellers are diplomats (who, in the craft tree, are similar to chancellors) and minstrels (who aren’t on the craft tree but should be); and vagrants. However, vagrants almost certainly don’t have positive favour, so aren’t likely to be useful gossip agents. Each game day, every habitual traveller within the ‘local’ gossip bubble exchanges some items of gossip with the nearest innkeeper to their current location. In the second and third gossip bubbles, it’s probably only more favoured gossip agents who do this. See The spread of knowledge in a large game world

            +
            \ No newline at end of file diff --git a/docs/codox/modelling_trading_cost_and_risk.html b/docs/codox/modelling_trading_cost_and_risk.html index 867badf..82372fa 100644 --- a/docs/codox/modelling_trading_cost_and_risk.html +++ b/docs/codox/modelling_trading_cost_and_risk.html @@ -1,7 +1,8 @@ -Modelling trading cost and risk

            Modelling trading cost and risk

            +Modelling trading cost and risk

            Modelling trading cost and risk

            In a dynamic pre-firearms world with many small states and contested regions, trade is not going to be straightforward. Not only will different routes have different physical characteristics - more or less mountainous, more or fewer unbridged river crossings - they will also have different political characteristics: more of less taxed, more or less effectively policed.

            Raids by outlaws are expected to be part of the game economy. News of raids are the sort of things which may propagate through the gossip system. So are changes in taxation regime. Obviously, knowledge items can affect merchants’ trading strategy; in existing prototype code, individual merchants already each keep their own cache of known historical prices, and exchange historical price data with one another; and use this price data to select trades to make.

            So: to what extent is it worth modelling the spread of knowledge of trade cost and risk?

            -

            Obviously the more we model, the more compute power modelling consumes. If the core objective is a Role Playing Games as currently understood, then there is no need to model very complex trade risk assessment behaviour.

            \ No newline at end of file +

            Obviously the more we model, the more compute power modelling consumes. If the core objective is a Role Playing Games as currently understood, then there is no need to model very complex trade risk assessment behaviour.

            +
            \ No newline at end of file diff --git a/docs/codox/naming-of-characters.html b/docs/codox/naming-of-characters.html index 0fb4044..c19bf56 100644 --- a/docs/codox/naming-of-characters.html +++ b/docs/codox/naming-of-characters.html @@ -1,26 +1,32 @@ -Naming of Characters

            Naming of Characters

            +Naming of Characters

            Naming of Characters

            Generally speaking, in modern RPGs, every character with any impact on the plot has a distinct name. But if we are going to give all non-player characters sufficient agency to impact on the plot, then we must have a way of naming tens or hundreds of thousands of characters, and distinct names will become problematic (even if we’re procedurally generating names, which we shall have to do. So this note is about how characters are named.

            The full name of each character will be made up as follows:

            -

            [epithet] [clan] [personal-name] the [trade-or-rank] of [location], son/daughter of [parent]

            +

            epithet clan personal-name the trade-or-rank of location, son/daughter of parent

            Based on, roughly, historical name patterns like

            Archibald (personal-name) the Grim (epithet), Earl (trade-or-rank) of Douglas (location)

            Where

              -
            1. -

              epithet is a prefix based on some notable feature or feat of the character. Most characters won’t have an epithet, unless they have some notable feature or they’ve done something notable. If a character does something notable in the course of the game, they will subsequently gain an epithet; ‘notability’ may be measured by how many times the event is transmitted through the gossip network.

            2. -
            3. -

              clan is special to the Western Clans, although people from the Great Place may possible use the name of their house similarly.

            4. -
            5. -

              personal-name is chosen from one of a limited set of limited sets; different cultural groups will have different (possibly overlapping) sets of names, but within each set there will only be a limited subset

            6. -
            7. -

              trade-or-rank is just that. “Smith”, “Miller”, “Ariston”, “Captain”. Either only master craftsfolk have the trade-or-rank name of their craft, or we distinguish between ‘Calon the Smith’, who may be a journeyman, and ‘Calon the Master Smith’, who is a master.

            8. -
            9. -

              location is the name of a location; a village, town, city or province. The location which forms part of a character’s name is the location where there current home is, not the location where they were born or where their ancestors came from

            10. +
            11. +

              epithet is a prefix based on some notable feature or feat of the character. Most characters won’t have an epithet, unless they have some notable feature or they’ve done something notable. If a character does something notable in the course of the game, they will subsequently gain an epithet; ‘notability’ may be measured by how many times the event is transmitted through the gossip network.

              +
            12. +
            13. +

              clan is special to the Western Clans, although people from the Great Place may possible use the name of their house similarly.

              +
            14. +
            15. +

              personal-name is chosen from one of a limited set of limited sets; different cultural groups will have different (possibly overlapping) sets of names, but within each set there will only be a limited subset

              +
            16. +
            17. +

              trade-or-rank is just that. “Smith”, “Miller”, “Ariston”, “Captain”. Either only master craftsfolk have the trade-or-rank name of their craft, or we distinguish between ‘Calon the Smith’, who may be a journeyman, and ‘Calon the Master Smith’, who is a master.

              +
            18. +
            19. +

              location is the name of a location; a village, town, city or province. The location which forms part of a character’s name is the location where there current home is, not the location where they were born or where their ancestors came from

              +

            Full names will almost never be used - only, perhaps, in extremely formal circumstances. The form of a name used will depend on context, and will generally be just sufficient to disambiguate the character in the context.

            If the speaker is in Sinhua and referring to someone from Sinhua, they won’t refer to them as ‘of Sinhua’.

            If everyone present is a bargee and the speaker referring to someone who is also a bargee, they won’t refer to them as ‘the bargee’.

            The question asked influences the context: in answer to the question ‘who is the best sword smith’, the answer will not be ‘Calon the Smith’ but ‘Calon of Sinhua’.

            -

            Patronymics/matronymics will not normally be used of adults (although they may be used of apprentices and journeymen.

            \ No newline at end of file +

            Patronymics/matronymics will not normally be used of adults (although they may be used of apprentices and journeymen.

            +
            \ No newline at end of file diff --git a/docs/codox/on-dying.html b/docs/codox/on-dying.html index 2f3206e..030f121 100644 --- a/docs/codox/on-dying.html +++ b/docs/codox/on-dying.html @@ -1,9 +1,17 @@ -On Dying

            On Dying

            +On Dying, and Injury

            On Dying, and Injury

            Death is the end of your story. One of the tropes in games which, for me, most breaks immersion is when you lose a fight and are presented with a screen that says ‘you are dead. Do you want to reload your last save?’ Life is not like that. We do not have save-states. We die.

            So how could this be better handled?

            You lose a fight. Switch to cutscene: the battlefield, after the fight, your body is there. Probably no sound. A party of non-enemies crosses the battlefield and finds your body. We see surprise and concern. They gather around you. Cut to interior scene, you are in a bed, unconcious, being tended; cut to similar interior scene, you are in a bed, conscious, being tended; cut to exterior scene, you are sitting with some of your saviours, and the game restarts.

            Time has passed; events in the game world have moved on. You can talk to your saviours about it. You have lost a lot of strength, and most of the gear you were carrying. You must do whatever it is you do within the game mechanics to rebuild strength, and to acquire more gear. Significantly you have acquired a debt of honour to your saviours, which they may call on later. You almost certainly have new scars, and might possibly have some lasting effects (although how that interacts with other game mechanics might be tricky).

            So who are the non-enemies? It depends on context. If you have a party, and some of that party survived the fight, it’s your party. Otherwise, if you’re in a populated place, it’s locals. If it’s on a road or other route, it’s passing merchants. If you’re in the wilderness, a hunting party. It’s a bunch of non-hostiles who might reasonably be expected to be around: that’s what matters. It’s about not breaking immersion.

            -

            Obviously losing a fight must have weight, it must have meaning, it must have in-game consequences; otherwise it is meaningless.

            \ No newline at end of file +

            Obviously losing a fight must have weight, it must have meaning, it must have in-game consequences; otherwise it is meaningless.

            +

            Injury

            +

            Similarly to death, injury must have meaning. Any injury takes time to recover from. It takes a certain amount of time if you’re able to rest somewhere safe, and considerably longer if you’re not. If you fight while injured, you’ll have less strength, less stramina, and probably also less agility. Depending where you’re injured, there will be certain things you cannot do. If you fight while injured, also, your recovery time will be extended, even if you take no further injury.

            +

            Some serious injuries will lead to permanent scarring, and permanent loss of agility; you’ll be just slightly slower in fights.

            +

            It should be said that Kenshi — a game I’ve only recently become aware of and greatly admire — handles all of this extremely well, and is worth studying.

            +

            Reciprocity

            +

            If the player is going to depend on good samaritans for rescue after losing a fight, then there must be at least a social convention that people should assist people found injured on the wayside. Consequently, if the player fails to do this, that should in itself become a ‘gossip’ event which will lower the player’s reputation with non-player characters.

            +

            On the other hand, helping NPCs found injured at the wayside can be another category of organic quest, as a special subcategory of an escort quest.

            +
            \ No newline at end of file diff --git a/docs/codox/orgnic-quests.html b/docs/codox/orgnic-quests.html index 49b6973..ae56c9c 100644 --- a/docs/codox/orgnic-quests.html +++ b/docs/codox/orgnic-quests.html @@ -1,6 +1,6 @@ -Organic Quests

            Organic Quests

            +Organic Quests

            Organic Quests

            The structure of a modern Role Playing Came revolves around ‘quests’: tasks that the player character is invited to do, either by the framing narrative of the game or by some non-player character (‘the Quest Giver’). Normally there is one core quest which provides the overarching narrative for the whole game. [Wikipedia](https://en.wikipedia.org/wiki/Quest_(gaming)) offers a typology of quests as follows:

            1. Kill quests
            2. diff --git a/docs/codox/sandbox.html b/docs/codox/sandbox.html index 6b51109..7803bcb 100644 --- a/docs/codox/sandbox.html +++ b/docs/codox/sandbox.html @@ -1,39 +1,41 @@ -Sandbox

              Sandbox

              +Sandbox

              Sandbox

              Up to now I’ve been thinking of the Great Game as essentially an RPG with some sandbox-like elements; but I think it may be better to think of it as a sandbox game with some RPG like elements.

              Why?

              The core of the game is a world in which non-player characters have enough individual knowledge of the world and their immediate surroundings that they can sensibly answer questions like

                -
              • Where is the nearest craftsman of this craft?
              • -
              • What price can I expect to get for this item in the local market?
              • -
              • What news have you heard recently?
              • -
              • Where does this person from your village live?
              • +
              • Where is the nearest craftsman of this craft?
              • +
              • What price can I expect to get for this item in the local market?
              • +
              • What news have you heard recently?
              • +
              • Where does this person from your village live?

              and where there’s a sufficiently sophisticated and robust economy simulation that buying goods in one market and selling them in another is viable.

              The original BBC Micro space trading game Elite had very little more in terms of game mechanics than a sandbox with a means to navigate it and an economy simulation, which wasn’t even nearly as sophisticated as the one I have working now. Yet that combination resulted in engaging game play.

              -

              Main sandbox roles

              +

              Main sandbox roles

              The idea of a sandbox is that the player character should be able to do pretty much anything they like within the mechanics of the game. From that, it seems to me reasonable that the player ought to be able to do more or less everything a non-player character can do. But creating the game mechanics to make each additional task doable takes time and investment, so there’s a need to prioritise.

              So, as Elite did, I propose to make the first available sandbox roles

              -

              Merchant

              +

              Merchant

              Someone who travels from city to city, buying goods cheap in one and selling them for more in another; and

              -

              Outlaw

              +

              Outlaw

              Someone who intercepts and steals from merchants (and may also attack outlying farms and villages)

              -

              Second tier playable roles

              +

              Second tier playable roles

              The next tier of playable roles rotates around issues arising from the mercantile ecosystem.

              -

              Aristocracy

              -

              Aristocrats are basically settled outlaws who seek to establish a monopoly on extracting taxes from inhabitants and travellers in a particular region by driving out all other outlaws. Within the comain of an aristocrat, you have to pay tax but you’re reasonably safe from being attacked by other outlaws and losing everything. Aristocrats may also maintain and improve roads and bridges and do other things to boost the economy of their territory, may expant into adjoining territory with no current aristocratic control, and may wage war on other aristocrats.

              +

              Aristocracy

              +

              Aristocrats are basically settled outlaws who seek to establish a monopoly on extracting taxes from inhabitants and travellers in a particular region by driving out all other outlaws. Within the domain of an aristocrat, you have to pay tax but you’re reasonably safe from being attacked by other outlaws and losing everything. Aristocrats may also maintain and improve roads and bridges and do other things to boost the economy of their territory, may expand into adjoining territory with no current aristocratic control, and may wage war on other aristocrats.

              An outlaw ought to be able to become an aristocrat, by dominating an ungoverned area or by defeating an existing aristocrat.

              -

              Soldiery

              +

              Soldiery

              Soldiers, like aristocrats, are basically on the same spectrum as outlaws. Outlaws may hire themselves out to merchants as caravan guards, or to aristocrats as soldiers. Soldiers or guards, falling on bad times, may revert to outlawry.

              -

              Routine, Discretion and Playability

              -

              There’s a term that’s used in criticism of many computer games which is worth thinking about hard here: that term is ‘farming’. ‘Farming’, in this sense, is doing something repetitive and dull to earn credits in a game. Generally this is not fun. What makes roles in a game-world fun is having individual discretion - the ability to choose between actions and strategies - and a lack of routine.

              -

              Most craft skills - especially in the learning phase - are not like this, and crafts which are sophisticated enough to be actually engaging are very hard to model in a game. Learning a craft is essentially, inherently, repetitive and dull, and if you take that repetition out of it you probably don’t have enough left to yield the feeling of mastery which would reward success; so it doesn’t seem to me that making craft roles playable should be a priority.

              -

              Cruise control

              -

              One of the most enjoyable aspects of The Witcher 3 - still my go-to game for ideas I want to improve on - is simply travelling through the world. Although fast travel is possible I find I rarely use it, and a journey which takes fifteen minutes of real world wall clock time can be enjoyable in and of itself. This is, of course, a credit to the beautiful way the world is realised.

              -

              But nevertheless, in The Witcher 3, a decision was made to pack incident fairly densely - because players would find just travelling boring. This leads to a situation where peaceful villages exist two minutes travel from dangerous monsters or bandit camps, and the suspension of disbelief gets a little strained. Building a world big enough that a market simulation is believable means that for the individual, the travel time to a market where a particular desired good is likely to be cheaper becomes costly in itself. Otherwise, there’s no arbitrage between markets and no ecological niche for a merchant to fill. The journey time from market to market has to be several in-game days.

              -

              An in-game day doesn’t have to be as long as a wall clock day, and, indeed, typically isn’t. But nevertheless, doing several game days of incident-free travel, even in beautiful scenery, is not going to be engaging - which implies a fast-travel mechanic.

              -

              I don’t like fast travel, I find it a too-obvious breaking of immersion. Also, of course, one of the interesting things about a game in a merchant/outlaw ecosystem is the risk of interception on a journey. The Dragon Age series handled interrupted travel in ‘fast travel’ by randomly interrupting the loading screen you get when moving from location to location in Dragon Age’s patchwork worlds by dumping you into a tiny arena with enemies. That’s really, really bad - there’s no other way to say this. Everything about it shouts artifice.

              +

              Routine, Discretion and Playability

              +

              There’s a term that’s used in criticism of many computer games which is worth thinking about hard here: that term is ‘farming’. ‘Farming’, in this sense, is doing something repetitive and dull to earn credits in a game. Generally this is not fun. What makes roles in a game-world fun is having individual discretion — the ability to choose between actions and strategies — and a lack of routine.

              +

              Most craft skills — especially in the learning phase — are not like this, and crafts which are sophisticated enough to be actually engaging are very hard to model in a game. Learning a craft is essentially, inherently, repetitive and dull, and if you take that repetition out of it you probably don’t have enough left to yield the feeling of mastery which would reward success; so it doesn’t seem to me that making craft roles playable should be a priority.

              +

              Cruise control

              +

              One of the most enjoyable aspects of The Witcher 3 — still my go-to game for ideas I want to improve on — is simply travelling through the world. Although fast travel is possible I find I rarely use it, and a journey which takes fifteen minutes of real world wall clock time can be enjoyable in and of itself. This is, of course, a credit to the beautiful way the world is realised.

              +

              (It’s worth noting that Kenshi, a game I’m coming to greatly admire, does not allow fast travel at all, but has an equivalent of ‘cruise control’ — you can set a destination and then accelerate time and simply watch as your characters journey).

              +

              But nevertheless, in The Witcher 3, a decision was made to pack incident fairly densely — because players would find just travelling boring. This leads to a situation where peaceful villages exist two minutes travel from dangerous monsters or bandit camps, and the suspension of disbelief gets a little strained. Building a world big enough that a market simulation is believable means that for the individual, the travel time to a market where a particular desired good is likely to be cheaper becomes costly in itself. Otherwise, there’s no arbitrage between markets and no ecological niche for a merchant to fill. The journey time from market to market has to be several in-game days.

              +

              An in-game day doesn’t have to be as long as a wall clock day, and, indeed, typically isn’t. But nevertheless, doing several game days of incident-free travel, even in beautiful scenery, is not going to be engaging — which implies a fast-travel mechanic.

              +

              I don’t like fast travel, I find it a too-obvious breaking of immersion. Also, of course, one of the interesting things about a game in a merchant/outlaw ecosystem is the risk of interception on a journey. The Dragon Age series handled interrupted travel in ‘fast travel’ by randomly interrupting the loading screen you get when moving from location to location in Dragon Age’s patchwork worlds by dumping you into a tiny arena with enemies. That’s really, really bad — there’s no other way to say this. Everything about it shouts artifice.

              So I’m thinking of a different mechanism: one I’m calling cruise control.

              -

              You set out on a task which will take a long time - such as a journey, but also such as any routine task. You’re shown either a ‘fast forward’ of your character carrying out this task, or a series of cinematic ‘shots along the way’. This depends, of course, on there being continuous renderable landscape between your departure and your destination, but there will be. This fast-forward proceeds at a substantially higher time gearing than normal game time - ten times as fast perhaps; we need it to, because as well as doing backgound scenery loading to move from one location to another, we’re also simulating lots of non-player agents’ actions in parts of the world where the player currently isn’t. So a ‘jump cut’ from one location to another isn’t going to work anyway.

              -

              The player can interrupt ‘fast forward’ at any time. But also, the game itself may bring you out of fast forward when it anticipates that there may be action which requires decision - for example, when there are outlaws in the vicinity. And it will do this before the player’s party is under immediate attack - the player will have time to take stock of the situation and prepare appropriately. Finally, this will take place in the full open world; the player will have the option to choose not to enter the narrow defile, for example, to ask local people (if there are any) for any news of outlaw activity, or, if they are available, to send forward scouts.

              \ No newline at end of file +

              You set out on a task which will take a long time — such as a journey, but also such as any routine task. You’re shown either a ‘fast forward’ of your character carrying out this task, or a series of cinematic ‘shots along the way’. This depends, of course, on there being continuous renderable landscape between your departure and your destination, but there will be. This fast-forward proceeds at a substantially higher time gearing than normal game time — ten times as fast perhaps; we need it to, because as well as doing backgound scenery loading to move from one location to another, we’re also simulating lots of non-player agents’ actions in parts of the world where the player currently isn’t. So a ‘jump cut’ from one location to another isn’t going to work anyway.

              +

              The player can interrupt ‘fast forward’ at any time. But also, the game itself may bring you out of fast forward when it anticipates that there may be action which requires decision — for example, when there are outlaws in the vicinity. And it will do this before the player’s party is under immediate attack — the player will have time to take stock of the situation and prepare appropriately. Finally, this will take place in the full open world; the player will have the option to choose not to enter the narrow defile, for example, to ask local people (if there are any) for any news of outlaw activity, or, if they are available, to send forward scouts.

              +
              \ No newline at end of file diff --git a/docs/codox/sexual-dimorphism.html b/docs/codox/sexual-dimorphism.html index 901ec84..d254cdc 100644 --- a/docs/codox/sexual-dimorphism.html +++ b/docs/codox/sexual-dimorphism.html @@ -1,6 +1,6 @@ -Sexual dimorphism

              Sexual dimorphism

              +Sexual dimorphism

              Sexual dimorphism

              This essay is going to upset a lot of people, so let’s start with a statement of what it is about: it is an attempt to describe the systematically different behaviours of men and women, in sufficient detail that this can be represented by agents in a game world. It’s trying to allow as broad as possible a range of cultures to be represented, so when I’m talking about what I consider to be behaviours of particular cultures, I’ll say that.

              Of course, I’m writing this from the view point of an old white male. It’s not possible to write about these things from a totally neutral viewpoint, and every one of us will have prejudices.

              OK? Let’s start.

              @@ -10,19 +10,28 @@

              For all sorts of reasons, some of which are clearly cultural but others of which are fundamental, it’s much easier for men to walk away from responsibility for their children than it is for women. For example, considering a pre-modern world, women would always know for certain which children were theirs, and men would not.

              For a woman, consequently, the best breeding strategy is to have sex only with men who will be ‘good fathers’, where there are three essential parameters to “good fathers”:

                -
              1. Desirable genetic traits;
              2. -
              3. Preparedness to stick around and share the work;
              4. -
              5. Ability to provide and protect.
              6. +
              7. Desirable genetic traits;
              8. +
              9. Preparedness to stick around and share the work;
              10. +
              11. Ability to provide and protect.

              The essential trade-off in the traditional western marriage is that the man gets to have sex, and the woman gets to have protection for her progeny.

              Another significant point is that women’s ability to bear children ceases at a much younger age than men’s ability to father them.

              -

              Why have sex at all?

              +

              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.

              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.

              -

              Why have children?

              +

              Why have children?

              In modern Scotland, I have met a lot of women with a strong drive to have children for the sake of having children, where the best explanation they could give is that it’s instinctual; it may be so. But beyond that, in many cultures children provide their (acknowledged) parents with care and security in their old age, may tend their graves and perform belief-related services after they die, and carry on their name and their stories into the future.

              Not everyone wants to have children; in thinking about the driving aspirations of game characters, I view having children one of six potential key aspirations.

              -

              Why else have sex?

              +

              Why else have sex?

              Sex, done right, is an extremely pleasant pastime. Sex can also be used to create and maintain bonds of committment, to demonstrate social status, to defuse tense situations, and transactionally in many ways, both formal and informal.

              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.

              -

              ##

              \ No newline at end of file +

              Women and warrior/adventurer lifestyles

              +

              Generally speaking, people do not want to take their children onto a battlefield. If you’re going to have a game world in which women significantly take on warrior or adventurer roles, then you must either have

              +
                +
              • A culture which expects female warriors to be celibate; or
              • +
              • A culture with access to and acceptance of safe and reliable contraception or abortion; or
              • +
              • An acceptance of leaving infant children with grandparents, other relatives or foster carers for long periods;
              • +
              • A system of long term creches;
              • +
              • Any combination of the above.
              • +
              +
              \ No newline at end of file diff --git a/docs/codox/the-great-game.agent.agent.html b/docs/codox/the-great-game.agent.agent.html index bab56e9..efd5f84 100644 --- a/docs/codox/the-great-game.agent.agent.html +++ b/docs/codox/the-great-game.agent.agent.html @@ -1,3 +1,10 @@ -the-great-game.agent.agent documentation

              the-great-game.agent.agent

              Anything in the game world with agency

              \ No newline at end of file +the-great-game.agent.agent documentation

              the-great-game.agent.agent

              Anything in the game world with agency

              ProtoAgent

              protocol

              An object which can act in the world

              members

              act

              (act actor world circle)

              Allow actor to do something in this world, in the context of this circle; return the new state of the actor if something was done, nil if nothing was done. Circle is expected to be one of

              +
                +
              • :active - actors within visual/audible range of the player character;
              • +
              • :pending - actors not in the active circle, but sufficiently close to it that they may enter the active circle within a short period;
              • +
              • :background - actors who are active in the background in order to handle trade, news, et cetera;
              • +
              • other - actors who are not members of any other circle, although I’m not clear whether it would ever be appropriate to invoke an act method on them.
              • +
              +

              The act method must not have side effects; it must only return a new state. If the actor’s intention is to seek to change the state of something else in the game world, it must add a representation of that intention to the sequence which will be returned by its pending-intentions method.

              pending-intentions

              (pending-intentions actor)

              Returns a sequence of effects an actor intends, as a consequence of acting. The encoding of these is not yet defined.

              \ No newline at end of file diff --git a/docs/codox/the-great-game.merchants.merchant-utils.html b/docs/codox/the-great-game.merchants.merchant-utils.html index a22e629..6479e51 100644 --- a/docs/codox/the-great-game.merchants.merchant-utils.html +++ b/docs/codox/the-great-game.merchants.merchant-utils.html @@ -1,7 +1,3 @@ -<<<<<<< HEAD -the-great-game.merchants.merchant-utils documentation

              the-great-game.merchants.merchant-utils

              Useful functions for doing low-level things with merchants.

              add-known-prices

              (add-known-prices merchant world)

              Add the current prices at this merchant’s location in the world to a new cache of known prices, and return it.

              add-stock

              (add-stock a b)

              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.

              burden

              (burden merchant world)

              The total weight of the current cargo carried by this merchant in this world.

              can-afford

              (can-afford merchant world commodity)

              Return the number of units of this commodity which this merchant can afford to buy in this world.

              can-carry

              (can-carry merchant world commodity)

              Return the number of units of this commodity which this merchant can carry in this world, given their current burden.

              expected-price

              (expected-price merchant commodity city)

              Find the price anticipated, given this world, by this merchant for this commodity in this city. If no information, assume 1. merchant should be passed as a map, commodity and city should be passed as keywords.

              -======= -the-great-game.merchants.merchant-utils documentation

              the-great-game.merchants.merchant-utils

              Useful functions for doing low-level things with merchants.

              add-known-prices

              (add-known-prices merchant world)

              Add the current prices at this merchant’s location in the world to a new cache of known prices, and return it.

              add-stock

              (add-stock a b)

              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.

              burden

              (burden merchant world)

              The total weight of the current cargo carried by this merchant in this world.

              can-afford

              (can-afford merchant world commodity)

              Return the number of units of this commodity which this merchant can afford to buy in this world.

              can-carry

              (can-carry merchant world commodity)

              Return the number of units of this commodity which this merchant can carry in this world, given their current burden.

              expected-price

              (expected-price merchant commodity city)

              Find the price anticipated, given this world, by this merchant for this commodity in this city. If no information, assume 1. merchant should be passed as a map, commodity and city should be passed as keywords.

              ->>>>>>> master +the-great-game.merchants.merchant-utils documentation

              the-great-game.merchants.merchant-utils

              Useful functions for doing low-level things with merchants.

              add-known-prices

              (add-known-prices merchant world)

              Add the current prices at this merchant’s location in the world to a new cache of known prices, and return it.

              add-stock

              (add-stock a b)

              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.

              burden

              (burden merchant world)

              The total weight of the current cargo carried by this merchant in this world.

              can-afford

              (can-afford merchant world commodity)

              Return the number of units of this commodity which this merchant can afford to buy in this world.

              can-carry

              (can-carry merchant world commodity)

              Return the number of units of this commodity which this merchant can carry in this world, given their current burden.

              expected-price

              (expected-price merchant commodity city)

              Find the price anticipated, given this world, by this merchant for this commodity in this city. If no information, assume 1. merchant should be passed as a map, commodity and city should be passed as keywords.

              \ No newline at end of file diff --git a/docs/codox/the-great-game.objects.container.html b/docs/codox/the-great-game.objects.container.html index 58d2d56..2a28aac 100644 --- a/docs/codox/the-great-game.objects.container.html +++ b/docs/codox/the-great-game.objects.container.html @@ -1,3 +1,3 @@ -the-great-game.objects.container documentation

              the-great-game.objects.container

              TODO: write docs

              ProtoContainer

              protocol

              members

              contents

              (contents container)

              Return a sequence of the contents of this container, or nil if empty.

              is-empty?

              (is-empty? container)

              Return true if this container is empty, else false.

              \ No newline at end of file +the-great-game.objects.container documentation

              the-great-game.objects.container

              TODO: write docs

              ProtoContainer

              protocol

              members

              contents

              (contents container)

              Return a sequence of the contents of this container, or nil if empty.

              is-empty?

              (is-empty? container)

              Return true if this container is empty, else false.

              \ No newline at end of file diff --git a/docs/codox/the-great-game.objects.game-object.html b/docs/codox/the-great-game.objects.game-object.html index 70023d4..b486c1c 100644 --- a/docs/codox/the-great-game.objects.game-object.html +++ b/docs/codox/the-great-game.objects.game-object.html @@ -1,3 +1,3 @@ -the-great-game.objects.game-object documentation

              the-great-game.objects.game-object

              Anything at all in the game world

              ProtoObject

              protocol

              An object in the world

              members

              id

              (id object)

              Returns the unique id of this object.

              reify-object

              (reify-object object)

              Adds this object to the global object list. If the object has a non-nil value for its id method, keys it to that id - but if the id value is already in use, throws a hard exception. Returns the id to which the object is keyed in the global object list.

              \ No newline at end of file +the-great-game.objects.game-object documentation

              the-great-game.objects.game-object

              Anything at all in the game world

              ProtoObject

              protocol

              An object in the world

              members

              id

              (id object)

              Returns the unique id of this object.

              reify-object

              (reify-object object)

              Adds this object to the global object list. If the object has a non-nil value for its id method, keys it to that id - but if the id value is already in use, throws a hard exception. Returns the id to which the object is keyed in the global object list.

              \ No newline at end of file diff --git a/project.clj b/project.clj index cb2ca83..56344f1 100644 --- a/project.clj +++ b/project.clj @@ -1,22 +1,41 @@ -(defproject the-great-game "0.1.1" - :cloverage {:output "docs/cloverage"} - :codox {:metadata {:doc "**TODO**: write docs" +(defproject journeyman-cc/the-great-game "0.1.2-SNAPSHOT" + :cloverage {:output "docs/cloverage" + :codecov? true + :emma-xml? true} + :codox {:froboz.cloverage {:output "docs/cloverage" + :codecov? true + :html? true + :debug? true} + :metadata {:doc "**TODO**: write docs" :doc/format :markdown} :output-path "docs/codox" :source-uri "https://github.com/simon-brooke/the-great-game/blob/master/{filepath}#L{line}"} :cucumber-feature-paths ["test/features/"] - :dependencies [[org.clojure/clojure "1.8.0"] - [org.clojure/math.numeric-tower "0.0.4"] - [environ "1.1.0"] - [com.taoensso/timbre "4.10.0"]] + :dependencies [[com.taoensso/timbre "6.5.0"] + [environ "1.2.0"] + [jme-clj "0.1.13"] +;; [jme3-core "3.4.0-stable"] + [journeyman-cc/walkmap "0.1.0-SNAPSHOT"] + [me.raynes/fs "1.4.6"] + [mw-engine "0.3.0-SNAPSHOT"] + [org.apache.commons/commons-math3 "3.6.1"] ;; for mersenne-twister implementation + [org.clojure/algo.generic "1.0.0"] + [org.clojure/clojure "1.11.2"] + [org.clojure/math.numeric-tower "0.1.0"] + [org.clojure/tools.namespace "1.5.0"] + [org.clojure/tools.reader "1.4.1"]] :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"} - :plugins [[lein-cloverage "1.1.1"] - [lein-codox "0.10.7"] + :plugins [[lein-adl "0.1.7"] + [lein-cloverage "1.2.2"] + [lein-codox "0.10.8"] ;;[lein-codox "0.10.7-cloverage"] [lein-cucumber "1.0.2"] - [lein-gorilla "0.4.0"]] + [org.clojars.benfb/lein-gorilla "0.7.0"] + ] + ;; NOTE WELL: `lein release` won't work until we have a release repository + ;; set, which we don't! :release-tasks [["vcs" "assert-committed"] ["change" "version" "leiningen.release/bump-version" "release"] ["vcs" "commit"] @@ -28,5 +47,4 @@ ["change" "version" "leiningen.release/bump-version"] ["vcs" "commit"]] - :url "https://github.com/simon-brooke/the-great-game" - ) + :url "https://github.com/simon-brooke/the-great-game") diff --git a/resources/data/crafts.edn b/resources/data/crafts.edn new file mode 100644 index 0000000..e69de29 diff --git a/resources/maps/barra/barra.edn b/resources/maps/barra/barra.edn new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/resources/maps/barra/barra.edn @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/resources/maps/barra/barra.html b/resources/maps/barra/barra.html new file mode 100644 index 0000000..cdee284 --- /dev/null +++ b/resources/maps/barra/barra.html @@ -0,0 +1 @@ +Microworld render
              \ No newline at end of file diff --git a/resources/maps/barra/barra.png b/resources/maps/barra/barra.png new file mode 100644 index 0000000..b5f0799 Binary files /dev/null and b/resources/maps/barra/barra.png differ diff --git a/resources/maps/barra/barra.xcf b/resources/maps/barra/barra.xcf new file mode 100644 index 0000000..766fe52 Binary files /dev/null and b/resources/maps/barra/barra.xcf differ diff --git a/resources/maps/barra/barra_100.edn b/resources/maps/barra/barra_100.edn new file mode 100644 index 0000000..a6ac638 --- /dev/null +++ b/resources/maps/barra/barra_100.edn @@ -0,0 +1 @@ +[[{:x 0, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 0, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 0, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 0, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 0, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 0, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 0, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 0, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 0, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 0, :state :climax, :altitude 14, :gradient 14, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 43, :y 0, :state :climax, :altitude 15, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} {:x 44, :y 0, :state :climax, :altitude 31, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 45, :y 0, :state :climax, :altitude 36, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 46, :y 0, :state :climax, :altitude 15, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 94} {:x 47, :y 0, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 1, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 1, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 1, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 1, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 1, :state :climax, :altitude 12, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} {:x 36, :y 1, :state :climax, :altitude 13, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 76} {:x 37, :y 1, :state :climax, :altitude 15, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} {:x 38, :y 1, :state :climax, :altitude 23, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 39, :y 1, :state :climax, :altitude 23, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 40, :y 1, :state :climax, :altitude 28, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} {:x 41, :y 1, :state :camp, :altitude 15, :gradient 28, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 15} {:x 42, :y 1, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 1, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 1, :state :water, :altitude 2, :gradient 35, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 1, :state :water, :altitude 2, :gradient 35, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 1, :state :water, :altitude 1, :gradient 35, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 1, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 2, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 2, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 2, :state :water, :altitude 2, :gradient 31, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 2, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 2, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 2, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 2, :state :climax, :altitude 22, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 36, :y 2, :state :climax, :altitude 31, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 75} {:x 37, :y 2, :state :climax, :altitude 29, :gradient 38, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} {:x 38, :y 2, :state :climax, :altitude 33, :gradient 36, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} {:x 39, :y 2, :state :climax, :altitude 36, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} {:x 40, :y 2, :state :climax, :altitude 29, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 41, :y 2, :state :climax, :altitude 15, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} {:x 42, :y 2, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 2, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 2, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 2, :state :climax, :altitude 15, :gradient 16, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 94} {:x 46, :y 2, :state :house, :altitude 14, :gradient 16, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 51} {:x 47, :y 2, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 3, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 3, :state :climax, :altitude 14, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} {:x 29, :y 3, :state :grassland, :altitude 32, :gradient 16, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 72} {:x 30, :y 3, :state :climax, :altitude 17, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} {:x 31, :y 3, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 3, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 3, :state :climax, :altitude 22, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} {:x 36, :y 3, :state :climax, :altitude 31, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} {:x 37, :y 3, :state :climax, :altitude 43, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 66} {:x 38, :y 3, :state :climax, :altitude 51, :gradient 17, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 39, :y 3, :state :climax, :altitude 42, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 40, :y 3, :state :climax, :altitude 28, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} {:x 41, :y 3, :state :water, :altitude 2, :gradient 28, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 3, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 3, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 3, :state :camp, :altitude 17, :gradient 14, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 39} {:x 46, :y 3, :state :climax, :altitude 14, :gradient 16, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} {:x 47, :y 3, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 4, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 4, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 4, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 4, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 4, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 4, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 4, :state :water, :altitude 2, :gradient 31, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 4, :state :climax, :altitude 17, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 30, :y 4, :state :house, :altitude 12, :gradient 31, :generation 101, :rule "if state is in camp or abandoned and some neighbours are crop then state should be house", :fertility 77} {:x 31, :y 4, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 4, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 4, :state :house, :altitude 13, :gradient 30, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 55} {:x 36, :y 4, :state :pasture, :altitude 29, :gradient 42, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 24} {:x 37, :y 4, :state :pasture, :altitude 42, :gradient 22, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 38} {:x 38, :y 4, :state :climax, :altitude 46, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 39, :y 4, :state :climax, :altitude 38, :gradient 37, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} {:x 40, :y 4, :state :climax, :altitude 27, :gradient 41, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 41, :y 4, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 4, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 4, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 4, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 4, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 4, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 5, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 5, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 5, :state :house, :altitude 12, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 21} {:x 20, :y 5, :state :house, :altitude 12, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 21, :y 5, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 5, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 5, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 5, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 5, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 5, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 5, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 5, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 5, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 5, :state :grassland, :altitude 31, :gradient 41, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 33} {:x 37, :y 5, :state :pasture, :altitude 32, :gradient 17, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 45} {:x 38, :y 5, :state :grassland, :altitude 37, :gradient 19, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 32} {:x 39, :y 5, :state :grassland, :altitude 33, :gradient 34, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 44} {:x 40, :y 5, :state :grassland, :altitude 14, :gradient 37, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 41} {:x 41, :y 5, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 5, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 6, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 6, :state :climax, :altitude 17, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} {:x 19, :y 6, :state :pasture, :altitude 28, :gradient 25, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 27} {:x 20, :y 6, :state :climax, :altitude 24, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} {:x 21, :y 6, :state :water, :altitude 2, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 6, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 6, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 6, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 6, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 6, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 6, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 6, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 6, :state :house, :altitude 15, :gradient 34, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 36} {:x 36, :y 6, :state :crop, :altitude 35, :gradient 42, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 61} {:x 37, :y 6, :state :crop, :altitude 32, :gradient 14, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 56} {:x 38, :y 6, :state :crop, :altitude 29, :gradient 16, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 21} {:x 39, :y 6, :state :camp, :altitude 27, :gradient 25, :generation 101, :rule "if state is camp and some neighbours are ploughland then state should be camp", :fertility 34} {:x 40, :y 6, :state :pasture, :altitude 12, :gradient 32, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 41, :y 6, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 7, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 7, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 7, :state :climax, :altitude 18, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} {:x 19, :y 7, :state :climax, :altitude 27, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} {:x 20, :y 7, :state :climax, :altitude 14, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 21, :y 7, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 7, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 7, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 7, :state :climax, :altitude 19, :gradient 34, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 92} {:x 26, :y 7, :state :forest, :altitude 22, :gradient 34, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 29} {:x 27, :y 7, :state :house, :altitude 12, :gradient 34, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 11} {:x 28, :y 7, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 7, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 7, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 7, :state :camp, :altitude 15, :gradient 34, :generation 101, :rule "if state is camp and some neighbours are ploughland then state should be camp", :fertility 37} {:x 36, :y 7, :state :grassland, :altitude 35, :gradient 41, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} {:x 37, :y 7, :state :crop, :altitude 43, :gradient 9, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 61} {:x 38, :y 7, :state :house, :altitude 37, :gradient 20, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 34} {:x 39, :y 7, :state :grassland, :altitude 27, :gradient 35, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 46} {:x 40, :y 7, :state :house, :altitude 12, :gradient 26, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 30} {:x 41, :y 7, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 8, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 8, :state :climax, :altitude 14, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} {:x 18, :y 8, :state :crop, :altitude 31, :gradient 28, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 15} {:x 19, :y 8, :state :climax, :altitude 28, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} {:x 20, :y 8, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 8, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 8, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 8, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 8, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 8, :state :climax, :altitude 24, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} {:x 26, :y 8, :state :scrub, :altitude 35, :gradient 29, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 6} {:x 27, :y 8, :state :pasture, :altitude 35, :gradient 40, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 28, :y 8, :state :house, :altitude 22, :gradient 34, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 11} {:x 29, :y 8, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 8, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 8, :state :water, :altitude 2, :gradient 34, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 8, :state :house, :altitude 28, :gradient 42, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 65} {:x 37, :y 8, :state :crop, :altitude 37, :gradient 28, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 42} {:x 38, :y 8, :state :house, :altitude 36, :gradient 31, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 27} {:x 39, :y 8, :state :pasture, :altitude 23, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 33} {:x 40, :y 8, :state :water, :altitude 2, :gradient 26, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 8, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 9, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 9, :state :house, :altitude 12, :gradient 30, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 18, :y 9, :state :climax, :altitude 29, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} {:x 19, :y 9, :state :climax, :altitude 28, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 20, :y 9, :state :pasture, :altitude 18, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 47} {:x 21, :y 9, :state :pasture, :altitude 17, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 23} {:x 22, :y 9, :state :house, :altitude 23, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 20} {:x 23, :y 9, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 9, :state :house, :altitude 14, :gradient 35, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 25, :y 9, :state :pasture, :altitude 31, :gradient 40, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 26, :y 9, :state :scrub, :altitude 41, :gradient 13, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 20} {:x 27, :y 9, :state :forest, :altitude 35, :gradient 39, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 25} {:x 28, :y 9, :state :house, :altitude 20, :gradient 34, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 8} {:x 29, :y 9, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 9, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 9, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 9, :state :crop, :altitude 15, :gradient 36, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 25} {:x 37, :y 9, :state :forest, :altitude 26, :gradient 25, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 68} {:x 38, :y 9, :state :crop, :altitude 23, :gradient 36, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 37} {:x 39, :y 9, :state :house, :altitude 12, :gradient 35, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 38} {:x 40, :y 9, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 9, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 10, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 10, :state :water, :altitude 1, :gradient 28, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 10, :state :house, :altitude 23, :gradient 35, :generation 101, :rule "if state is house and some neighbours are crop then state should be house", :fertility 24} {:x 19, :y 10, :state :grassland, :altitude 28, :gradient 18, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 35} {:x 20, :y 10, :state :climax, :altitude 28, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} {:x 21, :y 10, :state :climax, :altitude 28, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 22, :y 10, :state :ploughland, :altitude 23, :gradient 27, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 22} {:x 23, :y 10, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 10, :state :pasture, :altitude 23, :gradient 35, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 40} {:x 25, :y 10, :state :pasture, :altitude 36, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 26, :y 10, :state :pasture, :altitude 37, :gradient 28, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 27, :y 10, :state :climax, :altitude 26, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 28, :y 10, :state :water, :altitude 2, :gradient 34, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 10, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 10, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 10, :state :pasture, :altitude 18, :gradient 26, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 29} {:x 37, :y 10, :state :pasture, :altitude 27, :gradient 25, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 37} {:x 38, :y 10, :state :scrub, :altitude 12, :gradient 26, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 79} {:x 39, :y 10, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 10, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 11, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 11, :state :grassland, :altitude 20, :gradient 35, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 12} {:x 19, :y 11, :state :grassland, :altitude 36, :gradient 22, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 51} {:x 20, :y 11, :state :forest, :altitude 32, :gradient 10, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 48} {:x 21, :y 11, :state :scrub, :altitude 27, :gradient 22, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 86} {:x 22, :y 11, :state :forest, :altitude 19, :gradient 30, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 58} {:x 23, :y 11, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 11, :state :house, :altitude 14, :gradient 35, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 65} {:x 25, :y 11, :state :forest, :altitude 22, :gradient 36, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 39} {:x 26, :y 11, :state :pasture, :altitude 20, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 27, :y 11, :state :house, :altitude 13, :gradient 36, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 25} {:x 28, :y 11, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 11, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 11, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 11, :state :house, :altitude 15, :gradient 26, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 28} {:x 37, :y 11, :state :house, :altitude 18, :gradient 26, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 10} {:x 38, :y 11, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 11, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 12, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 12, :state :crop, :altitude 15, :gradient 35, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 55} {:x 19, :y 12, :state :house, :altitude 32, :gradient 22, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 50} {:x 20, :y 12, :state :grassland, :altitude 37, :gradient 12, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 54} {:x 21, :y 12, :state :house, :altitude 31, :gradient 22, :generation 101, :rule "if state is in camp or abandoned and some neighbours are crop then state should be house", :fertility 30} {:x 22, :y 12, :state :grassland, :altitude 15, :gradient 30, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 24} {:x 23, :y 12, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 12, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 12, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 12, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 12, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 12, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 12, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 12, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 12, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 12, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 13, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 13, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 13, :state :climax, :altitude 22, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 19, :y 13, :state :climax, :altitude 27, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} {:x 20, :y 13, :state :grassland, :altitude 27, :gradient 24, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} {:x 21, :y 13, :state :house, :altitude 24, :gradient 24, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 13} {:x 22, :y 13, :state :house, :altitude 23, :gradient 30, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 30} {:x 23, :y 13, :state :house, :altitude 22, :gradient 28, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 24, :y 13, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 13, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 13, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 13, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 13, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 13, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 14, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 14, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 14, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 14, :state :forest, :altitude 15, :gradient 30, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 47} {:x 18, :y 14, :state :climax, :altitude 27, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} {:x 19, :y 14, :state :climax, :altitude 26, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} {:x 20, :y 14, :state :crop, :altitude 17, :gradient 18, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 45} {:x 21, :y 14, :state :crop, :altitude 13, :gradient 20, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 19} {:x 22, :y 14, :state :ploughland, :altitude 29, :gradient 23, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 23} {:x 23, :y 14, :state :house, :altitude 18, :gradient 28, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 49} {:x 24, :y 14, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 14, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 14, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 14, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 14, :state :house, :altitude 14, :gradient 39, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 44} {:x 33, :y 14, :state :climax, :altitude 22, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 76} {:x 34, :y 14, :state :climax, :altitude 13, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} {:x 35, :y 14, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 15, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 15, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 15, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 15, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 15, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 15, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 15, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 15, :state :fire, :altitude 13, :gradient 40, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 37} {:x 16, :y 15, :state :climax, :altitude 19, :gradient 44, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 39} {:x 17, :y 15, :state :climax, :altitude 31, :gradient 46, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} {:x 18, :y 15, :state :climax, :altitude 29, :gradient 32, :generation 101, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 43} {:x 19, :y 15, :state :scrub, :altitude 26, :gradient 33, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 57} {:x 20, :y 15, :state :pasture, :altitude 14, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 27} {:x 21, :y 15, :state :water, :altitude 9, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 15, :state :grassland, :altitude 13, :gradient 28, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 27} {:x 23, :y 15, :state :water, :altitude 1, :gradient 28, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 15, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 15, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 15, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 15, :state :waste, :altitude 14, :gradient 31, :generation 101, :rule "if state is camp then 1 chance in 5 state should be waste", :fertility 72} {:x 31, :y 15, :state :grassland, :altitude 19, :gradient 32, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 54} {:x 32, :y 15, :state :climax, :altitude 31, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 33, :y 15, :state :ploughland, :altitude 40, :gradient 20, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 42} {:x 34, :y 15, :state :climax, :altitude 23, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 76} {:x 35, :y 15, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 16, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 16, :state :house, :altitude 18, :gradient 30, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 40} {:x 10, :y 16, :state :crop, :altitude 19, :gradient 35, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 33} {:x 11, :y 16, :state :climax, :altitude 20, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 38} {:x 12, :y 16, :state :climax, :altitude 18, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} {:x 13, :y 16, :state :scrub, :altitude 17, :gradient 34, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 74} {:x 14, :y 16, :state :waste, :altitude 19, :gradient 51, :generation 101, :rule "if state is fire then state should be waste", :fertility 75} {:x 15, :y 16, :state :scrub, :altitude 35, :gradient 55, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 62} {:x 16, :y 16, :state :climax, :altitude 41, :gradient 43, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 41} {:x 17, :y 16, :state :climax, :altitude 45, :gradient 42, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 52} {:x 18, :y 16, :state :climax, :altitude 47, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 51} {:x 19, :y 16, :state :forest, :altitude 45, :gradient 47, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 65} {:x 20, :y 16, :state :climax, :altitude 35, :gradient 45, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 28} {:x 21, :y 16, :state :pasture, :altitude 19, :gradient 33, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 52} {:x 22, :y 16, :state :climax, :altitude 15, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 23, :y 16, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 16, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 16, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 16, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 16, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 16, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 16, :state :ploughland, :altitude 18, :gradient 31, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 85} {:x 30, :y 16, :state :ploughland, :altitude 32, :gradient 31, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 52} {:x 31, :y 16, :state :climax, :altitude 32, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 32, :y 16, :state :climax, :altitude 33, :gradient 21, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 33, :y 16, :state :climax, :altitude 32, :gradient 25, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} {:x 34, :y 16, :state :climax, :altitude 28, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 35, :y 16, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 17, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 17, :state :crop, :altitude 26, :gradient 30, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 40} {:x 10, :y 17, :state :pasture, :altitude 31, :gradient 23, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 25} {:x 11, :y 17, :state :climax, :altitude 36, :gradient 17, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 12, :y 17, :state :heath, :altitude 35, :gradient 19, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 69} {:x 13, :y 17, :state :heath, :altitude 29, :gradient 18, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 54} {:x 14, :y 17, :state :scrub, :altitude 32, :gradient 35, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 63} {:x 15, :y 17, :state :scrub, :altitude 52, :gradient 37, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 51} {:x 16, :y 17, :state :climax, :altitude 56, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 27} {:x 17, :y 17, :state :climax, :altitude 55, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} {:x 18, :y 17, :state :climax, :altitude 61, :gradient 12, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 19, :y 17, :state :climax, :altitude 54, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 20, :y 17, :state :scrub, :altitude 42, :gradient 35, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} {:x 21, :y 17, :state :scrub, :altitude 31, :gradient 27, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 29} {:x 22, :y 17, :state :climax, :altitude 27, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} {:x 23, :y 17, :state :climax, :altitude 22, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 61} {:x 24, :y 17, :state :climax, :altitude 17, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 25, :y 17, :state :climax, :altitude 12, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 26, :y 17, :state :climax, :altitude 12, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 45} {:x 27, :y 17, :state :waste, :altitude 12, :gradient 26, :generation 101, :rule "if state is fire then state should be waste", :fertility 57} {:x 28, :y 17, :state :heath, :altitude 13, :gradient 26, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 65} {:x 29, :y 17, :state :pasture, :altitude 23, :gradient 31, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 55} {:x 30, :y 17, :state :grassland, :altitude 31, :gradient 17, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 69} {:x 31, :y 17, :state :crop, :altitude 32, :gradient 16, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 48} {:x 32, :y 17, :state :crop, :altitude 29, :gradient 15, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 49} {:x 33, :y 17, :state :climax, :altitude 26, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 34, :y 17, :state :camp, :altitude 15, :gradient 31, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 46} {:x 35, :y 17, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 18, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 18, :state :house, :altitude 13, :gradient 30, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 31} {:x 10, :y 18, :state :crop, :altitude 19, :gradient 35, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 29} {:x 11, :y 18, :state :waste, :altitude 27, :gradient 35, :generation 101, :rule "if state is fire then state should be waste", :fertility 64} {:x 12, :y 18, :state :heath, :altitude 31, :gradient 14, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 67} {:x 13, :y 18, :state :scrub, :altitude 31, :gradient 8, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 37} {:x 14, :y 18, :state :scrub, :altitude 31, :gradient 24, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 55} {:x 15, :y 18, :state :climax, :altitude 41, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 39} {:x 16, :y 18, :state :scrub, :altitude 49, :gradient 27, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} {:x 17, :y 18, :state :climax, :altitude 43, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 18, :y 18, :state :climax, :altitude 47, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} {:x 19, :y 18, :state :fire, :altitude 47, :gradient 25, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 45} {:x 20, :y 18, :state :forest, :altitude 40, :gradient 26, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 63} {:x 21, :y 18, :state :climax, :altitude 28, :gradient 16, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 32} {:x 22, :y 18, :state :climax, :altitude 27, :gradient 9, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 23, :y 18, :state :climax, :altitude 27, :gradient 10, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 24, :y 18, :state :climax, :altitude 27, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 75} {:x 25, :y 18, :state :climax, :altitude 22, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 24} {:x 26, :y 18, :state :climax, :altitude 23, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 48} {:x 27, :y 18, :state :climax, :altitude 23, :gradient 17, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} {:x 28, :y 18, :state :fire, :altitude 27, :gradient 17, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 43} {:x 29, :y 18, :state :pasture, :altitude 15, :gradient 19, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 43} {:x 30, :y 18, :state :waste, :altitude 17, :gradient 20, :generation 101, :rule "if state is fire then state should be waste", :fertility 61} {:x 31, :y 18, :state :house, :altitude 18, :gradient 20, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 52} {:x 32, :y 18, :state :house, :altitude 27, :gradient 19, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 43} {:x 33, :y 18, :state :climax, :altitude 31, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 74} {:x 34, :y 18, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 18, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 19, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 19, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 19, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 19, :state :waste, :altitude 22, :gradient 31, :generation 101, :rule "if state is fire then state should be waste", :fertility 28} {:x 12, :y 19, :state :waste, :altitude 27, :gradient 14, :generation 101, :rule "if state is fire then state should be waste", :fertility 85} {:x 13, :y 19, :state :fire, :altitude 31, :gradient 9, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 70} {:x 14, :y 19, :state :scrub, :altitude 28, :gradient 12, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} {:x 15, :y 19, :state :forest, :altitude 29, :gradient 24, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 47} {:x 16, :y 19, :state :scrub, :altitude 37, :gradient 27, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 26} {:x 17, :y 19, :state :scrub, :altitude 41, :gradient 19, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 30} {:x 18, :y 19, :state :climax, :altitude 37, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} {:x 19, :y 19, :state :heath, :altitude 38, :gradient 11, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 40} {:x 20, :y 19, :state :waste, :altitude 36, :gradient 19, :generation 101, :rule "if state is fire then state should be waste", :fertility 51} {:x 21, :y 19, :state :fire, :altitude 28, :gradient 20, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 46} {:x 22, :y 19, :state :climax, :altitude 26, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 56} {:x 23, :y 19, :state :climax, :altitude 26, :gradient 3, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 24, :y 19, :state :climax, :altitude 27, :gradient 6, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 41} {:x 25, :y 19, :state :climax, :altitude 27, :gradient 11, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 32} {:x 26, :y 19, :state :forest, :altitude 22, :gradient 11, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 41} {:x 27, :y 19, :state :fire, :altitude 24, :gradient 19, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 40} {:x 28, :y 19, :state :climax, :altitude 29, :gradient 21, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 29, :y 19, :state :heath, :altitude 22, :gradient 24, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 61} {:x 30, :y 19, :state :waste, :altitude 12, :gradient 22, :generation 101, :rule "if state is fire then state should be waste", :fertility 45} {:x 31, :y 19, :state :crop, :altitude 13, :gradient 21, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 52} {:x 32, :y 19, :state :grassland, :altitude 15, :gradient 32, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 38} {:x 33, :y 19, :state :house, :altitude 17, :gradient 30, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 47} {:x 34, :y 19, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 20, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 20, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 20, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 20, :state :climax, :altitude 23, :gradient 44, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} {:x 12, :y 20, :state :heath, :altitude 32, :gradient 37, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 63} {:x 13, :y 20, :state :fire, :altitude 36, :gradient 32, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 44} {:x 14, :y 20, :state :heath, :altitude 35, :gradient 31, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 47} {:x 15, :y 20, :state :scrub, :altitude 37, :gradient 36, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 65} {:x 16, :y 20, :state :scrub, :altitude 52, :gradient 36, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 75} {:x 17, :y 20, :state :scrub, :altitude 56, :gradient 28, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 60} {:x 18, :y 20, :state :scrub, :altitude 43, :gradient 29, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 40} {:x 19, :y 20, :state :scrub, :altitude 36, :gradient 14, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} {:x 20, :y 20, :state :climax, :altitude 46, :gradient 13, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 21, :y 20, :state :climax, :altitude 41, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 22, :y 20, :state :climax, :altitude 29, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 23, :y 20, :state :scrub, :altitude 26, :gradient 3, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 45} {:x 24, :y 20, :state :climax, :altitude 28, :gradient 3, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 55} {:x 25, :y 20, :state :climax, :altitude 28, :gradient 18, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 56} {:x 26, :y 20, :state :climax, :altitude 17, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 27, :y 20, :state :climax, :altitude 20, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 48} {:x 28, :y 20, :state :waste, :altitude 36, :gradient 15, :generation 101, :rule "if state is fire then state should be waste", :fertility 38} {:x 29, :y 20, :state :waste, :altitude 35, :gradient 24, :generation 101, :rule "if state is fire then state should be waste", :fertility 49} {:x 30, :y 20, :state :fire, :altitude 28, :gradient 23, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 86} {:x 31, :y 20, :state :climax, :altitude 33, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} {:x 32, :y 20, :state :climax, :altitude 15, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} {:x 33, :y 20, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 20, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 21, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 21, :state :climax, :altitude 12, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 10, :y 21, :state :forest, :altitude 12, :gradient 26, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 60} {:x 11, :y 21, :state :scrub, :altitude 24, :gradient 44, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} {:x 12, :y 21, :state :fire, :altitude 45, :gradient 36, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 40} {:x 13, :y 21, :state :forest, :altitude 59, :gradient 27, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 64} {:x 14, :y 21, :state :climax, :altitude 50, :gradient 24, :generation 101, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 55} {:x 15, :y 21, :state :scrub, :altitude 49, :gradient 38, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 76} {:x 16, :y 21, :state :climax, :altitude 64, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 57} {:x 17, :y 21, :state :scrub, :altitude 65, :gradient 34, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} {:x 18, :y 21, :state :climax, :altitude 50, :gradient 41, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 47} {:x 19, :y 21, :state :heath, :altitude 38, :gradient 19, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 49} {:x 20, :y 21, :state :fire, :altitude 38, :gradient 10, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 64} {:x 21, :y 21, :state :scrub, :altitude 38, :gradient 17, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 52} {:x 22, :y 21, :state :climax, :altitude 29, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} {:x 23, :y 21, :state :climax, :altitude 27, :gradient 5, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 56} {:x 24, :y 21, :state :climax, :altitude 28, :gradient 7, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 38} {:x 25, :y 21, :state :climax, :altitude 29, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 30} {:x 26, :y 21, :state :climax, :altitude 35, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 36} {:x 27, :y 21, :state :climax, :altitude 28, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 28, :y 21, :state :climax, :altitude 28, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 70} {:x 29, :y 21, :state :fire, :altitude 27, :gradient 35, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 70} {:x 30, :y 21, :state :climax, :altitude 23, :gradient 34, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 44} {:x 31, :y 21, :state :camp, :altitude 22, :gradient 32, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 47} {:x 32, :y 21, :state :water, :altitude 2, :gradient 32, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 21, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 22, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 22, :state :pasture, :altitude 23, :gradient 26, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 48} {:x 10, :y 22, :state :scrub, :altitude 27, :gradient 15, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 71} {:x 11, :y 22, :state :waste, :altitude 27, :gradient 33, :generation 101, :rule "if state is fire then state should be waste", :fertility 40} {:x 12, :y 22, :state :heath, :altitude 40, :gradient 35, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 70} {:x 13, :y 22, :state :scrub, :altitude 59, :gradient 32, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 37} {:x 14, :y 22, :state :climax, :altitude 54, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 33} {:x 15, :y 22, :state :scrub, :altitude 54, :gradient 35, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 70} {:x 16, :y 22, :state :fire, :altitude 73, :gradient 34, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 75} {:x 17, :y 22, :state :forest, :altitude 77, :gradient 23, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 45} {:x 18, :y 22, :state :climax, :altitude 55, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} {:x 19, :y 22, :state :climax, :altitude 42, :gradient 17, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 20, :y 22, :state :waste, :altitude 40, :gradient 15, :generation 101, :rule "if state is fire then state should be waste", :fertility 51} {:x 21, :y 22, :state :fire, :altitude 36, :gradient 22, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 31} {:x 22, :y 22, :state :fire, :altitude 31, :gradient 14, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 76} {:x 23, :y 22, :state :fire, :altitude 29, :gradient 9, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 49} {:x 24, :y 22, :state :climax, :altitude 28, :gradient 7, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} {:x 25, :y 22, :state :climax, :altitude 33, :gradient 10, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} {:x 26, :y 22, :state :pasture, :altitude 36, :gradient 8, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 11} {:x 27, :y 22, :state :pasture, :altitude 28, :gradient 22, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 23} {:x 28, :y 22, :state :climax, :altitude 14, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 78} {:x 29, :y 22, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 22, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 22, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 22, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 22, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 23, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 23, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 23, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 23, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 23, :state :pasture, :altitude 15, :gradient 26, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 34} {:x 10, :y 23, :state :waste, :altitude 27, :gradient 25, :generation 101, :rule "if state is fire then state should be waste", :fertility 52} {:x 11, :y 23, :state :heath, :altitude 27, :gradient 18, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 74} {:x 12, :y 23, :state :waste, :altitude 27, :gradient 32, :generation 101, :rule "if state is fire then state should be waste", :fertility 47} {:x 13, :y 23, :state :waste, :altitude 32, :gradient 32, :generation 101, :rule "if state is fire then state should be waste", :fertility 56} {:x 14, :y 23, :state :scrub, :altitude 38, :gradient 27, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} {:x 15, :y 23, :state :waste, :altitude 43, :gradient 35, :generation 101, :rule "if state is fire then state should be waste", :fertility 67} {:x 16, :y 23, :state :climax, :altitude 57, :gradient 36, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} {:x 17, :y 23, :state :climax, :altitude 69, :gradient 25, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 38} {:x 18, :y 23, :state :scrub, :altitude 54, :gradient 37, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 60} {:x 19, :y 23, :state :climax, :altitude 50, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 20, :y 23, :state :waste, :altitude 51, :gradient 15, :generation 101, :rule "if state is fire then state should be waste", :fertility 52} {:x 21, :y 23, :state :heath, :altitude 41, :gradient 22, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 64} {:x 22, :y 23, :state :waste, :altitude 35, :gradient 13, :generation 101, :rule "if state is fire then state should be waste", :fertility 68} {:x 23, :y 23, :state :fire, :altitude 31, :gradient 16, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 38} {:x 24, :y 23, :state :climax, :altitude 26, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} {:x 25, :y 23, :state :climax, :altitude 29, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 51} {:x 26, :y 23, :state :pasture, :altitude 29, :gradient 22, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 29} {:x 27, :y 23, :state :climax, :altitude 27, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} {:x 28, :y 23, :state :climax, :altitude 26, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 29, :y 23, :state :camp, :altitude 12, :gradient 25, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 24} {:x 30, :y 23, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 24, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 24, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 24, :state :water, :altitude 2, :gradient 28, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 24, :state :house, :altitude 14, :gradient 28, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 32} {:x 8, :y 24, :state :climax, :altitude 14, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} {:x 9, :y 24, :state :grassland, :altitude 12, :gradient 28, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 29} {:x 10, :y 24, :state :climax, :altitude 22, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} {:x 11, :y 24, :state :climax, :altitude 37, :gradient 37, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 12, :y 24, :state :fire, :altitude 37, :gradient 34, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 31} {:x 13, :y 24, :state :fire, :altitude 36, :gradient 34, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 51} {:x 14, :y 24, :state :scrub, :altitude 41, :gradient 45, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 40} {:x 15, :y 24, :state :heath, :altitude 54, :gradient 56, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 46} {:x 16, :y 24, :state :climax, :altitude 64, :gradient 51, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 17, :y 24, :state :forest, :altitude 79, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 18, :y 24, :state :climax, :altitude 69, :gradient 43, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 19, :y 24, :state :forest, :altitude 51, :gradient 37, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 58} {:x 20, :y 24, :state :fire, :altitude 43, :gradient 20, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 43} {:x 21, :y 24, :state :forest, :altitude 37, :gradient 24, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 30} {:x 22, :y 24, :state :waste, :altitude 29, :gradient 24, :generation 101, :rule "if state is fire then state should be waste", :fertility 67} {:x 23, :y 24, :state :climax, :altitude 28, :gradient 33, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} {:x 24, :y 24, :state :climax, :altitude 19, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 25, :y 24, :state :climax, :altitude 14, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 26, :y 24, :state :climax, :altitude 22, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} {:x 27, :y 24, :state :climax, :altitude 20, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} {:x 28, :y 24, :state :house, :altitude 20, :gradient 26, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 43} {:x 29, :y 24, :state :water, :altitude 2, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 24, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 25, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 25, :state :house, :altitude 12, :gradient 44, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 16} {:x 6, :y 25, :state :climax, :altitude 24, :gradient 51, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 7, :y 25, :state :crop, :altitude 29, :gradient 50, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 27} {:x 8, :y 25, :state :house, :altitude 29, :gradient 40, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 20} {:x 9, :y 25, :state :grassland, :altitude 26, :gradient 34, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 48} {:x 10, :y 25, :state :climax, :altitude 26, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} {:x 11, :y 25, :state :climax, :altitude 41, :gradient 37, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 55} {:x 12, :y 25, :state :climax, :altitude 59, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 13, :y 25, :state :scrub, :altitude 61, :gradient 27, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} {:x 14, :y 25, :state :scrub, :altitude 59, :gradient 41, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 73} {:x 15, :y 25, :state :forest, :altitude 77, :gradient 55, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 48} {:x 16, :y 25, :state :forest, :altitude 94, :gradient 42, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} {:x 17, :y 25, :state :scrub, :altitude 93, :gradient 35, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} {:x 18, :y 25, :state :forest, :altitude 79, :gradient 52, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} {:x 19, :y 25, :state :scrub, :altitude 55, :gradient 48, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 42} {:x 20, :y 25, :state :fire, :altitude 42, :gradient 27, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 49} {:x 21, :y 25, :state :scrub, :altitude 35, :gradient 19, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} {:x 22, :y 25, :state :climax, :altitude 27, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 23, :y 25, :state :fire, :altitude 17, :gradient 28, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 72} {:x 24, :y 25, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 25, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 25, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 25, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 25, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 25, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 25, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 26, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 26, :state :climax, :altitude 20, :gradient 51, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 6, :y 26, :state :crop, :altitude 45, :gradient 65, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 22} {:x 7, :y 26, :state :grassland, :altitude 52, :gradient 62, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 37} {:x 8, :y 26, :state :grassland, :altitude 46, :gradient 60, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} {:x 9, :y 26, :state :grassland, :altitude 31, :gradient 60, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 29} {:x 10, :y 26, :state :pasture, :altitude 28, :gradient 37, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 60} {:x 11, :y 26, :state :scrub, :altitude 37, :gradient 33, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 50} {:x 12, :y 26, :state :scrub, :altitude 55, :gradient 30, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 25} {:x 13, :y 26, :state :scrub, :altitude 63, :gradient 28, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 18} {:x 14, :y 26, :state :climax, :altitude 60, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 15, :y 26, :state :forest, :altitude 74, :gradient 49, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} {:x 16, :y 26, :state :scrub, :altitude 96, :gradient 44, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} {:x 17, :y 26, :state :forest, :altitude 77, :gradient 58, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 74} {:x 18, :y 26, :state :pasture, :altitude 61, :gradient 65, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 56} {:x 19, :y 26, :state :climax, :altitude 41, :gradient 52, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} {:x 20, :y 26, :state :pasture, :altitude 31, :gradient 28, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 60} {:x 21, :y 26, :state :waste, :altitude 28, :gradient 22, :generation 101, :rule "if state is fire then state should be waste", :fertility 64} {:x 22, :y 26, :state :pasture, :altitude 24, :gradient 34, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 74} {:x 23, :y 26, :state :water, :altitude 2, :gradient 26, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 26, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 26, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 27, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 27, :state :water, :altitude 1, :gradient 35, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 27, :state :climax, :altitude 22, :gradient 51, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} {:x 6, :y 27, :state :climax, :altitude 52, :gradient 57, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} {:x 7, :y 27, :state :pasture, :altitude 77, :gradient 41, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 50} {:x 8, :y 27, :state :heath, :altitude 86, :gradient 48, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 50} {:x 9, :y 27, :state :climax, :altitude 63, :gradient 58, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 10, :y 27, :state :pasture, :altitude 38, :gradient 50, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 48} {:x 11, :y 27, :state :scrub, :altitude 33, :gradient 30, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 48} {:x 12, :y 27, :state :scrub, :altitude 33, :gradient 37, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 75} {:x 13, :y 27, :state :climax, :altitude 47, :gradient 37, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 14, :y 27, :state :scrub, :altitude 47, :gradient 41, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 60} {:x 15, :y 27, :state :pasture, :altitude 50, :gradient 63, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 64} {:x 16, :y 27, :state :crop, :altitude 64, :gradient 63, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 32} {:x 17, :y 27, :state :crop, :altitude 55, :gradient 58, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 58} {:x 18, :y 27, :state :crop, :altitude 38, :gradient 49, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 31} {:x 19, :y 27, :state :climax, :altitude 28, :gradient 34, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} {:x 20, :y 27, :state :fire, :altitude 27, :gradient 15, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 75} {:x 21, :y 27, :state :climax, :altitude 27, :gradient 16, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} {:x 22, :y 27, :state :pasture, :altitude 20, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 23, :y 27, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 27, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 28, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 28, :state :house, :altitude 14, :gradient 35, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 25} {:x 5, :y 28, :state :crop, :altitude 36, :gradient 51, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 38} {:x 6, :y 28, :state :climax, :altitude 52, :gradient 55, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 47} {:x 7, :y 28, :state :forest, :altitude 70, :gradient 46, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} {:x 8, :y 28, :state :scrub, :altitude 79, :gradient 46, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 59} {:x 9, :y 28, :state :scrub, :altitude 78, :gradient 48, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 29} {:x 10, :y 28, :state :climax, :altitude 56, :gradient 45, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 51} {:x 11, :y 28, :state :scrub, :altitude 35, :gradient 30, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 52} {:x 12, :y 28, :state :climax, :altitude 26, :gradient 23, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 57} {:x 13, :y 28, :state :climax, :altitude 33, :gradient 23, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} {:x 14, :y 28, :state :pasture, :altitude 37, :gradient 26, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 56} {:x 15, :y 28, :state :pasture, :altitude 33, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 62} {:x 16, :y 28, :state :crop, :altitude 40, :gradient 31, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 35} {:x 17, :y 28, :state :house, :altitude 50, :gradient 26, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 43} {:x 18, :y 28, :state :pasture, :altitude 42, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 19, :y 28, :state :house, :altitude 37, :gradient 15, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 19} {:x 20, :y 28, :state :ploughland, :altitude 33, :gradient 16, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 30} {:x 21, :y 28, :state :pasture, :altitude 26, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 19} {:x 22, :y 28, :state :house, :altitude 17, :gradient 26, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 14} {:x 23, :y 28, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 29, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 29, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 29, :state :ploughland, :altitude 12, :gradient 35, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 31} {:x 5, :y 29, :state :grassland, :altitude 32, :gradient 40, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 44} {:x 6, :y 29, :state :heath, :altitude 41, :gradient 42, :generation 101, :rule "if state is waste and some neighbours are forest then state should be heath", :fertility 62} {:x 7, :y 29, :state :scrub, :altitude 40, :gradient 51, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} {:x 8, :y 29, :state :scrub, :altitude 50, :gradient 52, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} {:x 9, :y 29, :state :scrub, :altitude 60, :gradient 52, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 62} {:x 10, :y 29, :state :climax, :altitude 52, :gradient 51, :generation 101, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 67} {:x 11, :y 29, :state :climax, :altitude 35, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} {:x 12, :y 29, :state :scrub, :altitude 26, :gradient 22, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 59} {:x 13, :y 29, :state :scrub, :altitude 24, :gradient 24, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 49} {:x 14, :y 29, :state :pasture, :altitude 28, :gradient 24, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 67} {:x 15, :y 29, :state :house, :altitude 33, :gradient 19, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 47} {:x 16, :y 29, :state :ploughland, :altitude 43, :gradient 17, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 18} {:x 17, :y 29, :state :house, :altitude 49, :gradient 21, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 21} {:x 18, :y 29, :state :grassland, :altitude 41, :gradient 23, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 13} {:x 19, :y 29, :state :inn, :altitude 38, :gradient 15, :generation 101, :rule "if state is house and some neighbours are market and more than 1 neighbours are house then 1 chance in 5 state should be inn", :fertility 34} {:x 20, :y 29, :state :crop, :altitude 37, :gradient 36, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 25} {:x 21, :y 29, :state :grassland, :altitude 22, :gradient 36, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 18} {:x 22, :y 29, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 29, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 30, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 30, :state :house, :altitude 12, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 17} {:x 4, :y 30, :state :ploughland, :altitude 28, :gradient 31, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 20} {:x 5, :y 30, :state :climax, :altitude 31, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 6, :y 30, :state :climax, :altitude 28, :gradient 13, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 70} {:x 7, :y 30, :state :scrub, :altitude 28, :gradient 23, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 52} {:x 8, :y 30, :state :fire, :altitude 37, :gradient 34, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 83} {:x 9, :y 30, :state :forest, :altitude 27, :gradient 42, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 64} {:x 10, :y 30, :state :climax, :altitude 28, :gradient 47, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 28} {:x 11, :y 30, :state :climax, :altitude 32, :gradient 42, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 47} {:x 12, :y 30, :state :fire, :altitude 28, :gradient 26, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 58} {:x 13, :y 30, :state :pasture, :altitude 13, :gradient 19, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 74} {:x 14, :y 30, :state :pasture, :altitude 24, :gradient 24, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 44} {:x 15, :y 30, :state :scrub, :altitude 33, :gradient 30, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 66} {:x 16, :y 30, :state :house, :altitude 35, :gradient 36, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 32} {:x 17, :y 30, :state :pasture, :altitude 36, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 18, :y 30, :state :house, :altitude 29, :gradient 47, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 28} {:x 19, :y 30, :state :grassland, :altitude 27, :gradient 40, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 12} {:x 20, :y 30, :state :house, :altitude 27, :gradient 37, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 21, :y 30, :state :water, :altitude 2, :gradient 36, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 30, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 31, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 31, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 31, :state :water, :altitude 1, :gradient 35, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 31, :state :ploughland, :altitude 24, :gradient 44, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 35} {:x 5, :y 31, :state :climax, :altitude 29, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 6, :y 31, :state :climax, :altitude 31, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 75} {:x 7, :y 31, :state :heath, :altitude 28, :gradient 23, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 45} {:x 8, :y 31, :state :scrub, :altitude 27, :gradient 19, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 68} {:x 9, :y 31, :state :waste, :altitude 26, :gradient 19, :generation 101, :rule "if state is fire then state should be waste", :fertility 68} {:x 10, :y 31, :state :scrub, :altitude 18, :gradient 19, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 45} {:x 11, :y 31, :state :heath, :altitude 13, :gradient 22, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 48} {:x 12, :y 31, :state :waste, :altitude 10, :gradient 23, :generation 101, :rule "if state is fire then state should be waste", :fertility 66} {:x 13, :y 31, :state :water, :altitude 9, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 31, :state :pasture, :altitude 23, :gradient 32, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 59} {:x 15, :y 31, :state :pasture, :altitude 17, :gradient 34, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 52} {:x 16, :y 31, :state :scrub, :altitude 13, :gradient 35, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 59} {:x 17, :y 31, :state :ploughland, :altitude 14, :gradient 35, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 21} {:x 18, :y 31, :state :house, :altitude 14, :gradient 35, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 19, :y 31, :state :water, :altitude 2, :gradient 28, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 31, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 31, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 31, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 32, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 32, :state :camp, :altitude 17, :gradient 31, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 56} {:x 3, :y 32, :state :climax, :altitude 22, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 92} {:x 4, :y 32, :state :climax, :altitude 36, :gradient 44, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 70} {:x 5, :y 32, :state :climax, :altitude 45, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 25} {:x 6, :y 32, :state :climax, :altitude 50, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} {:x 7, :y 32, :state :heath, :altitude 45, :gradient 29, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 44} {:x 8, :y 32, :state :heath, :altitude 35, :gradient 30, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 46} {:x 9, :y 32, :state :waste, :altitude 32, :gradient 38, :generation 101, :rule "if state is fire then state should be waste", :fertility 27} {:x 10, :y 32, :state :climax, :altitude 24, :gradient 25, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 11, :y 32, :state :climax, :altitude 19, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 12, :y 32, :state :waste, :altitude 20, :gradient 23, :generation 101, :rule "if state is fire then state should be waste", :fertility 77} {:x 13, :y 32, :state :climax, :altitude 20, :gradient 23, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 36} {:x 14, :y 32, :state :pasture, :altitude 14, :gradient 30, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 49} {:x 15, :y 32, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 32, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 32, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 32, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 32, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 32, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 33, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 33, :state :climax, :altitude 26, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} {:x 3, :y 33, :state :climax, :altitude 32, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 4, :y 33, :state :climax, :altitude 33, :gradient 33, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 5, :y 33, :state :fire, :altitude 41, :gradient 35, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 63} {:x 6, :y 33, :state :waste, :altitude 46, :gradient 38, :generation 101, :rule "if state is fire then state should be waste", :fertility 73} {:x 7, :y 33, :state :climax, :altitude 55, :gradient 38, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} {:x 8, :y 33, :state :waste, :altitude 56, :gradient 32, :generation 101, :rule "if state is fire then state should be waste", :fertility 48} {:x 9, :y 33, :state :climax, :altitude 38, :gradient 44, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 55} {:x 10, :y 33, :state :climax, :altitude 27, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 11, :y 33, :state :climax, :altitude 31, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 78} {:x 12, :y 33, :state :fire, :altitude 32, :gradient 17, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 47} {:x 13, :y 33, :state :climax, :altitude 31, :gradient 18, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} {:x 14, :y 33, :state :pasture, :altitude 26, :gradient 30, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 32} {:x 15, :y 33, :state :pasture, :altitude 12, :gradient 25, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 24} {:x 16, :y 33, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 33, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 34, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 34, :state :climax, :altitude 12, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 90} {:x 3, :y 34, :state :climax, :altitude 12, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 45} {:x 4, :y 34, :state :climax, :altitude 15, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} {:x 5, :y 34, :state :climax, :altitude 17, :gradient 45, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 6, :y 34, :state :fire, :altitude 18, :gradient 38, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 78} {:x 7, :y 34, :state :climax, :altitude 29, :gradient 38, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 66} {:x 8, :y 34, :state :climax, :altitude 36, :gradient 33, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} {:x 9, :y 34, :state :fire, :altitude 23, :gradient 44, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 61} {:x 10, :y 34, :state :climax, :altitude 12, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 11, :y 34, :state :climax, :altitude 14, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 12, :y 34, :state :climax, :altitude 17, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 57} {:x 13, :y 34, :state :climax, :altitude 18, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 14, :y 34, :state :climax, :altitude 18, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} {:x 15, :y 34, :state :climax, :altitude 23, :gradient 25, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 52} {:x 16, :y 34, :state :house, :altitude 18, :gradient 22, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 17, :y 34, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 34, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 34, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 34, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 34, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 35, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 35, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 35, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 35, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 35, :state :ploughland, :altitude 22, :gradient 36, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 49} {:x 6, :y 35, :state :ploughland, :altitude 24, :gradient 20, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 40} {:x 7, :y 35, :state :pasture, :altitude 26, :gradient 19, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 49} {:x 8, :y 35, :state :climax, :altitude 26, :gradient 13, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} {:x 9, :y 35, :state :climax, :altitude 27, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} {:x 10, :y 35, :state :climax, :altitude 24, :gradient 21, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 50} {:x 11, :y 35, :state :climax, :altitude 27, :gradient 21, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 39} {:x 12, :y 35, :state :climax, :altitude 22, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} {:x 13, :y 35, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 35, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 35, :state :climax, :altitude 13, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 16, :y 35, :state :climax, :altitude 12, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} {:x 17, :y 35, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 35, :state :climax, :altitude 17, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} {:x 19, :y 35, :state :climax, :altitude 32, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 20, :y 35, :state :climax, :altitude 26, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} {:x 21, :y 35, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 36, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 36, :state :house, :altitude 24, :gradient 36, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 42} {:x 6, :y 36, :state :scrub, :altitude 37, :gradient 22, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 39} {:x 7, :y 36, :state :crop, :altitude 32, :gradient 13, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 35} {:x 8, :y 36, :state :grassland, :altitude 27, :gradient 9, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} {:x 9, :y 36, :state :climax, :altitude 32, :gradient 7, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 10, :y 36, :state :climax, :altitude 31, :gradient 10, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 66} {:x 11, :y 36, :state :climax, :altitude 33, :gradient 13, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 12, :y 36, :state :climax, :altitude 26, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} {:x 13, :y 36, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 36, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 36, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 36, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 36, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 36, :state :climax, :altitude 19, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} {:x 19, :y 36, :state :climax, :altitude 49, :gradient 18, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 20, :y 36, :state :climax, :altitude 35, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} {:x 21, :y 36, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 37, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 37, :state :house, :altitude 13, :gradient 36, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 34} {:x 6, :y 37, :state :crop, :altitude 35, :gradient 35, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 20} {:x 7, :y 37, :state :house, :altitude 35, :gradient 19, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 49} {:x 8, :y 37, :state :house, :altitude 28, :gradient 23, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 34} {:x 9, :y 37, :state :climax, :altitude 27, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} {:x 10, :y 37, :state :climax, :altitude 29, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 11, :y 37, :state :climax, :altitude 23, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} {:x 12, :y 37, :state :heath, :altitude 18, :gradient 32, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 50} {:x 13, :y 37, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 37, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 37, :state :climax, :altitude 17, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 95} {:x 19, :y 37, :state :climax, :altitude 33, :gradient 47, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 20, :y 37, :state :camp, :altitude 23, :gradient 48, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp"} {:x 21, :y 37, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 38, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 38, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 38, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 38, :state :water, :altitude 2, :gradient 34, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 38, :state :house, :altitude 19, :gradient 34, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 28} {:x 7, :y 38, :state :grassland, :altitude 19, :gradient 34, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 20} {:x 8, :y 38, :state :pasture, :altitude 18, :gradient 34, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 41} {:x 9, :y 38, :state :grassland, :altitude 12, :gradient 27, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 20} {:x 10, :y 38, :state :water, :altitude 2, :gradient 28, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 38, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 38, :state :water, :altitude 2, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 38, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 38, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 38, :state :camp, :altitude 12, :gradient 32, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 15} {:x 19, :y 38, :state :climax, :altitude 17, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} {:x 20, :y 38, :state :water, :altitude 2, :gradient 32, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 38, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 39, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 39, :state :climax, :altitude 12, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} {:x 4, :y 39, :state :house, :altitude 19, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 5, :y 39, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 39, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 39, :state :water, :altitude 1, :gradient 28, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 39, :state :pasture, :altitude 15, :gradient 48, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 26} {:x 9, :y 39, :state :house, :altitude 26, :gradient 47, :generation 101, :rule "if state is house and some neighbours are crop then state should be house", :fertility 43} {:x 10, :y 39, :state :camp, :altitude 26, :gradient 48, :generation 101, :rule "if state is in waste or grassland and some neighbours are market then state should be camp", :fertility 49} {:x 11, :y 39, :state :crop, :altitude 23, :gradient 48, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 52} {:x 12, :y 39, :state :house, :altitude 13, :gradient 41, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 58} {:x 13, :y 39, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 39, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 39, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 39, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 39, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 39, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 39, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 40, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 40, :state :pasture, :altitude 13, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 4, :y 40, :state :ploughland, :altitude 28, :gradient 26, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 12} {:x 5, :y 40, :state :house, :altitude 14, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 15} {:x 6, :y 40, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 40, :state :house, :altitude 15, :gradient 28, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 39} {:x 8, :y 40, :state :house, :altitude 29, :gradient 49, :generation 101, :rule "if state is house and some neighbours are market then state should be house", :fertility 37} {:x 9, :y 40, :state :grassland, :altitude 49, :gradient 46, :generation 101, :rule "if state is market then state should be grassland", :fertility 9} {:x 10, :y 40, :state :climax, :altitude 49, :gradient 38, :generation 101, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 68} {:x 11, :y 40, :state :grassland, :altitude 42, :gradient 48, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 46} {:x 12, :y 40, :state :pasture, :altitude 28, :gradient 50, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 77} {:x 13, :y 40, :state :grassland, :altitude 18, :gradient 34, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 49} {:x 14, :y 40, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 41, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 41, :state :climax, :altitude 12, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} {:x 4, :y 41, :state :climax, :altitude 28, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 5, :y 41, :state :scrub, :altitude 18, :gradient 27, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 17} {:x 6, :y 41, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 41, :state :house, :altitude 14, :gradient 28, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 8, :y 41, :state :scrub, :altitude 29, :gradient 49, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 62} {:x 9, :y 41, :state :house, :altitude 50, :gradient 37, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 38} {:x 10, :y 41, :state :scrub, :altitude 61, :gradient 19, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 54} {:x 11, :y 41, :state :scrub, :altitude 51, :gradient 33, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 53} {:x 12, :y 41, :state :climax, :altitude 35, :gradient 33, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 13, :y 41, :state :pasture, :altitude 20, :gradient 34, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 75} {:x 14, :y 41, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 41, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 42, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 42, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 42, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 42, :state :camp, :altitude 14, :gradient 27, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 21} {:x 5, :y 42, :state :house, :altitude 12, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 22} {:x 6, :y 42, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 42, :state :water, :altitude 1, :gradient 28, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 42, :state :climax, :altitude 24, :gradient 49, :generation 101, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 36} {:x 9, :y 42, :state :crop, :altitude 32, :gradient 47, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 20} {:x 10, :y 42, :state :house, :altitude 40, :gradient 41, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 18} {:x 11, :y 42, :state :grassland, :altitude 40, :gradient 33, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 33} {:x 12, :y 42, :state :pasture, :altitude 32, :gradient 31, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 52} {:x 13, :y 42, :state :climax, :altitude 23, :gradient 34, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 14, :y 42, :state :water, :altitude 2, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 42, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 43, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 43, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 3, :y 43, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 4, :y 43, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 43, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 43, :state :water, :altitude 2, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 43, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 43, :state :house, :altitude 14, :gradient 31, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 38} {:x 9, :y 43, :state :pasture, :altitude 20, :gradient 39, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 29} {:x 10, :y 43, :state :grassland, :altitude 28, :gradient 39, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 30} {:x 11, :y 43, :state :pasture, :altitude 28, :gradient 23, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 50} {:x 12, :y 43, :state :fire, :altitude 28, :gradient 25, :generation 101, :rule "if state is climax then 1 chance in 500 state should be fire", :fertility 73} {:x 13, :y 43, :state :climax, :altitude 23, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 14, :y 43, :state :water, :altitude 2, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 43, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 44, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 44, :state :house, :altitude 17, :gradient 36, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 6} {:x 3, :y 44, :state :camp, :altitude 28, :gradient 36, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 20} {:x 4, :y 44, :state :water, :altitude 2, :gradient 36, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 44, :state :camp, :altitude 12, :gradient 21, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 47} {:x 6, :y 44, :state :climax, :altitude 22, :gradient 14, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 95} {:x 7, :y 44, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 44, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 44, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 44, :state :house, :altitude 20, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 36} {:x 11, :y 44, :state :climax, :altitude 17, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} {:x 12, :y 44, :state :climax, :altitude 22, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 88} {:x 13, :y 44, :state :climax, :altitude 15, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 88} {:x 14, :y 44, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 44, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 45, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 45, :state :climax, :altitude 19, :gradient 36, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} {:x 3, :y 45, :state :climax, :altitude 37, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 4, :y 45, :state :climax, :altitude 14, :gradient 36, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 78} {:x 5, :y 45, :state :water, :altitude 2, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 45, :state :house, :altitude 15, :gradient 21, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 7, :y 45, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 45, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 45, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 45, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 45, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 45, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 45, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] [{:x 0, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 1, :y 46, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} {:x 2, :y 46, :state :climax, :altitude 13, :gradient 36, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} {:x 3, :y 46, :state :climax, :altitude 22, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} {:x 4, :y 46, :state :water, :altitude 2, :gradient 36, :generation 101, :rule "if state is water then state should be water"} {:x 5, :y 46, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 6, :y 46, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 7, :y 46, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} {:x 8, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 9, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 10, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 11, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 12, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 13, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 14, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 15, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 16, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 17, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 18, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 19, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 20, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 21, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 22, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 23, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 24, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 25, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 26, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 27, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 28, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 29, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 30, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 31, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 32, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 33, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 34, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 35, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 36, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 37, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 38, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 39, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 40, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 41, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 42, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 43, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 44, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 45, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 46, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} {:x 47, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}]] \ No newline at end of file diff --git a/resources/maps/barra/barra_100.html b/resources/maps/barra/barra_100.html new file mode 100644 index 0000000..400d8d1 --- /dev/null +++ b/resources/maps/barra/barra_100.html @@ -0,0 +1 @@ +Microworld render
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxclimaxclimaxclimaxwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxclimaxclimaxclimaxclimaxcampwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxclimaxclimaxclimaxclimaxclimaxwaterwaterwaterclimaxhousewater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxgrasslandclimaxwaterwaterwaterwaterclimaxclimaxclimaxclimaxclimaxclimaxwaterwaterwaterwatercampclimaxwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxhousewaterwaterwaterwaterhousepasturepastureclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterhousehousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwatergrasslandpasturegrasslandgrasslandgrasslandwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxpastureclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterhousecropcropcropcamppasturewaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxclimaxwaterwaterwaterwaterclimaxforesthousewaterwaterwaterwaterwaterwaterwatercampgrasslandcrophousegrasslandhousewaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxcropclimaxwaterwaterwaterwaterwaterclimaxscrubpasturehousewaterwaterwaterwaterwaterwaterwaterhousecrophousepasturewaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterhouseclimaxclimaxpasturepasturehousewaterhousepasturescrubforesthousewaterwaterwaterwaterwaterwaterwatercropforestcrophousewaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterhousegrasslandclimaxclimaxploughlandwaterpasturepasturepastureclimaxwaterwaterwaterwaterwaterwaterwaterwaterpasturepasturescrubwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwatergrasslandgrasslandforestscrubforestwaterhouseforestpasturehousewaterwaterwaterwaterwaterwaterwaterwaterhousehousewaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwatercrophousegrasslandhousegrasslandwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxgrasslandhousehousehousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterforestclimaxclimaxcropcropploughlandhousewaterwaterwaterwaterwaterwaterwaterwaterhouseclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterfireclimaxclimaxclimaxscrubpasturewatergrasslandwaterwaterwaterwaterwaterwaterwaterwastegrasslandclimaxploughlandclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterhousecropclimaxclimaxscrubwastescrubclimaxclimaxclimaxforestclimaxpastureclimaxwaterwaterwaterwaterwaterwaterploughlandploughlandclimaxclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwatercroppastureclimaxheathheathscrubscrubclimaxclimaxclimaxclimaxscrubscrubclimaxclimaxclimaxclimaxclimaxwasteheathpasturegrasslandcropcropclimaxcampwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterhousecropwasteheathscrubscrubclimaxscrubclimaxclimaxfireforestclimaxclimaxclimaxclimaxclimaxclimaxclimaxfirepasturewastehousehouseclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwastewastefirescrubforestscrubscrubclimaxheathwastefireclimaxclimaxclimaxclimaxforestfireclimaxheathwastecropgrasslandhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxheathfireheathscrubscrubscrubscrubscrubclimaxclimaxclimaxscrubclimaxclimaxclimaxclimaxwastewastefireclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterclimaxforestscrubfireforestclimaxscrubclimaxscrubclimaxheathfirescrubclimaxclimaxclimaxclimaxclimaxclimaxclimaxfireclimaxcampwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterpasturescrubwasteheathscrubclimaxscrubfireforestclimaxclimaxwastefirefirefireclimaxclimaxpasturepastureclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterpasturewasteheathwastewastescrubwasteclimaxclimaxscrubclimaxwasteheathwastefireclimaxclimaxpastureclimaxclimaxcampwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterhouseclimaxgrasslandclimaxclimaxfirefirescrubheathclimaxforestclimaxforestfireforestwasteclimaxclimaxclimaxclimaxclimaxhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterhouseclimaxcrophousegrasslandclimaxclimaxclimaxscrubscrubforestforestscrubforestscrubfirescrubclimaxfirewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterclimaxcropgrasslandgrasslandgrasslandpasturescrubscrubscrubclimaxforestscrubforestpastureclimaxpasturewastepasturewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterclimaxclimaxpastureheathclimaxpasturescrubscrubclimaxscrubpasturecropcropcropclimaxfireclimaxpasturewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterhousecropclimaxforestscrubscrubclimaxscrubclimaxclimaxpasturepasturecrophousepasturehouseploughlandpasturehousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterploughlandgrasslandheathscrubscrubscrubclimaxclimaxscrubscrubpasturehouseploughlandhousegrasslandinncropgrasslandwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterhouseploughlandclimaxclimaxscrubfireforestclimaxclimaxfirepasturepasturescrubhousepasturehousegrasslandhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterploughlandclimaxclimaxheathscrubwastescrubheathwastewaterpasturepasturescrubploughlandhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwatercampclimaxclimaxclimaxclimaxheathheathwasteclimaxclimaxwasteclimaxpasturewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterclimaxclimaxclimaxfirewasteclimaxwasteclimaxclimaxclimaxfireclimaxpasturepasturewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterclimaxclimaxclimaxclimaxfireclimaxclimaxfireclimaxclimaxclimaxclimaxclimaxclimaxhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterploughlandploughlandpastureclimaxclimaxclimaxclimaxclimaxwaterwaterclimaxclimaxwaterclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterhousescrubcropgrasslandclimaxclimaxclimaxclimaxwaterwaterwaterwaterwaterclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterhousecrophousehouseclimaxclimaxclimaxheathwaterwaterwaterwaterwaterclimaxclimaxcampwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterhousegrasslandpasturegrasslandwaterwaterwaterwaterwaterwaterwaterwatercampclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterclimaxhousewaterwaterwaterpasturehousecampcrophousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterpastureploughlandhousewaterhousehousegrasslandclimaxgrasslandpasturegrasslandwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterclimaxclimaxscrubwaterhousescrubhousescrubscrubclimaxpasturewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwatercamphousewaterwaterclimaxcrophousegrasslandpastureclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterhousepasturegrasslandpasturefireclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterhousecampwatercampclimaxwaterwaterwaterhouseclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterclimaxclimaxclimaxwaterhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              \ No newline at end of file diff --git a/resources/maps/barra/barra_100_edited.edn b/resources/maps/barra/barra_100_edited.edn new file mode 100644 index 0000000..019936e --- /dev/null +++ b/resources/maps/barra/barra_100_edited.edn @@ -0,0 +1,2256 @@ +[[{:x 0, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 0, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 0, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 0, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 0, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 0, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 0, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 0, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 0, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 0, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 0, :state :climax, :altitude 14, :gradient 14, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} + {:x 43, :y 0, :state :climax, :altitude 15, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} + {:x 44, :y 0, :state :climax, :altitude 31, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} + {:x 45, :y 0, :state :climax, :altitude 36, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} + {:x 46, :y 0, :state :climax, :altitude 15, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 94} + {:x 47, :y 0, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 1, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 1, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 1, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 1, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 1, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 1, :state :climax, :altitude 12, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} + {:x 36, :y 1, :state :climax, :altitude 13, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 76} + {:x 37, :y 1, :state :climax, :altitude 15, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} + {:x 38, :y 1, :state :climax, :altitude 23, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} + {:x 39, :y 1, :state :climax, :altitude 23, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} + {:x 40, :y 1, :state :climax, :altitude 28, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} + {:x 41, :y 1, :state :camp, :altitude 15, :gradient 28, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 15} + {:x 42, :y 1, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 1, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 1, :state :water, :altitude 2, :gradient 35, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 1, :state :water, :altitude 2, :gradient 35, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 1, :state :water, :altitude 1, :gradient 35, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 1, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 2, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 2, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 2, :state :water, :altitude 2, :gradient 31, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 2, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 2, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 2, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 2, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 2, :state :climax, :altitude 22, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} + {:x 36, :y 2, :state :climax, :altitude 31, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 75} + {:x 37, :y 2, :state :climax, :altitude 29, :gradient 38, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} + {:x 38, :y 2, :state :climax, :altitude 33, :gradient 36, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} + {:x 39, :y 2, :state :climax, :altitude 36, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} + {:x 40, :y 2, :state :climax, :altitude 29, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} + {:x 41, :y 2, :state :climax, :altitude 15, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} + {:x 42, :y 2, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 2, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 2, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 2, :state :climax, :altitude 15, :gradient 16, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 94} + {:x 46, :y 2, :state :house, :altitude 14, :gradient 16, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 51} + {:x 47, :y 2, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 3, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 3, :state :climax, :altitude 14, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} + {:x 29, :y 3, :state :grassland, :altitude 32, :gradient 16, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 72} + {:x 30, :y 3, :state :climax, :altitude 17, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} + {:x 31, :y 3, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 3, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 3, :state :climax, :altitude 22, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} + {:x 36, :y 3, :state :climax, :altitude 31, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} + {:x 37, :y 3, :state :climax, :altitude 43, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 66} + {:x 38, :y 3, :state :climax, :altitude 51, :gradient 17, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} + {:x 39, :y 3, :state :climax, :altitude 42, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} + {:x 40, :y 3, :state :climax, :altitude 28, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} + {:x 41, :y 3, :state :water, :altitude 2, :gradient 28, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 3, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 3, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 3, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 3, :state :camp, :altitude 17, :gradient 14, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 39} + {:x 46, :y 3, :state :climax, :altitude 14, :gradient 16, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} + {:x 47, :y 3, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 4, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 4, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 4, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 4, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 4, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 4, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 4, :state :water, :altitude 2, :gradient 31, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 4, :state :climax, :altitude 17, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} + {:x 30, :y 4, :state :house, :altitude 12, :gradient 31, :generation 101, :rule "if state is in camp or abandoned and some neighbours are crop then state should be house", :fertility 77} + {:x 31, :y 4, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 4, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 4, :state :house, :altitude 13, :gradient 30, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 55} + {:x 36, :y 4, :state :pasture, :altitude 29, :gradient 42, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 24} + {:x 37, :y 4, :state :pasture, :altitude 42, :gradient 22, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 38} + {:x 38, :y 4, :state :climax, :altitude 46, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} + {:x 39, :y 4, :state :climax, :altitude 38, :gradient 37, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} + {:x 40, :y 4, :state :climax, :altitude 27, :gradient 41, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} + {:x 41, :y 4, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 4, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 4, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 4, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 4, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 4, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 4, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 5, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 5, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 5, :state :house, :altitude 12, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 21} + {:x 20, :y 5, :state :house, :altitude 12, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} + {:x 21, :y 5, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 5, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 5, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 5, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 5, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 5, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 5, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 5, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 5, :state :harbour, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 5, :state :market, :altitude 31, :gradient 41, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 33} + {:x 37, :y 5, :state :pasture, :altitude 32, :gradient 17, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 45} + {:x 38, :y 5, :state :grassland, :altitude 37, :gradient 19, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 32} + {:x 39, :y 5, :state :grassland, :altitude 33, :gradient 34, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 44} + {:x 40, :y 5, :state :grassland, :altitude 14, :gradient 37, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 41} + {:x 41, :y 5, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 5, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 5, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 6, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 6, :state :climax, :altitude 17, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} + {:x 19, :y 6, :state :pasture, :altitude 28, :gradient 25, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 27} + {:x 20, :y 6, :state :climax, :altitude 24, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} + {:x 21, :y 6, :state :water, :altitude 2, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 6, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 6, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 6, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 6, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 6, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 6, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 6, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 6, :state :inn, :altitude 15, :gradient 34, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 36} + {:x 36, :y 6, :state :crop, :altitude 35, :gradient 42, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 61} + {:x 37, :y 6, :state :crop, :altitude 32, :gradient 14, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 56} + {:x 38, :y 6, :state :crop, :altitude 29, :gradient 16, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 21} + {:x 39, :y 6, :state :camp, :altitude 27, :gradient 25, :generation 101, :rule "if state is camp and some neighbours are ploughland then state should be camp", :fertility 34} + {:x 40, :y 6, :state :pasture, :altitude 12, :gradient 32, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} + {:x 41, :y 6, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 6, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 7, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 7, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 7, :state :climax, :altitude 18, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} + {:x 19, :y 7, :state :climax, :altitude 27, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} + {:x 20, :y 7, :state :climax, :altitude 14, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} + {:x 21, :y 7, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 7, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 7, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 7, :state :climax, :altitude 19, :gradient 34, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 92} + {:x 26, :y 7, :state :forest, :altitude 22, :gradient 34, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 29} + {:x 27, :y 7, :state :house, :altitude 12, :gradient 34, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 11} + {:x 28, :y 7, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 7, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 7, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 7, :state :camp, :altitude 15, :gradient 34, :generation 101, :rule "if state is camp and some neighbours are ploughland then state should be camp", :fertility 37} + {:x 36, :y 7, :state :grassland, :altitude 35, :gradient 41, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} + {:x 37, :y 7, :state :crop, :altitude 43, :gradient 9, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 61} + {:x 38, :y 7, :state :house, :altitude 37, :gradient 20, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 34} + {:x 39, :y 7, :state :grassland, :altitude 27, :gradient 35, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 46} + {:x 40, :y 7, :state :house, :altitude 12, :gradient 26, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 30} + {:x 41, :y 7, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 7, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 8, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 8, :state :climax, :altitude 14, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} + {:x 18, :y 8, :state :crop, :altitude 31, :gradient 28, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 15} + {:x 19, :y 8, :state :climax, :altitude 28, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} + {:x 20, :y 8, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 8, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 8, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 8, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 8, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 8, :state :climax, :altitude 24, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} + {:x 26, :y 8, :state :scrub, :altitude 35, :gradient 29, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 6} + {:x 27, :y 8, :state :pasture, :altitude 35, :gradient 40, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} + {:x 28, :y 8, :state :house, :altitude 22, :gradient 34, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 11} + {:x 29, :y 8, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 8, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 8, :state :water, :altitude 2, :gradient 34, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 8, :state :house, :altitude 28, :gradient 42, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 65} + {:x 37, :y 8, :state :crop, :altitude 37, :gradient 28, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 42} + {:x 38, :y 8, :state :house, :altitude 36, :gradient 31, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 27} + {:x 39, :y 8, :state :pasture, :altitude 23, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 33} + {:x 40, :y 8, :state :water, :altitude 2, :gradient 26, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 8, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 8, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 9, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 9, :state :house, :altitude 12, :gradient 30, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} + {:x 18, :y 9, :state :climax, :altitude 29, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} + {:x 19, :y 9, :state :climax, :altitude 28, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} + {:x 20, :y 9, :state :pasture, :altitude 18, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 47} + {:x 21, :y 9, :state :pasture, :altitude 17, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 23} + {:x 22, :y 9, :state :house, :altitude 23, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 20} + {:x 23, :y 9, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 9, :state :house, :altitude 14, :gradient 35, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} + {:x 25, :y 9, :state :pasture, :altitude 31, :gradient 40, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} + {:x 26, :y 9, :state :scrub, :altitude 41, :gradient 13, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 20} + {:x 27, :y 9, :state :forest, :altitude 35, :gradient 39, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 25} + {:x 28, :y 9, :state :house, :altitude 20, :gradient 34, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 8} + {:x 29, :y 9, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 9, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 9, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 9, :state :crop, :altitude 15, :gradient 36, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 25} + {:x 37, :y 9, :state :forest, :altitude 26, :gradient 25, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 68} + {:x 38, :y 9, :state :crop, :altitude 23, :gradient 36, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 37} + {:x 39, :y 9, :state :house, :altitude 12, :gradient 35, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 38} + {:x 40, :y 9, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 9, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 9, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 10, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 10, :state :water, :altitude 1, :gradient 28, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 10, :state :house, :altitude 23, :gradient 35, :generation 101, :rule "if state is house and some neighbours are crop then state should be house", :fertility 24} + {:x 19, :y 10, :state :grassland, :altitude 28, :gradient 18, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 35} + {:x 20, :y 10, :state :climax, :altitude 28, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} + {:x 21, :y 10, :state :climax, :altitude 28, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} + {:x 22, :y 10, :state :ploughland, :altitude 23, :gradient 27, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 22} + {:x 23, :y 10, :state :harbour, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 10, :state :pasture, :altitude 23, :gradient 35, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 40} + {:x 25, :y 10, :state :pasture, :altitude 36, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} + {:x 26, :y 10, :state :pasture, :altitude 37, :gradient 28, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} + {:x 27, :y 10, :state :climax, :altitude 26, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} + {:x 28, :y 10, :state :water, :altitude 2, :gradient 34, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 10, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 10, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 10, :state :pasture, :altitude 18, :gradient 26, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 29} + {:x 37, :y 10, :state :pasture, :altitude 27, :gradient 25, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 37} + {:x 38, :y 10, :state :scrub, :altitude 12, :gradient 26, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 79} + {:x 39, :y 10, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 10, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 10, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 11, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 11, :state :grassland, :altitude 20, :gradient 35, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 12} + {:x 19, :y 11, :state :grassland, :altitude 36, :gradient 22, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 51} + {:x 20, :y 11, :state :forest, :altitude 32, :gradient 10, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 48} + {:x 21, :y 11, :state :scrub, :altitude 27, :gradient 22, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 86} + {:x 22, :y 11, :state :forest, :altitude 19, :gradient 30, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 58} + {:x 23, :y 11, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 11, :state :house, :altitude 14, :gradient 35, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 65} + {:x 25, :y 11, :state :forest, :altitude 22, :gradient 36, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 39} + {:x 26, :y 11, :state :pasture, :altitude 20, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} + {:x 27, :y 11, :state :house, :altitude 13, :gradient 36, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 25} + {:x 28, :y 11, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 11, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 11, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 11, :state :house, :altitude 15, :gradient 26, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 28} + {:x 37, :y 11, :state :house, :altitude 18, :gradient 26, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 10} + {:x 38, :y 11, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 11, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 11, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 12, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 12, :state :crop, :altitude 15, :gradient 35, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 55} + {:x 19, :y 12, :state :house, :altitude 32, :gradient 22, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 50} + {:x 20, :y 12, :state :grassland, :altitude 37, :gradient 12, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 54} + {:x 21, :y 12, :state :inn, :altitude 31, :gradient 22, :generation 101, :rule "if state is in camp or abandoned and some neighbours are crop then state should be house", :fertility 30} + {:x 22, :y 12, :state :market, :altitude 15, :gradient 30, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 24} + {:x 23, :y 12, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 12, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 12, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 12, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 12, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 12, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 12, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 12, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 12, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 12, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 12, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 13, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 13, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 13, :state :climax, :altitude 22, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} + {:x 19, :y 13, :state :climax, :altitude 27, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} + {:x 20, :y 13, :state :grassland, :altitude 27, :gradient 24, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} + {:x 21, :y 13, :state :house, :altitude 24, :gradient 24, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 13} + {:x 22, :y 13, :state :house, :altitude 23, :gradient 30, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 30} + {:x 23, :y 13, :state :house, :altitude 22, :gradient 28, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} + {:x 24, :y 13, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 13, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 13, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 13, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 13, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 13, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 13, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 14, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 14, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 14, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 14, :state :forest, :altitude 15, :gradient 30, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 47} + {:x 18, :y 14, :state :climax, :altitude 27, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} + {:x 19, :y 14, :state :climax, :altitude 26, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} + {:x 20, :y 14, :state :crop, :altitude 17, :gradient 18, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 45} + {:x 21, :y 14, :state :crop, :altitude 13, :gradient 20, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 19} + {:x 22, :y 14, :state :ploughland, :altitude 29, :gradient 23, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 23} + {:x 23, :y 14, :state :house, :altitude 18, :gradient 28, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 49} + {:x 24, :y 14, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 14, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 14, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 14, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 14, :state :house, :altitude 14, :gradient 39, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 44} + {:x 33, :y 14, :state :climax, :altitude 22, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 76} + {:x 34, :y 14, :state :climax, :altitude 13, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} + {:x 35, :y 14, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 14, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 15, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 15, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 15, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 15, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 15, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 15, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 15, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 15, :state :climax, :altitude 13, :gradient 40, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 37} + {:x 16, :y 15, :state :climax, :altitude 19, :gradient 44, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 39} + {:x 17, :y 15, :state :climax, :altitude 31, :gradient 46, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} + {:x 18, :y 15, :state :climax, :altitude 29, :gradient 32, :generation 101, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 43} + {:x 19, :y 15, :state :scrub, :altitude 26, :gradient 33, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 57} + {:x 20, :y 15, :state :pasture, :altitude 14, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 27} + {:x 21, :y 15, :state :water, :altitude 9, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 15, :state :grassland, :altitude 13, :gradient 28, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 27} + {:x 23, :y 15, :state :water, :altitude 1, :gradient 28, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 15, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 15, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 15, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 15, :state :scrub, :altitude 14, :gradient 31, :generation 101, :rule "if state is camp then 1 chance in 5 state should be waste", :fertility 72} + {:x 31, :y 15, :state :grassland, :altitude 19, :gradient 32, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 54} + {:x 32, :y 15, :state :climax, :altitude 31, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} + {:x 33, :y 15, :state :ploughland, :altitude 40, :gradient 20, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 42} + {:x 34, :y 15, :state :climax, :altitude 23, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 76} + {:x 35, :y 15, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 15, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 16, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 16, :state :house, :altitude 18, :gradient 30, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 40} + {:x 10, :y 16, :state :crop, :altitude 19, :gradient 35, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 33} + {:x 11, :y 16, :state :climax, :altitude 20, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 38} + {:x 12, :y 16, :state :climax, :altitude 18, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} + {:x 13, :y 16, :state :scrub, :altitude 17, :gradient 34, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 74} + {:x 14, :y 16, :state :scrub, :altitude 19, :gradient 51, :generation 101, :rule "if state is fire then state should be waste", :fertility 75} + {:x 15, :y 16, :state :scrub, :altitude 35, :gradient 55, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 62} + {:x 16, :y 16, :state :climax, :altitude 41, :gradient 43, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 41} + {:x 17, :y 16, :state :climax, :altitude 45, :gradient 42, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 52} + {:x 18, :y 16, :state :climax, :altitude 47, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 51} + {:x 19, :y 16, :state :forest, :altitude 45, :gradient 47, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 65} + {:x 20, :y 16, :state :climax, :altitude 35, :gradient 45, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 28} + {:x 21, :y 16, :state :pasture, :altitude 19, :gradient 33, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 52} + {:x 22, :y 16, :state :climax, :altitude 15, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} + {:x 23, :y 16, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 16, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 16, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 16, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 16, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 16, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 16, :state :ploughland, :altitude 18, :gradient 31, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 85} + {:x 30, :y 16, :state :ploughland, :altitude 32, :gradient 31, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 52} + {:x 31, :y 16, :state :climax, :altitude 32, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} + {:x 32, :y 16, :state :climax, :altitude 33, :gradient 21, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} + {:x 33, :y 16, :state :climax, :altitude 32, :gradient 25, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} + {:x 34, :y 16, :state :climax, :altitude 28, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} + {:x 35, :y 16, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 16, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 17, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 17, :state :crop, :altitude 26, :gradient 30, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 40} + {:x 10, :y 17, :state :pasture, :altitude 31, :gradient 23, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 25} + {:x 11, :y 17, :state :climax, :altitude 36, :gradient 17, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} + {:x 12, :y 17, :state :heath, :altitude 35, :gradient 19, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 69} + {:x 13, :y 17, :state :heath, :altitude 29, :gradient 18, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 54} + {:x 14, :y 17, :state :scrub, :altitude 32, :gradient 35, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 63} + {:x 15, :y 17, :state :scrub, :altitude 52, :gradient 37, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 51} + {:x 16, :y 17, :state :climax, :altitude 56, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 27} + {:x 17, :y 17, :state :climax, :altitude 55, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} + {:x 18, :y 17, :state :climax, :altitude 61, :gradient 12, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} + {:x 19, :y 17, :state :climax, :altitude 54, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} + {:x 20, :y 17, :state :scrub, :altitude 42, :gradient 35, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} + {:x 21, :y 17, :state :scrub, :altitude 31, :gradient 27, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 29} + {:x 22, :y 17, :state :climax, :altitude 27, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} + {:x 23, :y 17, :state :climax, :altitude 22, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 61} + {:x 24, :y 17, :state :climax, :altitude 17, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} + {:x 25, :y 17, :state :climax, :altitude 12, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} + {:x 26, :y 17, :state :climax, :altitude 12, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 45} + {:x 27, :y 17, :state :scrub, :altitude 12, :gradient 26, :generation 101, :rule "if state is fire then state should be waste", :fertility 57} + {:x 28, :y 17, :state :heath, :altitude 13, :gradient 26, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 65} + {:x 29, :y 17, :state :pasture, :altitude 23, :gradient 31, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 55} + {:x 30, :y 17, :state :grassland, :altitude 31, :gradient 17, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 69} + {:x 31, :y 17, :state :crop, :altitude 32, :gradient 16, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 48} + {:x 32, :y 17, :state :crop, :altitude 29, :gradient 15, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 49} + {:x 33, :y 17, :state :climax, :altitude 26, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} + {:x 34, :y 17, :state :camp, :altitude 15, :gradient 31, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 46} + {:x 35, :y 17, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 17, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 18, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 18, :state :house, :altitude 13, :gradient 30, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 31} + {:x 10, :y 18, :state :crop, :altitude 19, :gradient 35, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 29} + {:x 11, :y 18, :state :scrub, :altitude 27, :gradient 35, :generation 101, :rule "if state is fire then state should be waste", :fertility 64} + {:x 12, :y 18, :state :heath, :altitude 31, :gradient 14, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 67} + {:x 13, :y 18, :state :scrub, :altitude 31, :gradient 8, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 37} + {:x 14, :y 18, :state :scrub, :altitude 31, :gradient 24, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 55} + {:x 15, :y 18, :state :climax, :altitude 41, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 39} + {:x 16, :y 18, :state :scrub, :altitude 49, :gradient 27, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} + {:x 17, :y 18, :state :climax, :altitude 43, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} + {:x 18, :y 18, :state :climax, :altitude 47, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} + {:x 19, :y 18, :state :climax, :altitude 47, :gradient 25, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 45} + {:x 20, :y 18, :state :forest, :altitude 40, :gradient 26, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 63} + {:x 21, :y 18, :state :climax, :altitude 28, :gradient 16, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 32} + {:x 22, :y 18, :state :climax, :altitude 27, :gradient 9, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} + {:x 23, :y 18, :state :climax, :altitude 27, :gradient 10, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} + {:x 24, :y 18, :state :climax, :altitude 27, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 75} + {:x 25, :y 18, :state :climax, :altitude 22, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 24} + {:x 26, :y 18, :state :climax, :altitude 23, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 48} + {:x 27, :y 18, :state :climax, :altitude 23, :gradient 17, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} + {:x 28, :y 18, :state :climax, :altitude 27, :gradient 17, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 43} + {:x 29, :y 18, :state :pasture, :altitude 15, :gradient 19, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 43} + {:x 30, :y 18, :state :scrub, :altitude 17, :gradient 20, :generation 101, :rule "if state is fire then state should be waste", :fertility 61} + {:x 31, :y 18, :state :house, :altitude 18, :gradient 20, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 52} + {:x 32, :y 18, :state :house, :altitude 27, :gradient 19, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 43} + {:x 33, :y 18, :state :climax, :altitude 31, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 74} + {:x 34, :y 18, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 18, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 18, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 19, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 19, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 19, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 19, :state :scrub, :altitude 22, :gradient 31, :generation 101, :rule "if state is fire then state should be waste", :fertility 28} + {:x 12, :y 19, :state :scrub, :altitude 27, :gradient 14, :generation 101, :rule "if state is fire then state should be waste", :fertility 85} + {:x 13, :y 19, :state :climax, :altitude 31, :gradient 9, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 70} + {:x 14, :y 19, :state :scrub, :altitude 28, :gradient 12, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} + {:x 15, :y 19, :state :forest, :altitude 29, :gradient 24, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 47} + {:x 16, :y 19, :state :scrub, :altitude 37, :gradient 27, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 26} + {:x 17, :y 19, :state :scrub, :altitude 41, :gradient 19, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 30} + {:x 18, :y 19, :state :climax, :altitude 37, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} + {:x 19, :y 19, :state :heath, :altitude 38, :gradient 11, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 40} + {:x 20, :y 19, :state :scrub, :altitude 36, :gradient 19, :generation 101, :rule "if state is fire then state should be waste", :fertility 51} + {:x 21, :y 19, :state :climax, :altitude 28, :gradient 20, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 46} + {:x 22, :y 19, :state :climax, :altitude 26, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 56} + {:x 23, :y 19, :state :climax, :altitude 26, :gradient 3, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} + {:x 24, :y 19, :state :climax, :altitude 27, :gradient 6, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 41} + {:x 25, :y 19, :state :climax, :altitude 27, :gradient 11, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 32} + {:x 26, :y 19, :state :forest, :altitude 22, :gradient 11, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 41} + {:x 27, :y 19, :state :climax, :altitude 24, :gradient 19, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 40} + {:x 28, :y 19, :state :climax, :altitude 29, :gradient 21, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} + {:x 29, :y 19, :state :heath, :altitude 22, :gradient 24, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 61} + {:x 30, :y 19, :state :scrub, :altitude 12, :gradient 22, :generation 101, :rule "if state is fire then state should be waste", :fertility 45} + {:x 31, :y 19, :state :crop, :altitude 13, :gradient 21, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 52} + {:x 32, :y 19, :state :grassland, :altitude 15, :gradient 32, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 38} + {:x 33, :y 19, :state :house, :altitude 17, :gradient 30, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 47} + {:x 34, :y 19, :state :water, :altitude 1, :gradient 30, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 19, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 20, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 20, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 20, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 20, :state :climax, :altitude 23, :gradient 44, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} + {:x 12, :y 20, :state :heath, :altitude 32, :gradient 37, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 63} + {:x 13, :y 20, :state :climax, :altitude 36, :gradient 32, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 44} + {:x 14, :y 20, :state :heath, :altitude 35, :gradient 31, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 47} + {:x 15, :y 20, :state :scrub, :altitude 37, :gradient 36, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 65} + {:x 16, :y 20, :state :scrub, :altitude 52, :gradient 36, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 75} + {:x 17, :y 20, :state :scrub, :altitude 56, :gradient 28, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 60} + {:x 18, :y 20, :state :scrub, :altitude 43, :gradient 29, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 40} + {:x 19, :y 20, :state :scrub, :altitude 36, :gradient 14, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} + {:x 20, :y 20, :state :climax, :altitude 46, :gradient 13, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} + {:x 21, :y 20, :state :climax, :altitude 41, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} + {:x 22, :y 20, :state :climax, :altitude 29, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} + {:x 23, :y 20, :state :scrub, :altitude 26, :gradient 3, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 45} + {:x 24, :y 20, :state :climax, :altitude 28, :gradient 3, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 55} + {:x 25, :y 20, :state :climax, :altitude 28, :gradient 18, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 56} + {:x 26, :y 20, :state :climax, :altitude 17, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} + {:x 27, :y 20, :state :climax, :altitude 20, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 48} + {:x 28, :y 20, :state :scrub, :altitude 36, :gradient 15, :generation 101, :rule "if state is fire then state should be waste", :fertility 38} + {:x 29, :y 20, :state :scrub, :altitude 35, :gradient 24, :generation 101, :rule "if state is fire then state should be waste", :fertility 49} + {:x 30, :y 20, :state :climax, :altitude 28, :gradient 23, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 86} + {:x 31, :y 20, :state :climax, :altitude 33, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} + {:x 32, :y 20, :state :climax, :altitude 15, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} + {:x 33, :y 20, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 20, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 20, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 21, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 21, :state :climax, :altitude 12, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} + {:x 10, :y 21, :state :forest, :altitude 12, :gradient 26, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 60} + {:x 11, :y 21, :state :scrub, :altitude 24, :gradient 44, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} + {:x 12, :y 21, :state :climax, :altitude 45, :gradient 36, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 40} + {:x 13, :y 21, :state :forest, :altitude 59, :gradient 27, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 64} + {:x 14, :y 21, :state :climax, :altitude 50, :gradient 24, :generation 101, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 55} + {:x 15, :y 21, :state :scrub, :altitude 49, :gradient 38, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 76} + {:x 16, :y 21, :state :climax, :altitude 64, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 57} + {:x 17, :y 21, :state :scrub, :altitude 65, :gradient 34, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} + {:x 18, :y 21, :state :climax, :altitude 50, :gradient 41, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 47} + {:x 19, :y 21, :state :heath, :altitude 38, :gradient 19, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 49} + {:x 20, :y 21, :state :climax, :altitude 38, :gradient 10, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 64} + {:x 21, :y 21, :state :scrub, :altitude 38, :gradient 17, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 52} + {:x 22, :y 21, :state :climax, :altitude 29, :gradient 15, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} + {:x 23, :y 21, :state :climax, :altitude 27, :gradient 5, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 56} + {:x 24, :y 21, :state :climax, :altitude 28, :gradient 7, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 38} + {:x 25, :y 21, :state :climax, :altitude 29, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 30} + {:x 26, :y 21, :state :climax, :altitude 35, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 36} + {:x 27, :y 21, :state :climax, :altitude 28, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} + {:x 28, :y 21, :state :climax, :altitude 28, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 70} + {:x 29, :y 21, :state :climax, :altitude 27, :gradient 35, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 70} + {:x 30, :y 21, :state :climax, :altitude 23, :gradient 34, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 44} + {:x 31, :y 21, :state :camp, :altitude 22, :gradient 32, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 47} + {:x 32, :y 21, :state :water, :altitude 2, :gradient 32, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 21, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 21, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 22, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 22, :state :pasture, :altitude 23, :gradient 26, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 48} + {:x 10, :y 22, :state :scrub, :altitude 27, :gradient 15, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 71} + {:x 11, :y 22, :state :scrub, :altitude 27, :gradient 33, :generation 101, :rule "if state is fire then state should be waste", :fertility 40} + {:x 12, :y 22, :state :heath, :altitude 40, :gradient 35, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 70} + {:x 13, :y 22, :state :scrub, :altitude 59, :gradient 32, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 37} + {:x 14, :y 22, :state :climax, :altitude 54, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 33} + {:x 15, :y 22, :state :scrub, :altitude 54, :gradient 35, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 70} + {:x 16, :y 22, :state :climax, :altitude 73, :gradient 34, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 75} + {:x 17, :y 22, :state :forest, :altitude 77, :gradient 23, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 45} + {:x 18, :y 22, :state :climax, :altitude 55, :gradient 39, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} + {:x 19, :y 22, :state :climax, :altitude 42, :gradient 17, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} + {:x 20, :y 22, :state :scrub, :altitude 40, :gradient 15, :generation 101, :rule "if state is fire then state should be waste", :fertility 51} + {:x 21, :y 22, :state :climax, :altitude 36, :gradient 22, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 31} + {:x 22, :y 22, :state :climax, :altitude 31, :gradient 14, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 76} + {:x 23, :y 22, :state :climax, :altitude 29, :gradient 9, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 49} + {:x 24, :y 22, :state :climax, :altitude 28, :gradient 7, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} + {:x 25, :y 22, :state :climax, :altitude 33, :gradient 10, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} + {:x 26, :y 22, :state :pasture, :altitude 36, :gradient 8, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 11} + {:x 27, :y 22, :state :pasture, :altitude 28, :gradient 22, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 23} + {:x 28, :y 22, :state :climax, :altitude 14, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 78} + {:x 29, :y 22, :state :harbour, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 22, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 22, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 22, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 22, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 22, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 23, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 23, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 23, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 23, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 23, :state :pasture, :altitude 15, :gradient 26, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 34} + {:x 10, :y 23, :state :scrub, :altitude 27, :gradient 25, :generation 101, :rule "if state is fire then state should be waste", :fertility 52} + {:x 11, :y 23, :state :heath, :altitude 27, :gradient 18, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 74} + {:x 12, :y 23, :state :scrub, :altitude 27, :gradient 32, :generation 101, :rule "if state is fire then state should be waste", :fertility 47} + {:x 13, :y 23, :state :scrub, :altitude 32, :gradient 32, :generation 101, :rule "if state is fire then state should be waste", :fertility 56} + {:x 14, :y 23, :state :scrub, :altitude 38, :gradient 27, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} + {:x 15, :y 23, :state :scrub, :altitude 43, :gradient 35, :generation 101, :rule "if state is fire then state should be waste", :fertility 67} + {:x 16, :y 23, :state :climax, :altitude 57, :gradient 36, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} + {:x 17, :y 23, :state :climax, :altitude 69, :gradient 25, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 38} + {:x 18, :y 23, :state :scrub, :altitude 54, :gradient 37, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 60} + {:x 19, :y 23, :state :climax, :altitude 50, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} + {:x 20, :y 23, :state :scrub, :altitude 51, :gradient 15, :generation 101, :rule "if state is fire then state should be waste", :fertility 52} + {:x 21, :y 23, :state :heath, :altitude 41, :gradient 22, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 64} + {:x 22, :y 23, :state :scrub, :altitude 35, :gradient 13, :generation 101, :rule "if state is fire then state should be waste", :fertility 68} + {:x 23, :y 23, :state :climax, :altitude 31, :gradient 16, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 38} + {:x 24, :y 23, :state :climax, :altitude 26, :gradient 19, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} + {:x 25, :y 23, :state :climax, :altitude 29, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 51} + {:x 26, :y 23, :state :pasture, :altitude 29, :gradient 22, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 29} + {:x 27, :y 23, :state :climax, :altitude 27, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} + {:x 28, :y 23, :state :climax, :altitude 26, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} + {:x 29, :y 23, :state :camp, :altitude 12, :gradient 25, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 24} + {:x 30, :y 23, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 23, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 24, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 24, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 24, :state :water, :altitude 2, :gradient 28, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 24, :state :house, :altitude 14, :gradient 28, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 32} + {:x 8, :y 24, :state :climax, :altitude 14, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} + {:x 9, :y 24, :state :grassland, :altitude 12, :gradient 28, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 29} + {:x 10, :y 24, :state :climax, :altitude 22, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} + {:x 11, :y 24, :state :climax, :altitude 37, :gradient 37, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} + {:x 12, :y 24, :state :climax, :altitude 37, :gradient 34, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 31} + {:x 13, :y 24, :state :climax, :altitude 36, :gradient 34, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 51} + {:x 14, :y 24, :state :scrub, :altitude 41, :gradient 45, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 40} + {:x 15, :y 24, :state :heath, :altitude 54, :gradient 56, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 46} + {:x 16, :y 24, :state :climax, :altitude 64, :gradient 51, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} + {:x 17, :y 24, :state :forest, :altitude 79, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} + {:x 18, :y 24, :state :climax, :altitude 69, :gradient 43, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} + {:x 19, :y 24, :state :forest, :altitude 51, :gradient 37, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 58} + {:x 20, :y 24, :state :climax, :altitude 43, :gradient 20, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 43} + {:x 21, :y 24, :state :forest, :altitude 37, :gradient 24, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 30} + {:x 22, :y 24, :state :scrub, :altitude 29, :gradient 24, :generation 101, :rule "if state is fire then state should be waste", :fertility 67} + {:x 23, :y 24, :state :climax, :altitude 28, :gradient 33, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} + {:x 24, :y 24, :state :climax, :altitude 19, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} + {:x 25, :y 24, :state :climax, :altitude 14, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} + {:x 26, :y 24, :state :climax, :altitude 22, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} + {:x 27, :y 24, :state :climax, :altitude 20, :gradient 28, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} + {:x 28, :y 24, :state :house, :altitude 20, :gradient 26, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 43} + {:x 29, :y 24, :state :water, :altitude 2, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 24, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 24, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 25, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 25, :state :house, :altitude 12, :gradient 44, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 16} + {:x 6, :y 25, :state :climax, :altitude 24, :gradient 51, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} + {:x 7, :y 25, :state :crop, :altitude 29, :gradient 50, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 27} + {:x 8, :y 25, :state :house, :altitude 29, :gradient 40, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 20} + {:x 9, :y 25, :state :grassland, :altitude 26, :gradient 34, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 48} + {:x 10, :y 25, :state :climax, :altitude 26, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} + {:x 11, :y 25, :state :climax, :altitude 41, :gradient 37, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 55} + {:x 12, :y 25, :state :climax, :altitude 59, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} + {:x 13, :y 25, :state :scrub, :altitude 61, :gradient 27, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} + {:x 14, :y 25, :state :scrub, :altitude 59, :gradient 41, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 73} + {:x 15, :y 25, :state :forest, :altitude 77, :gradient 55, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 48} + {:x 16, :y 25, :state :forest, :altitude 94, :gradient 42, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} + {:x 17, :y 25, :state :scrub, :altitude 93, :gradient 35, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} + {:x 18, :y 25, :state :forest, :altitude 79, :gradient 52, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} + {:x 19, :y 25, :state :scrub, :altitude 55, :gradient 48, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 42} + {:x 20, :y 25, :state :climax, :altitude 42, :gradient 27, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 49} + {:x 21, :y 25, :state :scrub, :altitude 35, :gradient 19, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} + {:x 22, :y 25, :state :climax, :altitude 27, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} + {:x 23, :y 25, :state :climax, :altitude 17, :gradient 28, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 72} + {:x 24, :y 25, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 25, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 25, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 25, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 25, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 25, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 25, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 25, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 26, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 26, :state :climax, :altitude 20, :gradient 51, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} + {:x 6, :y 26, :state :crop, :altitude 45, :gradient 65, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 22} + {:x 7, :y 26, :state :grassland, :altitude 52, :gradient 62, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 37} + {:x 8, :y 26, :state :grassland, :altitude 46, :gradient 60, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} + {:x 9, :y 26, :state :grassland, :altitude 31, :gradient 60, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 29} + {:x 10, :y 26, :state :pasture, :altitude 28, :gradient 37, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 60} + {:x 11, :y 26, :state :scrub, :altitude 37, :gradient 33, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 50} + {:x 12, :y 26, :state :scrub, :altitude 55, :gradient 30, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 25} + {:x 13, :y 26, :state :scrub, :altitude 63, :gradient 28, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 18} + {:x 14, :y 26, :state :climax, :altitude 60, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} + {:x 15, :y 26, :state :forest, :altitude 74, :gradient 49, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} + {:x 16, :y 26, :state :scrub, :altitude 96, :gradient 44, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} + {:x 17, :y 26, :state :forest, :altitude 77, :gradient 58, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 74} + {:x 18, :y 26, :state :pasture, :altitude 61, :gradient 65, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 56} + {:x 19, :y 26, :state :climax, :altitude 41, :gradient 52, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} + {:x 20, :y 26, :state :pasture, :altitude 31, :gradient 28, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 60} + {:x 21, :y 26, :state :scrub, :altitude 28, :gradient 22, :generation 101, :rule "if state is fire then state should be waste", :fertility 64} + {:x 22, :y 26, :state :pasture, :altitude 24, :gradient 34, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 74} + {:x 23, :y 26, :state :water, :altitude 2, :gradient 26, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 26, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 26, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 26, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 27, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 27, :state :water, :altitude 1, :gradient 35, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 27, :state :climax, :altitude 22, :gradient 51, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} + {:x 6, :y 27, :state :climax, :altitude 52, :gradient 57, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} + {:x 7, :y 27, :state :pasture, :altitude 77, :gradient 41, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 50} + {:x 8, :y 27, :state :heath, :altitude 86, :gradient 48, :generation 101, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 50} + {:x 9, :y 27, :state :climax, :altitude 63, :gradient 58, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} + {:x 10, :y 27, :state :pasture, :altitude 38, :gradient 50, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 48} + {:x 11, :y 27, :state :scrub, :altitude 33, :gradient 30, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 48} + {:x 12, :y 27, :state :scrub, :altitude 33, :gradient 37, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 75} + {:x 13, :y 27, :state :climax, :altitude 47, :gradient 37, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} + {:x 14, :y 27, :state :scrub, :altitude 47, :gradient 41, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 60} + {:x 15, :y 27, :state :pasture, :altitude 50, :gradient 63, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 64} + {:x 16, :y 27, :state :crop, :altitude 64, :gradient 63, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 32} + {:x 17, :y 27, :state :crop, :altitude 55, :gradient 58, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 58} + {:x 18, :y 27, :state :crop, :altitude 38, :gradient 49, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 31} + {:x 19, :y 27, :state :climax, :altitude 28, :gradient 34, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} + {:x 20, :y 27, :state :climax, :altitude 27, :gradient 15, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 75} + {:x 21, :y 27, :state :climax, :altitude 27, :gradient 16, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} + {:x 22, :y 27, :state :pasture, :altitude 20, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} + {:x 23, :y 27, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 27, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 27, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 28, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 28, :state :house, :altitude 14, :gradient 35, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 25} + {:x 5, :y 28, :state :crop, :altitude 36, :gradient 51, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 38} + {:x 6, :y 28, :state :climax, :altitude 52, :gradient 55, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 47} + {:x 7, :y 28, :state :forest, :altitude 70, :gradient 46, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} + {:x 8, :y 28, :state :scrub, :altitude 79, :gradient 46, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 59} + {:x 9, :y 28, :state :scrub, :altitude 78, :gradient 48, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 29} + {:x 10, :y 28, :state :climax, :altitude 56, :gradient 45, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 51} + {:x 11, :y 28, :state :scrub, :altitude 35, :gradient 30, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 52} + {:x 12, :y 28, :state :climax, :altitude 26, :gradient 23, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 57} + {:x 13, :y 28, :state :climax, :altitude 33, :gradient 23, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} + {:x 14, :y 28, :state :pasture, :altitude 37, :gradient 26, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 56} + {:x 15, :y 28, :state :pasture, :altitude 33, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 62} + {:x 16, :y 28, :state :crop, :altitude 40, :gradient 31, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 35} + {:x 17, :y 28, :state :house, :altitude 50, :gradient 26, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 43} + {:x 18, :y 28, :state :pasture, :altitude 42, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} + {:x 19, :y 28, :state :house, :altitude 37, :gradient 15, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 19} + {:x 20, :y 28, :state :ploughland, :altitude 33, :gradient 16, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 30} + {:x 21, :y 28, :state :pasture, :altitude 26, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 19} + {:x 22, :y 28, :state :house, :altitude 17, :gradient 26, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 14} + {:x 23, :y 28, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 28, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 29, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 29, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 29, :state :ploughland, :altitude 12, :gradient 35, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 31} + {:x 5, :y 29, :state :grassland, :altitude 32, :gradient 40, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 44} + {:x 6, :y 29, :state :heath, :altitude 41, :gradient 42, :generation 101, :rule "if state is waste and some neighbours are forest then state should be heath", :fertility 62} + {:x 7, :y 29, :state :scrub, :altitude 40, :gradient 51, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} + {:x 8, :y 29, :state :scrub, :altitude 50, :gradient 52, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} + {:x 9, :y 29, :state :scrub, :altitude 60, :gradient 52, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 62} + {:x 10, :y 29, :state :climax, :altitude 52, :gradient 51, :generation 101, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 67} + {:x 11, :y 29, :state :climax, :altitude 35, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} + {:x 12, :y 29, :state :scrub, :altitude 26, :gradient 22, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 59} + {:x 13, :y 29, :state :scrub, :altitude 24, :gradient 24, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 49} + {:x 14, :y 29, :state :pasture, :altitude 28, :gradient 24, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 67} + {:x 15, :y 29, :state :house, :altitude 33, :gradient 19, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 47} + {:x 16, :y 29, :state :ploughland, :altitude 43, :gradient 17, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 18} + {:x 17, :y 29, :state :house, :altitude 49, :gradient 21, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 21} + {:x 18, :y 29, :state :grassland, :altitude 41, :gradient 23, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 13} + {:x 19, :y 29, :state :inn, :altitude 38, :gradient 15, :generation 101, :rule "if state is house and some neighbours are market and more than 1 neighbours are house then 1 chance in 5 state should be inn", :fertility 34} + {:x 20, :y 29, :state :crop, :altitude 37, :gradient 36, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 25} + {:x 21, :y 29, :state :grassland, :altitude 22, :gradient 36, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 18} + {:x 22, :y 29, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 29, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 29, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 30, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 30, :state :house, :altitude 12, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 17} + {:x 4, :y 30, :state :ploughland, :altitude 28, :gradient 31, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 20} + {:x 5, :y 30, :state :climax, :altitude 31, :gradient 29, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} + {:x 6, :y 30, :state :climax, :altitude 28, :gradient 13, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 70} + {:x 7, :y 30, :state :scrub, :altitude 28, :gradient 23, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 52} + {:x 8, :y 30, :state :climax, :altitude 37, :gradient 34, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 83} + {:x 9, :y 30, :state :forest, :altitude 27, :gradient 42, :generation 101, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 64} + {:x 10, :y 30, :state :climax, :altitude 28, :gradient 47, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 28} + {:x 11, :y 30, :state :climax, :altitude 32, :gradient 42, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 47} + {:x 12, :y 30, :state :climax, :altitude 28, :gradient 26, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 58} + {:x 13, :y 30, :state :pasture, :altitude 13, :gradient 19, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 74} + {:x 14, :y 30, :state :pasture, :altitude 24, :gradient 24, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 44} + {:x 15, :y 30, :state :scrub, :altitude 33, :gradient 30, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 66} + {:x 16, :y 30, :state :house, :altitude 35, :gradient 36, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 32} + {:x 17, :y 30, :state :pasture, :altitude 36, :gradient 36, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} + {:x 18, :y 30, :state :house, :altitude 29, :gradient 47, :generation 101, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 28} + {:x 19, :y 30, :state :market, :altitude 27, :gradient 40, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 12} + {:x 20, :y 30, :state :house, :altitude 27, :gradient 37, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} + {:x 21, :y 30, :state :water, :altitude 2, :gradient 36, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 30, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 30, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 31, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 31, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 31, :state :harbour, :altitude 1, :gradient 35, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 31, :state :ploughland, :altitude 24, :gradient 44, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 35} + {:x 5, :y 31, :state :climax, :altitude 29, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} + {:x 6, :y 31, :state :climax, :altitude 31, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 75} + {:x 7, :y 31, :state :heath, :altitude 28, :gradient 23, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 45} + {:x 8, :y 31, :state :scrub, :altitude 27, :gradient 19, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 68} + {:x 9, :y 31, :state :scrub, :altitude 26, :gradient 19, :generation 101, :rule "if state is fire then state should be waste", :fertility 68} + {:x 10, :y 31, :state :scrub, :altitude 18, :gradient 19, :generation 101, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 45} + {:x 11, :y 31, :state :heath, :altitude 13, :gradient 22, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 48} + {:x 12, :y 31, :state :scrub, :altitude 10, :gradient 23, :generation 101, :rule "if state is fire then state should be waste", :fertility 66} + {:x 13, :y 31, :state :water, :altitude 9, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 31, :state :pasture, :altitude 23, :gradient 32, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 59} + {:x 15, :y 31, :state :pasture, :altitude 17, :gradient 34, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 52} + {:x 16, :y 31, :state :scrub, :altitude 13, :gradient 35, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 59} + {:x 17, :y 31, :state :ploughland, :altitude 14, :gradient 35, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 21} + {:x 18, :y 31, :state :house, :altitude 14, :gradient 35, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} + {:x 19, :y 31, :state :water, :altitude 2, :gradient 28, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 31, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 31, :state :water, :altitude 1, :gradient 26, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 31, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 31, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 32, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 32, :state :camp, :altitude 17, :gradient 31, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 56} + {:x 3, :y 32, :state :climax, :altitude 22, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 92} + {:x 4, :y 32, :state :climax, :altitude 36, :gradient 44, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 70} + {:x 5, :y 32, :state :climax, :altitude 45, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 25} + {:x 6, :y 32, :state :climax, :altitude 50, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} + {:x 7, :y 32, :state :heath, :altitude 45, :gradient 29, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 44} + {:x 8, :y 32, :state :heath, :altitude 35, :gradient 30, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 46} + {:x 9, :y 32, :state :scrub, :altitude 32, :gradient 38, :generation 101, :rule "if state is fire then state should be waste", :fertility 27} + {:x 10, :y 32, :state :climax, :altitude 24, :gradient 25, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} + {:x 11, :y 32, :state :climax, :altitude 19, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} + {:x 12, :y 32, :state :scrub, :altitude 20, :gradient 23, :generation 101, :rule "if state is fire then state should be waste", :fertility 77} + {:x 13, :y 32, :state :climax, :altitude 20, :gradient 23, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 36} + {:x 14, :y 32, :state :pasture, :altitude 14, :gradient 30, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 49} + {:x 15, :y 32, :state :harbour, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 32, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 32, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 32, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 32, :state :water, :altitude 1, :gradient 13, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 32, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 32, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 33, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 33, :state :climax, :altitude 26, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} + {:x 3, :y 33, :state :climax, :altitude 32, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} + {:x 4, :y 33, :state :climax, :altitude 33, :gradient 33, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} + {:x 5, :y 33, :state :climax, :altitude 41, :gradient 35, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 63} + {:x 6, :y 33, :state :scrub, :altitude 46, :gradient 38, :generation 101, :rule "if state is fire then state should be waste", :fertility 73} + {:x 7, :y 33, :state :climax, :altitude 55, :gradient 38, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} + {:x 8, :y 33, :state :scrub, :altitude 56, :gradient 32, :generation 101, :rule "if state is fire then state should be waste", :fertility 48} + {:x 9, :y 33, :state :climax, :altitude 38, :gradient 44, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 55} + {:x 10, :y 33, :state :climax, :altitude 27, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} + {:x 11, :y 33, :state :climax, :altitude 31, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 78} + {:x 12, :y 33, :state :climax, :altitude 32, :gradient 17, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 47} + {:x 13, :y 33, :state :climax, :altitude 31, :gradient 18, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} + {:x 14, :y 33, :state :pasture, :altitude 26, :gradient 30, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 32} + {:x 15, :y 33, :state :pasture, :altitude 12, :gradient 25, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 24} + {:x 16, :y 33, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 33, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 33, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 34, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 34, :state :climax, :altitude 12, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 90} + {:x 3, :y 34, :state :climax, :altitude 12, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 45} + {:x 4, :y 34, :state :climax, :altitude 15, :gradient 40, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} + {:x 5, :y 34, :state :climax, :altitude 17, :gradient 45, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} + {:x 6, :y 34, :state :climax, :altitude 18, :gradient 38, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 78} + {:x 7, :y 34, :state :climax, :altitude 29, :gradient 38, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 66} + {:x 8, :y 34, :state :climax, :altitude 36, :gradient 33, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} + {:x 9, :y 34, :state :climax, :altitude 23, :gradient 44, :generation 101, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 61} + {:x 10, :y 34, :state :climax, :altitude 12, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} + {:x 11, :y 34, :state :climax, :altitude 14, :gradient 20, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} + {:x 12, :y 34, :state :climax, :altitude 17, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 57} + {:x 13, :y 34, :state :climax, :altitude 18, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} + {:x 14, :y 34, :state :climax, :altitude 18, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} + {:x 15, :y 34, :state :climax, :altitude 23, :gradient 25, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 52} + {:x 16, :y 34, :state :house, :altitude 18, :gradient 22, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} + {:x 17, :y 34, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 34, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 34, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 34, :state :water, :altitude 1, :gradient 31, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 34, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 34, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 35, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 35, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 35, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 35, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 35, :state :ploughland, :altitude 22, :gradient 36, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 49} + {:x 6, :y 35, :state :ploughland, :altitude 24, :gradient 20, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 40} + {:x 7, :y 35, :state :pasture, :altitude 26, :gradient 19, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 49} + {:x 8, :y 35, :state :climax, :altitude 26, :gradient 13, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} + {:x 9, :y 35, :state :climax, :altitude 27, :gradient 24, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} + {:x 10, :y 35, :state :climax, :altitude 24, :gradient 21, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 50} + {:x 11, :y 35, :state :climax, :altitude 27, :gradient 21, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 39} + {:x 12, :y 35, :state :climax, :altitude 22, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} + {:x 13, :y 35, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 35, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 35, :state :climax, :altitude 13, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} + {:x 16, :y 35, :state :climax, :altitude 12, :gradient 22, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} + {:x 17, :y 35, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 35, :state :climax, :altitude 17, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} + {:x 19, :y 35, :state :climax, :altitude 32, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} + {:x 20, :y 35, :state :climax, :altitude 26, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} + {:x 21, :y 35, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 35, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 36, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 36, :state :house, :altitude 24, :gradient 36, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 42} + {:x 6, :y 36, :state :scrub, :altitude 37, :gradient 22, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 39} + {:x 7, :y 36, :state :crop, :altitude 32, :gradient 13, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 35} + {:x 8, :y 36, :state :grassland, :altitude 27, :gradient 9, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} + {:x 9, :y 36, :state :climax, :altitude 32, :gradient 7, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} + {:x 10, :y 36, :state :climax, :altitude 31, :gradient 10, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 66} + {:x 11, :y 36, :state :climax, :altitude 33, :gradient 13, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} + {:x 12, :y 36, :state :climax, :altitude 26, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} + {:x 13, :y 36, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 36, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 36, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 36, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 36, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 36, :state :climax, :altitude 19, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} + {:x 19, :y 36, :state :climax, :altitude 49, :gradient 18, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} + {:x 20, :y 36, :state :climax, :altitude 35, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} + {:x 21, :y 36, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 36, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 37, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 37, :state :house, :altitude 13, :gradient 36, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 34} + {:x 6, :y 37, :state :crop, :altitude 35, :gradient 35, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 20} + {:x 7, :y 37, :state :house, :altitude 35, :gradient 19, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 49} + {:x 8, :y 37, :state :house, :altitude 28, :gradient 23, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 34} + {:x 9, :y 37, :state :climax, :altitude 27, :gradient 30, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} + {:x 10, :y 37, :state :climax, :altitude 29, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} + {:x 11, :y 37, :state :climax, :altitude 23, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} + {:x 12, :y 37, :state :heath, :altitude 18, :gradient 32, :generation 101, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 50} + {:x 13, :y 37, :state :water, :altitude 1, :gradient 25, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 37, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 37, :state :climax, :altitude 17, :gradient 48, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 95} + {:x 19, :y 37, :state :climax, :altitude 33, :gradient 47, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} + {:x 20, :y 37, :state :camp, :altitude 23, :gradient 48, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp"} + {:x 21, :y 37, :state :water, :altitude 1, :gradient 34, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 37, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 38, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 38, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 38, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 38, :state :water, :altitude 2, :gradient 34, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 38, :state :house, :altitude 19, :gradient 34, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 28} + {:x 7, :y 38, :state :grassland, :altitude 19, :gradient 34, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 20} + {:x 8, :y 38, :state :pasture, :altitude 18, :gradient 34, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 41} + {:x 9, :y 38, :state :market, :altitude 12, :gradient 27, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 20} + {:x 10, :y 38, :state :harbour, :altitude 2, :gradient 28, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 38, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 38, :state :water, :altitude 2, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 38, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 38, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 38, :state :camp, :altitude 12, :gradient 32, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 15} + {:x 19, :y 38, :state :climax, :altitude 17, :gradient 32, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} + {:x 20, :y 38, :state :water, :altitude 2, :gradient 32, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 38, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 38, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 39, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 39, :state :climax, :altitude 12, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} + {:x 4, :y 39, :state :house, :altitude 19, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} + {:x 5, :y 39, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 39, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 39, :state :harbour, :altitude 1, :gradient 28, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 39, :state :pasture, :altitude 15, :gradient 48, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 26} + {:x 9, :y 39, :state :inn, :altitude 26, :gradient 47, :generation 101, :rule "if state is house and some neighbours are crop then state should be house", :fertility 43} + {:x 10, :y 39, :state :camp, :altitude 26, :gradient 48, :generation 101, :rule "if state is in waste or grassland and some neighbours are market then state should be camp", :fertility 49} + {:x 11, :y 39, :state :crop, :altitude 23, :gradient 48, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 52} + {:x 12, :y 39, :state :house, :altitude 13, :gradient 41, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 58} + {:x 13, :y 39, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 39, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 39, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 39, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 39, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 39, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 39, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 39, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 40, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 40, :state :pasture, :altitude 13, :gradient 27, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} + {:x 4, :y 40, :state :ploughland, :altitude 28, :gradient 26, :generation 101, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 12} + {:x 5, :y 40, :state :house, :altitude 14, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 15} + {:x 6, :y 40, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 40, :state :house, :altitude 15, :gradient 28, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 39} + {:x 8, :y 40, :state :house, :altitude 29, :gradient 49, :generation 101, :rule "if state is house and some neighbours are market then state should be house", :fertility 37} + {:x 9, :y 40, :state :grassland, :altitude 49, :gradient 46, :generation 101, :rule "if state is market then state should be grassland", :fertility 9} + {:x 10, :y 40, :state :climax, :altitude 49, :gradient 38, :generation 101, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 68} + {:x 11, :y 40, :state :grassland, :altitude 42, :gradient 48, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 46} + {:x 12, :y 40, :state :pasture, :altitude 28, :gradient 50, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 77} + {:x 13, :y 40, :state :grassland, :altitude 18, :gradient 34, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 49} + {:x 14, :y 40, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 40, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 41, :state :water, :altitude 1, :gradient 12, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 41, :state :climax, :altitude 12, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} + {:x 4, :y 41, :state :climax, :altitude 28, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} + {:x 5, :y 41, :state :scrub, :altitude 18, :gradient 27, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 17} + {:x 6, :y 41, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 41, :state :house, :altitude 14, :gradient 28, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} + {:x 8, :y 41, :state :scrub, :altitude 29, :gradient 49, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 62} + {:x 9, :y 41, :state :house, :altitude 50, :gradient 37, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 38} + {:x 10, :y 41, :state :scrub, :altitude 61, :gradient 19, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 54} + {:x 11, :y 41, :state :scrub, :altitude 51, :gradient 33, :generation 101, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 53} + {:x 12, :y 41, :state :climax, :altitude 35, :gradient 33, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} + {:x 13, :y 41, :state :pasture, :altitude 20, :gradient 34, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 75} + {:x 14, :y 41, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 41, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 41, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 42, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 42, :state :water, :altitude 1, :gradient 11, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 42, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 42, :state :camp, :altitude 14, :gradient 27, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 21} + {:x 5, :y 42, :state :house, :altitude 12, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 22} + {:x 6, :y 42, :state :water, :altitude 1, :gradient 17, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 42, :state :water, :altitude 1, :gradient 28, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 42, :state :climax, :altitude 24, :gradient 49, :generation 101, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 36} + {:x 9, :y 42, :state :crop, :altitude 32, :gradient 47, :generation 101, :rule "if state is ploughland then state should be crop", :fertility 20} + {:x 10, :y 42, :state :house, :altitude 40, :gradient 41, :generation 101, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 18} + {:x 11, :y 42, :state :grassland, :altitude 40, :gradient 33, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 33} + {:x 12, :y 42, :state :pasture, :altitude 32, :gradient 31, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 52} + {:x 13, :y 42, :state :climax, :altitude 23, :gradient 34, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} + {:x 14, :y 42, :state :water, :altitude 2, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 42, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 42, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 43, :state :water, :altitude 1, :gradient 16, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 43, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 3, :y 43, :state :water, :altitude 2, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 4, :y 43, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 43, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 43, :state :water, :altitude 2, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 43, :state :water, :altitude 1, :gradient 23, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 43, :state :house, :altitude 14, :gradient 31, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 38} + {:x 9, :y 43, :state :pasture, :altitude 20, :gradient 39, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 29} + {:x 10, :y 43, :state :grassland, :altitude 28, :gradient 39, :generation 101, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 30} + {:x 11, :y 43, :state :pasture, :altitude 28, :gradient 23, :generation 101, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 50} + {:x 12, :y 43, :state :climax, :altitude 28, :gradient 25, :generation 101, :rule "if state is climax then 1 chance in 500 state should be fire", :fertility 73} + {:x 13, :y 43, :state :climax, :altitude 23, :gradient 31, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} + {:x 14, :y 43, :state :water, :altitude 2, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 43, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 43, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 44, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 44, :state :house, :altitude 17, :gradient 36, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 6} + {:x 3, :y 44, :state :camp, :altitude 28, :gradient 36, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 20} + {:x 4, :y 44, :state :water, :altitude 2, :gradient 36, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 44, :state :camp, :altitude 12, :gradient 21, :generation 101, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 47} + {:x 6, :y 44, :state :climax, :altitude 22, :gradient 14, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 95} + {:x 7, :y 44, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 44, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 44, :state :water, :altitude 1, :gradient 27, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 44, :state :house, :altitude 20, :gradient 27, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 36} + {:x 11, :y 44, :state :climax, :altitude 17, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} + {:x 12, :y 44, :state :climax, :altitude 22, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 88} + {:x 13, :y 44, :state :climax, :altitude 15, :gradient 27, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 88} + {:x 14, :y 44, :state :water, :altitude 1, :gradient 22, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 44, :state :water, :altitude 1, :gradient 1, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 44, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 45, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 45, :state :climax, :altitude 19, :gradient 36, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} + {:x 3, :y 45, :state :climax, :altitude 37, :gradient 26, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} + {:x 4, :y 45, :state :climax, :altitude 14, :gradient 36, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 78} + {:x 5, :y 45, :state :harbour, :altitude 2, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 45, :state :house, :altitude 15, :gradient 21, :generation 101, :rule "if state is house and more than 2 neighbours are water then state should be house"} + {:x 7, :y 45, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 45, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 45, :state :water, :altitude 1, :gradient 19, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 45, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 45, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 45, :state :water, :altitude 1, :gradient 21, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 45, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 45, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}] + [{:x 0, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 1, :y 46, :state :water, :altitude 1, :gradient 18, :generation 101, :rule "if state is water then state should be water"} + {:x 2, :y 46, :state :climax, :altitude 13, :gradient 36, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} + {:x 3, :y 46, :state :climax, :altitude 22, :gradient 35, :generation 101, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} + {:x 4, :y 46, :state :water, :altitude 2, :gradient 36, :generation 101, :rule "if state is water then state should be water"} + {:x 5, :y 46, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 6, :y 46, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 7, :y 46, :state :water, :altitude 1, :gradient 14, :generation 101, :rule "if state is water then state should be water"} + {:x 8, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 9, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 10, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 11, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 12, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 13, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 14, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 15, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 16, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 17, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 18, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 19, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 20, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 21, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 22, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 23, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 24, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 25, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 26, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 27, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 28, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 29, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 30, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 31, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 32, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 33, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 34, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 35, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 36, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 37, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 38, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 39, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 40, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 41, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 42, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 43, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 44, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 45, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 46, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"} + {:x 47, :y 46, :state :water, :altitude 1, :gradient 0, :generation 101, :rule "if state is water then state should be water"}]] diff --git a/resources/maps/barra/barra_101.edn b/resources/maps/barra/barra_101.edn new file mode 100644 index 0000000..a0e5511 --- /dev/null +++ b/resources/maps/barra/barra_101.edn @@ -0,0 +1 @@ +[[{:x 0, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 0, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 0, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 0, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 0, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 0, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 0, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 0, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 0, :state :water, :altitude 2, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 0, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 0, :state :climax, :altitude 14, :gradient 14, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 43, :y 0, :state :climax, :altitude 15, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} {:x 44, :y 0, :state :climax, :altitude 31, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 45, :y 0, :state :climax, :altitude 36, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 46, :y 0, :state :climax, :altitude 15, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 94} {:x 47, :y 0, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 1, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 1, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 1, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 1, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 1, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 1, :state :climax, :altitude 12, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} {:x 36, :y 1, :state :climax, :altitude 13, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 76} {:x 37, :y 1, :state :climax, :altitude 15, :gradient 32, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} {:x 38, :y 1, :state :climax, :altitude 23, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 39, :y 1, :state :climax, :altitude 23, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 40, :y 1, :state :climax, :altitude 28, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} {:x 41, :y 1, :state :camp, :altitude 15, :gradient 28, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 15} {:x 42, :y 1, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 1, :state :water, :altitude 1, :gradient 30, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 1, :state :water, :altitude 2, :gradient 35, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 1, :state :water, :altitude 2, :gradient 35, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 1, :state :water, :altitude 1, :gradient 35, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 1, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 2, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 2, :state :water, :altitude 1, :gradient 31, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 2, :state :water, :altitude 2, :gradient 31, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 2, :state :water, :altitude 1, :gradient 31, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 2, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 2, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 2, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 2, :state :climax, :altitude 22, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 36, :y 2, :state :climax, :altitude 31, :gradient 31, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 75} {:x 37, :y 2, :state :climax, :altitude 29, :gradient 38, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} {:x 38, :y 2, :state :climax, :altitude 33, :gradient 36, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} {:x 39, :y 2, :state :climax, :altitude 36, :gradient 28, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} {:x 40, :y 2, :state :climax, :altitude 29, :gradient 40, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 41, :y 2, :state :climax, :altitude 15, :gradient 28, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} {:x 42, :y 2, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 2, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 2, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 2, :state :climax, :altitude 15, :gradient 16, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 94} {:x 46, :y 2, :state :house, :altitude 14, :gradient 16, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 51} {:x 47, :y 2, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 3, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 3, :state :climax, :altitude 14, :gradient 31, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} {:x 29, :y 3, :state :grassland, :altitude 32, :gradient 16, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 72} {:x 30, :y 3, :state :climax, :altitude 17, :gradient 31, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} {:x 31, :y 3, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 3, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 3, :state :climax, :altitude 22, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} {:x 36, :y 3, :state :climax, :altitude 31, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} {:x 37, :y 3, :state :climax, :altitude 43, :gradient 22, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 66} {:x 38, :y 3, :state :climax, :altitude 51, :gradient 17, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 39, :y 3, :state :climax, :altitude 42, :gradient 24, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 40, :y 3, :state :climax, :altitude 28, :gradient 40, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} {:x 41, :y 3, :state :water, :altitude 2, :gradient 28, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 3, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 3, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 3, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 3, :state :camp, :altitude 17, :gradient 14, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 39} {:x 46, :y 3, :state :climax, :altitude 14, :gradient 16, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} {:x 47, :y 3, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 4, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 4, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 4, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 4, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 4, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 4, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 4, :state :water, :altitude 2, :gradient 31, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 4, :state :climax, :altitude 17, :gradient 31, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 30, :y 4, :state :house, :altitude 12, :gradient 31, :generation 103, :rule "if state is in camp or abandoned and some neighbours are crop then state should be house", :fertility 77} {:x 31, :y 4, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 4, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 4, :state :house, :altitude 13, :gradient 30, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 55} {:x 36, :y 4, :state :pasture, :altitude 29, :gradient 42, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 24} {:x 37, :y 4, :state :pasture, :altitude 42, :gradient 22, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 38} {:x 38, :y 4, :state :climax, :altitude 46, :gradient 19, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 39, :y 4, :state :climax, :altitude 38, :gradient 37, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} {:x 40, :y 4, :state :climax, :altitude 27, :gradient 41, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 41, :y 4, :state :water, :altitude 2, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 4, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 4, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 4, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 4, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 4, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 4, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 5, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 5, :state :water, :altitude 2, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 5, :state :house, :altitude 12, :gradient 27, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 21} {:x 20, :y 5, :state :house, :altitude 12, :gradient 27, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 21, :y 5, :state :water, :altitude 1, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 5, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 5, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 5, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 5, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 5, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 5, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 5, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 5, :state :harbour, :altitude 1, :gradient 34, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 5, :state :market, :altitude 31, :gradient 41, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 33} {:x 37, :y 5, :state :pasture, :altitude 32, :gradient 17, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 45} {:x 38, :y 5, :state :grassland, :altitude 37, :gradient 19, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 32} {:x 39, :y 5, :state :grassland, :altitude 33, :gradient 34, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 44} {:x 40, :y 5, :state :grassland, :altitude 14, :gradient 37, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 41} {:x 41, :y 5, :state :water, :altitude 1, :gradient 26, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 5, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 5, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 6, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 6, :state :climax, :altitude 17, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} {:x 19, :y 6, :state :pasture, :altitude 28, :gradient 25, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 27} {:x 20, :y 6, :state :climax, :altitude 24, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 93} {:x 21, :y 6, :state :water, :altitude 2, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 6, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 6, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 6, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 6, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 6, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 6, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 6, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 6, :state :inn, :altitude 15, :gradient 34, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 36} {:x 36, :y 6, :state :crop, :altitude 35, :gradient 42, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 61} {:x 37, :y 6, :state :crop, :altitude 32, :gradient 14, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 56} {:x 38, :y 6, :state :crop, :altitude 29, :gradient 16, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 21} {:x 39, :y 6, :state :camp, :altitude 27, :gradient 25, :generation 103, :rule "if state is camp and some neighbours are ploughland then state should be camp", :fertility 34} {:x 40, :y 6, :state :pasture, :altitude 12, :gradient 32, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 41, :y 6, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 6, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 7, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 7, :state :water, :altitude 1, :gradient 30, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 7, :state :climax, :altitude 18, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} {:x 19, :y 7, :state :climax, :altitude 27, :gradient 29, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} {:x 20, :y 7, :state :climax, :altitude 14, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 21, :y 7, :state :water, :altitude 1, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 7, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 7, :state :water, :altitude 1, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 7, :state :climax, :altitude 19, :gradient 34, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 92} {:x 26, :y 7, :state :forest, :altitude 22, :gradient 34, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 29} {:x 27, :y 7, :state :house, :altitude 12, :gradient 34, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 11} {:x 28, :y 7, :state :water, :altitude 1, :gradient 34, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 7, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 7, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 7, :state :camp, :altitude 15, :gradient 34, :generation 103, :rule "if state is camp and some neighbours are ploughland then state should be camp", :fertility 37} {:x 36, :y 7, :state :grassland, :altitude 35, :gradient 41, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} {:x 37, :y 7, :state :crop, :altitude 43, :gradient 9, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 61} {:x 38, :y 7, :state :house, :altitude 37, :gradient 20, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 34} {:x 39, :y 7, :state :grassland, :altitude 27, :gradient 35, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 46} {:x 40, :y 7, :state :house, :altitude 12, :gradient 26, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 30} {:x 41, :y 7, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 7, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 8, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 8, :state :climax, :altitude 14, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 89} {:x 18, :y 8, :state :crop, :altitude 31, :gradient 28, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 15} {:x 19, :y 8, :state :climax, :altitude 28, :gradient 29, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} {:x 20, :y 8, :state :water, :altitude 2, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 8, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 8, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 8, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 8, :state :water, :altitude 1, :gradient 30, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 8, :state :climax, :altitude 24, :gradient 40, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} {:x 26, :y 8, :state :scrub, :altitude 35, :gradient 29, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 6} {:x 27, :y 8, :state :pasture, :altitude 35, :gradient 40, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 28, :y 8, :state :house, :altitude 22, :gradient 34, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 11} {:x 29, :y 8, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 8, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 8, :state :water, :altitude 2, :gradient 34, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 8, :state :house, :altitude 28, :gradient 42, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 65} {:x 37, :y 8, :state :crop, :altitude 37, :gradient 28, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 42} {:x 38, :y 8, :state :house, :altitude 36, :gradient 31, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 27} {:x 39, :y 8, :state :pasture, :altitude 23, :gradient 36, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 33} {:x 40, :y 8, :state :water, :altitude 2, :gradient 26, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 8, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 8, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 9, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 9, :state :house, :altitude 12, :gradient 30, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 18, :y 9, :state :climax, :altitude 29, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} {:x 19, :y 9, :state :climax, :altitude 28, :gradient 29, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 20, :y 9, :state :pasture, :altitude 18, :gradient 27, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 47} {:x 21, :y 9, :state :pasture, :altitude 17, :gradient 27, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 23} {:x 22, :y 9, :state :house, :altitude 23, :gradient 27, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 20} {:x 23, :y 9, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 9, :state :house, :altitude 14, :gradient 35, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 25, :y 9, :state :pasture, :altitude 31, :gradient 40, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 26, :y 9, :state :scrub, :altitude 41, :gradient 13, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 20} {:x 27, :y 9, :state :forest, :altitude 35, :gradient 39, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 25} {:x 28, :y 9, :state :house, :altitude 20, :gradient 34, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 8} {:x 29, :y 9, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 9, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 9, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 9, :state :crop, :altitude 15, :gradient 36, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 25} {:x 37, :y 9, :state :forest, :altitude 26, :gradient 25, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 68} {:x 38, :y 9, :state :crop, :altitude 23, :gradient 36, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 37} {:x 39, :y 9, :state :house, :altitude 12, :gradient 35, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 38} {:x 40, :y 9, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 9, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 9, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 10, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 10, :state :water, :altitude 1, :gradient 28, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 10, :state :house, :altitude 23, :gradient 35, :generation 103, :rule "if state is house and some neighbours are crop then state should be house", :fertility 24} {:x 19, :y 10, :state :grassland, :altitude 28, :gradient 18, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 35} {:x 20, :y 10, :state :climax, :altitude 28, :gradient 19, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} {:x 21, :y 10, :state :climax, :altitude 28, :gradient 15, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 22, :y 10, :state :ploughland, :altitude 23, :gradient 27, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 22} {:x 23, :y 10, :state :harbour, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 10, :state :pasture, :altitude 23, :gradient 35, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 40} {:x 25, :y 10, :state :pasture, :altitude 36, :gradient 27, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 26, :y 10, :state :pasture, :altitude 37, :gradient 28, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 27, :y 10, :state :climax, :altitude 26, :gradient 40, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 28, :y 10, :state :water, :altitude 2, :gradient 34, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 10, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 10, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 10, :state :pasture, :altitude 18, :gradient 26, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 29} {:x 37, :y 10, :state :pasture, :altitude 27, :gradient 25, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 37} {:x 38, :y 10, :state :scrub, :altitude 12, :gradient 26, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 79} {:x 39, :y 10, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 10, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 10, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 11, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 11, :state :grassland, :altitude 20, :gradient 35, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 12} {:x 19, :y 11, :state :grassland, :altitude 36, :gradient 22, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 51} {:x 20, :y 11, :state :forest, :altitude 32, :gradient 10, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 48} {:x 21, :y 11, :state :scrub, :altitude 27, :gradient 22, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 86} {:x 22, :y 11, :state :forest, :altitude 19, :gradient 30, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 58} {:x 23, :y 11, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 11, :state :house, :altitude 14, :gradient 35, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 65} {:x 25, :y 11, :state :forest, :altitude 22, :gradient 36, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 39} {:x 26, :y 11, :state :pasture, :altitude 20, :gradient 36, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 27, :y 11, :state :house, :altitude 13, :gradient 36, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 25} {:x 28, :y 11, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 11, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 11, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 11, :state :house, :altitude 15, :gradient 26, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 28} {:x 37, :y 11, :state :house, :altitude 18, :gradient 26, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 10} {:x 38, :y 11, :state :water, :altitude 1, :gradient 26, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 11, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 11, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 12, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 12, :state :crop, :altitude 15, :gradient 35, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 55} {:x 19, :y 12, :state :house, :altitude 32, :gradient 22, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 50} {:x 20, :y 12, :state :grassland, :altitude 37, :gradient 12, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 54} {:x 21, :y 12, :state :inn, :altitude 31, :gradient 22, :generation 103, :rule "if state is in camp or abandoned and some neighbours are crop then state should be house", :fertility 30} {:x 22, :y 12, :state :market, :altitude 15, :gradient 30, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 24} {:x 23, :y 12, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 12, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 12, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 12, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 12, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 12, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 12, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 12, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 12, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 12, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 12, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 13, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 13, :state :water, :altitude 1, :gradient 26, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 13, :state :climax, :altitude 22, :gradient 31, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 19, :y 13, :state :climax, :altitude 27, :gradient 22, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} {:x 20, :y 13, :state :grassland, :altitude 27, :gradient 24, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} {:x 21, :y 13, :state :house, :altitude 24, :gradient 24, :generation 103, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 13} {:x 22, :y 13, :state :house, :altitude 23, :gradient 30, :generation 103, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 30} {:x 23, :y 13, :state :house, :altitude 22, :gradient 28, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 24, :y 13, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 13, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 13, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 13, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 13, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 13, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 13, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 14, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 14, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 14, :state :water, :altitude 1, :gradient 30, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 14, :state :forest, :altitude 15, :gradient 30, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 47} {:x 18, :y 14, :state :climax, :altitude 27, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} {:x 19, :y 14, :state :climax, :altitude 26, :gradient 15, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} {:x 20, :y 14, :state :crop, :altitude 17, :gradient 18, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 45} {:x 21, :y 14, :state :crop, :altitude 13, :gradient 20, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 19} {:x 22, :y 14, :state :ploughland, :altitude 29, :gradient 23, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 23} {:x 23, :y 14, :state :house, :altitude 18, :gradient 28, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 49} {:x 24, :y 14, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 14, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 14, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 14, :state :water, :altitude 1, :gradient 30, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 14, :state :house, :altitude 14, :gradient 39, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 44} {:x 33, :y 14, :state :climax, :altitude 22, :gradient 39, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 76} {:x 34, :y 14, :state :climax, :altitude 13, :gradient 39, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} {:x 35, :y 14, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 14, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 15, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 15, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 15, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 15, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 15, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 15, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 15, :state :water, :altitude 1, :gradient 34, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 15, :state :climax, :altitude 13, :gradient 40, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 37} {:x 16, :y 15, :state :climax, :altitude 19, :gradient 44, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 39} {:x 17, :y 15, :state :climax, :altitude 31, :gradient 46, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} {:x 18, :y 15, :state :climax, :altitude 29, :gradient 32, :generation 103, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 43} {:x 19, :y 15, :state :scrub, :altitude 26, :gradient 33, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 57} {:x 20, :y 15, :state :pasture, :altitude 14, :gradient 36, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 27} {:x 21, :y 15, :state :water, :altitude 9, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 15, :state :grassland, :altitude 13, :gradient 28, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 27} {:x 23, :y 15, :state :water, :altitude 1, :gradient 28, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 15, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 15, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 15, :state :water, :altitude 1, :gradient 31, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 15, :state :scrub, :altitude 14, :gradient 31, :generation 103, :rule "if state is camp then 1 chance in 5 state should be waste", :fertility 72} {:x 31, :y 15, :state :grassland, :altitude 19, :gradient 32, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 54} {:x 32, :y 15, :state :climax, :altitude 31, :gradient 39, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 33, :y 15, :state :ploughland, :altitude 40, :gradient 20, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 42} {:x 34, :y 15, :state :climax, :altitude 23, :gradient 39, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 76} {:x 35, :y 15, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 15, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 16, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 16, :state :house, :altitude 18, :gradient 30, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 40} {:x 10, :y 16, :state :crop, :altitude 19, :gradient 35, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 33} {:x 11, :y 16, :state :climax, :altitude 20, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 38} {:x 12, :y 16, :state :climax, :altitude 18, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} {:x 13, :y 16, :state :scrub, :altitude 17, :gradient 34, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 74} {:x 14, :y 16, :state :scrub, :altitude 19, :gradient 51, :generation 103, :rule "if state is fire then state should be waste", :fertility 75} {:x 15, :y 16, :state :scrub, :altitude 35, :gradient 55, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 62} {:x 16, :y 16, :state :climax, :altitude 41, :gradient 43, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 41} {:x 17, :y 16, :state :climax, :altitude 45, :gradient 42, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 52} {:x 18, :y 16, :state :climax, :altitude 47, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 51} {:x 19, :y 16, :state :forest, :altitude 45, :gradient 47, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 65} {:x 20, :y 16, :state :climax, :altitude 35, :gradient 45, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 28} {:x 21, :y 16, :state :pasture, :altitude 19, :gradient 33, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 52} {:x 22, :y 16, :state :climax, :altitude 15, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 23, :y 16, :state :water, :altitude 1, :gradient 26, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 16, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 16, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 16, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 16, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 16, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 16, :state :ploughland, :altitude 18, :gradient 31, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 85} {:x 30, :y 16, :state :ploughland, :altitude 32, :gradient 31, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 52} {:x 31, :y 16, :state :climax, :altitude 32, :gradient 19, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 32, :y 16, :state :climax, :altitude 33, :gradient 21, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 33, :y 16, :state :climax, :altitude 32, :gradient 25, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} {:x 34, :y 16, :state :climax, :altitude 28, :gradient 39, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 35, :y 16, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 16, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 17, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 17, :state :crop, :altitude 26, :gradient 30, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 40} {:x 10, :y 17, :state :pasture, :altitude 31, :gradient 23, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 25} {:x 11, :y 17, :state :climax, :altitude 36, :gradient 17, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 12, :y 17, :state :heath, :altitude 35, :gradient 19, :generation 103, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 69} {:x 13, :y 17, :state :heath, :altitude 29, :gradient 18, :generation 103, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 54} {:x 14, :y 17, :state :scrub, :altitude 32, :gradient 35, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 63} {:x 15, :y 17, :state :scrub, :altitude 52, :gradient 37, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 51} {:x 16, :y 17, :state :climax, :altitude 56, :gradient 20, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 27} {:x 17, :y 17, :state :climax, :altitude 55, :gradient 20, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} {:x 18, :y 17, :state :climax, :altitude 61, :gradient 12, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 19, :y 17, :state :climax, :altitude 54, :gradient 26, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 20, :y 17, :state :scrub, :altitude 42, :gradient 35, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} {:x 21, :y 17, :state :scrub, :altitude 31, :gradient 27, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 29} {:x 22, :y 17, :state :climax, :altitude 27, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} {:x 23, :y 17, :state :climax, :altitude 22, :gradient 26, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 61} {:x 24, :y 17, :state :climax, :altitude 17, :gradient 26, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 25, :y 17, :state :climax, :altitude 12, :gradient 26, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 26, :y 17, :state :climax, :altitude 12, :gradient 22, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 45} {:x 27, :y 17, :state :scrub, :altitude 12, :gradient 26, :generation 103, :rule "if state is fire then state should be waste", :fertility 57} {:x 28, :y 17, :state :heath, :altitude 13, :gradient 26, :generation 103, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 65} {:x 29, :y 17, :state :pasture, :altitude 23, :gradient 31, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 55} {:x 30, :y 17, :state :grassland, :altitude 31, :gradient 17, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 69} {:x 31, :y 17, :state :crop, :altitude 32, :gradient 16, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 48} {:x 32, :y 17, :state :crop, :altitude 29, :gradient 15, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 49} {:x 33, :y 17, :state :climax, :altitude 26, :gradient 32, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 34, :y 17, :state :camp, :altitude 15, :gradient 31, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 46} {:x 35, :y 17, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 17, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 18, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 18, :state :house, :altitude 13, :gradient 30, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 31} {:x 10, :y 18, :state :crop, :altitude 19, :gradient 35, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 29} {:x 11, :y 18, :state :scrub, :altitude 27, :gradient 35, :generation 103, :rule "if state is fire then state should be waste", :fertility 64} {:x 12, :y 18, :state :heath, :altitude 31, :gradient 14, :generation 103, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 67} {:x 13, :y 18, :state :scrub, :altitude 31, :gradient 8, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 37} {:x 14, :y 18, :state :scrub, :altitude 31, :gradient 24, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 55} {:x 15, :y 18, :state :climax, :altitude 41, :gradient 28, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 39} {:x 16, :y 18, :state :scrub, :altitude 49, :gradient 27, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} {:x 17, :y 18, :state :climax, :altitude 43, :gradient 24, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 18, :y 18, :state :climax, :altitude 47, :gradient 24, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} {:x 19, :y 18, :state :climax, :altitude 47, :gradient 25, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 45} {:x 20, :y 18, :state :forest, :altitude 40, :gradient 26, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 63} {:x 21, :y 18, :state :climax, :altitude 28, :gradient 16, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 32} {:x 22, :y 18, :state :climax, :altitude 27, :gradient 9, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 23, :y 18, :state :climax, :altitude 27, :gradient 10, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 24, :y 18, :state :climax, :altitude 27, :gradient 15, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 75} {:x 25, :y 18, :state :climax, :altitude 22, :gradient 15, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 24} {:x 26, :y 18, :state :climax, :altitude 23, :gradient 15, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 48} {:x 27, :y 18, :state :climax, :altitude 23, :gradient 17, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} {:x 28, :y 18, :state :climax, :altitude 27, :gradient 17, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 43} {:x 29, :y 18, :state :pasture, :altitude 15, :gradient 19, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 43} {:x 30, :y 18, :state :scrub, :altitude 17, :gradient 20, :generation 103, :rule "if state is fire then state should be waste", :fertility 61} {:x 31, :y 18, :state :house, :altitude 18, :gradient 20, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 52} {:x 32, :y 18, :state :house, :altitude 27, :gradient 19, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 43} {:x 33, :y 18, :state :climax, :altitude 31, :gradient 28, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 74} {:x 34, :y 18, :state :water, :altitude 1, :gradient 30, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 18, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 18, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 19, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 19, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 19, :state :water, :altitude 1, :gradient 26, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 19, :state :scrub, :altitude 22, :gradient 31, :generation 103, :rule "if state is fire then state should be waste", :fertility 28} {:x 12, :y 19, :state :scrub, :altitude 27, :gradient 14, :generation 103, :rule "if state is fire then state should be waste", :fertility 85} {:x 13, :y 19, :state :climax, :altitude 31, :gradient 9, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 70} {:x 14, :y 19, :state :scrub, :altitude 28, :gradient 12, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} {:x 15, :y 19, :state :forest, :altitude 29, :gradient 24, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 47} {:x 16, :y 19, :state :scrub, :altitude 37, :gradient 27, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 26} {:x 17, :y 19, :state :scrub, :altitude 41, :gradient 19, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 30} {:x 18, :y 19, :state :climax, :altitude 37, :gradient 20, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} {:x 19, :y 19, :state :heath, :altitude 38, :gradient 11, :generation 103, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 40} {:x 20, :y 19, :state :scrub, :altitude 36, :gradient 19, :generation 103, :rule "if state is fire then state should be waste", :fertility 51} {:x 21, :y 19, :state :climax, :altitude 28, :gradient 20, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 46} {:x 22, :y 19, :state :climax, :altitude 26, :gradient 15, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 56} {:x 23, :y 19, :state :climax, :altitude 26, :gradient 3, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 24, :y 19, :state :climax, :altitude 27, :gradient 6, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 41} {:x 25, :y 19, :state :climax, :altitude 27, :gradient 11, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 32} {:x 26, :y 19, :state :forest, :altitude 22, :gradient 11, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 41} {:x 27, :y 19, :state :climax, :altitude 24, :gradient 19, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 40} {:x 28, :y 19, :state :climax, :altitude 29, :gradient 21, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 29, :y 19, :state :heath, :altitude 22, :gradient 24, :generation 103, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 61} {:x 30, :y 19, :state :scrub, :altitude 12, :gradient 22, :generation 103, :rule "if state is fire then state should be waste", :fertility 45} {:x 31, :y 19, :state :crop, :altitude 13, :gradient 21, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 52} {:x 32, :y 19, :state :grassland, :altitude 15, :gradient 32, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 38} {:x 33, :y 19, :state :house, :altitude 17, :gradient 30, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 47} {:x 34, :y 19, :state :water, :altitude 1, :gradient 30, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 19, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 20, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 20, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 20, :state :water, :altitude 1, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 20, :state :climax, :altitude 23, :gradient 44, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} {:x 12, :y 20, :state :heath, :altitude 32, :gradient 37, :generation 103, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 63} {:x 13, :y 20, :state :climax, :altitude 36, :gradient 32, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 44} {:x 14, :y 20, :state :heath, :altitude 35, :gradient 31, :generation 103, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 47} {:x 15, :y 20, :state :scrub, :altitude 37, :gradient 36, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 65} {:x 16, :y 20, :state :scrub, :altitude 52, :gradient 36, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 75} {:x 17, :y 20, :state :scrub, :altitude 56, :gradient 28, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 60} {:x 18, :y 20, :state :scrub, :altitude 43, :gradient 29, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 40} {:x 19, :y 20, :state :scrub, :altitude 36, :gradient 14, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} {:x 20, :y 20, :state :climax, :altitude 46, :gradient 13, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 21, :y 20, :state :climax, :altitude 41, :gradient 20, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 22, :y 20, :state :climax, :altitude 29, :gradient 15, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 23, :y 20, :state :scrub, :altitude 26, :gradient 3, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 45} {:x 24, :y 20, :state :climax, :altitude 28, :gradient 3, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 55} {:x 25, :y 20, :state :climax, :altitude 28, :gradient 18, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 56} {:x 26, :y 20, :state :climax, :altitude 17, :gradient 15, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 27, :y 20, :state :climax, :altitude 20, :gradient 19, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 48} {:x 28, :y 20, :state :scrub, :altitude 36, :gradient 15, :generation 103, :rule "if state is fire then state should be waste", :fertility 38} {:x 29, :y 20, :state :scrub, :altitude 35, :gradient 24, :generation 103, :rule "if state is fire then state should be waste", :fertility 49} {:x 30, :y 20, :state :climax, :altitude 28, :gradient 23, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 86} {:x 31, :y 20, :state :climax, :altitude 33, :gradient 26, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} {:x 32, :y 20, :state :climax, :altitude 15, :gradient 32, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} {:x 33, :y 20, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 20, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 20, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 21, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 21, :state :climax, :altitude 12, :gradient 26, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 10, :y 21, :state :forest, :altitude 12, :gradient 26, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 60} {:x 11, :y 21, :state :scrub, :altitude 24, :gradient 44, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} {:x 12, :y 21, :state :climax, :altitude 45, :gradient 36, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 40} {:x 13, :y 21, :state :forest, :altitude 59, :gradient 27, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 64} {:x 14, :y 21, :state :climax, :altitude 50, :gradient 24, :generation 103, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 55} {:x 15, :y 21, :state :scrub, :altitude 49, :gradient 38, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 76} {:x 16, :y 21, :state :climax, :altitude 64, :gradient 40, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 57} {:x 17, :y 21, :state :scrub, :altitude 65, :gradient 34, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} {:x 18, :y 21, :state :climax, :altitude 50, :gradient 41, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 47} {:x 19, :y 21, :state :heath, :altitude 38, :gradient 19, :generation 103, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 49} {:x 20, :y 21, :state :climax, :altitude 38, :gradient 10, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 64} {:x 21, :y 21, :state :scrub, :altitude 38, :gradient 17, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 52} {:x 22, :y 21, :state :climax, :altitude 29, :gradient 15, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} {:x 23, :y 21, :state :climax, :altitude 27, :gradient 5, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 56} {:x 24, :y 21, :state :climax, :altitude 28, :gradient 7, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 38} {:x 25, :y 21, :state :climax, :altitude 29, :gradient 19, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 30} {:x 26, :y 21, :state :climax, :altitude 35, :gradient 19, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 36} {:x 27, :y 21, :state :climax, :altitude 28, :gradient 22, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 28, :y 21, :state :climax, :altitude 28, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 70} {:x 29, :y 21, :state :climax, :altitude 27, :gradient 35, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 70} {:x 30, :y 21, :state :climax, :altitude 23, :gradient 34, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 44} {:x 31, :y 21, :state :camp, :altitude 22, :gradient 32, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 47} {:x 32, :y 21, :state :water, :altitude 2, :gradient 32, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 21, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 21, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 22, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 22, :state :pasture, :altitude 23, :gradient 26, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 48} {:x 10, :y 22, :state :scrub, :altitude 27, :gradient 15, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 71} {:x 11, :y 22, :state :scrub, :altitude 27, :gradient 33, :generation 103, :rule "if state is fire then state should be waste", :fertility 40} {:x 12, :y 22, :state :heath, :altitude 40, :gradient 35, :generation 103, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 70} {:x 13, :y 22, :state :scrub, :altitude 59, :gradient 32, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 37} {:x 14, :y 22, :state :climax, :altitude 54, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 33} {:x 15, :y 22, :state :scrub, :altitude 54, :gradient 35, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 70} {:x 16, :y 22, :state :climax, :altitude 73, :gradient 34, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 75} {:x 17, :y 22, :state :forest, :altitude 77, :gradient 23, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 45} {:x 18, :y 22, :state :climax, :altitude 55, :gradient 39, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} {:x 19, :y 22, :state :climax, :altitude 42, :gradient 17, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 60} {:x 20, :y 22, :state :scrub, :altitude 40, :gradient 15, :generation 103, :rule "if state is fire then state should be waste", :fertility 51} {:x 21, :y 22, :state :climax, :altitude 36, :gradient 22, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 31} {:x 22, :y 22, :state :climax, :altitude 31, :gradient 14, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 76} {:x 23, :y 22, :state :climax, :altitude 29, :gradient 9, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 49} {:x 24, :y 22, :state :climax, :altitude 28, :gradient 7, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} {:x 25, :y 22, :state :climax, :altitude 33, :gradient 10, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} {:x 26, :y 22, :state :pasture, :altitude 36, :gradient 8, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 11} {:x 27, :y 22, :state :pasture, :altitude 28, :gradient 22, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 23} {:x 28, :y 22, :state :climax, :altitude 14, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 78} {:x 29, :y 22, :state :harbour, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 22, :state :water, :altitude 1, :gradient 26, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 22, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 22, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 22, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 22, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 23, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 23, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 23, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 23, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 23, :state :pasture, :altitude 15, :gradient 26, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 34} {:x 10, :y 23, :state :scrub, :altitude 27, :gradient 25, :generation 103, :rule "if state is fire then state should be waste", :fertility 52} {:x 11, :y 23, :state :heath, :altitude 27, :gradient 18, :generation 103, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 74} {:x 12, :y 23, :state :scrub, :altitude 27, :gradient 32, :generation 103, :rule "if state is fire then state should be waste", :fertility 47} {:x 13, :y 23, :state :scrub, :altitude 32, :gradient 32, :generation 103, :rule "if state is fire then state should be waste", :fertility 56} {:x 14, :y 23, :state :scrub, :altitude 38, :gradient 27, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} {:x 15, :y 23, :state :scrub, :altitude 43, :gradient 35, :generation 103, :rule "if state is fire then state should be waste", :fertility 67} {:x 16, :y 23, :state :climax, :altitude 57, :gradient 36, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} {:x 17, :y 23, :state :climax, :altitude 69, :gradient 25, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 38} {:x 18, :y 23, :state :scrub, :altitude 54, :gradient 37, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 60} {:x 19, :y 23, :state :climax, :altitude 50, :gradient 29, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 20, :y 23, :state :scrub, :altitude 51, :gradient 15, :generation 103, :rule "if state is fire then state should be waste", :fertility 52} {:x 21, :y 23, :state :heath, :altitude 41, :gradient 22, :generation 103, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 64} {:x 22, :y 23, :state :scrub, :altitude 35, :gradient 13, :generation 103, :rule "if state is fire then state should be waste", :fertility 68} {:x 23, :y 23, :state :climax, :altitude 31, :gradient 16, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 38} {:x 24, :y 23, :state :climax, :altitude 26, :gradient 19, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} {:x 25, :y 23, :state :climax, :altitude 29, :gradient 22, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 51} {:x 26, :y 23, :state :pasture, :altitude 29, :gradient 22, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 29} {:x 27, :y 23, :state :climax, :altitude 27, :gradient 22, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} {:x 28, :y 23, :state :climax, :altitude 26, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 29, :y 23, :state :camp, :altitude 12, :gradient 25, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 24} {:x 30, :y 23, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 23, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 24, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 24, :state :water, :altitude 1, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 24, :state :water, :altitude 2, :gradient 28, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 24, :state :house, :altitude 14, :gradient 28, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 32} {:x 8, :y 24, :state :climax, :altitude 14, :gradient 28, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} {:x 9, :y 24, :state :grassland, :altitude 12, :gradient 28, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 29} {:x 10, :y 24, :state :climax, :altitude 22, :gradient 29, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} {:x 11, :y 24, :state :climax, :altitude 37, :gradient 37, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 12, :y 24, :state :climax, :altitude 37, :gradient 34, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 31} {:x 13, :y 24, :state :climax, :altitude 36, :gradient 34, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 51} {:x 14, :y 24, :state :scrub, :altitude 41, :gradient 45, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 40} {:x 15, :y 24, :state :heath, :altitude 54, :gradient 56, :generation 103, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 46} {:x 16, :y 24, :state :climax, :altitude 64, :gradient 51, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 17, :y 24, :state :forest, :altitude 79, :gradient 40, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 18, :y 24, :state :climax, :altitude 69, :gradient 43, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 19, :y 24, :state :forest, :altitude 51, :gradient 37, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 58} {:x 20, :y 24, :state :climax, :altitude 43, :gradient 20, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 43} {:x 21, :y 24, :state :forest, :altitude 37, :gradient 24, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 30} {:x 22, :y 24, :state :scrub, :altitude 29, :gradient 24, :generation 103, :rule "if state is fire then state should be waste", :fertility 67} {:x 23, :y 24, :state :climax, :altitude 28, :gradient 33, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} {:x 24, :y 24, :state :climax, :altitude 19, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 25, :y 24, :state :climax, :altitude 14, :gradient 28, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 26, :y 24, :state :climax, :altitude 22, :gradient 28, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} {:x 27, :y 24, :state :climax, :altitude 20, :gradient 28, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} {:x 28, :y 24, :state :house, :altitude 20, :gradient 26, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 43} {:x 29, :y 24, :state :water, :altitude 2, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 24, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 24, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 25, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 25, :state :house, :altitude 12, :gradient 44, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 16} {:x 6, :y 25, :state :climax, :altitude 24, :gradient 51, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 7, :y 25, :state :crop, :altitude 29, :gradient 50, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 27} {:x 8, :y 25, :state :house, :altitude 29, :gradient 40, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 20} {:x 9, :y 25, :state :grassland, :altitude 26, :gradient 34, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 48} {:x 10, :y 25, :state :climax, :altitude 26, :gradient 29, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} {:x 11, :y 25, :state :climax, :altitude 41, :gradient 37, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 55} {:x 12, :y 25, :state :climax, :altitude 59, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 13, :y 25, :state :scrub, :altitude 61, :gradient 27, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} {:x 14, :y 25, :state :scrub, :altitude 59, :gradient 41, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 73} {:x 15, :y 25, :state :forest, :altitude 77, :gradient 55, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 48} {:x 16, :y 25, :state :forest, :altitude 94, :gradient 42, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} {:x 17, :y 25, :state :scrub, :altitude 93, :gradient 35, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} {:x 18, :y 25, :state :forest, :altitude 79, :gradient 52, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 43} {:x 19, :y 25, :state :scrub, :altitude 55, :gradient 48, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 42} {:x 20, :y 25, :state :climax, :altitude 42, :gradient 27, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 49} {:x 21, :y 25, :state :scrub, :altitude 35, :gradient 19, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 54} {:x 22, :y 25, :state :climax, :altitude 27, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 23, :y 25, :state :climax, :altitude 17, :gradient 28, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 72} {:x 24, :y 25, :state :water, :altitude 2, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 25, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 25, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 25, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 25, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 25, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 25, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 25, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 26, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 26, :state :climax, :altitude 20, :gradient 51, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 6, :y 26, :state :crop, :altitude 45, :gradient 65, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 22} {:x 7, :y 26, :state :grassland, :altitude 52, :gradient 62, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 37} {:x 8, :y 26, :state :grassland, :altitude 46, :gradient 60, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} {:x 9, :y 26, :state :grassland, :altitude 31, :gradient 60, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 29} {:x 10, :y 26, :state :pasture, :altitude 28, :gradient 37, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 60} {:x 11, :y 26, :state :scrub, :altitude 37, :gradient 33, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 50} {:x 12, :y 26, :state :scrub, :altitude 55, :gradient 30, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 25} {:x 13, :y 26, :state :scrub, :altitude 63, :gradient 28, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 18} {:x 14, :y 26, :state :climax, :altitude 60, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 77} {:x 15, :y 26, :state :forest, :altitude 74, :gradient 49, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} {:x 16, :y 26, :state :scrub, :altitude 96, :gradient 44, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} {:x 17, :y 26, :state :forest, :altitude 77, :gradient 58, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 74} {:x 18, :y 26, :state :pasture, :altitude 61, :gradient 65, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 56} {:x 19, :y 26, :state :climax, :altitude 41, :gradient 52, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 58} {:x 20, :y 26, :state :pasture, :altitude 31, :gradient 28, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 60} {:x 21, :y 26, :state :scrub, :altitude 28, :gradient 22, :generation 103, :rule "if state is fire then state should be waste", :fertility 64} {:x 22, :y 26, :state :pasture, :altitude 24, :gradient 34, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 74} {:x 23, :y 26, :state :water, :altitude 2, :gradient 26, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 26, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 26, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 26, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 27, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 27, :state :water, :altitude 1, :gradient 35, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 27, :state :climax, :altitude 22, :gradient 51, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} {:x 6, :y 27, :state :climax, :altitude 52, :gradient 57, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} {:x 7, :y 27, :state :pasture, :altitude 77, :gradient 41, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 50} {:x 8, :y 27, :state :heath, :altitude 86, :gradient 48, :generation 103, :rule "if state is waste and some neighbours are scrub then state should be heath", :fertility 50} {:x 9, :y 27, :state :climax, :altitude 63, :gradient 58, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 49} {:x 10, :y 27, :state :pasture, :altitude 38, :gradient 50, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 48} {:x 11, :y 27, :state :scrub, :altitude 33, :gradient 30, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 48} {:x 12, :y 27, :state :scrub, :altitude 33, :gradient 37, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 75} {:x 13, :y 27, :state :climax, :altitude 47, :gradient 37, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 14, :y 27, :state :scrub, :altitude 47, :gradient 41, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 60} {:x 15, :y 27, :state :pasture, :altitude 50, :gradient 63, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 64} {:x 16, :y 27, :state :crop, :altitude 64, :gradient 63, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 32} {:x 17, :y 27, :state :crop, :altitude 55, :gradient 58, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 58} {:x 18, :y 27, :state :crop, :altitude 38, :gradient 49, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 31} {:x 19, :y 27, :state :climax, :altitude 28, :gradient 34, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} {:x 20, :y 27, :state :climax, :altitude 27, :gradient 15, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 75} {:x 21, :y 27, :state :climax, :altitude 27, :gradient 16, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} {:x 22, :y 27, :state :pasture, :altitude 20, :gradient 27, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 23, :y 27, :state :water, :altitude 1, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 27, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 27, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 28, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 28, :state :house, :altitude 14, :gradient 35, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 25} {:x 5, :y 28, :state :crop, :altitude 36, :gradient 51, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 38} {:x 6, :y 28, :state :climax, :altitude 52, :gradient 55, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 47} {:x 7, :y 28, :state :forest, :altitude 70, :gradient 46, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} {:x 8, :y 28, :state :scrub, :altitude 79, :gradient 46, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 59} {:x 9, :y 28, :state :scrub, :altitude 78, :gradient 48, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 29} {:x 10, :y 28, :state :climax, :altitude 56, :gradient 45, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 51} {:x 11, :y 28, :state :scrub, :altitude 35, :gradient 30, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 52} {:x 12, :y 28, :state :climax, :altitude 26, :gradient 23, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 57} {:x 13, :y 28, :state :climax, :altitude 33, :gradient 23, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 46} {:x 14, :y 28, :state :pasture, :altitude 37, :gradient 26, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 56} {:x 15, :y 28, :state :pasture, :altitude 33, :gradient 36, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 62} {:x 16, :y 28, :state :crop, :altitude 40, :gradient 31, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 35} {:x 17, :y 28, :state :house, :altitude 50, :gradient 26, :generation 103, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 43} {:x 18, :y 28, :state :pasture, :altitude 42, :gradient 27, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 19, :y 28, :state :house, :altitude 37, :gradient 15, :generation 103, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 19} {:x 20, :y 28, :state :ploughland, :altitude 33, :gradient 16, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 30} {:x 21, :y 28, :state :pasture, :altitude 26, :gradient 36, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 19} {:x 22, :y 28, :state :house, :altitude 17, :gradient 26, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 14} {:x 23, :y 28, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 28, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 29, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 29, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 29, :state :ploughland, :altitude 12, :gradient 35, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 31} {:x 5, :y 29, :state :grassland, :altitude 32, :gradient 40, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 44} {:x 6, :y 29, :state :heath, :altitude 41, :gradient 42, :generation 103, :rule "if state is waste and some neighbours are forest then state should be heath", :fertility 62} {:x 7, :y 29, :state :scrub, :altitude 40, :gradient 51, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 32} {:x 8, :y 29, :state :scrub, :altitude 50, :gradient 52, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 58} {:x 9, :y 29, :state :scrub, :altitude 60, :gradient 52, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 62} {:x 10, :y 29, :state :climax, :altitude 52, :gradient 51, :generation 103, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 67} {:x 11, :y 29, :state :climax, :altitude 35, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 71} {:x 12, :y 29, :state :scrub, :altitude 26, :gradient 22, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 59} {:x 13, :y 29, :state :scrub, :altitude 24, :gradient 24, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 49} {:x 14, :y 29, :state :pasture, :altitude 28, :gradient 24, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 67} {:x 15, :y 29, :state :house, :altitude 33, :gradient 19, :generation 103, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 47} {:x 16, :y 29, :state :ploughland, :altitude 43, :gradient 17, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 18} {:x 17, :y 29, :state :house, :altitude 49, :gradient 21, :generation 103, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 21} {:x 18, :y 29, :state :grassland, :altitude 41, :gradient 23, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 13} {:x 19, :y 29, :state :inn, :altitude 38, :gradient 15, :generation 103, :rule "if state is house and some neighbours are market and more than 1 neighbours are house then 1 chance in 5 state should be inn", :fertility 34} {:x 20, :y 29, :state :crop, :altitude 37, :gradient 36, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 25} {:x 21, :y 29, :state :grassland, :altitude 22, :gradient 36, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 18} {:x 22, :y 29, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 29, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 29, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 30, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 30, :state :house, :altitude 12, :gradient 27, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 17} {:x 4, :y 30, :state :ploughland, :altitude 28, :gradient 31, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 20} {:x 5, :y 30, :state :climax, :altitude 31, :gradient 29, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 6, :y 30, :state :climax, :altitude 28, :gradient 13, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 70} {:x 7, :y 30, :state :scrub, :altitude 28, :gradient 23, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 52} {:x 8, :y 30, :state :climax, :altitude 37, :gradient 34, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 83} {:x 9, :y 30, :state :forest, :altitude 27, :gradient 42, :generation 103, :rule "if state is scrub then 1 chance in 5 state should be forest", :fertility 64} {:x 10, :y 30, :state :climax, :altitude 28, :gradient 47, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 28} {:x 11, :y 30, :state :climax, :altitude 32, :gradient 42, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 47} {:x 12, :y 30, :state :climax, :altitude 28, :gradient 26, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 58} {:x 13, :y 30, :state :pasture, :altitude 13, :gradient 19, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 74} {:x 14, :y 30, :state :pasture, :altitude 24, :gradient 24, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 44} {:x 15, :y 30, :state :scrub, :altitude 33, :gradient 30, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 66} {:x 16, :y 30, :state :house, :altitude 35, :gradient 36, :generation 103, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 32} {:x 17, :y 30, :state :pasture, :altitude 36, :gradient 36, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 18, :y 30, :state :house, :altitude 29, :gradient 47, :generation 103, :rule "if state is house and some neighbours are pasture then state should be house", :fertility 28} {:x 19, :y 30, :state :market, :altitude 27, :gradient 40, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 12} {:x 20, :y 30, :state :house, :altitude 27, :gradient 37, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 21, :y 30, :state :water, :altitude 2, :gradient 36, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 30, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 30, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 31, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 31, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 31, :state :harbour, :altitude 1, :gradient 35, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 31, :state :ploughland, :altitude 24, :gradient 44, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 35} {:x 5, :y 31, :state :climax, :altitude 29, :gradient 26, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 64} {:x 6, :y 31, :state :climax, :altitude 31, :gradient 22, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 75} {:x 7, :y 31, :state :heath, :altitude 28, :gradient 23, :generation 103, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 45} {:x 8, :y 31, :state :scrub, :altitude 27, :gradient 19, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 68} {:x 9, :y 31, :state :scrub, :altitude 26, :gradient 19, :generation 103, :rule "if state is fire then state should be waste", :fertility 68} {:x 10, :y 31, :state :scrub, :altitude 18, :gradient 19, :generation 103, :rule "if state is heath and altitude is less than 120 then state should be scrub", :fertility 45} {:x 11, :y 31, :state :heath, :altitude 13, :gradient 22, :generation 103, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 48} {:x 12, :y 31, :state :scrub, :altitude 10, :gradient 23, :generation 103, :rule "if state is fire then state should be waste", :fertility 66} {:x 13, :y 31, :state :water, :altitude 9, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 31, :state :pasture, :altitude 23, :gradient 32, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 59} {:x 15, :y 31, :state :pasture, :altitude 17, :gradient 34, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 52} {:x 16, :y 31, :state :scrub, :altitude 13, :gradient 35, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 59} {:x 17, :y 31, :state :ploughland, :altitude 14, :gradient 35, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 21} {:x 18, :y 31, :state :house, :altitude 14, :gradient 35, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 19, :y 31, :state :water, :altitude 2, :gradient 28, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 31, :state :water, :altitude 1, :gradient 26, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 31, :state :water, :altitude 1, :gradient 26, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 31, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 31, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 32, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 32, :state :camp, :altitude 17, :gradient 31, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 56} {:x 3, :y 32, :state :climax, :altitude 22, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 92} {:x 4, :y 32, :state :climax, :altitude 36, :gradient 44, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 70} {:x 5, :y 32, :state :climax, :altitude 45, :gradient 26, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 25} {:x 6, :y 32, :state :climax, :altitude 50, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} {:x 7, :y 32, :state :heath, :altitude 45, :gradient 29, :generation 103, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 44} {:x 8, :y 32, :state :heath, :altitude 35, :gradient 30, :generation 103, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 46} {:x 9, :y 32, :state :scrub, :altitude 32, :gradient 38, :generation 103, :rule "if state is fire then state should be waste", :fertility 27} {:x 10, :y 32, :state :climax, :altitude 24, :gradient 25, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 11, :y 32, :state :climax, :altitude 19, :gradient 22, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 12, :y 32, :state :scrub, :altitude 20, :gradient 23, :generation 103, :rule "if state is fire then state should be waste", :fertility 77} {:x 13, :y 32, :state :climax, :altitude 20, :gradient 23, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 36} {:x 14, :y 32, :state :pasture, :altitude 14, :gradient 30, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 49} {:x 15, :y 32, :state :harbour, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 32, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 32, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 32, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 32, :state :water, :altitude 1, :gradient 13, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 32, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 32, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 33, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 33, :state :climax, :altitude 26, :gradient 31, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} {:x 3, :y 33, :state :climax, :altitude 32, :gradient 24, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 4, :y 33, :state :climax, :altitude 33, :gradient 33, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 5, :y 33, :state :climax, :altitude 41, :gradient 35, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 63} {:x 6, :y 33, :state :scrub, :altitude 46, :gradient 38, :generation 103, :rule "if state is fire then state should be waste", :fertility 73} {:x 7, :y 33, :state :climax, :altitude 55, :gradient 38, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 53} {:x 8, :y 33, :state :scrub, :altitude 56, :gradient 32, :generation 103, :rule "if state is fire then state should be waste", :fertility 48} {:x 9, :y 33, :state :climax, :altitude 38, :gradient 44, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 55} {:x 10, :y 33, :state :climax, :altitude 27, :gradient 26, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 11, :y 33, :state :climax, :altitude 31, :gradient 20, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 78} {:x 12, :y 33, :state :climax, :altitude 32, :gradient 17, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 47} {:x 13, :y 33, :state :climax, :altitude 31, :gradient 18, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} {:x 14, :y 33, :state :pasture, :altitude 26, :gradient 30, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 32} {:x 15, :y 33, :state :pasture, :altitude 12, :gradient 25, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 24} {:x 16, :y 33, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 33, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 33, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 34, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 34, :state :climax, :altitude 12, :gradient 31, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 90} {:x 3, :y 34, :state :climax, :altitude 12, :gradient 32, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 45} {:x 4, :y 34, :state :climax, :altitude 15, :gradient 40, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} {:x 5, :y 34, :state :climax, :altitude 17, :gradient 45, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 6, :y 34, :state :climax, :altitude 18, :gradient 38, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 78} {:x 7, :y 34, :state :climax, :altitude 29, :gradient 38, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 66} {:x 8, :y 34, :state :climax, :altitude 36, :gradient 33, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 67} {:x 9, :y 34, :state :climax, :altitude 23, :gradient 44, :generation 103, :rule "if state is in forest or climax or camp or house or inn and some neighbours are fire then 1 chance in 3 state should be fire", :fertility 61} {:x 10, :y 34, :state :climax, :altitude 12, :gradient 24, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 11, :y 34, :state :climax, :altitude 14, :gradient 20, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 59} {:x 12, :y 34, :state :climax, :altitude 17, :gradient 31, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 57} {:x 13, :y 34, :state :climax, :altitude 18, :gradient 31, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 63} {:x 14, :y 34, :state :climax, :altitude 18, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 85} {:x 15, :y 34, :state :climax, :altitude 23, :gradient 25, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 52} {:x 16, :y 34, :state :house, :altitude 18, :gradient 22, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 17, :y 34, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 34, :state :water, :altitude 1, :gradient 31, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 34, :state :water, :altitude 1, :gradient 31, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 34, :state :water, :altitude 1, :gradient 31, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 34, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 34, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 35, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 35, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 35, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 35, :state :water, :altitude 1, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 35, :state :ploughland, :altitude 22, :gradient 36, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 49} {:x 6, :y 35, :state :ploughland, :altitude 24, :gradient 20, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 40} {:x 7, :y 35, :state :pasture, :altitude 26, :gradient 19, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 49} {:x 8, :y 35, :state :climax, :altitude 26, :gradient 13, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} {:x 9, :y 35, :state :climax, :altitude 27, :gradient 24, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} {:x 10, :y 35, :state :climax, :altitude 24, :gradient 21, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 50} {:x 11, :y 35, :state :climax, :altitude 27, :gradient 21, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 39} {:x 12, :y 35, :state :climax, :altitude 22, :gradient 32, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 62} {:x 13, :y 35, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 35, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 35, :state :climax, :altitude 13, :gradient 22, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 16, :y 35, :state :climax, :altitude 12, :gradient 22, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} {:x 17, :y 35, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 35, :state :climax, :altitude 17, :gradient 48, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 91} {:x 19, :y 35, :state :climax, :altitude 32, :gradient 48, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 20, :y 35, :state :climax, :altitude 26, :gradient 48, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 54} {:x 21, :y 35, :state :water, :altitude 1, :gradient 34, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 35, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 36, :state :water, :altitude 1, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 36, :state :house, :altitude 24, :gradient 36, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 42} {:x 6, :y 36, :state :scrub, :altitude 37, :gradient 22, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 39} {:x 7, :y 36, :state :crop, :altitude 32, :gradient 13, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 35} {:x 8, :y 36, :state :grassland, :altitude 27, :gradient 9, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 39} {:x 9, :y 36, :state :climax, :altitude 32, :gradient 7, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 10, :y 36, :state :climax, :altitude 31, :gradient 10, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 66} {:x 11, :y 36, :state :climax, :altitude 33, :gradient 13, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 12, :y 36, :state :climax, :altitude 26, :gradient 32, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 72} {:x 13, :y 36, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 36, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 36, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 36, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 36, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 36, :state :climax, :altitude 19, :gradient 48, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} {:x 19, :y 36, :state :climax, :altitude 49, :gradient 18, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 79} {:x 20, :y 36, :state :climax, :altitude 35, :gradient 48, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 83} {:x 21, :y 36, :state :water, :altitude 1, :gradient 34, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 36, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 37, :state :water, :altitude 1, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 37, :state :house, :altitude 13, :gradient 36, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 34} {:x 6, :y 37, :state :crop, :altitude 35, :gradient 35, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 20} {:x 7, :y 37, :state :house, :altitude 35, :gradient 19, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 49} {:x 8, :y 37, :state :house, :altitude 28, :gradient 23, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 34} {:x 9, :y 37, :state :climax, :altitude 27, :gradient 30, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} {:x 10, :y 37, :state :climax, :altitude 29, :gradient 32, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 11, :y 37, :state :climax, :altitude 23, :gradient 32, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 40} {:x 12, :y 37, :state :heath, :altitude 18, :gradient 32, :generation 103, :rule "if state is waste and some neighbours are climax then state should be heath", :fertility 50} {:x 13, :y 37, :state :water, :altitude 1, :gradient 25, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 37, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 37, :state :climax, :altitude 17, :gradient 48, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 95} {:x 19, :y 37, :state :climax, :altitude 33, :gradient 47, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 20, :y 37, :state :camp, :altitude 23, :gradient 48, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp"} {:x 21, :y 37, :state :water, :altitude 1, :gradient 34, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 37, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 38, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 38, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 38, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 38, :state :water, :altitude 2, :gradient 34, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 38, :state :house, :altitude 19, :gradient 34, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 28} {:x 7, :y 38, :state :grassland, :altitude 19, :gradient 34, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 20} {:x 8, :y 38, :state :pasture, :altitude 18, :gradient 34, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 41} {:x 9, :y 38, :state :market, :altitude 12, :gradient 27, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 20} {:x 10, :y 38, :state :harbour, :altitude 2, :gradient 28, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 38, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 38, :state :water, :altitude 2, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 38, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 38, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 38, :state :camp, :altitude 12, :gradient 32, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 15} {:x 19, :y 38, :state :climax, :altitude 17, :gradient 32, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 86} {:x 20, :y 38, :state :water, :altitude 2, :gradient 32, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 38, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 38, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 39, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 39, :state :climax, :altitude 12, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} {:x 4, :y 39, :state :house, :altitude 19, :gradient 27, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 5, :y 39, :state :water, :altitude 2, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 39, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 39, :state :harbour, :altitude 1, :gradient 28, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 39, :state :pasture, :altitude 15, :gradient 48, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 26} {:x 9, :y 39, :state :inn, :altitude 26, :gradient 47, :generation 103, :rule "if state is house and some neighbours are crop then state should be house", :fertility 43} {:x 10, :y 39, :state :camp, :altitude 26, :gradient 48, :generation 103, :rule "if state is in waste or grassland and some neighbours are market then state should be camp", :fertility 49} {:x 11, :y 39, :state :crop, :altitude 23, :gradient 48, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 52} {:x 12, :y 39, :state :house, :altitude 13, :gradient 41, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 58} {:x 13, :y 39, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 39, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 39, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 39, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 39, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 39, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 39, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 39, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 40, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 40, :state :pasture, :altitude 13, :gradient 27, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 10} {:x 4, :y 40, :state :ploughland, :altitude 28, :gradient 26, :generation 103, :rule "if state is pasture and fertility is more than 10 and altitude is less than 100 and some neighbours are camp or some neighbours are house then state should be ploughland", :fertility 12} {:x 5, :y 40, :state :house, :altitude 14, :gradient 27, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 15} {:x 6, :y 40, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 40, :state :house, :altitude 15, :gradient 28, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 39} {:x 8, :y 40, :state :house, :altitude 29, :gradient 49, :generation 103, :rule "if state is house and some neighbours are market then state should be house", :fertility 37} {:x 9, :y 40, :state :grassland, :altitude 49, :gradient 46, :generation 103, :rule "if state is market then state should be grassland", :fertility 9} {:x 10, :y 40, :state :climax, :altitude 49, :gradient 38, :generation 103, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 68} {:x 11, :y 40, :state :grassland, :altitude 42, :gradient 48, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 46} {:x 12, :y 40, :state :pasture, :altitude 28, :gradient 50, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 77} {:x 13, :y 40, :state :grassland, :altitude 18, :gradient 34, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 49} {:x 14, :y 40, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 40, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 41, :state :water, :altitude 1, :gradient 12, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 41, :state :climax, :altitude 12, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 82} {:x 4, :y 41, :state :climax, :altitude 28, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 65} {:x 5, :y 41, :state :scrub, :altitude 18, :gradient 27, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 17} {:x 6, :y 41, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 41, :state :house, :altitude 14, :gradient 28, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 8, :y 41, :state :scrub, :altitude 29, :gradient 49, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 62} {:x 9, :y 41, :state :house, :altitude 50, :gradient 37, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 38} {:x 10, :y 41, :state :scrub, :altitude 61, :gradient 19, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 54} {:x 11, :y 41, :state :scrub, :altitude 51, :gradient 33, :generation 103, :rule "if state is in climax and more than 3 neighbours within 2 are house then state should be scrub", :fertility 53} {:x 12, :y 41, :state :climax, :altitude 35, :gradient 33, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 13, :y 41, :state :pasture, :altitude 20, :gradient 34, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 75} {:x 14, :y 41, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 41, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 41, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 42, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 42, :state :water, :altitude 1, :gradient 11, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 42, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 42, :state :camp, :altitude 14, :gradient 27, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 21} {:x 5, :y 42, :state :house, :altitude 12, :gradient 27, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 22} {:x 6, :y 42, :state :water, :altitude 1, :gradient 17, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 42, :state :water, :altitude 1, :gradient 28, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 42, :state :climax, :altitude 24, :gradient 49, :generation 103, :rule "if state is forest and fertility is more than 5 and altitude is less than 70 then state should be climax", :fertility 36} {:x 9, :y 42, :state :crop, :altitude 32, :gradient 47, :generation 103, :rule "if state is ploughland then state should be crop", :fertility 20} {:x 10, :y 42, :state :house, :altitude 40, :gradient 41, :generation 103, :rule "if state is house and some neighbours are ploughland then state should be house", :fertility 18} {:x 11, :y 42, :state :grassland, :altitude 40, :gradient 33, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 33} {:x 12, :y 42, :state :pasture, :altitude 32, :gradient 31, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 52} {:x 13, :y 42, :state :climax, :altitude 23, :gradient 34, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 73} {:x 14, :y 42, :state :water, :altitude 2, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 42, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 42, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 43, :state :water, :altitude 1, :gradient 16, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 43, :state :water, :altitude 2, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 3, :y 43, :state :water, :altitude 2, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 4, :y 43, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 43, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 43, :state :water, :altitude 2, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 43, :state :water, :altitude 1, :gradient 23, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 43, :state :house, :altitude 14, :gradient 31, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 38} {:x 9, :y 43, :state :pasture, :altitude 20, :gradient 39, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 29} {:x 10, :y 43, :state :grassland, :altitude 28, :gradient 39, :generation 103, :rule "if state is crop then state should be grassland and fertility should be fertility - 1", :fertility 30} {:x 11, :y 43, :state :pasture, :altitude 28, :gradient 23, :generation 103, :rule "if state is in grassland or heath and some neighbours within 2 are house then state should be pasture", :fertility 50} {:x 12, :y 43, :state :climax, :altitude 28, :gradient 25, :generation 103, :rule "if state is climax then 1 chance in 500 state should be fire", :fertility 73} {:x 13, :y 43, :state :climax, :altitude 23, :gradient 31, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 81} {:x 14, :y 43, :state :water, :altitude 2, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 43, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 43, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 44, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 44, :state :house, :altitude 17, :gradient 36, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 6} {:x 3, :y 44, :state :camp, :altitude 28, :gradient 36, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 20} {:x 4, :y 44, :state :water, :altitude 2, :gradient 36, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 44, :state :camp, :altitude 12, :gradient 21, :generation 103, :rule "if state is in grassland or heath and more than 3 neighbours are water and generation is more than 20 then state should be camp", :fertility 47} {:x 6, :y 44, :state :climax, :altitude 22, :gradient 14, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 95} {:x 7, :y 44, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 44, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 44, :state :water, :altitude 1, :gradient 27, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 44, :state :house, :altitude 20, :gradient 27, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house", :fertility 36} {:x 11, :y 44, :state :climax, :altitude 17, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 69} {:x 12, :y 44, :state :climax, :altitude 22, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 88} {:x 13, :y 44, :state :climax, :altitude 15, :gradient 27, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 88} {:x 14, :y 44, :state :water, :altitude 1, :gradient 22, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 44, :state :water, :altitude 1, :gradient 1, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 44, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 45, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 45, :state :climax, :altitude 19, :gradient 36, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 84} {:x 3, :y 45, :state :climax, :altitude 37, :gradient 26, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 68} {:x 4, :y 45, :state :climax, :altitude 14, :gradient 36, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 78} {:x 5, :y 45, :state :harbour, :altitude 2, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 45, :state :house, :altitude 15, :gradient 21, :generation 103, :rule "if state is house and more than 2 neighbours are water then state should be house"} {:x 7, :y 45, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 45, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 45, :state :water, :altitude 1, :gradient 19, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 45, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 45, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 45, :state :water, :altitude 1, :gradient 21, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 45, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 45, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}] [{:x 0, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 1, :y 46, :state :water, :altitude 1, :gradient 18, :generation 103, :rule "if state is water then state should be water"} {:x 2, :y 46, :state :climax, :altitude 13, :gradient 36, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} {:x 3, :y 46, :state :climax, :altitude 22, :gradient 35, :generation 103, :rule "if state is in forest or climax then fertility should be fertility + 1", :fertility 80} {:x 4, :y 46, :state :water, :altitude 2, :gradient 36, :generation 103, :rule "if state is water then state should be water"} {:x 5, :y 46, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 6, :y 46, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 7, :y 46, :state :water, :altitude 1, :gradient 14, :generation 103, :rule "if state is water then state should be water"} {:x 8, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 9, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 10, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 11, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 12, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 13, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 14, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 15, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 16, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 17, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 18, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 19, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 20, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 21, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 22, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 23, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 24, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 25, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 26, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 27, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 28, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 29, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 30, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 31, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 32, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 33, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 34, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 35, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 36, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 37, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 38, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 39, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 40, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 41, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 42, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 43, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 44, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 45, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 46, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"} {:x 47, :y 46, :state :water, :altitude 1, :gradient 0, :generation 103, :rule "if state is water then state should be water"}]] \ No newline at end of file diff --git a/resources/maps/barra/barra_101.html b/resources/maps/barra/barra_101.html new file mode 100644 index 0000000..d273b71 --- /dev/null +++ b/resources/maps/barra/barra_101.html @@ -0,0 +1 @@ +Microworld render
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxclimaxclimaxclimaxwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxclimaxclimaxclimaxclimaxcampwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxclimaxclimaxclimaxclimaxclimaxwaterwaterwaterclimaxhousewater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxgrasslandclimaxwaterwaterwaterwaterclimaxclimaxclimaxclimaxclimaxclimaxwaterwaterwaterwatercampclimaxwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxhousewaterwaterwaterwaterhousepasturepastureclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterhousehousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterharbourmarketpasturegrasslandgrasslandgrasslandwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxpastureclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterinncropcropcropcamppasturewaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxclimaxwaterwaterwaterwaterclimaxforesthousewaterwaterwaterwaterwaterwaterwatercampgrasslandcrophousegrasslandhousewaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxcropclimaxwaterwaterwaterwaterwaterclimaxscrubpasturehousewaterwaterwaterwaterwaterwaterwaterhousecrophousepasturewaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterhouseclimaxclimaxpasturepasturehousewaterhousepasturescrubforesthousewaterwaterwaterwaterwaterwaterwatercropforestcrophousewaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterhousegrasslandclimaxclimaxploughlandharbourpasturepasturepastureclimaxwaterwaterwaterwaterwaterwaterwaterwaterpasturepasturescrubwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwatergrasslandgrasslandforestscrubforestwaterhouseforestpasturehousewaterwaterwaterwaterwaterwaterwaterwaterhousehousewaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwatercrophousegrasslandinnmarketwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxgrasslandhousehousehousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterforestclimaxclimaxcropcropploughlandhousewaterwaterwaterwaterwaterwaterwaterwaterhouseclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxclimaxclimaxclimaxscrubpasturewatergrasslandwaterwaterwaterwaterwaterwaterwaterscrubgrasslandclimaxploughlandclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterhousecropclimaxclimaxscrubscrubscrubclimaxclimaxclimaxforestclimaxpastureclimaxwaterwaterwaterwaterwaterwaterploughlandploughlandclimaxclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwatercroppastureclimaxheathheathscrubscrubclimaxclimaxclimaxclimaxscrubscrubclimaxclimaxclimaxclimaxclimaxscrubheathpasturegrasslandcropcropclimaxcampwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterhousecropscrubheathscrubscrubclimaxscrubclimaxclimaxclimaxforestclimaxclimaxclimaxclimaxclimaxclimaxclimaxclimaxpasturescrubhousehouseclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterscrubscrubclimaxscrubforestscrubscrubclimaxheathscrubclimaxclimaxclimaxclimaxclimaxforestclimaxclimaxheathscrubcropgrasslandhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterclimaxheathclimaxheathscrubscrubscrubscrubscrubclimaxclimaxclimaxscrubclimaxclimaxclimaxclimaxscrubscrubclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterclimaxforestscrubclimaxforestclimaxscrubclimaxscrubclimaxheathclimaxscrubclimaxclimaxclimaxclimaxclimaxclimaxclimaxclimaxclimaxcampwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterpasturescrubscrubheathscrubclimaxscrubclimaxforestclimaxclimaxscrubclimaxclimaxclimaxclimaxclimaxpasturepastureclimaxharbourwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterwaterpasturescrubheathscrubscrubscrubscrubclimaxclimaxscrubclimaxscrubheathscrubclimaxclimaxclimaxpastureclimaxclimaxcampwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterhouseclimaxgrasslandclimaxclimaxclimaxclimaxscrubheathclimaxforestclimaxforestclimaxforestscrubclimaxclimaxclimaxclimaxclimaxhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterhouseclimaxcrophousegrasslandclimaxclimaxclimaxscrubscrubforestforestscrubforestscrubclimaxscrubclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterclimaxcropgrasslandgrasslandgrasslandpasturescrubscrubscrubclimaxforestscrubforestpastureclimaxpasturescrubpasturewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterclimaxclimaxpastureheathclimaxpasturescrubscrubclimaxscrubpasturecropcropcropclimaxclimaxclimaxpasturewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterhousecropclimaxforestscrubscrubclimaxscrubclimaxclimaxpasturepasturecrophousepasturehouseploughlandpasturehousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterploughlandgrasslandheathscrubscrubscrubclimaxclimaxscrubscrubpasturehouseploughlandhousegrasslandinncropgrasslandwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterhouseploughlandclimaxclimaxscrubclimaxforestclimaxclimaxclimaxpasturepasturescrubhousepasturehousemarkethousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterharbourploughlandclimaxclimaxheathscrubscrubscrubheathscrubwaterpasturepasturescrubploughlandhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwatercampclimaxclimaxclimaxclimaxheathheathscrubclimaxclimaxscrubclimaxpastureharbourwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterclimaxclimaxclimaxclimaxscrubclimaxscrubclimaxclimaxclimaxclimaxclimaxpasturepasturewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterclimaxclimaxclimaxclimaxclimaxclimaxclimaxclimaxclimaxclimaxclimaxclimaxclimaxclimaxhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterploughlandploughlandpastureclimaxclimaxclimaxclimaxclimaxwaterwaterclimaxclimaxwaterclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterhousescrubcropgrasslandclimaxclimaxclimaxclimaxwaterwaterwaterwaterwaterclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterhousecrophousehouseclimaxclimaxclimaxheathwaterwaterwaterwaterwaterclimaxclimaxcampwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterhousegrasslandpasturemarketharbourwaterwaterwaterwaterwaterwaterwatercampclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterclimaxhousewaterwaterharbourpastureinncampcrophousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterpastureploughlandhousewaterhousehousegrasslandclimaxgrasslandpasturegrasslandwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterclimaxclimaxscrubwaterhousescrubhousescrubscrubclimaxpasturewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwatercamphousewaterwaterclimaxcrophousegrasslandpastureclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterwaterwaterwaterwaterwaterwaterhousepasturegrasslandpastureclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterhousecampwatercampclimaxwaterwaterwaterhouseclimaxclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterclimaxclimaxclimaxharbourhousewaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              waterwaterclimaxclimaxwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwaterwater
              \ No newline at end of file diff --git a/resources/maps/noise.png b/resources/maps/noise.png new file mode 100644 index 0000000..8e9c001 Binary files /dev/null and b/resources/maps/noise.png differ diff --git a/resources/maps/noise.xcf b/resources/maps/noise.xcf new file mode 100644 index 0000000..9d78e5d Binary files /dev/null and b/resources/maps/noise.xcf differ diff --git a/resources/textures/Monkey.jpg b/resources/textures/Monkey.jpg new file mode 100644 index 0000000..cfe465d Binary files /dev/null and b/resources/textures/Monkey.jpg differ diff --git a/src/the_great_game/architecture.md b/src/cc/journeyman/architecture.md similarity index 100% rename from src/the_great_game/architecture.md rename to src/cc/journeyman/architecture.md diff --git a/src/cc/journeyman/the_great_game/agent/agent.clj b/src/cc/journeyman/the_great_game/agent/agent.clj new file mode 100644 index 0000000..f63c915 --- /dev/null +++ b/src/cc/journeyman/the_great_game/agent/agent.clj @@ -0,0 +1,111 @@ +(ns cc.journeyman.the-great-game.agent.agent + "Anything in the game world with agency; primarily but not exclusively + characters." + (:require [cc.journeyman.the-great-game.objects.game-object :refer [ProtoObject]] + [cc.journeyman.the-great-game.objects.container :refer [ProtoContainer]])) + +;;; hierarchy of needs probably gets implemented here +;;; I'm probably going to want to defprotocol stuff, to define the hierarchy +;;; of things in the gameworld; either that or drop to Java, wich I'd rather not do. + +;;; attitudes - liking/disliking, attraction/repulsion, amity/hostility, trust/fear +;;; also need to live at this layer, even though dynamic change in attitudes belongs +;;; in the character layer. + +(defprotocol ProtoAgent + "An object which can act in the world" + (act + [actor world circle] + "Allow `actor` to do something in this `world`, in the context of this + `circle`; return the new state of the actor if something was done, `nil` + if nothing was done. `Circle` is expected to be one of + + * `:active` - actors within visual/audible range of the player + character; + * `:pending` - actors not in the active circle, but sufficiently close + to it that they may enter the active circle within a short period; + * `:background` - actors who are active in the background in order to + handle trade, news, et cetera; + * `:other` - actors who are not members of any other circle. + + The `act` method *must not* have side effects; it must *only* return a + new state. If the actor's intention is to seek to change the state of + something else in the game world, it must add a representation of that + intention to the sequence which will be returned by its + `pending-intentions` method.") + (hungry? [actor world circle] "True if this actor is hungry and has no + immediate access to food.") + (pending-intentions + [actor] + "Returns a sequence of effects an actor intends, as a consequence of + acting.") + (pending-scheduled-action? [actor world circle] + "True if there is a plan in this `actor`'s + schedule which should be activated now. + NOTE THAT plans in the `daily` schedule are + NOT activated when in circles `:background` + or `:other`") + (plan-fight-or-flight [actor world circle] + "Return a plan to resolve any active threat to this + `actor` in this `world`.") + (plan-find-food [actor workd circle] + "Return a plan to find this `actor` food in this `world`.") + (plan-find-rest [actor workd circle] + "Return a plan to find this `actor` a safe place to rest, or + if in one, to actually rest, in this `world`.") + (plan-goal [actor world circle] "Return a plan to advance this `actor` + towards their personal objective, in this + world, or `nil` for default actors with no + objective.") + (plan-scheduled-action [actor workd circle] + "Return a plan taken from the schedule of this actor + for the current date and time, if any, else `nil`.") + (schedule [actor] "Return a map of scheduled actions for this `actor`. + TODO: work out the detailed format!") + (threatened? [actor world circle] "True if this `actor` is threatened in this + `world`.") + (tired? [actor world circle] "True if this `actor` needs rest.")) + +;; (defrecord Agent +;; ;; "A default agent." +;; [name craft home culture] +;; ProtoObject +;; ProtoContainer +;; ProtoAgent + +;; (act +;; “Return a world like this `world `except that this `actor `has acted in it. +;; ‘Circle’ indicates which activation circle the actor is in. + +;; Note that this implies that a `plan `is a function of three arguments, an +;; actor, a world. and a circle.” +;; [actor world circle] +;; (let [urgent (case circle +;; :other (cond +;; (pending-scheduled-action? actor world circle) +;; (plan-scheduled-action actor world circle) +;; (empty? (:plans actor)) +;; (plan-goal actor world circle)) +;; :background (cond +;; (threatened? actor world circle) +;; (plan-fight-or-flight actor world circle) +;; (pending-scheduled-action? actor world circle) +;; (plan-scheduled-action actor world circle) +;; (empty? (:plans actor)) +;; (plan-goal actor world circle)) +;; ;; else +;; (cond +;; (threatened? actor world circle) +;; (plan-fight-or-flight actor world circle) +;; (hungry? actor world circle) +;; (plan-find-food actor world circle) +;; (tired? actor world circle) +;; (plan-find-rest actor world circle) +;; (pending-scheduled-action? actor world circle) +;; (plan-scheduled-action actor world circle) +;; (empty? (:plans actor)) +;; (plan-goal actor world circle))) +;; a’ (if urgent +;; (assoc actor :plans (cons urgent (:plans actor))) +;; actor)] +;; (eval ((first (:plans a’)) a’ world))))) diff --git a/src/cc/journeyman/the_great_game/agent/schedule.clj b/src/cc/journeyman/the_great_game/agent/schedule.clj new file mode 100644 index 0000000..8fef3cb --- /dev/null +++ b/src/cc/journeyman/the_great_game/agent/schedule.clj @@ -0,0 +1,55 @@ +(ns cc.journeyman.the-great-game.agent.schedule + "Schedules of plans for actors in the game, in order that they may have + daily and seasonal patterns of behaviour.") + +;; TODO: I don't have a good handle yet on when a new scheduled task can +;; interrupt an existing scheduled task. It's highly undesirable that +;; uncompleted scheduled tasks should be left on the queue. The simplest +;; solution is to arrange the schedule such that, under notmal circumstances, +;; no scheduled task will interrupt another. But if a scheduled task is +;; interrupted by an attack, say, or a conversation, and then continued, +;; there's a chance of overrunning the start of the next. +;; +;; Perhaps I need to give scheduled tasks the equivalent of a watchdog timer, +;; but that makes them much more sophisticated objects than I wanted them to +;; be. + +;; NOTE: this assumes that a world contains a key `:time` whose values are +;; a map with at least the keys +;; 1. `:day`, whose value is an integer representing the current day of the +;; year, and +;; 2. `minute`, whose value is an integer representing the current minute of +;; the day. +;; it probably also includes a `:year`, but that isn't needed here. + +;; (def default-human-schedule +;; "A sample schedule for a human actor. This assumes that each of: +;; 1. `find-food`; +;; 2. `goto-market`; +;; 3. `help-with-harvest`; +;; 3. `perform-craft` +;; 4. `sleep-until-dawn` +;; Are plans, which is to say, functions of three arguments, an `actor`, +;; a `world` and a `circle`." +;; {:annual {32 {:daily {1020 (fn [a w c] (attend-festival a w c :imbolc))}} +;; 122 {:daily {1020 (fn [a w c] (attend-festival a w c :bealtaine))}} +;; 210 {:daily {480 help-with-harvest}} +;; 211 {:daily {480 help-with-harvest}} +;; 212 {:daily {480 help-with-harvest}} +;; 213 {:daily {480 help-with-harvest}} +;; 214 {:daily {480 help-with-harvest +;; 1020 (fn [a w c](attend-festival a w c :lughnasadh))}} +;; 306 {:daily {1020 (fn [a w c] (attend-festival a w c :samhain))}}} +;; :daily {420 find-food +;; 720 find-food +;; 1020 find-food +;; 1320 sleep-until-dawn}}) + +(defn plan-scheduled-action [actor world circle] + "Return the scheduled plan for the current time in this `world` from the + schedule of this `actor`, provided the `actor is in an appropriate `circle`" + (case circle + (:active :pending) (let [s (:schedule actor) + d (or (:daily (-> s :annual (-> world :time :day))) + (:daily s))] + (when d (d (-> world :time :minute)))))) \ No newline at end of file diff --git a/src/cc/journeyman/the_great_game/buildings/module.clj b/src/cc/journeyman/the_great_game/buildings/module.clj new file mode 100644 index 0000000..6791e9f --- /dev/null +++ b/src/cc/journeyman/the_great_game/buildings/module.clj @@ -0,0 +1,81 @@ +(ns cc.journeyman.the-great-game.buildings.module + + "A module of a building; essentially something like a portacabin, which can be + assembled together with other modules to make a complete building. + + Modules need to include + + 1. Ground floor modules, having external doors; + 2. Craft modules -- workshops -- which will normally be ground floor (except + weavers) and may have the constraint that no upper floor module can cover them; + 3. Upper floor modules, having NO external doors (but linking internal doors); + 4. Roof modules + + **Role** must be one of: + + 1. `:primary` a ground floor main entrance module + 2. `:secondary` a module which can be upper or ground floor + 3. `:upper` a module which can only be on an upper floor, for example one + with a projecting gallery, balcony or overhang. + + Other values for `role` will emerge. + + **Exits** must be a sequence of keywords taken from the following list: + + 1. `:left` an exit in the centre of the left wall + 2. `:left-front` an exit in the centre of the left half of the front wall + 3. `:front` an exit in the centre of the front wall + 4. `:right-front` an exit in the centre of the right half of the front wall + 5. `:right` an exit in the centre of the right wall + 6. `:right-back` an exit in the centre of the right half of the back wall + 7. `:left-back` an exit in the centre of the back wall + + A module placed on an upper floor must have no exit which opens beyond the + footprint of the floor below - no doors into mid air! However, it is allowable + (and indeed is necessary) to allow doors into roof spaces if the adjacent + module on the same floor does not yet exist, since otherwise it would be + impossible to access a new room which might later be built there. + + **Load** must be a small integer indicating both the weight of the module and + the total amount of weight it can support. So for example a stone-built module + might have a `load` value of 4, a brick built one of 3, and a half-timbered one + of 2, and a tent of 0. This means a stone ground floor module could support one + further floor of stone or brick, or two further floors of half timbered + construction; while a brick built ground floor could support a single brick or + half-timbered upper floor but not a stone one, and a half-timbered ground floor + could only support a half timbered upper floor. + + There also needs to be an undercroft or platform module, such that the area of + the top of the platform is identical with the footprint of the building, and + the altitude of the top of the platform is equal to the altitude of the + terrain at the heighest corner of the building; so that the actual + building doesn't float in the air, and also so that none of the doors or windows + are partly underground. + + Each module needs to wrap an actual 3d model created in Blender or whatever, + and have a list of optional **textures** with which that model can be rendered. + So an upper floor bedroom module might have the following renders: + + 1. Bare masonry - constrained to upland or plateau terrain, and to coastal culture + 2. Painted masonry - constrained to upland or plateau terrain, and to coastal culture + 3. Half-timbered - not available on plateau terrain + 4. Weatherboarded - constrained to forest terrain + 5. Brick - constrained to arable or arid terrain + + of course these are only examples, and also, it's entirely possible to have + for example multiple different weatherboard renders for the same module. + There needs to be a way of rendering what can be built above what: for + example, you can't have a masonry clad module over a half timbered one, + but you can have a half-timbered one over a masonry one.") + +(defrecord BuildingModule + [model + ^Double length + ^Double width + ^Double height + ^Integer load + ^clojure.lang.Keyword role + ^clojure.lang.IPersistentCollection textures + ^clojure.lang.IPersistentCollection exits + ] + ) \ No newline at end of file diff --git a/src/cc/journeyman/the_great_game/buildings/rectangular.clj b/src/cc/journeyman/the_great_game/buildings/rectangular.clj new file mode 100644 index 0000000..1000a6d --- /dev/null +++ b/src/cc/journeyman/the_great_game/buildings/rectangular.clj @@ -0,0 +1,150 @@ +(ns cc.journeyman.the-great-game.buildings.rectangular + "Build buildings with a generally rectangular floow plan. + + ## Motivations + + Right, the idea behind this namespace is many fold. + + 1. To establish the broad principle of genetic buildings, by creating a + function which reproducibly creates reproducible buildings at specified + locations, such that different buildings are credibly varied but a + building at a specified location is always (modulo economic change) the + same. + 2. Create good rectangular buildings, and investigate whether a single + function can be used to create buildings of more than one family (e.g. + can it produce flat roofed, north African style, mud brick houses as + well as pitch roofed, half timbered northern European houses?) + 3. Establish whether, in my current state of fairly severe mental illness, + I can actually produce any usable code at all. + + ## Key factors in the creation of a building + + ### Holding + + Every building is on a holding, and, indeed, what I mean by 'building' here + may well turn out to be 'the collection of all the permanent structures on + a holding. A holding is a polygonal area of the map which does not + intersect with any other holding, but for the time being we'll make the + simplifying assumption that every holding is a rectangular strip, and that + 'urban' holdings are of a reasonably standard width (see Viking-period + York) and length. Rural holdings (farms, ?wood lots) may be much larger. + + ### Terrain + + A building is made of the stuff of the place. In a forest, buildings will + tend to be wooden; in a terrain with rocky outcrops -- normally found on + steep slopes -- stone. On the flat lands where there's river mud, of brick, + cob, or wattle and daub. So to build a building we need to know the + terrain. Terrain can be inferred from location but in practice this will + be computationally expensive, so we'll pass terrain in as an argument to + the build function. + + For the time being we'll pass it in simply as a keyword from a defined set + of keywords; later it may be a more sophisticated data structure. + + ### Culture + + People of different cultures build distinctively different buildings, even + when using the same materials. So, in our world, a Japanese wooden house + looks quite different from an Anglo Saxon stave house which looks quite + different from a Canadian log cabin, even though the materials are much the + same and the tools available to build with are not much different. + + Culture can affect not just the overall shape of a building but also its + finish and surface detail. For example, in many places in England, stone + buildings are typically left bare; in rural Scotland, typically painted + white or in pastel shades; in Ireland, often quite vivid colours. + + People may also show religious or cultural symbols on their buildings. + + For all these reasons, we need to know the culture of the occupant when + creating a building. Again, this will initially be passed in as a keyword. + + ### Craft + + People in the game world have a craft, and some crafts will require + different features in the building. In the broadly late-bronze-age-to + medieval period within which the game is set, residence and workplace + are for most people pretty much the same. + + So a baker needs an oven, a smith a forge, and so on. All crafts who do + some degree retail trade will want a shop front as part of the ground + floor of their dwelling. Merchants and bankers will probably have houses + that are a bit more showy than others. + + Whether the 'genetic buildings' idea will ever really produce suitable + buildings for aristons I don't know; it seems more likely that significant + strongholds (of which there will be relatively few) should all be hand + modelled rather than procedurally generated." + (:require [cc.journeyman.the-great-game.holdings.holding :refer [ProtoHolding]] + [cc.journeyman.the-great-game.location.location :refer [ProtoLocation]]) + (:import [org.apache.commons.math3.random MersenneTwister])) + + +(def ^:dynamic *terrain-types* + "Types of terrain which affect building families. TODO: This is a placeholder; + a more sophisticated model will be needed." + #{:arable :arid :forest :plateau :upland}) + +(def ^:dynamic *cultures* + "Cultures which affect building families. TODO: placeholder" + #{:ariston :coastal :steppe-clans :western-clans :wild-herd}) + +(def ^:dynamic *crafts* + "Crafts which affect building types in the game. See + `Populating a game world`. TODO: placeholder" + #{:baker :banker :butcher :chancellor :innkeeper :lawyer :magus :merchant :miller :priest :scholar :smith :weaver}) + +(def ^:dynamic *building-families* + "Families of buildings. + + Each family has + + * terrain types to which it is appropriate; + * crafts to which it is appropriate; + * cultures to which it is appropriate. + + Each generated building will be of one family, and will comprise modules + taken only from that family." + {:pitched-rectangular {:terrains #{:arable :forest :upland} + :crafts *crafts* + :cultures #{:coastal :western-clans} + :modules []} + :flatroof-rectangular {:terrains #{:arid :plateau} + :crafts *crafts* + :cultures #{:coastal} + :modules []}}) + + +(defn building-family + "A building family is essentially a collection of models of building modules + which can be assembled to create buildings of a particular structural and + architectural style." + [terrain culture craft gene] + (let [candidates (filter #(and + ((:terrains %) terrain) + ((:crafts %) craft) + ((:cultures %) culture)) + (vals *building-families*))] + (nth candidates (mod (Math/abs (.nextInt gene)) (count candidates))))) + +(building-family :arable :coastal :baker (MersenneTwister. 5)) + +(defn build! + "Builds a building, and returns a data structure which represents it. In + building the building, it adds a model of the building to the representation + of the world, so it does have a side effect." + [holding terrain culture craft size] + (if (satisfies? ProtoHolding holding) + (let [location (.building-origin holding) + gene (MersenneTwister. (int (+ (* (.easting location) 1000000) (.northing location)))) + family (building-family terrain culture craft gene)] + (if + (and (instance? ProtoLocation location) (:orientation location)) + :stuff + :nonsense + )) + :froboz)) + +;; (def ol (cc.journeyman.the-great-game.location.location/OrientedLocation. 123.45 543.76 12.34 0.00 {})) + diff --git a/src/cc/journeyman/the_great_game/character/character.clj b/src/cc/journeyman/the_great_game/character/character.clj new file mode 100644 index 0000000..ce174f4 --- /dev/null +++ b/src/cc/journeyman/the_great_game/character/character.clj @@ -0,0 +1,9 @@ +(ns cc.journeyman.the-great-game.character.character + "A character that can talk; either human or dragon (although very probably + we won't do talking dragons until really well into this process). All + characters have the news-passing abilities of a gossip, but we use `gossip` + to mean a special character who is part of the news-passing network." + (:require [cc.journeyman.the-great-game.gossip.gossip :refer [dialogue]] + [cc.journeyman.the-great-game.agent.agent :refer [Agent]])) + + diff --git a/src/cc/journeyman/the_great_game/gossip/gossip.clj b/src/cc/journeyman/the_great_game/gossip/gossip.clj new file mode 100644 index 0000000..6686c36 --- /dev/null +++ b/src/cc/journeyman/the_great_game/gossip/gossip.clj @@ -0,0 +1,73 @@ +(ns cc.journeyman.the-great-game.gossip.gossip + "Interchange of news events between gossip agents. + + 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. + + Innkeepers are also gossip agents but do not typically move." + (:require [cc.journeyman.the-great-game.utils :refer [deep-merge]] + [cc.journeyman.the-great-game.gossip.news-items :refer [learn-news-item]] + )) + + +(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 + "Gather news for the specified `gossip` in this `world`." + [world gossip] + (let [g (cond (keyword? gossip) + (-> world :gossips gossip) + (map? gossip) + gossip)] + (if g + {:gossips + {(:id g) + (reduce + deep-merge + {} + (map + #(dialogue g % world) + (remove + #(= g %) + (filter + #(= (:location %) (:location g)) + (vals (:gossips world))))))}} + {}))) + +(defn move-gossip + "Return a world like this `world` but with this `gossip` moved to this + `new-location`. Many gossips are essentially shadow-records of agents of + other types, and the movement of the gossip should be controlled by the + run function of the type of the record they shadow. The [[#run]] function + below does NOT call this function." + [gossip world new-location] + (let [id (cond + (map? gossip) + (-> world :gossips gossip :id) + (keyword? gossip) + gossip)] + (deep-merge + world + {:gossips + {id + {:location new-location}}}))) + +(defn run + "Return a world like this `world`, with news items exchanged between gossip + agents." + [world] + (reduce + deep-merge + world + (map + #(gather-news world %) + (keys (:gossips world))))) + + diff --git a/src/cc/journeyman/the_great_game/gossip/news_items.clj b/src/cc/journeyman/the_great_game/gossip/news_items.clj new file mode 100644 index 0000000..ce97716 --- /dev/null +++ b/src/cc/journeyman/the_great_game/gossip/news_items.clj @@ -0,0 +1,341 @@ +(ns cc.journeyman.the-great-game.gossip.news-items + "Using news items (propositions) to transfer knowledge between gossip agents. + + ## Status + + What is here is essentially working. It's not, however, working with the + rich data objects which will be needed, and it's not yet nearly efficient + enough, but it allows knowledge to propagate through the world procedurally, + at a rate limited by the speed of movement of the gossip agents. + + ## Discussion + + The ideas here are based on the essay [The spread of knowledge in a large + game world](The-spread-of-knowledge-in-a-large-game-world.html), q.v.; + they've advanced a little beyond that and will doubtless + advance further in the course of writing and debugging this namespace. + + A news item is a map with the keys: + + * `date` - the date on which the reported event is claimed to have happened; + * `nth-hand` - the number of agents the news item has passed through; + * `verb` - what it is that happened (key into `news-topics`); + + plus other keys taken from the `keys` value associated with the verb in + `news-topics`. + + ## Notes: + + *TODO* + This namespace at present considers the `:knowledge` of a gossip to be a flat + list of propositions, each of which must be checked every time any new + proposition is offered. This is woefully inefficient. " + (:require [clojure.set :refer [union]] + [cc.journeyman.the-great-game.world.location :refer [distance-between]] + [cc.journeyman.the-great-game.time :refer [game-time]] + [cc.journeyman.the-great-game.utils :refer [inc-or-one truthy?]] + [taoensso.timbre :as l])) + +(declare interesting-location?) + +(def news-topics + "Topics of interest to gossip agents. Topics are keyed in this map by + their `verbs`. The `keys` associated with each topic are the extra pieces + of information required to give context to a gossip item. Generally: + + * `actor` is the id of the character who it is reported performed the + action; + * `other` is the id of the character on whom it is reported the action + was performed; + * `location` is the place at which the action was performed; + * `object` is an object (or possibly list of objects?) relevant to the + action; + * `price` is special to buy/sell, but of significant interest to merchants. + + ## Characters + + *TODO* but note that at most all the receiver can learn about a character + from a news item is what the giver knows about that character, degraded by + what the receiver finds interesting about them. If we just pass the id here, + then either the receiver knows everything in the database about the + character, or else the receiver knows nothing at all about the character. + Neither is desirable. Further thought needed. + + By implication, the character values passed should include *all* the + information the giver knows about the character; that can then be degraded + as the receiver stores only that segment which the receiver finds + interesting. + + ## Locations + + A 'location' value is a list comprising at most the x/y coordinate location + and the ids of the settlement and region (possibly hierarchically) that contain + the location. If the x/y is not local to the home of the receiving agent, they + won't remember it and won't pass it on; if any of the ids are not interesting + So location information will degrade progressively as the item is passed along. + + It is assumed that the `:home` of a character is a location in this sense. + + ## Inferences + + If an agent learns that Adam has married Betty, they can infer that Betty has + married Adam; if they learn that Charles killed Dorothy, that Dorothy has died. + I'm not convinced that my representation of inferences here is ideal." + {;; A significant attack is interesting whether or not it leads to deaths + :attack {:verb :attack :keys [:actor :other :location]} + ;; Deaths of characters may be interesting + :die {:verb :die :keys [:actor :location]} + ;; Deliberate killings are interesting. + :kill {:verb :kill :keys [:actor :other :location] + :inferences [{:verb :die :actor :other :other :nil}]} + ;; Marriages may be interesting + :marry {:verb :marry :keys [:actor :other :location] + :inferences [{:verb :marry :actor :other :other :actor}]} + ;; The end of ongoing open conflict between to characters may be interesting + :peace {:verb :peace :keys [:actor :other :location] + :inferences [{:verb :peace :actor :other :other :actor}]} + ;; Things related to the plot are interesting, but will require special + ;; handling. Extra keys may be required by particular plot events. + :plot {:verb :plot :keys [:actor :other :object :location]} + ;; Rapes are interesting. + :rape {:verb :rape :keys [:actor :other :location] + ;; Should you also infer from rape that actor is male and adult? + :inferences [{:verb :attack} + {:verb :sex} + {:verb :sex :actor :other :other :actor}]} + ;; Merchants, especially, are interested in prices in other markets + :sell {:verb :sell :keys [:actor :other :object :location :quantity :price]} + ;; Sex can juicy gossip, although not normally if the participants are in an + ;; established sexual relationship. + :sex {:verb :sex :keys [:actor :other :location] + :inferences [{:verb :sex :actor :other :other :actor}]} + ;; Thefts are interesting. + :steal {:verb :steal :keys [:actor :other :object :location]} + ;; The succession of rulers is interesting; of respected craftsmen, + ;; potentially also interesting. + :succession {:verb :succession :keys [:actor :other :location :rank]} + ;; The start of ongoing open conflict between two characters may be interesting. + :war {:verb :war :keys [:actor :other :location] + :inferences [{:verb :war :actor :other :other :actor}]}}) + +(def all-known-verbs + "All verbs currently known to the gossip system." + (set (keys news-topics))) + +(defn interest-in-character + "Integer representation of how interesting this `character` is to this + `gossip`. + *TODO:* this assumes that characters are passed as keywords, but, as + documented above, they probably have to be maps, to allow for degradation." + [gossip character] + (count + (concat + ;; TODO: we ought also check the relationships of the gossip. + ;; Are relationships just propositions in the knowledge base? + (filter #(= (:actor %) character) (:knowledge gossip)) + (filter #(= (:other %) character) (:knowledge gossip)) + (when (interesting-location? gossip (:home character)) + (list true))))) + +(defn interesting-character? + "Boolean representation of whether this `character` is interesting to this + `gossip`." + [gossip character] + (> (interest-in-character gossip character) 0)) + +(defn interest-in-location + "Integer representation of how interesting this `location` is to this + `gossip`." + [gossip location] + (cond + (and (map? location) (number? (:x location)) (number? (:y location))) + (if-let [home (:home gossip)] + (let [d (distance-between location home) + i (if + (zero? d) 1 + (/ 10000 d)) + ;; 10000 at metre scale is 10km; interest should + ;;fall off with distance from home, but possibly on a log scale + ] + (if (>= i 1) i 0)) + 0) + (coll? location) + (reduce + + + (map + #(interest-in-location gossip %) + location)) + :else + (count + (filter + #(some (fn [x] (= x location)) (:location %)) + (cons {:location (:home gossip)} (:knowledge gossip)))))) + +;; (distance-between {:x 25 :y 37} {:x 25 :y 37}) +;; (interest-in-location {:home [{0, 0} :test-home] :knowledge []} [:test-home]) + +(defn interesting-location? + "True if the location of this news `item` is interesting to this `gossip`." + [gossip location] + (> (interest-in-location gossip location) 0)) + +(defn interesting-object? + [gossip object] + ;; TODO: Not yet (really) implemented + true) + +(defn interesting-verb? + "Is this `verb` interesting to this `gossip`?" + [gossip verb] + (let [vs (:interesting-verbs gossip)] + (truthy? + (when (set? vs) + (vs verb))))) + +;; (interesting-verb? {:interesting-verbs #{:kill :sell}} :sell) + +(defn compatible-value? + "True if `known-value` is the same as `new-value`, or, for each key present + in `new-value`, has the same value for that key. + + The rationale here is that if `new-value` contains new or different + information, it's worth learning; otherwise, not." + [new-value known-value] + (or + (= new-value known-value) + ;; TODO: some handwaving here about being a slightly better descriptor -- + ;; having more keys than might + (when (and (map? new-value) (map? known-value)) + (every? true? (map #(= (new-value %) (known-value %)) + (keys new-value)))))) + +(defn compatible-item? + "True if `new-item` is identical with, or less specific than, `known-item`. + + If we already know 'Bad Joe killed Sweet Daisy', there's no point in + learning that 'someone killed Sweet Daisy', but there is point in learning + 'someone killed Sweet Daisy _with poison_'." + [new-item known-item] + (truthy? + (reduce + #(and %1 %2) + (map #(if + (known-item %) ;; if known-item has this key + (compatible-value? (new-item %) (known-item %)) + true) + (remove #{:nth-hand :confidence :learned-from} (keys new-item)))))) + +(defn known-item? + "True if this news `item` is already known to this `gossip`. + + This means that the `gossip` already knows an item which identifiably has + the same _or more specific_ values for all the keys of this `item` except + `:nth-hand`, `:confidence` and `:learned-from`." + [gossip item] + (truthy? + (reduce + #(or %1 %2) + false + (filter true? (map #(compatible-item? item %) (:knowledge gossip)))))) + +(defn interesting-item? + "True if anything about this news `item` is interesting to this `gossip`." + [gossip item] + (and (not (known-item? gossip item)) + (interesting-verb? gossip (:verb item)) ;; news is only interesting if the topic is. + (or + (interesting-character? gossip (:actor item)) + (interesting-character? gossip (:other item)) + (interesting-location? gossip (:location item)) + (interesting-object? gossip (:object item))))) + +(defn infer + "Infer a new knowledge item from this `item`, following this `rule`." + [item rule] + (l/info "Applying rule '" rule "' to item '" item "'") + (reduce merge + item + (cons + {:verb (:verb rule) + :nth-hand (inc-or-one (:nth-hand item))} + (map (fn [k] {k (item (rule k))}) + (remove + #{:verb :nth-hand} + (keys rule)))))) + +(declare learn-news-item) + +(defn make-all-inferences + "Return a set of knowledge entries that can be inferred from this news + `item`." + [item] + (set + (map + #(infer item %) + (:inferences (news-topics (:verb item)))))) + +(defn degrade-character + "Return a character specification like this `character`, but comprising + only those properties this `gossip` is interested in." + [gossip character] + ;; TODO: Not yet (really) implemented + character) + +(defn degrade-location + "Return a location specification like this `location`, but comprising + only those elements this `gossip` is interested in. If none, return + `nil`." + [gossip location] + (let [l (when + (coll? location) + (filter + #(when (interesting-location? gossip %) %) + location))] + (when-not (empty? l) l))) + +(defn degrade-news-item + [gossip item] + (assoc + item + :nth-hand (inc-or-one (:nth-hand item)) + :time-stamp (if + (number? (:time-stamp item)) + (:time-stamp item) + (game-time)) + :location (degrade-location gossip (:location item)) + :actor (degrade-character gossip (:actor item)) + :other (degrade-character gossip (:other item)) + ;; TODO: do something to degrade confidence in the item, + ;; probably as a function of the provider's confidence in + ;; the item and the gossip's trust in the provider + )) + +;; (degrade-news-item {:home [{:x 25 :y 37} :auchencairn :scotland]} +;; {:verb :marry :actor :adam :other :belinda :location [{:x 25 :y 37} :auchencairn :scotland]}) + +(defn learn-news-item + "Return a gossip like this `gossip`, which has learned this news `item` if + it is of interest to them." + ([gossip item] + (learn-news-item gossip item true)) + ([gossip item follow-inferences?] + (if + (interesting-item? gossip item) + (let [item' (degrade-news-item gossip item) + g (assoc + gossip + :knowledge + (set + (cons + item' + (:knowledge gossip))))] + (if follow-inferences? + (assoc + g + :knowledge + (union (:knowledge g) (make-all-inferences item'))) + g)) + gossip))) + + + diff --git a/src/cc/journeyman/the_great_game/holdings/holding.clj b/src/cc/journeyman/the_great_game/holdings/holding.clj new file mode 100644 index 0000000..a84deff --- /dev/null +++ b/src/cc/journeyman/the_great_game/holdings/holding.clj @@ -0,0 +1,46 @@ +(ns cc.journeyman.the-great-game.holdings.holding + (:require [cc.journeyman.the-great-game.agent.agent :refer [ProtoAgent]] + [cc.journeyman.the-great-game.objects.container :refer [ProtoContainer]] + [cc.journeyman.the-great-game.objects.game-object :refer [ProtoObject]] +;; [cc.journeyman.the-great-game.location.location :refer [OrientedLocation]] + [cc.journeyman.the-great-game.world.routes :refer []])) + +;;; A holding is a polygonal area of the map which does not +;;; intersect with any other holding, or with any road or water feature. For +;;; the time being we'll make the +;;; simplifying assumption that every holding is a rectangular strip, and that +;;; 'urban' holdings are of a reasonably standard width (see Viking-period +;;; York) and length. Rural holdings (farms, ?wood lots) may be much larger. + +(defprotocol ProtoHolding + (frontage + [holding] + "Returns a sequence of two locations representing the edge of the polygon + which defines this holding which is considered to be the front.") + (building-origin + [holding] + "Returns an oriented location - normally the right hand end of the + frontage, for an urban holding - from which buildings on the holding + should be built.")) + +(defrecord Holding [perimeter holder] + ;; Perimeter should be a list of locations in exactly the same sense as a + ;; route in `cc.journeyman.the-great-game.world.routes`. Some sanity checking + ;; is needed to ensure this! + ProtoContainer + ProtoHolding + (frontage + [holding] + "TODO: this is WRONG, but will work for now. The frontage should + be the side of the perimeter nearest to the nearest existing + route." + [(first (perimeter holding)) (nth (perimeter holding) 1)]) + (building-origin + [holding] + "TODO: again this is WRONG. The default building origin for rectangular + buildings should be the right hand end of the frontage when viewed + from outside the holding. But that's not general; celtic-style circular + buildings should normally be in the centre of their holdings. So probably + building-origin becomes a method of building-family rather than of holding." + (first (frontage holding))) + ProtoObject) diff --git a/src/cc/journeyman/the_great_game/location/location.clj b/src/cc/journeyman/the_great_game/location/location.clj new file mode 100644 index 0000000..1fdc3b9 --- /dev/null +++ b/src/cc/journeyman/the_great_game/location/location.clj @@ -0,0 +1,45 @@ +(ns cc.journeyman.the-great-game.location.location) + +;;; There's probably conflict between this sense of a reified location and +;;; the simpler sense of a location described in +;;; `cc.journeyman.the-great-game.world.location`, q.v. This needs to +;;; be resolved! + +(defprotocol ProtoLocation + (easting [location] + "Return the easting of this location") + (northing [location] "Return the northing of this location") + (altitude [location] + "Return the absolute altitude of this location, which may be + different from the terrain height at this location, if, for + example, the location is underground or on an upper floor.") + (terrain-altitude [location] + "Return the 'ground level' (altitude of the terrain) + at this location given this world. TODO: possibly + terrain-altitude should be a method of the world.") + (settlement [location] + "Return the settlement record of the settlement in this world + within whose parish polygon this location exists, or if none + whose centre (inn location) is closest to this location")) + + +(defrecord Location [^Double easting ^Double northing ^Double altitude world] + ProtoLocation + (easting [l] (:easting l)) + (northing [l] (:northing l)) + (altitude [l] (:altitude l)) + (terrain-altitude [l] 0.0) ;; TODO + (settlement [l] :tchahua)) + +(defrecord OrientedLocation + ;; "Identical to a Location except having, additionally, an orientation" + [^Double easting ^Double northing ^Double altitude ^Double orientation world] + ProtoLocation + (easting [l] (:easting l)) + (northing [l] (:northing l)) + (altitude [l] (:altitude l)) + (terrain-altitude [l] 0.0) ;; TODO + (settlement [l] :tchahua)) ;; TODO + + ;; (.settlement (OrientedLocation. 123.45 543.76 12.34 0.00 {})) + diff --git a/src/cc/journeyman/the_great_game/lore/digester.clj b/src/cc/journeyman/the_great_game/lore/digester.clj new file mode 100644 index 0000000..b7d2d54 --- /dev/null +++ b/src/cc/journeyman/the_great_game/lore/digester.clj @@ -0,0 +1,5 @@ +(ns cc.journeyman.the-great-game.lore.digester + ;; (:require [org.clojurenlp.core :refer [pos-tag sentenize split-sentences + ;; tag-ner tokenize word + ;; ]]) + ) diff --git a/src/the_great_game/merchants/markets.clj b/src/cc/journeyman/the_great_game/merchants/markets.clj similarity index 95% rename from src/the_great_game/merchants/markets.clj rename to src/cc/journeyman/the_great_game/merchants/markets.clj index c4f0898..09bce1a 100644 --- a/src/the_great_game/merchants/markets.clj +++ b/src/cc/journeyman/the_great_game/merchants/markets.clj @@ -1,7 +1,7 @@ -(ns the-great-game.merchants.markets +(ns cc.journeyman.the-great-game.merchants.markets "Adjusting quantities and prices in markets." (:require [taoensso.timbre :as l :refer [info error]] - [the-great-game.utils :refer [deep-merge]])) + [cc.journeyman.the-great-game.utils :refer [deep-merge]])) (defn new-price "If `stock` is greater than the maximum of `supply` and `demand`, then diff --git a/src/the_great_game/merchants/merchant_utils.clj b/src/cc/journeyman/the_great_game/merchants/merchant_utils.clj similarity index 98% rename from src/the_great_game/merchants/merchant_utils.clj rename to src/cc/journeyman/the_great_game/merchants/merchant_utils.clj index 9cfb5b4..ae6b8b0 100644 --- a/src/the_great_game/merchants/merchant_utils.clj +++ b/src/cc/journeyman/the_great_game/merchants/merchant_utils.clj @@ -1,4 +1,4 @@ -(ns the-great-game.merchants.merchant-utils +(ns cc.journeyman.the-great-game.merchants.merchant-utils "Useful functions for doing low-level things with merchants.") (defn expected-price diff --git a/src/cc/journeyman/the_great_game/merchants/merchants.clj b/src/cc/journeyman/the_great_game/merchants/merchants.clj new file mode 100644 index 0000000..a4124b4 --- /dev/null +++ b/src/cc/journeyman/the_great_game/merchants/merchants.clj @@ -0,0 +1,28 @@ +(ns cc.journeyman.the-great-game.merchants.merchants + "Trade planning for merchants, primarily." + (:require [cc.journeyman.the-great-game.utils :refer [deep-merge]] + [cc.journeyman.the-great-game.merchants.strategies.simple :refer [move-merchant]] + [taoensso.timbre :as l])) + + +(defn run + "Return a partial world based on this `world`, but with each merchant moved." + [world] + (try + (reduce + deep-merge + world + (map + #(try + (let [move-fn (or + (-> world :merchants % :move-fn) + move-merchant)] + (apply move-fn (list % 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))) + diff --git a/src/the_great_game/merchants/planning.clj b/src/cc/journeyman/the_great_game/merchants/planning.clj similarity index 92% rename from src/the_great_game/merchants/planning.clj rename to src/cc/journeyman/the_great_game/merchants/planning.clj index e784036..333eead 100644 --- a/src/the_great_game/merchants/planning.clj +++ b/src/cc/journeyman/the_great_game/merchants/planning.clj @@ -1,12 +1,12 @@ -(ns the-great-game.merchants.planning +(ns cc.journeyman.the-great-game.merchants.planning "Trade planning for merchants, primarily. This follows a simple-minded generate-and-test strategy and currently generates plans for all possible routes from the current location. This may not scale. Also, routes do not currently have cost or risk associated with them." - (:require [the-great-game.utils :refer [deep-merge make-target-filter]] - [the-great-game.merchants.merchant-utils :refer :all] - [the-great-game.world.routes :refer [find-route]] - [the-great-game.world.world :refer [actual-price default-world]])) + (:require [cc.journeyman.the-great-game.utils :refer [deep-merge make-target-filter]] + [cc.journeyman.the-great-game.merchants.merchant-utils :refer [can-afford can-carry expected-price]] + [cc.journeyman.the-great-game.world.routes :refer [find-route]] + [cc.journeyman.the-great-game.world.world :refer [actual-price default-world]])) (defn generate-trade-plans "Generate all possible trade plans for this `merchant` and this `commodity` @@ -146,8 +146,7 @@ #(let [q (-> world :cities origin :stock %)] (and (number? q) (pos? q))) (keys available)))] - (if - (not (empty? plans)) + (when-not (empty? plans) (first (sort-by #(- 0 (:dist-to-home %)) diff --git a/src/the_great_game/merchants/strategies/simple.clj b/src/cc/journeyman/the_great_game/merchants/strategies/simple.clj similarity index 92% rename from src/the_great_game/merchants/strategies/simple.clj rename to src/cc/journeyman/the_great_game/merchants/strategies/simple.clj index d43e952..b8062f7 100644 --- a/src/the_great_game/merchants/strategies/simple.clj +++ b/src/cc/journeyman/the_great_game/merchants/strategies/simple.clj @@ -1,4 +1,4 @@ -(ns the-great-game.merchants.strategies.simple +(ns cc.journeyman.the-great-game.merchants.strategies.simple "Default trading strategy for merchants. The simple strategy buys a single product in the local market if there is @@ -7,12 +7,12 @@ profitably, moves towards home with no cargo. If at home and no commodity can be traded profitably, does not move." (:require [taoensso.timbre :as l :refer [info error spy]] - [the-great-game.utils :refer [deep-merge]] - [the-great-game.gossip.gossip :refer [move-gossip]] - [the-great-game.merchants.planning :refer :all] - [the-great-game.merchants.merchant-utils :refer + [cc.journeyman.the-great-game.utils :refer [deep-merge]] + [cc.journeyman.the-great-game.gossip.gossip :refer [move-gossip]] + [cc.journeyman.the-great-game.merchants.planning :refer [augment-plan plan-trade select-cargo]] + [cc.journeyman.the-great-game.merchants.merchant-utils :refer [add-stock add-known-prices]] - [the-great-game.world.routes :refer [find-route]])) + [cc.journeyman.the-great-game.world.routes :refer [find-route]])) (defn plan-and-buy "Return a world like this `world`, in which this `merchant` has planned @@ -30,7 +30,7 @@ plan (select-cargo merchant world)] (l/debug "plan-and-buy: merchant" id) (cond - (not (empty? plan)) + (seq? plan) (let [c (:commodity plan) p (* (:quantity plan) (:buy-price plan)) diff --git a/src/cc/journeyman/the_great_game/objects/character.clj b/src/cc/journeyman/the_great_game/objects/character.clj new file mode 100644 index 0000000..cc8baab --- /dev/null +++ b/src/cc/journeyman/the_great_game/objects/character.clj @@ -0,0 +1,2 @@ +(ns cc.journeyman.the-great-game.objects.character + (:require [cc.journeyman.the-great-game.objects.game-object :as obj])) \ No newline at end of file diff --git a/src/the_great_game/objects/container.clj b/src/cc/journeyman/the_great_game/objects/container.clj similarity index 67% rename from src/the_great_game/objects/container.clj rename to src/cc/journeyman/the_great_game/objects/container.clj index 80a18ce..5d5b48f 100644 --- a/src/the_great_game/objects/container.clj +++ b/src/cc/journeyman/the_great_game/objects/container.clj @@ -1,6 +1,6 @@ -(ns the-great-game.objects.container +(ns cc.journeyman.the-great-game.objects.container (:require - [the-great-game.objects.game-object :refer :all])) + [cc.journeyman.the-great-game.objects.game-object :refer :all])) (defprotocol ProtoContainer (contents diff --git a/src/the_great_game/objects/game_object.clj b/src/cc/journeyman/the_great_game/objects/game_object.clj similarity index 79% rename from src/the_great_game/objects/game_object.clj rename to src/cc/journeyman/the_great_game/objects/game_object.clj index 25c878c..be497e3 100644 --- a/src/the_great_game/objects/game_object.clj +++ b/src/cc/journeyman/the_great_game/objects/game_object.clj @@ -1,4 +1,4 @@ -(ns the-great-game.objects.game-object +(ns cc.journeyman.the-great-game.objects.game-object "Anything at all in the game world") (defprotocol ProtoObject @@ -12,8 +12,10 @@ which the object is keyed in the global object list.")) (defrecord GameObject - [id] + [id] ;; "An object in the world" ProtoObject (id [_] id) - (reify-object [object] "TODO: doesn't work yet")) + (reify-object [object] + "TODO: doesn't work yet" + object)) diff --git a/src/cc/journeyman/the_great_game/playroom.clj b/src/cc/journeyman/the_great_game/playroom.clj new file mode 100644 index 0000000..ad2cb2f --- /dev/null +++ b/src/cc/journeyman/the_great_game/playroom.clj @@ -0,0 +1,72 @@ +(ns cc.journeyman.the-great-game.playroom + (:require [jme-clj.core :refer [add add-to-root box defsimpleapp fly-cam geo + get* get-state load-texture rotate run set* + setc set-state start unshaded-mat]]) + (:import [com.jme3.math ColorRGBA])) + +;; At present this file is just somewhere to play around with jme-clj examples + +(declare app) + +(defn init [] + (let [cube (geo "jMonkey cube" (box 1 1 1)) + mat (unshaded-mat)] + (set* mat :texture "ColorMap" (load-texture "textures/Monkey.jpg")) + (set* cube :material mat) + (add-to-root cube) + {:cube cube})) + +;; Let's create simple-update fn with no body for now. + (defn simple-update [tpf] + (let [{:keys [cube]} (get-state)] + (rotate cube 0 (* 2 tpf) 0))) + + +;; Kills the running app var and closes its window. +;; (unbind-app #'app) + +;; We define the `app` var. +(defsimpleapp app + :opts {:show-settings? false + :pause-on-lost-focus? false + :settings {:title "My JME Game" + :load-defaults? true + :frame-rate 60 + :width 800 + :height 600}} + :init init + :update simple-update) + +;; (start app) + +;; Reinitialises the running app +;;(run app +;; (re-init init)) + + ;; By default, there is a Fly Camera attached to the app that you can control with W, A, S and D keys. + ;; Let's increase its movement speed. Now, you fly faster :) + ;; (run app + ;; (set* (fly-cam) :move-speed 15)) + + + ;; Updates the app +;; (run app +;; (let [{:keys [cube]} (get-state)] +;; (set* cube :local-translation (add (get* cube :local-translation) 1 1 1)))) + + ;; Updates the app adding a second cube +;; (run app +;; (let [cube (geo "jMonkey cube" (box 1 1 1)) +;; mat (unshaded-mat)] +;; (set* mat :texture "ColorMap" (load-texture "textures/Monkey.jpg")) +;; (setc cube +;; :material mat +;; :local-translation [-3 0 0]) +;; (add-to-root cube) +;; (set-state :cube2 cube))) + + ;; We added the new cube, but it's not rotating. We need to update the simple-update fn. + ;; (defn simple-update [tpf] + ;; (let [{:keys [cube cube2]} (get-state)] + ;; (rotate cube 0 (* 2 tpf) 0) + ;; (rotate cube2 0 (* 2 tpf) 0))) diff --git a/src/the_great_game/time.clj b/src/cc/journeyman/the_great_game/time.clj similarity index 99% rename from src/the_great_game/time.clj rename to src/cc/journeyman/the_great_game/time.clj index 2378937..b5bf753 100644 --- a/src/the_great_game/time.clj +++ b/src/cc/journeyman/the_great_game/time.clj @@ -1,4 +1,4 @@ -(ns the-great-game.time +(ns cc.journeyman.the-great-game.time (:require [clojure.string :as s])) (def game-start-time diff --git a/src/the_great_game/utils.clj b/src/cc/journeyman/the_great_game/utils.clj similarity index 54% rename from src/the_great_game/utils.clj rename to src/cc/journeyman/the_great_game/utils.clj index 98c2f6f..a25545f 100644 --- a/src/the_great_game/utils.clj +++ b/src/cc/journeyman/the_great_game/utils.clj @@ -1,4 +1,4 @@ -(ns the-great-game.utils) +(ns cc.journeyman.the-great-game.utils) (defn cyclic? "True if two or more elements of `route` are identical" @@ -33,3 +33,29 @@ (list (first %) 'm) (nth % 1)) targets))))) + +(defn value-or-default + "Return the value of this key `k` in this map `m`, or this `dflt` value if + there is none." + [m k dflt] + (or (when (map? m) (m k)) dflt)) + +;; (value-or-default {:x 0 :y 0 :altitude 7} :altitude 8) +;; (value-or-default {:x 0 :y 0 :altitude 7} :alt 8) +;; (value-or-default nil :altitude 8) + +(defn truthy? + "Returns `true` unless `val` is `nil`, `false` or an empty sequence. + Otherwise always 'false'; never any other value." + [val] + (and (or val false) true)) + + +(defn inc-or-one + "If this `val` is a number, return that number incremented by one; otherwise, + return 1. TODO: should probably be in `utils`." + [val] + (if + (number? val) + (inc val) + 1)) diff --git a/src/cc/journeyman/the_great_game/world/heightmap.clj b/src/cc/journeyman/the_great_game/world/heightmap.clj new file mode 100644 index 0000000..99369c8 --- /dev/null +++ b/src/cc/journeyman/the_great_game/world/heightmap.clj @@ -0,0 +1,159 @@ +(ns cc.journeyman.the-great-game.world.heightmap + "Functions dealing with the tessellated multi-layer heightmap." + (:require [clojure.math.numeric-tower :refer [expt sqrt]] + [mw-engine.core :refer []] + [mw-engine.heightmap :refer [apply-heightmap]] + [mw-engine.utils :refer [get-cell in-bounds? map-world]] + [cc.journeyman.the-great-game.utils :refer [value-or-default]])) + +;; It's not at all clear to me yet what the workflow for getting a MicroWorld +;; map into The Great Game, and whether it passes through Walkmap to get here. +;; This file as currently written assumes it doesn't. + +;; It's utterly impossible to hold a whole continent at one metre scale in +;; memory at one time. So we have to be able to regenerate high resolution +;; surfaces from much lower resolution heightmaps. +;; +;; Thus to reproduce a segment of surface at a particular level of detail, +;; we: +;; 1. load the base heightmap into a grid (see +;; `mw-engine.heightmap/apply-heightmap`); +;; 2. scale the base hightmap to kilometre scale (see `scale-grid`); +;; 3. exerpt the portion of that that we want to reproduce (see `exerpt-grid`); +;; 4. interpolate that grid to get the resolution we require (see +;; `interpolate-grid`); +;; 5. create an appropriate purturbation grid from the noise map(s) for the +;; same coordinates to break up the smooth interpolation; +;; 6. sum the altitudes of the two grids. +;; +;; In production this will have to be done **very** fast! + +(def ^:dynamic *base-map* "resources/maps/heightmap.png") +(def ^:dynamic *noise-map* "resources/maps/noise.png") + +(defn scale-grid + "multiply all `:x` and `:y` values in this `grid` by this `n`." + [grid n] + (map-world grid (fn [w c x] (assoc c :x (* (:x c) n) :y (* (:y c) n))))) + + + +;; Each of the east-west curve and the north-south curve are of course two +;; dimensional curves; the east-west curve is in the :x/:z plane and the +;; north-south curve is in the :y/:z plane (except, perhaps unwisely, +;; we've been using :altitude to label the :z plane). We have a library +;; function `walkmap.edge/intersection2d`, but as currently written it +;; can only find intersections in :x/:y plane. +;; +;; TODO: rewrite the function so that it can use arbitrary coordinates. +;; AFTER TRYING: OK, there are too many assumptions about the way that +;; function is written to allow for easy rotation. TODO: think! + +(defn interpolate-altitude + "Return the altitude of the point at `x-offset`, `y-offset` within this + `cell` having this `src-width`, taken from this `grid`." + [cell grid src-width x-offset y-offset ] + (let [c-alt (:altitude cell) + n-alt (or (:altitude (get-cell grid (:x cell) (dec (:y cell)))) c-alt) + w-alt (or (:altitude (get-cell grid (inc (:x cell)) (:y cell))) c-alt) + s-alt (or (:altitude (get-cell grid (:x cell) (inc (:y cell)))) c-alt) + e-alt (or (:altitude (get-cell grid (dec (:x cell)) (:y cell))) c-alt)] + ;; TODO: construct two curves (arcs of circles good enough for now) + ;; n-alt...c-alt...s-alt and e-alt...c-alt...w-alt; + ;; then interpolate x-offset along e-alt...c-alt...w-alt and y-offset + ;; along n-alt...c-alt...s-alt; + ;; then return the average of the two + + 0)) + +(defn interpolate-cell + "Construct a grid (array of arrays) of cells each of width `target-width` + from this `cell`, of width `src-width`, taken from this `grid`" + [cell grid src-width target-width] + (let [offsets (map #(* target-width %) (range (/ src-width target-width)))] + (into + [] + (map + (fn [r] + (into + [] + (map + (fn [c] + (assoc cell + :x (+ (:x cell) c) + :y (+ (:y cell) r) + :altitude (interpolate-altitude cell grid src-width c r))) + offsets))) + offsets)))) + +(defn interpolate-grid + "Return a grid interpolated from this `grid` of rows, cols given scaling + from this `src-width` to this `target-width`" + [grid src-width target-width] + (reduce + concat + (into + [] + (map + (fn [row] + (reduce + (fn [g1 g2] + (into [] (map #(into [] (concat %1 %2)) g1 g2))) + (into [] (map #(interpolate-cell % grid src-width target-width) row)))) + grid)))) + +(defn excerpt-grid + "Return that section of this `grid` where the `:x` co-ordinate of each cell + is greater than or equal to this `x-offset`, the `:y` co-ordinate is greater + than or equal to this `y-offset`, whose width is not greater than this + `width`, and whose height is not greater than this `height`." + [grid x-offset y-offset width height] + (into + [] + (remove + nil? + (map + (fn [row] + (when + (and + (>= (:y (first row)) y-offset) + (< (:y (first row)) (+ y-offset height))) + (into + [] + (remove + nil? + (map + (fn [cell] + (when + (and + (>= (:x cell) x-offset) + (< (:x cell) (+ x-offset width))) + cell)) + row))))) + grid)))) + +(defn get-surface + "Return, as a vector of vectors of cells represented as Clojure maps, a + segment of surface from this `base-map` as modified by this + `noise-map` at this `cell-size` starting at this `x-offset` and `y-offset` + and having this `width` and `height`. + + If `base-map` and `noise-map` are not supplied, the bindings of `*base-map*` + and `*noise-map*` will be used, respectively. + + `base-map` and `noise-map` may be passed either as strings, assumed to be + file paths of PNG files, or as MicroWorld style world arrays. It is assumed + that one pixel in `base-map` represents one square kilometre in the game + world. It is assumed that `cell-size`, `x-offset`, `y-offset`, `width` and + `height` are integer numbers of metres." + ([cell-size x-offset y-offset width height] + (get-surface *base-map* *noise-map* cell-size x-offset y-offset width height)) + ([base-map noise-map cell-size x-offset y-offset width height] + (let [b (if (seq? base-map) base-map (scale-grid (apply-heightmap base-map) 1000)) + n (if (seq? noise-map) noise-map (apply-heightmap noise-map))] + (if (and (in-bounds? b x-offset y-offset) + (in-bounds? b (+ x-offset width) (+ y-offset height))) + b ;; actually do stuff + (throw (Exception. "Surface out of bounds for map."))) + ))) + diff --git a/src/the_great_game/world/location.clj b/src/cc/journeyman/the_great_game/world/location.clj similarity index 96% rename from src/the_great_game/world/location.clj rename to src/cc/journeyman/the_great_game/world/location.clj index b7c3fd0..b4a5c3a 100644 --- a/src/the_great_game/world/location.clj +++ b/src/cc/journeyman/the_great_game/world/location.clj @@ -1,4 +1,4 @@ -(ns the-great-game.world.location +(ns cc.journeyman.the-great-game.world.location "Functions dealing with location in the world." (:require [clojure.math.numeric-tower :refer [expt sqrt]])) diff --git a/src/cc/journeyman/the_great_game/world/mw.clj b/src/cc/journeyman/the_great_game/world/mw.clj new file mode 100644 index 0000000..162a64c --- /dev/null +++ b/src/cc/journeyman/the_great_game/world/mw.clj @@ -0,0 +1,7 @@ +(ns cc.journeyman.the-great-game.world.mw + "Functions dealing with building a great game world from a MicroWorld world." + (:require [clojure.math.numeric-tower :refer [expt sqrt]] + [mw-engine.core :refer []] + [mw-engine.world :refer []])) + +;; It's not at all clear to me yet what the workflow for getting a MicroWorld map into The Great Game, and whether it passes through Walkmap to get here. This file as currently written assumes it doesn't. diff --git a/src/the_great_game/world/routes.clj b/src/cc/journeyman/the_great_game/world/routes.clj similarity index 93% rename from src/the_great_game/world/routes.clj rename to src/cc/journeyman/the_great_game/world/routes.clj index c45debc..64585b9 100644 --- a/src/the_great_game/world/routes.clj +++ b/src/cc/journeyman/the_great_game/world/routes.clj @@ -1,6 +1,6 @@ -(ns the-great-game.world.routes +(ns cc.journeyman.the-great-game.world.routes "Conceptual (plan level) routes, represented as tuples of location ids." - (:require [the-great-game.utils :refer [cyclic?]])) + (:require [cc.journeyman.the-great-game.utils :refer [cyclic?]])) (defn find-routes "Find routes from among these `routes` from `from`; if `to` is supplied, diff --git a/src/the_great_game/world/run.clj b/src/cc/journeyman/the_great_game/world/run.clj similarity index 75% rename from src/the_great_game/world/run.clj rename to src/cc/journeyman/the_great_game/world/run.clj index b324101..081d247 100644 --- a/src/the_great_game/world/run.clj +++ b/src/cc/journeyman/the_great_game/world/run.clj @@ -1,12 +1,12 @@ -(ns the-great-game.world.run +(ns cc.journeyman.the-great-game.world.run "Run the whole simulation" (:require [environ.core :refer [env]] [taoensso.timbre :as timbre] [taoensso.timbre.appenders.3rd-party.rotor :as rotor] - [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])) + [cc.journeyman.the-great-game.gossip.gossip :as g] + [cc.journeyman.the-great-game.merchants.merchants :as m] + [cc.journeyman.the-great-game.merchants.markets :as k] + [cc.journeyman.the-great-game.world.world :as w])) (defn init ([] diff --git a/src/the_great_game/world/world.clj b/src/cc/journeyman/the_great_game/world/world.clj similarity index 99% rename from src/the_great_game/world/world.clj rename to src/cc/journeyman/the_great_game/world/world.clj index 9334237..4d873dc 100644 --- a/src/the_great_game/world/world.clj +++ b/src/cc/journeyman/the_great_game/world/world.clj @@ -1,4 +1,4 @@ -(ns the-great-game.world.world +(ns cc.journeyman.the-great-game.world.world "Access to data about the world") ;;; The world has to work either as map or a database. Initially, and for diff --git a/src/the_great_game/agent/agent.clj b/src/the_great_game/agent/agent.clj deleted file mode 100644 index 43d8ff6..0000000 --- a/src/the_great_game/agent/agent.clj +++ /dev/null @@ -1,43 +0,0 @@ -(ns the-great-game.agent.agent - "Anything in the game world with agency" - (:require [the-great-game.objects.game-object :refer [ProtoObject]] - [the-great-game.objects.container :refer [ProtoContainer]])) - -;; hierarchy of needs probably gets implemented here -;; I'm probably going to want to defprotocol stuff, to define the hierarchy -;; of things in the gameworld; either that or drop to Java, wich I'd rather not do. - -(defprotocol ProtoAgent - "An object which can act in the world" - (act - [actor world circle] - "Allow `actor` to do something in this `world`, in the context of this - `circle`; return the new state of the actor if something was done, `nil` - if nothing was done. Circle is expected to be one of - - * `:active` - actors within visual/audible range of the player - character; - * `:pending` - actors not in the active circle, but sufficiently close - to it that they may enter the active circle within a short period; - * `:background` - actors who are active in the background in order to - handle trade, news, et cetera; - * `other` - actors who are not members of any other circle, although - I'm not clear whether it would ever be appropriate to invoke an - `act` method on them. - - The `act` method *must not* have side effects; it must *only* return a - new state. If the actor's intention is to seek to change the state of - something else in the game world, it must add a representation of that - intention to the sequence which will be returned by its - `pending-intentions` method.") - (pending-intentions - [actor] - "Returns a sequence of effects an actor intends, as a consequence of - acting. The encoding of these is not yet defined.")) - -;; (defrecord Agent -;; "A default agent." -;; ProtoObject -;; ProtoContainer -;; ProtoAgent -;; ) diff --git a/src/the_great_game/gossip/gossip.clj b/src/the_great_game/gossip/gossip.clj deleted file mode 100644 index af743f3..0000000 --- a/src/the_great_game/gossip/gossip.clj +++ /dev/null @@ -1,66 +0,0 @@ -(ns the-great-game.gossip.gossip - "Interchange of news events between gossip agents" - (:require [the-great-game.utils :refer [deep-merge]] - [the-great-game.gossip.news-items :refer [learn-news-item]])) - -;; 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 move-gossip - "Return a world like this `world` but with this `gossip` moved to this - `new-location`. Many gossips are essentially shadow-records of agents of - other types, and the movement of the gossip should be controlled by the - run function of the type of the record they shadow. The [[#run]] function - below does NOT call this function." - [gossip world new-location] - (let [id (cond - (map? gossip) - (-> world :gossips gossip :id) - (keyword? gossip) - gossip)] - (deep-merge - world - {:gossips - {id - {:location new-location}}}))) - -(defn run - "Return a world like this `world`, with news items exchanged between gossip - agents." - [world] - (gather-news world)) diff --git a/src/the_great_game/gossip/news_items.clj b/src/the_great_game/gossip/news_items.clj deleted file mode 100644 index 2b02479..0000000 --- a/src/the_great_game/gossip/news_items.clj +++ /dev/null @@ -1,256 +0,0 @@ -(ns the-great-game.gossip.news-items - "Categories of news events interesting to gossip agents" - (:require [the-great-game.world.location :refer [distance-between]] - [the-great-game.time :refer [game-time]])) - -;; The ideas here are based on the essay 'The spread of knowledge in a large -;; game world', q.v.; they've advanced a little beyond that and will doubtless -;; advance further in the course of writing and debugging this namespace. - -;; A news item is a map with the keys: -;; -;; * `date` - the date on which the reported event happened; -;; * `nth-hand` - the number of agents the news item has passed through; -;; * `verb` - what it is that happened (key into `news-topics`); -;; -;; plus other keys taken from the `keys` value associated with the verb in -;; `news-topics` - -(def news-topics - "Topics of interest to gossip agents. Topics are keyed in this map by - their `verbs`. The `keys` associated with each topic are the extra pieces - of information required to give context to a gossip item. Generally: - - * `actor` is the id of the character who it is reported performed the - action; - * `other` is the id of the character on whom it is reported the action - was performed; - * `location` is the place at which the action was performed; - * `object` is an object (or possibly list of objects?) relevant to the - action; - * `price` is special to buy/sell, but of significant interest to merchants. - - #### Notes: - - ##### Characters: - - *TODO* but note that at most all the receiver can learn about a character - from a news item is what the giver knows about that character, degraded by - what the receiver finds interesting about them. If we just pass the id here, - then either the receiver knows everything in the database about the - character, or else the receiver knows nothing at all about the character. - Neither is desirable. Further thought needed. - - By implication, the character values passed should include *all* the - information the giver knows about the character; that can then be degraded - as the receiver stores only that segment which the receiver finds - interesting. - - ##### Locations: - - A 'location' value is a list comprising at most the x/y coordinate location - and the ids of the settlement and region (possibly hierarchically) that contain - the location. If the x/y is not local to the home of the receiving agent, they - won't remember it and won't pass it on; if any of the ids are not interesting - So location information will degrade progressively as the item is passed along. - - It is assumed that the `:home` of a character is a location in this sense. - - ##### Inferences: - - If an agent learns that Adam has married Betty, they can infer that Betty has - married Adam; if they learn that Charles killed Dorothy, that Dorothy has died. - I'm not convinced that my representation of inferences here is ideal. - " - { ;; A significant attack is interesting whether or not it leads to deaths - :attack {:verb :attack :keys [:actor :other :location]} - ;; Deaths of characters may be interesting - :die {:verb :die :keys [:actor :location]} - ;; Deliberate killings are interesting. - :kill {:verb :kill :keys [:actor :other :location] - :inferences [{:verb :die :actor :other :other :nil}]} - ;; Marriages may be interesting - :marry {:verb :marry :keys [:actor :other :location] - :inferences [{:verb :marry :actor :other :other :actor}]} - ;; The end of ongoing open conflict between to characters may be interesting - :peace {:verb :peace :keys [:actor :other :location] - :inferences [{:verb :peace :actor :other :other :actor}]} - ;; Things related to the plot are interesting, but will require special - ;; handling. Extra keys may be required by particular plot events. - :plot {:verb :plot :keys [:actor :other :object :location]} - ;; Rapes are interesting. - :rape {:verb :rape :keys [:actor :other :location] - ;; Should you also infer from rape that actor is male and adult? - :inferences [{:verb :attack} - {:verb :sex} - {:verb :sex :actor :other :other :actor}]} - ;; Merchants, especially, are interested in prices in other markets - :sell {:verb :sell :keys [:actor :other :object :location :price]} - ;; Sex can juicy gossip, although not normally if the participants are in an - ;; established sexual relationship. - :sex {:verb :sex :keys [:actor :other :location] - :inferences [{:verb :sex :actor :other :other :actor}]} - ;; Thefts are interesting - :steal {:verb :steal :keys [:actor :other :object :location]} - ;; The succession of rulers is interesting; of respected craftsmen, - ;; potentially also interesting. - :succession {:verb :succession :keys [:actor :other :location :rank]} - ;; The start of ongoing open conflict between to characters may be interesting - :war {:verb :war :keys [:actor :other :location] - :inferences [{:verb :war :actor :other :other :actor}]} - }) - - -(defn interest-in-character - "Integer representation of how interesting this `character` is to this - `gossip`. - *TODO:* this assumes that characters are passed as keywords, but, as - documented above, they probably have to be maps, to allow for degradation." - [gossip character] - (count - (concat - (filter #(= (:actor % character)) (:knowledge gossip)) - (filter #(= (:other % character)) (:knowledge gossip))))) - -(defn interesting-character? - "Boolean representation of whether this `character` is interesting to this - `gossip`." - [gossip character] - (> (interest-in-character gossip character) 0)) - -(defn interest-in-location - "Integer representation of how interesting this `location` is to this - `gossip`." - [gossip location] - (cond - (and (map? location) (number? (:x location)) (number? (:y location))) - (if-let [home (:home gossip)] - (let [d (distance-between location home) - i (/ 10000 d) ;; 10000 at metre scale is 10km; interest should - ;;fall off with distance from home, but possibly on a log scale - ] - (if (> i 1) i 0)) - 0) - (coll? location) - (reduce - + - (map - #(interest-in-location gossip %) - location)) - :else - (count - (filter - #(some (fn [x] (= x location)) (:location %)) - (cons {:location (:home gossip)} (:knowledge gossip)))))) - -;; (interest-in-location {:home [{0, 0} :test-home] :knowledge []} [:test-home]) - -(defn interesting-location? - "True if the location of this news `item` is interesting to this `gossip`." - [gossip item] - (> (interest-in-location gossip (:location item)) 0)) - -(defn interesting-object? - [gossip object] - ;; TODO: Not yet (really) implemented - true) - -(defn interesting-topic? - [gossip topic] - ;; TODO: Not yet (really) implemented - true) - -(defn interesting-item? - "True if anything about this news `item` is interesting to this `gossip`." - [gossip item] - (or - (interesting-character? gossip (:actor item)) - (interesting-character? gossip (:other item)) - (interesting-location? gossip (:location item)) - (interesting-object? gossip (:object item)) - (interesting-topic? gossip (:verb item)))) - -(defn infer - "Infer a new knowledge item from this `item`, following this `rule`" - [item rule] - (reduce merge - item - (cons - {:verb (:verb rule)} - (map (fn [k] {k (apply (k rule) (list item))}) - (remove - #(= % :verb) - (keys rule)))))) - -(declare learn-news-item) - -(defn make-all-inferences - "Return a list of knowledge entries that can be inferred from this news - `item`." - [item] - (set - (reduce - concat - (map - #(:knowledge (learn-news-item {} (infer item %) false)) - (:inferences (news-topics (:verb item))))))) - -(defn degrade-character - "Return a character specification like this `character`, but comprising - only those properties this `gossip` is interested in." - [gossip character] - ;; TODO: Not yet (really) implemented - character) - -(defn degrade-location - "Return a location specification like this `location`, but comprising - only those elements this `gossip` is interested in. If none, return - `nil`." - [gossip location] - (let [l (if - (coll? location) - (filter - #(when (interesting-location? gossip %) %) - location))] - (when-not (empty? l) l))) - -(defn learn-news-item - "Return a gossip like this `gossip`, which has learned this news `item` if - it is of interest to them." - ;; TODO: Not yet implemented - ([gossip item] - (learn-news-item gossip item true)) - ([gossip item follow-inferences?] - (if - (interesting-item? gossip item) - (let - [g (assoc - gossip - :knowledge - (cons - (assoc - item - :nth-hand (if - (number? (:nth-hand item)) - (inc (:nth-hand item)) - 1) - :time-stamp (if - (number? (:time-stamp item)) - (:time-stamp item) - (game-time)) - :location (degrade-location gossip (:location item)) - ;; TODO: ought to maybe-degrade characters we're not yet interested in - ) - ;; TODO: ought not to add knowledge items we already have, except - ;; to replace if new item is of increased specificity - (:knowledge gossip)))] - (if follow-inferences? - (assoc - g - :knowledge - (concat (:knowledge g) (make-all-inferences item))) - g)) - gossip))) - - - diff --git a/src/the_great_game/merchants/merchants.clj b/src/the_great_game/merchants/merchants.clj deleted file mode 100644 index 9ef160d..0000000 --- a/src/the_great_game/merchants/merchants.clj +++ /dev/null @@ -1,28 +0,0 @@ -(ns the-great-game.merchants.merchants - "Trade planning for merchants, primarily." - (:require [taoensso.timbre :as l :refer [info error spy]] - [the-great-game.utils :refer [deep-merge]] - [the-great-game.merchants.strategies.simple :refer [move-merchant]])) - - -(defn run - "Return a partial world based on this `world`, but with each merchant moved." - [world] - (try - (reduce - deep-merge - world - (map - #(try - (let [move-fn (or - (-> world :merchants % :move-fn) - move-merchant)] - (apply move-fn (list % 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))) - diff --git a/test/cc/journeyman/the_great_game/gossip/gossip_test.clj b/test/cc/journeyman/the_great_game/gossip/gossip_test.clj new file mode 100644 index 0000000..87b15b4 --- /dev/null +++ b/test/cc/journeyman/the_great_game/gossip/gossip_test.clj @@ -0,0 +1,4 @@ +(ns cc.journeyman.the-great-game.gossip.gossip-test + (:require [clojure.test :refer :all] + [cc.journeyman.the-great-game.gossip.gossip :refer :all])) + diff --git a/test/cc/journeyman/the_great_game/gossip/news_items_test.clj b/test/cc/journeyman/the_great_game/gossip/news_items_test.clj new file mode 100644 index 0000000..00e374d --- /dev/null +++ b/test/cc/journeyman/the_great_game/gossip/news_items_test.clj @@ -0,0 +1,210 @@ +(ns cc.journeyman.the-great-game.gossip.news-items-test + (:require [clojure.test :refer [deftest is testing]] + [cc.journeyman.the-great-game.gossip.news-items :refer + [all-known-verbs compatible-item? degrade-location infer + interest-in-character interesting-character? interest-in-location + interesting-location? learn-news-item make-all-inferences known-item?]])) + +(deftest interesting-character-tests + (testing "To what degree characters are of interest to the gossip" + (let [expected 1 + gossip {:home [{:x 0 :y 0} :test-home] + :interesting-verbs all-known-verbs + ;; already knows about adam + :knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]} + actual (interest-in-character + gossip + :adam)] + (is (= actual expected))) + (let [expected 0 + gossip {:home [{:x 0 :y 0} :test-home] + :interesting-verbs all-known-verbs + ;; already knows about adam + :knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]} + actual (interest-in-character + gossip + :dorothy)] + (is (= actual expected)))) + (testing "Whether characters are of interest to the gossip" + (let [expected true + gossip {:home [{:x 0 :y 0} :test-home] + :interesting-verbs all-known-verbs + ;; already knows about adam + :knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]} + actual (interesting-character? + gossip + :adam)] + (is (= actual expected))) + (let [expected false + gossip {:home [{:x 0 :y 0} :test-home] + :interesting-verbs all-known-verbs + ;; already knows about adam + :knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]} + actual (interesting-character? + gossip + :dorothy)] + (is (= actual expected))))) + +(deftest compatible-item-test + (testing "Compatible item: items are identical" + (let [expected true + new-item {:verb :kills :location :tchahua :actor :fierce-fred :other :dainty-daisy} + known-item {:verb :kills :location :tchahua :actor :fierce-fred :other :dainty-daisy} + actual (compatible-item? new-item known-item)] + (is (= actual expected) "Items which are identical are compatible."))) + (testing "Compatible item: new item is less specific" + (let [expected true + new-item {:verb :kills :location :tchahua :other :dainty-daisy} + known-item {:verb :kills :location :tchahua :actor :fierce-fred :other :dainty-daisy} + actual (compatible-item? new-item known-item)] + (is (= actual expected) + "An item which is less specific is compatible with existing knowledge."))) + (testing "Compatible item: new item is more specific" + (let [expected true + new-item {:verb :kills :location :tchahua :actor :fierce-fred :other :dainty-daisy :date 20210609} + known-item {:verb :kills :location :tchahua :actor :fierce-fred :other :dainty-daisy} + actual (compatible-item? new-item known-item)] + (is (= actual expected) "A new item which is more specific adds knowledge and is not compatible"))) + (testing "Compatible item: new item conflicts with existing knowledge." + (let [expected false + new-item {:verb :kills :location :tchahua :actor :jealous-joe :other :dainty-daisy} + known-item {:verb :kills :location :tchahua :actor :fierce-fred :other :dainty-daisy} + actual (compatible-item? new-item known-item)] + (is (= actual expected) "A new item which we don't yet intelligently handle but is not compatible")))) + +(deftest location-test + (testing "Interest in locations" + (let [expected 1 + actual (interest-in-location + {:knowledge [{:verb :steal + :actor :albert + :other :belinda + :object :foo + :location [{:x 35 :y 23} :auchencairn :galloway]}]} + :galloway)] + (is (= actual expected))) + (let [expected 2 + actual (interest-in-location + {:knowledge [{:verb :steal + :actor :albert + :other :belinda + :object :foo + :location [{:x 35 :y 23} :auchencairn :galloway :scotland]}]} + [:galloway :scotland])] + (is (= actual expected))) + (let [expected 2 + actual (interest-in-location + {:home [{:x 35 :y 23} :auchencairn :galloway :scotland]} + [:galloway :scotland])] + (is (= actual expected))) + (let [expected 0 + actual (interest-in-location + {:knowledge [{:verb :steal + :actor :albert + :other :belinda + :object :foo + :location [{:x 35 :y 23} :auchencairn :galloway]}]} + [:dumfries])] + (is (= actual expected))) + (let [expected 7071.067811865475 + actual (interest-in-location + {:home [{:x 35 :y 23}]} + [{:x 34 :y 24}])] + (is (= actual expected) + "TODO: 7071.067811865475 is actually a bad answer.")) + (let [expected 0 + actual (interest-in-location + {:home [{:x 35 :y 23}]} + [{:x 34 :y 24000}])] + (is (= actual expected) + "Too far apart (> 10000).")) + (let [expected true + actual (interesting-location? + {:knowledge [{:verb :steal + :actor :albert + :other :belinda + :object :foo + :location [{:x 35 :y 23} :auchencairn :galloway]}]} + :galloway)] + (is (= actual expected))) + (let [expected true + actual (interesting-location? + {:knowledge [{:verb :steal + :actor :albert + :other :belinda + :object :foo + :location [{:x 35 :y 23} :auchencairn :galloway]}]} + [:galloway :scotland])] + (is (= actual expected))) + (let [expected false + actual (interesting-location? + {:knowledge [{:verb :steal + :actor :albert + :other :belinda + :object :foo + :location [{:x 35 :y 23} :auchencairn :galloway]}]} + [:dumfries])] + (is (= actual expected))) + (let [expected true + actual (interesting-location? + {:home [{:x 35 :y 23}]} + [{:x 34 :y 24}])] + (is (= actual expected))) + (let [expected false + actual (interesting-location? + {:home [{:x 35 :y 23}]} + [{:x 34 :y 240000}])] + (is (= actual expected)))) + (testing "Degrading locations" + (let [expected [:galloway] + actual (degrade-location + {:home [{:x 0 :y 0} :test-home :galloway]} + [{-4 55} :auchencairn :galloway])] + (is (= actual expected))) + (let [expected nil + actual (degrade-location + {:home [{:x 0 :y 0} :test-home :galloway]} + [:froboz])] + (is (= actual expected))))) + +(deftest inference-tests + (testing "Ability to infer new knowledge from news items: single rule tests" + (let [expected {:verb :marry, :actor :belinda, :other :adam, :nth-hand 1} + item {:verb :marry :actor :adam :other :belinda} + rule {:verb :marry :actor :other :other :actor} + actual (infer item rule)] + (is (= actual expected))) + (let [expected {:verb :attack, :actor :adam, :other :belinda, :nth-hand 1} + item {:verb :rape :actor :adam :other :belinda} + rule {:verb :attack} + actual (infer item rule)] + (is (= actual expected))) + (let [expected {:verb :sex, :actor :belinda, :other :adam, :nth-hand 1} + item {:verb :rape :actor :adam :other :belinda} + rule {:verb :sex :actor :other :other :actor} + actual (infer item rule)] + (is (= actual expected)))) + (testing "Ability to infer new knowledge from news items: all applicable rules" + (let [expected #{{:verb :sex, :actor :belinda, :other :adam, :location :test-home, :nth-hand 1} + {:verb :sex, :actor :adam, :other :belinda, :location :test-home, :nth-hand 1} + {:verb :attack, :actor :adam, :other :belinda, :location :test-home, :nth-hand 1}} + ;; dates will not be and cannot be expected to be equal + actual (set (make-all-inferences + {:verb :rape :actor :adam :other :belinda :location :test-home}))] + (is (= actual expected))))) + +(deftest learn-tests + (testing "Learning from an interesting news item." + (let [before {:home [{:x 0 :y 0} :test-home] + :interesting-verbs all-known-verbs + ;; already knows about adam + :knowledge #{{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}}} + after (learn-news-item + before + {:verb :sex :actor :adam :other :belinda :location [:test-home]})] + (and + (is (known-item? after {:verb :sex :actor :adam :other :belinda :location [:test-home]}) + "has learned the item that was given") + (is (known-item? after {:verb :sex, :actor :belinda, :other :adam, :location [:test-home]}) + "has learned information that can be inferred from that item"))))) + diff --git a/test/the_great_game/merchants/markets_test.clj b/test/cc/journeyman/the_great_game/merchants/markets_test.clj similarity index 90% rename from test/the_great_game/merchants/markets_test.clj rename to test/cc/journeyman/the_great_game/merchants/markets_test.clj index 7cacd30..d972257 100644 --- a/test/the_great_game/merchants/markets_test.clj +++ b/test/cc/journeyman/the_great_game/merchants/markets_test.clj @@ -1,8 +1,8 @@ -(ns the-great-game.merchants.markets-test - (:require [clojure.test :refer :all] - [the-great-game.utils :refer [deep-merge]] - [the-great-game.world.world :refer [default-world]] - [the-great-game.merchants.markets :refer :all])) +(ns cc.journeyman.the-great-game.merchants.markets-test + (:require [clojure.test :refer [deftest is testing]] + [cc.journeyman.the-great-game.utils :refer [deep-merge]] + [cc.journeyman.the-great-game.world.world :refer [default-world]] + [cc.journeyman.the-great-game.merchants.markets :refer [adjust-quantity-and-price new-price run]])) (deftest new-price-test @@ -23,7 +23,7 @@ "The greater the relative oversupply, the more prices should fall") )) -(deftest adjust-qunatity-and-price-test +(deftest adjust-quantity-and-price-test (testing "Adjustment in quantity and price: supply only." (let [world (deep-merge default-world diff --git a/test/the_great_game/merchants/merchant_utils_test.clj b/test/cc/journeyman/the_great_game/merchants/merchant_utils_test.clj similarity index 91% rename from test/the_great_game/merchants/merchant_utils_test.clj rename to test/cc/journeyman/the_great_game/merchants/merchant_utils_test.clj index 086c691..52766f8 100644 --- a/test/the_great_game/merchants/merchant_utils_test.clj +++ b/test/cc/journeyman/the_great_game/merchants/merchant_utils_test.clj @@ -1,8 +1,9 @@ -(ns the-great-game.merchants.merchant-utils-test - (:require [clojure.test :refer :all] - [the-great-game.utils :refer [deep-merge]] - [the-great-game.world.world :refer [default-world]] - [the-great-game.merchants.merchant-utils :refer :all])) +(ns cc.journeyman.the-great-game.merchants.merchant-utils-test + (:require [clojure.test :refer [deftest is testing]] + [cc.journeyman.the-great-game.utils :refer [deep-merge]] + [cc.journeyman.the-great-game.world.world :refer [default-world]] + [cc.journeyman.the-great-game.merchants.merchant-utils :refer + [add-stock burden can-afford can-carry expected-price]])) (deftest expected-price-test (testing "Anticipated prices in markets" diff --git a/test/the_great_game/merchants/planning_test.clj b/test/cc/journeyman/the_great_game/merchants/planning_test.clj similarity index 90% rename from test/the_great_game/merchants/planning_test.clj rename to test/cc/journeyman/the_great_game/merchants/planning_test.clj index 5662e35..190aaf7 100644 --- a/test/the_great_game/merchants/planning_test.clj +++ b/test/cc/journeyman/the_great_game/merchants/planning_test.clj @@ -1,8 +1,8 @@ -(ns the-great-game.merchants.planning-test - (:require [clojure.test :refer :all] - [the-great-game.utils :refer [deep-merge]] - [the-great-game.world.world :refer [default-world]] - [the-great-game.merchants.planning :refer :all])) +(ns cc.journeyman.the-great-game.merchants.planning-test + (:require [clojure.test :refer [deftest is testing]] + [cc.journeyman.the-great-game.utils :refer [deep-merge]] + [cc.journeyman.the-great-game.world.world :refer [default-world]] + [cc.journeyman.the-great-game.merchants.planning :refer [plan-trade select-cargo]])) (deftest plan-trade-test diff --git a/test/the_great_game/time_test.clj b/test/cc/journeyman/the_great_game/time_test.clj similarity index 89% rename from test/the_great_game/time_test.clj rename to test/cc/journeyman/the_great_game/time_test.clj index 4727fdd..cbb8689 100644 --- a/test/the_great_game/time_test.clj +++ b/test/cc/journeyman/the_great_game/time_test.clj @@ -1,7 +1,9 @@ -(ns the-great-game.time-test - (:require [clojure.test :refer :all] +(ns cc.journeyman.the-great-game.time-test + (:require [clojure.test :refer [deftest is testing]] ;; [clojure.core.async :refer [thread 10000).")) - (let [expected true - actual (interesting-location? - {:knowledge [{:verb :steal - :actor :albert - :other :belinda - :object :foo - :location [{:x 35 :y 23} :auchencairn :galloway]}]} - :galloway)] - (is (= actual expected))) - (let [expected true - actual (interesting-location? - {:knowledge [{:verb :steal - :actor :albert - :other :belinda - :object :foo - :location [{:x 35 :y 23} :auchencairn :galloway]}]} - [:galloway :scotland])] - (is (= actual expected))) - (let [expected false - actual (interesting-location? - {:knowledge [{:verb :steal - :actor :albert - :other :belinda - :object :foo - :location [{:x 35 :y 23} :auchencairn :galloway]}]} - [:dumfries])] - (is (= actual expected))) - (let [expected true - actual (interesting-location? - {:home [{:x 35 :y 23}]} - [{:x 34 :y 24}])] - (is (= actual expected))) - (let [expected false - actual (interesting-location? - {:home [{:x 35 :y 23}]} - [{:x 34 :y 240000}])] - (is (= actual expected)))) - (testing "Degrading locations" - (let [expected [:galloway] - actual (degrade-location - {:home [{0 0} :test-home :galloway]} - [{-4 55} :auchencairn :galloway])] - (is (= actual expected))) - (let [expected nil - actual (degrade-location - {:home [{0 0} :test-home :galloway]} - [:froboz])] - (is (= actual expected))))) - -(deftest inference-tests - (testing "Ability to infer new knowledge from news items: single rule tests" - (let [expected {:verb :marry, :actor :belinda, :other :adam} - actual (infer {:verb :marry :actor :adam :other :belinda} - {:verb :marry :actor :other :other :actor})] - (is (= actual expected))) - (let [expected {:verb :attack, :actor :adam, :other :belinda} - actual (infer {:verb :rape :actor :adam :other :belinda} - {:verb :attack})] - (is (= actual expected))) - (let [expected {:verb :sex, :actor :belinda, :other :adam} - actual (infer {:verb :rape :actor :adam :other :belinda} - {:verb :sex :actor :other :other :actor})] - (is (= actual expected)))) - (testing "Ability to infer new knowledge from news items: all applicable rules" - (let [expected #{{:verb :sex, :actor :belinda, :other :adam, :location nil, :nth-hand 1} - {:verb :sex, :actor :adam, :other :belinda, :location nil, :nth-hand 1} - {:verb :attack, :actor :adam, :other :belinda, :location nil, :nth-hand 1}} - ;; dates will not be and cannot be expected to be equal - actual (make-all-inferences - {:verb :rape :actor :adam :other :belinda :location :test-home}) - actual' (set (map #(dissoc % :time-stamp) actual))] - (is (= actual' expected))))) - -(deftest learn-tests - (testing "Learning from an interesting news item." - (let [expected {:home [{0 0} :test-home], - :knowledge [{:verb :sex, :actor :adam, :other :belinda, :location nil, :nth-hand 1} - {:verb :sex, :actor :belinda, :other :adam, :location nil, :nth-hand 1}]} - actual (learn-news-item - {:home [{0, 0} :test-home] :knowledge []} - {:verb :sex :actor :adam :other :belinda :location [:test-home]}) - actual' (assoc actual :knowledge (vec (map #(dissoc % :time-stamp) (:knowledge actual))))] - (is (= actual' expected))))) diff --git a/test/the_great_game/world/world_test.clj b/test/the_great_game/world/world_test.clj deleted file mode 100644 index 3770f9a..0000000 --- a/test/the_great_game/world/world_test.clj +++ /dev/null @@ -1,4 +0,0 @@ -(ns the-great-game.world.world-test - (:require [clojure.test :refer :all] - [the-great-game.world.world :refer :all])) - diff --git a/the-great-game.adl.xml b/the-great-game.adl.xml new file mode 100644 index 0000000..4da2cfd --- /dev/null +++ b/the-great-game.adl.xml @@ -0,0 +1,77 @@ + + + + + At this stage, primarily a data-driven lore repository. + + At some future stage, perhaps a specification for the game's internal state. + + + All users + + + Physical opjects in the game world; it's probable that + properties like 'mesh' and 'skin' will end up here. + + + Note that this key is special, as for every instance of + a game object there will be an object record, and thus, for example, + every character will have exactly one object record associated with + it; thus, for example, the key value in the character table will be + the key value of the associated object record. + + + + + + Working notes about this object + + + Easting from the origin, in metres. + + + Northing from the origin, in metres. + + + Altitude above the mean sea level, in metres. + + + Contents of this object, if it is a container. + + + + + + + An object with agency: a hierarchy of needs, a planning + process, locomotion. + + + + + + + The function used to plan the next action for this agent. + + + + + A character with a repertoire: knowledge, dialect, voice, + et cetera. + + + + + + + + + + + + + + diff --git a/workspace.code-workspace b/workspace.code-workspace new file mode 100644 index 0000000..782fd7e --- /dev/null +++ b/workspace.code-workspace @@ -0,0 +1,29 @@ +{ + "folders": [ + { + "path": "../GreatGameTerrain" + }, + { + "path": "../walkmap" + }, + { + "path": "../jme-clj" + }, + { + "path": "../MicroWorld/mw-engine" + }, + { + "path": "." + }, + { + "path": "../test-graphs" + }, + { + "path": "../speechio" + } + ], + "settings": { + "java.configuration.updateBuildConfiguration": "automatic", + "java.compile.nullAnalysis.mode": "automatic" + } +} \ No newline at end of file