@@ -0,0 +1,22 @@ | |||||
The MIT License (MIT) | |||||
Copyright (c) 2015 Travis Briggs | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
of this software and associated documentation files (the "Software"), to deal | |||||
in the Software without restriction, including without limitation the rights | |||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
copies of the Software, and to permit persons to whom the Software is | |||||
furnished to do so, subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all | |||||
copies or substantial portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
SOFTWARE. | |||||
@@ -0,0 +1,9 @@ | |||||
# LaiNomic: Nomic on git.lain.chuch | |||||
This repository represents a game of | |||||
[Nomic](http://legacy.earlham.edu/~peters/nomic.htm) where the bookkeeping of | |||||
the rules and the scores is done through Markdown flavored text files in a Github repository. | |||||
The repository is the single source of authority on the current state of the game (unless, of course, the rules change and that is no longer the case). | |||||
The initial set of rules were taken from [here](https://github.com/audiodude/tiny-nomic/commit/21429fde4eb8455e72743e2946d37aa889677082), and modified in order to change each mention of 'Github' to 'git.lain.church' |
@@ -0,0 +1,4 @@ | |||||
All players must always abide by all the rules then in effect, in the form in | |||||
which they are then in effect. The rules in the Initial Set are in effect | |||||
whenever a game begins. The Initial Set consists of Rules 101-119 (immutable) | |||||
and 201-215 (mutable). |
@@ -0,0 +1,7 @@ | |||||
Initially rules in the 100's are immutable and rules in the 200's are mutable. | |||||
Rules subsequently enacted or transmuted (that is, changed from immutable to | |||||
mutable or *vice versa*) may be immutable or mutable regardless of their | |||||
numbers, and rules in the Initial Set may be transmuted regardless of their | |||||
numbers. | |||||
If the game is being played on git.lain.church, mutable rules must be stored in the mutable_rules/ directory and immutable rules must be stored in the immutable_rules/ directory. The directory in which a rule resides is the sole factor in determining its mutability. |
@@ -0,0 +1,11 @@ | |||||
A rule-change is any of the following: | |||||
1. the enactment, repeal, or amendment of a mutable rule; | |||||
2. the enactment, repeal, or amendment of an amendment of a mutable rule; or | |||||
3. the transmutation of an immutable rule into a mutable rule or *vice versa*. | |||||
(Note: This definition implies that, at least initially, all new rules are | |||||
mutable; immutable rules, as long as they are immutable, may not be amended or | |||||
repealed; mutable rules, as long as they are mutable, may be amended or | |||||
repealed; any rule of any status may be transmuted; no rule is absolutely | |||||
immune to change.) |
@@ -0,0 +1,2 @@ | |||||
All rule-changes proposed in the proper way shall be voted on. They will be | |||||
adopted if and only if they receive the required number of votes. |
@@ -0,0 +1,2 @@ | |||||
Every player is an eligible voter. Every eligible voter must participate in | |||||
every vote on rule-changes. |
@@ -0,0 +1,4 @@ | |||||
All proposed rule-changes shall be written down before they are voted on. If | |||||
they are adopted, they shall guide play in the form in which they were voted on. | |||||
If the game is being played on git.lain.church, Pull Requests which add files to the proper directory shall satisfy this rule. |
@@ -0,0 +1,3 @@ | |||||
No rule-change may take effect earlier than the moment of the completion of the | |||||
vote that adopted it, even if its wording explicitly states otherwise. No | |||||
rule-change may have retroactive application. |
@@ -0,0 +1,9 @@ | |||||
Each proposed rule-change shall be given a number for reference. The numbers | |||||
shall begin with 301, and each rule-change proposed in the proper way shall | |||||
receive the next successive integer, whether or not the proposal is adopted. | |||||
If a rule is repealed and reenacted, it receives the number of the proposal to | |||||
reenact it. If a rule is amended or transmuted, it receives the number of the | |||||
proposal to amend or transmute it. If an amendment is amended or repealed, the | |||||
entire rule of which it is a part receives the number of the proposal to amend | |||||
or repeal the amendment. |
@@ -0,0 +1,6 @@ | |||||
Rule-changes that transmute immutable rules into mutable rules may be adopted | |||||
if and only if the vote is unanimous among the eligible voters. Transmutation | |||||
shall not be implied, but must be stated explicitly in a proposal to take | |||||
effect. | |||||
If the game is being played on git.lain.church, a simple file move to or from the immutable_rules/mutable_rules directories shall satisfy this rule. |
@@ -0,0 +1,4 @@ | |||||
In a conflict between a mutable and an immutable rule, the immutable rule takes | |||||
precedence and the mutable rule shall be entirely void. For the purposes of this | |||||
rule a proposal to transmute an immutable rule does not "conflict" with that | |||||
immutable rule. |
@@ -0,0 +1,8 @@ | |||||
If a rule-change as proposed is unclear, ambiguous, paradoxical, or destructive | |||||
of play, or if it arguably consists of two or more rule-changes compounded or is | |||||
an amendment that makes no difference, or if it is otherwise of questionable | |||||
value, then the other players may suggest amendments or argue against the | |||||
proposal before the vote. A reasonable time must be allowed for this debate. The | |||||
proponent decides the final form in which the proposal is to be voted on and, | |||||
unless the Judge has been asked to do so, also decides the time to end debate | |||||
and vote. |
@@ -0,0 +1,5 @@ | |||||
The state of affairs that constitutes winning may not be altered from achieving | |||||
*n* points to any other state of affairs. The magnitude of *n* and the means of | |||||
earning points may be changed, and rules that establish a winner when play | |||||
cannot continue may be enacted and (while they are mutable) be amended or | |||||
repealed. |
@@ -0,0 +1,3 @@ | |||||
A player always has the option to forfeit the game rather than continue to play | |||||
or incur a game penalty. No penalty worse than losing, in the judgment of the | |||||
player to incur it, may be imposed. |
@@ -0,0 +1,2 @@ | |||||
There must always be at least one mutable rule. The adoption of rule-changes | |||||
must never become completely impermissible. |
@@ -0,0 +1,4 @@ | |||||
Rule-changes that affect rules needed to allow or apply rule-changes are as | |||||
permissible as other rule-changes. Even rule-changes that amend or repeal their | |||||
own authority are permissible. No rule-change or type of move is impermissible | |||||
solely on account of the self-reference or self-application of a rule. |
@@ -0,0 +1,3 @@ | |||||
Whatever is not prohibited or regulated by a rule is permitted and unregulated, | |||||
with the sole exception of changing the rules, which is permitted only when a | |||||
rule or set of rules explicitly or implicitly permits it. |
@@ -0,0 +1,27 @@ | |||||
Each rule shall be represented by a file in either the `immutable_rules/` or | |||||
`mutable_rules/` directory of the git repository where the game is being | |||||
recorded. No other files in the repository shall be constituted to represent a | |||||
rule or have the force of a rule. | |||||
The master branch of the repository will serve as a representation of the | |||||
current game state. No commits are allowed to be made to the master branch | |||||
except through the mechanism of a git.lain.church Pull Request. | |||||
Pull Requests must perform exactly one of the following actions: | |||||
1. Add a file to one of the rules directory, when a rule is enacted. | |||||
2. Remove a file from one of the rules directories when a rule is repealed. | |||||
3. Modify an existing rule file, when an amendment is made, or repealed, or when | |||||
an amendment to an amendment is made or repealed. | |||||
4. Move a rule from either the immutable_rules directory or the mutable_rules | |||||
directory to the other one, when a rule is transmuted. | |||||
5. Create a new player file in the `players/` directory | |||||
6. Perform some administrative task on the repository, at the discretion of the | |||||
players. Pull Requests of this type can happen outside of the normal turn | |||||
order, must be approved by majority vote of all players, and cannot | |||||
materially affect the operation of the rules or the game. An example of this | |||||
would be removing or replacing the LICENSE or README files. | |||||
The proper way to propose a rule-change is a Pull Request. Players vote on Pull | |||||
Requests/proposals by putting either "+1" or "-1" as a comment on the Pull | |||||
Request, or by using the proper :thumbsup: or :thumbsdown: emoji on the Pull Request comment. |
@@ -0,0 +1,23 @@ | |||||
Any person with a git.lain.church account is eligible to play the game (become a player). | |||||
However, a single person shall only ever constitute a single player in the game, | |||||
regardless of the number of git.lain.church accounts he or she has. | |||||
To become a player in the game, a candidate player shall send a git.lain.church Pull | |||||
Request to the master branch of the repository where the game is being recorded. | |||||
The Pull Request shall modify the players/ directory of the repository by adding | |||||
a single file whose name is exactly in the Name Format. | |||||
For the purposes of this rule, the Name Format means a string which: | |||||
* Starts with a zero-padded number that must contain 3 digits and be equal | |||||
in numerical value to the number of files that were present in the | |||||
directory before the candidate player's file was added. So if the | |||||
candidate player's file is the 4th, the number would be 003. | |||||
* This is followed by a hyphen, then ends with the git.lain.church username of the | |||||
candidate player, ie audiodude. | |||||
* For example, the file could be named `003-audiodude`. | |||||
Each player's file must at all times contain the numeric score of the player. | |||||
The Pull Request to add a player (as described in this rule) can be | |||||
approved/merged by any existing player. Only one player's approval is required. |
@@ -0,0 +1,3 @@ | |||||
All active players must have commit access to the repository where the game is | |||||
being recorded. Accordingly, no one who is not a player is allowed commit | |||||
access to the repository. |
@@ -0,0 +1,11 @@ | |||||
The game shall consist of a series of rounds. Each round begins immediately | |||||
after the end of the turn of the last player in the previous round. A player is | |||||
said to be *in* a round if the player has a player file in the `players/` | |||||
directory when the round begins. The order of turns is determined by taking the | |||||
numeric part of the name of each file in the `players/` directory and assigning | |||||
it to the player corresponding to the file. The player with the lowest number | |||||
goes first and play passes to each player in increasing numeric order of his or | |||||
her assigned number. | |||||
Turns may not be skipped or passed, and parts of turns may not be omitted. All | |||||
players begin with zero points, which (if the game is being played on git.lain.church) should be reflected in their player files. |
@@ -0,0 +1,12 @@ | |||||
One turn consists of two parts in this order: | |||||
1. proposing one rule-change and having it voted on, and | |||||
2. throwing one die once and adding the number of points on its face to one's | |||||
score. | |||||
In mail and computer games (and by extension, if playing on git.lain.church) instead of | |||||
throwing a die, players subtract 291 from the ordinal number of their proposal | |||||
and multiply the result by the fraction of favorable votes it received, rounded | |||||
to the nearest integer. (This yields a number between 0 and 10 for the first | |||||
player, with the upper limit increasing by one each turn; more points are | |||||
awarded for more popular proposals.) |
@@ -0,0 +1,3 @@ | |||||
A rule-change is adopted if and only if the vote is unanimous among the eligible | |||||
voters. If this rule is not amended by the end of the second round, it | |||||
automatically changes to require only a simple majority. |
@@ -0,0 +1,2 @@ | |||||
If and when rule-changes can be adopted without unanimity, the players who vote | |||||
against winning proposals shall receive 10 points each. |
@@ -0,0 +1,2 @@ | |||||
An adopted rule-change takes full effect at the moment of the completion of the | |||||
vote that adopted it. |
@@ -0,0 +1,2 @@ | |||||
When a proposed rule-change is defeated, the player who proposed it loses 10 | |||||
points. |
@@ -0,0 +1 @@ | |||||
Each player always has exactly one vote. |
@@ -0,0 +1,4 @@ | |||||
The winner is the first player to achieve 100 (positive) points. | |||||
In mail and computer games (and by extension, games played on git.lain.church), the | |||||
winner is the first player to achieve 200 (positive) points. |
@@ -0,0 +1 @@ | |||||
At no time may there be more than 25 mutable rules. |
@@ -0,0 +1,5 @@ | |||||
Players may not conspire or consult on the making of future rule-changes unless | |||||
they are team-mates. | |||||
The first paragraph of this rule does not apply to games by mail or computer | |||||
(or, by extension, those played on git.lain.church). |
@@ -0,0 +1,11 @@ | |||||
If two or more mutable rules conflict with one another, or if two or more | |||||
immutable rules conflict with one another, then the rule with the lowest ordinal | |||||
number takes precedence. | |||||
If at least one of the rules in conflict explicitly says of itself that it defers | |||||
to another rule (or type of rule) or takes precedence over another rule (or type | |||||
of rule), then such provisions shall supersede the numerical method for | |||||
determining precedence. | |||||
If two or more rules claim to take precedence over one another or to defer to | |||||
one another, then the numerical method again governs. |
@@ -0,0 +1,26 @@ | |||||
If players disagree about the legality of a move or the interpretation or | |||||
application of a rule, then the player preceding the one moving is to be the | |||||
Judge and decide the question. Disagreement for the purposes of this rule may | |||||
be created by the insistence of any player. This process is called *invoking | |||||
Judgment*. | |||||
When Judgment has been invoked, the next player may not begin his or her turn | |||||
without the consent of a majority of the other players. | |||||
The Judge's Judgment may be overruled only by a unanimous vote of the other | |||||
players taken before the next turn is begun. If a Judge's Judgment is overruled, | |||||
then the player preceding the Judge in the playing order becomes the new Judge | |||||
for the question, and so on, except that no player is to be Judge during his or | |||||
her own turn or during the turn of a team-mate. | |||||
Unless a Judge is overruled, one Judge settles all questions arising from the | |||||
game until the next turn is begun, including questions as to his or her own | |||||
legitimacy and jurisdiction as Judge. | |||||
New Judges are not bound by the decisions of old Judges. New Judges may, | |||||
however, settle only those questions on which the players currently disagree | |||||
and that affect the completion of the turn in which Judgment was invoked. All | |||||
decisions by Judges shall be in accordance with all the rules then in effect; | |||||
but when the rules are silent, inconsistent, or unclear on the point at issue, | |||||
then the Judge shall consider game-custom and the spirit of the game before | |||||
applying other standards. |
@@ -0,0 +1,6 @@ | |||||
If the rules are changed so that further play is impossible, or if the legality | |||||
of a move cannot be determined with finality, or if by the Judge's best | |||||
reasoning, not overruled, a move appears equally legal and illegal, then the | |||||
first player unable to complete a turn is the winner. | |||||
This rule takes precedence over every other rule determining the winner. |
@@ -0,0 +1,6 @@ | |||||
To the degree possible, the game should be played using git.lain.church. Conversation | |||||
relevant to the game should happen there. Earnest attempts should be made to | |||||
keep discussion and judging pertinent to a rule-change proposal attached to the | |||||
Pull Request that contains the proposal. | |||||
Judgement can be invoked at any time by opening a new issue on the git.lain.church repository that hosts the game. If possible, the current judge should be @mentioned in such an issue, to prompt a speedy reply. |
@@ -0,0 +1,3 @@ | |||||
The game shall begin (the first round shall start) once there are at least 5 | |||||
players. The game does not necessarily end when it is won or even when there | |||||
are less than 5 or even no players. |
@@ -0,0 +1,93 @@ | |||||
#!/usr/bin/env python | |||||
"""Find and concatenate all the rule files into one readable output. | |||||
""" | |||||
# n.b.: This shows any file, not just ones committed in git, which would | |||||
# require parsing output from git ls-files or something. | |||||
# This doesn't show files in subdirectories. | |||||
# This won't show anything that doesn't have a .md extension. | |||||
# This is supposed to generate valid markdown, but that depends on the | |||||
# rule files. | |||||
import os | |||||
import re | |||||
_FILENAME_RE = re.compile(r'(\d+)_(.*)\.md') | |||||
def file_paths_under(root): | |||||
"""Yield paths of files under the given root. | |||||
""" | |||||
for filename in sorted(os.listdir(root)): | |||||
full_path = os.path.join(root, filename) | |||||
# n.b.: lots of checks against filesystem. | |||||
if os.path.isfile(full_path): | |||||
yield full_path | |||||
def files(file_paths): | |||||
"""Yield file objects for the given file paths. | |||||
""" | |||||
# n.b.: no error handling if files don't exist or can't be opened. | |||||
for file_path in file_paths: | |||||
with open(file_path, "r") as file_obj: | |||||
yield file_obj | |||||
def parse_path(filename): | |||||
"""Extract rule number and title from given path to rule file. | |||||
""" | |||||
basename = os.path.basename(filename) | |||||
match = _FILENAME_RE.match(basename) | |||||
if not match: | |||||
return None | |||||
number = match.group(1) | |||||
words = [word.capitalize() for word in match.group(2).split("-")] | |||||
title = " ".join(words) | |||||
return number, title | |||||
def render_dir(root): | |||||
"""Yield lines presenting rule files in the given directory. | |||||
""" | |||||
for file_obj in files(file_paths_under(root)): | |||||
parsed = parse_path(file_obj.name) | |||||
# n.b.: parsed may be None and fail to unpack here. | |||||
number, title = parsed | |||||
content = file_obj.read().rstrip() | |||||
title_line = "{0}. {1}".format(number, title) | |||||
yield "" | |||||
yield title_line | |||||
yield "-" * len(title_line) | |||||
yield "" | |||||
yield content | |||||
def render_section(root, title): | |||||
"""Add a title to the output of render_dir. | |||||
""" | |||||
yield title | |||||
yield "=" * len(title) | |||||
for line in render_dir(root): | |||||
yield line | |||||
def main(): | |||||
"""What happens when the script is run | |||||
""" | |||||
this_file = os.path.abspath(__file__) | |||||
here = os.path.dirname(this_file) | |||||
parent = os.path.dirname(here) | |||||
immutable_rule_dir = os.path.join(parent, 'immutable_rules') | |||||
mutable_rule_dir = os.path.join(parent, 'mutable_rules') | |||||
for line in render_section(immutable_rule_dir, "Immutable Rules"): | |||||
print(line) | |||||
print("") | |||||
for line in render_section(mutable_rule_dir, "Mutable Rules"): | |||||
print(line) | |||||
# This is a script file, so __name__ stuff is not useful. | |||||
main() |