summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--play.html120
-rw-r--r--play.js251
-rw-r--r--rules.js22
-rw-r--r--tools/gencards.py72
4 files changed, 454 insertions, 11 deletions
diff --git a/play.html b/play.html
index 0a0510c..d1c4b04 100644
--- a/play.html
+++ b/play.html
@@ -17,6 +17,71 @@ main {
background-color: slategray;
}
+#role_Suffragist .role_name { background-color: hsl(273 39% 85%); }
+#role_Opposition .role_name { background-color: hsl(16 85% 85%); }
+.role.active span { text-decoration: underline; }
+
+body.Suffragist header.your_turn { background-color: hsl(273 39% 75%); }
+body.Opposition header.your_turn { background-color: hsl(16 85% 75%);; }
+.role_info {
+ padding: 3px 18px;
+ background-color: gainsboro;
+ white-space: pre-wrap;
+}
+
+#log { background-color: whitesmoke; }
+#log .h1, #log .h2 {
+ font-weight: bold;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ text-align: center;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+}
+#log .h1 { background-color: silver; }
+#log .h2 { background-color: gainsboro; }
+
+#log > .p { padding-left: 20px; text-align: right; font-style: italic; opacity: 75%; }
+#log > .i { padding-left: 20px; }
+
+/* PANELS */
+
+.panel_grid {
+ display: flex;
+ justify-content: center;
+ min-width: 1500px;
+ max-width: 1500px;
+ margin: 20px auto;
+ gap: 20px;
+}
+
+#hand, #discard, #states_draw, #strategy_draw, #set_aside { min-height: 350px; }
+#hand_panel, #states_draw { min-width: 1100px; }
+#strategy_draw, #set_aside_panel { min-width: 830px; }
+#discard_panel { min-width: 290px; }
+
+.panel {
+ background-color: #555;
+}
+
+.panel_header {
+ background-color: #444;
+ color: hsl(40, 60%, 90%);
+ font-weight: bold;
+ text-align: center;
+ padding: 3px 1em;
+}
+
+.panel_body {
+ display: flex;
+ justify-content: start;
+ flex-wrap: wrap;
+ padding: 20px;
+ gap: 20px;
+}
+
+/* MAP */
+
#mapwrap {
width: 1100px;
height: 850px;
@@ -123,7 +188,6 @@ div.region:hover {
.piece.no { width: 42px; height: 32px; background-size: 42px 32px; background-image: url(pieces/no.svg); }
.piece.congress { width: 32px; height: 32px; background-size: 32px 32px; background-image: url(pieces/cog.svg); }
-
.card {
background-size: cover;
background-repeat: no-repeat;
@@ -153,7 +217,7 @@ div.region:hover {
/* CARD IMAGES */
.card_support_back{background-image:url(cards100/support_01.jpg)}
-.card_oppisition_back{background-image:url(cards100/opposition_01.jpg)}
+.card_opposition_back{background-image:url(cards100/opposition_01.jpg)}
.card_1{background-image:url(cards100/support_02.jpg)}
.card_2{background-image:url(cards100/support_03.jpg)}
@@ -290,7 +354,7 @@ div.region:hover {
</head>
<body>
-<div id="tooltip" class="card"></div>
+<div id="tooltip" class="card hide"></div>
<menu id="popup">
<li class="title">TITLE
@@ -306,6 +370,9 @@ div.region:hover {
<li><a href="info/rules.html" target="_blank">Rules</a>
<li><a href="info/history.html" target="_blank">History</a>
<li><a href="info/cards.html" target="_blank">Cards</a>
+ <li class="debug separator">
+ <li class="debug" onclick="send_save()">&#x1F41E; Save
+ <li class="debug" onclick="send_restore()">&#x1F41E; Restore
<li class="resign separator">
<li class="resign" onclick="confirm_resign()">Resign
</menu>
@@ -317,15 +384,17 @@ div.region:hover {
<div id="roles">
<div class="role" id="role_Suffragist">
<div class="role_name">
- Suffragist
+ <span>Suffragist</span>
<div class="role_user">-</div>
</div>
+ <div class="role_info" id="support_info">0 cards in hand</div>
</div>
<div class="role" id="role_Opposition">
<div class="role_name">
- Opposition
+ <span>Opposition</span>
<div class="role_user">-</div>
</div>
+ <div class="role_info" id="opposition_info">0 cards in hand</div>
</div>
<div class="card_info"></div></div>
</div>
@@ -813,7 +882,46 @@ c5 3 13 7 17 8 8 2 9 3 11 12 1 5 5 12 8 16 5 8 5 8 3 22 l-3 14 -30 -1 c-35
</div>
</div>
- <div id="hand" class="hand">
+ <div class="panel_grid">
+
+ <div id="hand_panel" class="panel hide">
+ <div id="hand_header" class="panel_header">Hand</div>
+ <div id="hand" class="panel_body"></div>
+ </div>
+
+ <div id="discard_panel" class="panel">
+ <div id="discard_header" class="panel_header">Discard</div>
+ <div id="discard" class="panel_body"></div>
+ </div>
+
+ </div>
+
+ <div class="panel_grid">
+
+ <div id="strategy_draw_panel" class="panel">
+ <div id="strategy_draw_header" class="panel_header">Strategy cards</div>
+ <div id="strategy_draw" class="panel_body"></div>
+ </div>
+
+ </div>
+
+ <div class="panel_grid">
+
+ <div id="states_draw_panel" class="panel">
+ <div id="states_draw_header" class="panel_header">States cards</div>
+ <div id="states_draw" class="panel_body"></div>
+ </div>
+
+ </div>
+
+
+ <div class="panel_grid">
+
+ <div id="set_aside_panel" class="panel hide">
+ <div id="set_aside_header" class="panel_header">Set-aside cards</div>
+ <div id="set_aside" class="panel_body"></div>
+ </div>
+
</div>
<br><br><br>
diff --git a/play.js b/play.js
new file mode 100644
index 0000000..a8f7afc
--- /dev/null
+++ b/play.js
@@ -0,0 +1,251 @@
+"use strict"
+
+const SUF = 0
+const OPP = 1
+const SUF_NAME = "Suffragist"
+const OPP_NAME = "Opposition"
+
+let ui = {
+ status: document.getElementById("status"),
+ player: [
+ document.getElementById("role_Suffragist"),
+ document.getElementById("role_Opposition"),
+ ],
+ cards: [ null ],
+}
+
+// :r !python3 tools/gencards.py
+const CARDS = [null, { "id": 1, "type": "support", "title": "Seneca Falls Convention", "era": "Start", "text": "Add 1 :purple_campaigner and 1 :yellow_campaigner in the Northeast region. Receive 2 :badge and add 2 :purple_or_yellow_cube in New York." }, { "id": 2, "type": "support", "title": "Property Rights for Women", "era": "Early", "text": "For the remainder of the turn, roll :d6 instead of :d4 when taking a Campaigning action.", "persistent": "rest_of_turn" }, { "id": 3, "type": "support", "title": "Frances Willard", "era": "Early", "text": "Add 1 :congressional_marker in Congress and receive 2 :badge." }, { "id": 4, "type": "support", "title": "A Vindication of the Rights of Woman", "era": "Early", "text": "Draw 2 cards from your Draw Deck. Discard 1 card and play the other card for its event immediately." }, { "id": 5, "type": "support", "title": "Union Victory", "era": "Early", "text": "Playable if *The Civil War* is in effect. Roll :d6. On a roll of 3-6, receive two :badge and move *The Civil War* to the discard pile." }, { "id": 6, "type": "support", "title": "Fifteenth Amendment", "era": "Early", "text": "Playable if *The Civil War* is not in effect. Roll :d6. On a roll of 3-6, add 2 :congressional_marker in Congress and add 8 :purple_or_yellow_cube anywhere, no more than 2 per state.", "persistent": "rest_of_game" }, { "id": 7, "type": "support", "title": "Reconstruction", "era": "Early", "text": "Playable if *The Civil War* is not in effect and the *Fifteenth Amendment* is in effect. Add 1 :purple_or_yellow_cube in each of Virginia, North Carolina, South Carolina, Georgia, Florida, Alabama, Mississippi, Tennessee, Arkansas, Louisiana and Texas." }, { "id": 8, "type": "support", "title": "Petition to Congress", "era": "Early", "text": "Add 1 :congressional_marker in Congress and add 1 :purple_or_yellow_cube in one state of each region." }, { "id": 9, "type": "support", "title": "Lucy Stone", "era": "Early", "text": "Receive 1 :badge and add 1 :purple_or_yellow_cube in one state of each region." }, { "id": 10, "type": "support", "title": "Susan B. Anthony Indicted", "era": "Early", "text": "Receive 1 :badge and add 1 :purple_or_yellow_cube in one state of each region." }, { "id": 11, "type": "support", "title": "Anna Dickinson", "era": "Early", "text": "Receive 1 :badge and add 1 :purple_or_yellow_cube in one state of each region." }, { "id": 12, "type": "support", "title": "Frederick Douglass", "era": "Early", "text": "Roll :d8. Add that number :purple_or_yellow_cube in the Northeast region, no more than 1 per state." }, { "id": 13, "type": "support", "title": "Frances Harper", "era": "Early", "text": "Roll :d8. Add that number :purple_or_yellow_cube in the Atlantic & Appalachia region, no more than 1 per state." }, { "id": 14, "type": "support", "title": "The Union Signal", "era": "Early", "text": "Receive 1 :badge and add 1 :purple_or_yellow_cube in one state of each region." }, { "id": 15, "type": "support", "title": "Sojourner Truth", "era": "Early", "text": "Roll :d8. Add that number :purple_or_yellow_cube in the Midwest region, no more than 1 per state." }, { "id": 16, "type": "support", "title": "Pioneer Women", "era": "Early", "text": "Roll :d8. Add that number :purple_or_yellow_cube in the Plains region, no more than 1 per state." }, { "id": 17, "type": "support", "title": "Women to the Polls", "era": "Early", "text": "Add 2 :purple_or_yellow_cube in each of New Jersey, Pennsylvania and Delaware." }, { "id": 18, "type": "support", "title": "National Woman\u2019s Rights Convention", "era": "Early", "text": "Playable if *The Civil War* is not in effect. Add 1 :congressional_marker in Congress and 1 :purple_or_yellow_cube in one state of each region." }, { "id": 19, "type": "support", "title": "National American Woman Suffrage Association", "era": "Middle", "text": "Add 1 :purple_campaigner in the Atlantic & Appalachia region. Receive 3 :badge." }, { "id": 20, "type": "support", "title": "Jeannette Rankin", "era": "Middle", "text": "Roll :d6. On a roll of 3-6, add 1 :congressional_marker in Congress and 4 :purple_or_yellow_cube in Montana and 2 :purple_or_yellow_cube in each other state in the Plains region." }, { "id": 21, "type": "support", "title": "Ida B. Wells-Barnett", "era": "Middle", "text": "Receive 2 :badge. Add 2 :purple_or_yellow_cube in Illinois and 1 :purple_or_yellow_cube in each other state in the Midwest region." }, { "id": 22, "type": "support", "title": "The Club Movement", "era": "Middle", "text": "Receive 4 :badge." }, { "id": 23, "type": "support", "title": "Equality League of Self-Supporting Women", "era": "Middle", "text": "Receive 2 :badge. Add 1 :purple_or_yellow_cube in one state of each region." }, { "id": 24, "type": "support", "title": "Emmeline Pankhurst", "era": "Middle", "text": "Roll :d6 :d6. Add that number :purple_or_yellow_cube anywhere, no more than 2 per state." }, { "id": 25, "type": "support", "title": "\u201cDebate Us, You Cowards!\u201d", "era": "Middle", "text": "Roll :d6 :d6. Remove that number :red_cube anywhere, no more than 2 per state." }, { "id": 26, "type": "support", "title": "Carrie Chapman Catt", "era": "Middle", "text": "Receive 2 :badge. Add 1 :purple_or_yellow_cube in one state of each region." }, { "id": 27, "type": "support", "title": "Alice Paul & Lucy Burns", "era": "Middle", "text": "Roll :d6 :d6. Remove that number :red_cube anywhere, no more than 2 per state." }, { "id": 28, "type": "support", "title": "Inez Milholland", "era": "Middle", "text": "Add 1 :congressional_marker in Congress. Receive 2 :badge and add 1 :purple_or_yellow_cube in one state of each region." }, { "id": 29, "type": "support", "title": "Farmers for Suffrage", "era": "Middle", "text": "Add 2 :purple_or_yellow_cube in each of Wisconsin, Minnesota, Iowa, North Dakota and South Dakota." }, { "id": 30, "type": "support", "title": "Zitkala-\u0160a", "era": "Middle", "text": "Add 2 :purple_or_yellow_cube in each of North Dakota, South Dakota, Nebraska, Montana and Wyoming." }, { "id": 31, "type": "support", "title": "Helen Keller", "era": "Middle", "text": "Roll :d6 :d6. Add that number :purple_or_yellow_cube anywhere, no more than 2 per state." }, { "id": 32, "type": "support", "title": "Maria de Lopez", "era": "Middle", "text": "Recieve 2 :badge. Add 2 :purple_or_yellow_cube in each of California, Nevada and Arizona." }, { "id": 33, "type": "support", "title": "Marie Louise Bottineau Baldwin", "era": "Middle", "text": "For the remainder of the turn, roll :d6 instead of :d4 when taking a Campaigning action.", "persistent": "rest_of_turn" }, { "id": 34, "type": "support", "title": "The West\u2019s Awakening", "era": "Middle", "text": "Add 2 :purple_or_yellow_cube in each state in the West region." }, { "id": 35, "type": "support", "title": "Southern Strategy", "era": "Middle", "text": "Receive 2 :badge. Add 2 :purple_or_yellow_cube in each state in the South region. Select and place in front of you 1 available Strategy card.", "persistent": "rest_of_game" }, { "id": 36, "type": "support", "title": "Women\u2019s Trade Union League", "era": "Late", "text": "Add 1 :yellow_campaigner in the Atlantic & Appalachia region. Add 1 :congressional_marker in Congress and receive 2 :badge." }, { "id": 37, "type": "support", "title": "The Young Woman Citizen", "era": "Late", "text": "Draw 2 cards from your Draw Deck. Discard 1 card and play the other card for its event immediately." }, { "id": 38, "type": "support", "title": "1918 Midterm Elections", "era": "Late", "text": "Roll :d6. On a roll of 3-6, add 3 :congressional_marker in Congress." }, { "id": 39, "type": "support", "title": "Woodrow Wilson", "era": "Late", "text": "Spend 4 :badge to select and place in front of you 1 available Strategy card." }, { "id": 40, "type": "support", "title": "Maud Wood Park", "era": "Late", "text": "Add 2 :congressional_marker in Congress." }, { "id": 41, "type": "support", "title": "Voter Registration", "era": "Late", "text": "The Suffragist player rolls :d8 instead of :d6 during Final Voting.", "persistent": "ballot_box" }, { "id": 42, "type": "support", "title": "Processions for Suffrage", "era": "Late", "text": "For the remainder of the turn, roll :d8 instead of :d6 when taking a Lobbying action. For each 6, 7 or 8 rolled, add 1 :congressional_marker in Congress.", "persistent": "rest_of_turn" }, { "id": 43, "type": "support", "title": "Prison Tour Special", "era": "Late", "text": "For the remainder of the turn, roll :d6 instead of :d4 when taking a Campaigning action.", "persistent": "rest_of_turn" }, { "id": 44, "type": "support", "title": "Victory Map", "era": "Late", "text": "Add 1 :purple_or_yellow_cube in each state in the West and Plains regions. Add 1 :purple_or_yellow_cube in each of Texas, Arkansas, Illinois, Michigan, New York and Vermont." }, { "id": 45, "type": "support", "title": "Women and World War I", "era": "Late", "text": "Playable if *War in Europe* is in effect. Add 10 :purple_or_yellow_cube anywhere, no more than 2 per state." }, { "id": 46, "type": "support", "title": "Eighteenth Amendment", "era": "Late", "text": "Roll :d6. On a roll of 3-6, add 1 congressional_marker in Congress and receive 2 :badge.", "persistent": "rest_of_game" }, { "id": 47, "type": "support", "title": "Mary McLeod Bethune", "era": "Late", "text": "Roll :d8 :d8. Remove that number :red_cube anywhere, no more than 2 per state." }, { "id": 48, "type": "support", "title": "Make a Home Run for Suffrage", "era": "Late", "text": "Roll :d8 :d8. Remove that number :red_cube anywhere, no more than 2 per state." }, { "id": 49, "type": "support", "title": "Mary Church Terrell", "era": "Late", "text": "Roll :d8 :d8. Add that number :purple_or_yellow_cube anywhere, no more than 2 per state." }, { "id": 50, "type": "support", "title": "Tea Parties for Suffrage", "era": "Late", "text": "Add 1 :congressional_marker in Congress and receive 4 :badge" }, { "id": 51, "type": "support", "title": "Dr. Mabel Ping-Hua Lee", "era": "Late", "text": "Roll :d8 :d8. Add that number :purple_or_yellow_cube anywhere, no more than 2 per state." }, { "id": 52, "type": "support", "title": "Miss Febb Wins the Last Vote", "era": "Late", "text": "The Suffragist player wins all ties during Final Voting.", "persistent": "ballot_box" }, { "id": 53, "type": "opposition", "title": "The Patriarchy", "era": "Start", "text": "Add 1 :red_campaigner in the South region. Receive 4 :badge. Add 1 :red_cube in each state in the Northeast region, the Atlantic & Appalachia region, the South region and the Midwest region." }, { "id": 54, "type": "opposition", "title": "The Civil War", "era": "Early", "text": "Remove 1 :congressional_marker from Congress. For the remainder of the turn, the Suffragist player may not add :purple_or_yellow_cube to any state in the Atlantic & Appalachia and South regions.", "persistent": "rest_of_turn" }, { "id": 55, "type": "opposition", "title": "15th Divides Suffragists", "era": "Early", "text": "Playable if *Fifteenth Amendment* is in effect. Remove all :purple_cube in up to 4 states. The Suffragist player loses 2 :badge." }, { "id": 56, "type": "opposition", "title": "Senator Joseph Brown", "era": "Early", "text": "Remove 1 :congressional_marker from Congress and add 2 :red_cube in Georgia." }, { "id": 57, "type": "opposition", "title": "Minor v. Happersett", "era": "Early", "text": "Roll :d6. On a roll of 3-6, remove 1 :congressional_marker and add 2 :red_cube in Missouri." }, { "id": 58, "type": "opposition", "title": "Senate Rejects Suffrage Amendment", "era": "Early", "text": "Roll :d6. On a roll of 3-6, receive 1 :badge and remove 1 :congressional_marker from Congress." }, { "id": 59, "type": "opposition", "title": "South Dakota Rejects Suffrage", "era": "Early", "text": "Roll :d6. On a roll of 3-6, remove 1 :congressional_marker and add 2 :red_cube in South Dakota." }, { "id": 60, "type": "opposition", "title": "Gerrymandering", "era": "Early", "text": "Remove all :yellow_cube in up to 2 states." }, { "id": 61, "type": "opposition", "title": "Border States", "era": "Early", "text": "Add 1 :red_cube in each of Delaware, Maryland, West Virginia, Kentucky and Missouri." }, { "id": 62, "type": "opposition", "title": "Horace Greeley", "era": "Early", "text": "Place 2 :red_cube in each of New York and Connecticut." }, { "id": 63, "type": "opposition", "title": "New York Newspapers", "era": "Early", "text": "Place 2 :red_cube in each of New York and New Jersey." }, { "id": 64, "type": "opposition", "title": "Senator George Vest", "era": "Early", "text": "Remove 1 :congressional_marker from Congress and add 2 :red_cube in Missouri." }, { "id": 65, "type": "opposition", "title": "Catharine Beecher", "era": "Early", "text": "Roll :d4. Add that number :red_cube anywhere, no more than 1 per state." }, { "id": 66, "type": "opposition", "title": "Progress, Not Politics", "era": "Early", "text": "Draw 6 cards from your Draw Deck. Place any number of the 6 cards on the top of your Draw Deck and the rest at the bottom of your Draw Deck." }, { "id": 67, "type": "opposition", "title": "Southern \u201cHospitality\u201d", "era": "Early", "text": "Place 1 :red_cube in each of Virginia, North Carolina, South Carolina, Georgia and Tennessee." }, { "id": 68, "type": "opposition", "title": "Beer Brewers", "era": "Early", "text": "Playable if Eighteenth Amendment is not in effect. For the remainder of the turn, roll :d6 instead of :d4 when taking a Campaigning action.", "persistent": "rest_of_turn" }, { "id": 69, "type": "opposition", "title": "Southern Resentment", "era": "Early", "text": "Playable if *Fifteenth Amendment* is in effect. Add 1 :red_cube in each of Texas, Louisiana, Arkansas, Mississippi and Alabama." }, { "id": 70, "type": "opposition", "title": "Old Dixie", "era": "Early", "text": "Add 1 :red_cube in each of Louisiana, Mississippi, Alabama, Georgia and Florida." }, { "id": 71, "type": "opposition", "title": "NAOWS Forms", "era": "Middle", "text": "Add 1 :red_campaigner in the Northeast region. Receive 2 :badge." }, { "id": 72, "type": "opposition", "title": "Woman and the Republic", "era": "Middle", "text": "Draw 2 cards from your Draw Deck. Discard 1 card and play the other card for its event immediately." }, { "id": 73, "type": "opposition", "title": "The Ladies\u2019 Battle", "era": "Middle", "text": "Draw 2 cards from your Draw Deck. Discard 1 card and play the other card for its event immediately." }, { "id": 74, "type": "opposition", "title": "Backlash to the Movement", "era": "Middle", "text": "Remove 6 :purple_or_yellow_cube from anywhere, no more than 2 per state." }, { "id": 75, "type": "opposition", "title": "Xenophobia", "era": "Middle", "text": "Remove all from any 1 :purple_cube state. Remove all :yellow_cube from any 1 state." }, { "id": 76, "type": "opposition", "title": "\u201cO Save Us Senators, From Ourselves\u201d", "era": "Middle", "text": "Add 1 :red_cube in one state of each region." }, { "id": 77, "type": "opposition", "title": "Emma Goldman", "era": "Middle", "text": "Roll :d6. Add that number :red_cube anywhere, no more than 1 per state." }, { "id": 78, "type": "opposition", "title": "The Great 1906 San Francisco Earthquake", "era": "Middle", "text": "Remove all :yellow_cube and :purple_cube from California. The Suffragist player loses 1 :badge." }, { "id": 79, "type": "opposition", "title": "A Threat to the Ideal of Womanhood", "era": "Middle", "text": "For the remainder of the turn, the Suffragist player must spend 1 :badge in order to play a card as an event.", "persistent": "rest_of_turn" }, { "id": 80, "type": "opposition", "title": "\u201cUnwarranted, Unnecessary & Dangerous Interference\u201d", "era": "Middle", "text": "Add 1 :red_cube in one state of each region." }, { "id": 81, "type": "opposition", "title": "Conservative Opposition", "era": "Middle", "text": "For the remainder of the turn, roll :d6 instead of :d4 when taking a Campaigning action.", "persistent": "rest_of_turn" }, { "id": 82, "type": "opposition", "title": "The SSWSC", "era": "Middle", "text": "Playable if *Southern Strategy* is in effect. Receive 2 :badge and add 6 :red_cube in the South region, no more than 2 per state." }, { "id": 83, "type": "opposition", "title": "Western Saloons Push Suffrage Veto", "era": "Middle", "text": "Playable if *Eighteenth Amendment* is not in effect. Place 2 :red_cube in Arizona and 1 :red_cube in each of New Mexico, Nevada and Utah." }, { "id": 84, "type": "opposition", "title": "Transcontinental Railroad", "era": "Middle", "text": "Move each :red_campaigner to any region(s) without paying any :badge and then take a Campaigning action." }, { "id": 85, "type": "opposition", "title": "White Supremacy and the Suffrage Movement", "era": "Middle", "text": "Playable if *Southern Strategy* is in effect. Remove all :yellow_cube in up to 4 states. The Suffragist player loses 2 :badge." }, { "id": 86, "type": "opposition", "title": "Senator John Weeks", "era": "Middle", "text": "Remove 1 :congressional_marker from Congress and add 2 :red_cube in New Hampshire." }, { "id": 87, "type": "opposition", "title": "Senator \u201cCotton Ed\u201d Smith", "era": "Middle", "text": "Remove 1 :congressional_marker from Congress and add 2 :red_cube in South Carolina." }, { "id": 88, "type": "opposition", "title": "War in Europe", "era": "Late", "text": "Remove 1 :congressional_marker from Congress. For the remainder of the turn, the Suffragist player must spend 1 :badge in order to take a Campaigning action.", "persistent": "rest_of_turn" }, { "id": 89, "type": "opposition", "title": "1918 Pandemic", "era": "Late", "text": "Remove 1 :congressional_marker from Congress. For the remainder of the turn, the Suffragist player must spend 1 :badge in order to play a card as an event.", "persistent": "rest_of_turn" }, { "id": 90, "type": "opposition", "title": "The Business of Being a Woman", "era": "Late", "text": "Draw 2 cards from your Draw Deck. Discard 1 card and play the other card for its event immediately." }, { "id": 91, "type": "opposition", "title": "The Eden Sphinx", "era": "Late", "text": "Draw 2 cards from your Draw Deck. Discard 1 card and play the other card for its event immediately." }, { "id": 92, "type": "opposition", "title": "Big Liquor\u2019s Big Money", "era": "Late", "text": "Playable if *Eighteenth Amendment* is not in effect. For the remainder of the turn, roll :d6 instead of :d4 when taking a Campaigning action.", "persistent": "rest_of_turn" }, { "id": 93, "type": "opposition", "title": "Red Scare", "era": "Late", "text": "Remove all :purple_cube in up to 2 states." }, { "id": 94, "type": "opposition", "title": "Southern Women\u2019s Rejection League", "era": "Late", "text": "Playable if *Southern Strategy* is in effect. Roll :d8. Add that number :red_cube in the South region, no more than 2 per state." }, { "id": 95, "type": "opposition", "title": "United Daughters of the Confederacy", "era": "Late", "text": "Playable if *Southern Strategy* is in effect. Roll :d8. Add that number :red_cube in the South region, no more than 2 per state." }, { "id": 96, "type": "opposition", "title": "Cheers to \u201cNo on Suffrage\u201d", "era": "Late", "text": "Playable if *Eighteenth Amendment* is not in effect. Roll :d8. Add that number :red_cube anywhere, no more than 2 per state." }, { "id": 97, "type": "opposition", "title": "The Unnecessary Privilege", "era": "Late", "text": "Roll :d6. Add that number :red_cube anywhere, no more than 1 per state." }, { "id": 98, "type": "opposition", "title": "Voter Suppression", "era": "Late", "text": "The Opposition player rolls :d8 instead of :d6 during Final Voting.", "persistent": "ballot_box" }, { "id": 99, "type": "opposition", "title": "Anti-Suffrage Riots", "era": "Late", "text": "The Suffragist player must discard 2 cards from their hand at random and then draw 2 cards from the Suffragist Draw Deck." }, { "id": 100, "type": "opposition", "title": "American Constitutional League", "era": "Late", "text": "Spend 4 :badge to select, and place in front of you, 1 available Strategy card." }, { "id": 101, "type": "opposition", "title": "The Woman Patriot", "era": "Late", "text": "Receive 3 :badge." }, { "id": 102, "type": "opposition", "title": "Governor Clement\u2019s Veto", "era": "Late", "text": "Replace 1 :green_check in a state with 1 :red_x." }, { "id": 103, "type": "opposition", "title": "Senator Henry Cabot Lodge", "era": "Late", "text": "Remove 1 :congressional_marker from Congress and add 2 :red_cube in Massachusetts" }, { "id": 104, "type": "opposition", "title": "Senator William Borah", "era": "Late", "text": "Remove 1 :congressional_marker from Congress and add 2 :red_cube in Utah" }, { "id": 105, "type": "strategy", "title": "Efficient Organizing", "text": "Receive 5 :badge." }, { "id": 106, "type": "strategy", "title": "Reconsideration", "text": "Replace 1 :red_x with 2 :purple_or_yellow_cube or 1 :green_check with 2 :red_cube." }, { "id": 107, "type": "strategy", "title": "Opposition Research", "text": "Your opponent must lose half (rounded up) of their :badge." }, { "id": 108, "type": "strategy", "title": "Change In Plans", "text": "Look at your opponent\u2019s hand. Your opponent must discard 1 card of your choice that does not have a :yellow_campaigner / :purple_campaigner / :red_campaigner on it. Your opponent then draws 1 replacement card from their Draw Deck." }, { "id": 109, "type": "strategy", "title": "Bellwether State", "text": "Select one state and remove any :red_cube and add 4 :purple_or_yellow_cube or remove any :purple_or_yellow_cube and add 4 :red_cube." }, { "id": 110, "type": "strategy", "title": "Superior Lobbying", "text": "Roll 4 :d8. For each 6, 7 or 8 rolled, add 1 :congressional_marker to Congress or remove 1 :congressional_marker from Congress." }, { "id": 111, "type": "strategy", "title": "The Winning Plan", "text": "Draw 6 cards from your Draw Deck. Play 1 card for its event immediately. Place any number of the remaining 5 cards on the top of your Draw Deck and the rest at the bottom of your Draw Deck." }, { "id": 112, "type": "strategy", "title": "Regional Focus", "text": "Add 1 :purple_or_yellow_cube or 1 :red_cube per state in any one region." }, { "id": 113, "type": "strategy", "title": "Eye on the Future", "text": "Playable if it is Turn 5 or Turn 6. Look through your Draw Deck and select 1 card and play for its event immediately. Then reshuffle your Draw Deck." }, { "id": 114, "type": "strategy", "title": "Transportation", "text": "Move all of your :purple_campaigner and :yellow_campaigner OR :red_campaigner to any region(s) without playing any :badge and then take a Campaigning action." }, { "id": 115, "type": "strategy", "title": "Counter Strat", "text": "Remove one card that is \u201cin effect for the remainder of the turn\u201d and place it in the appropriate discard pile." }, { "id": 116, "type": "strategy", "title": "National Focus", "text": "Add 2 :purple_or_yellow_cube or 2 :red_cube in one state of each region." }, { "id": 117, "type": "states", "title": "California", "text": "Draw 2 cards from your Draw Deck. Discard 1 card and play the other card for its event immediately." }, { "id": 118, "type": "states", "title": "Utah", "text": "Add 6 :pink_yellow_cube or 6 :red_cube in the West region, no more than 2 per state." }, { "id": 119, "type": "states", "title": "Montana", "text": "Receive 2 :badge." }, { "id": 120, "type": "states", "title": "Kansas", "text": "Add 6 :pink_yellow_cube or 6 :red_cube in the Plains region, no more than 2 per state." }, { "id": 121, "type": "states", "title": "Texas", "text": "Add 6 :pink_yellow_cube or 6 :red_cube in the South region, no more than 2 per state." }, { "id": 122, "type": "states", "title": "Georgia", "text": "Receive 2 :badge." }, { "id": 123, "type": "states", "title": "Illinois", "text": "Add 6 :pink_yellow_cube or 6 :red_cube in the Midwest region, no more than 2 per state." }, { "id": 124, "type": "states", "title": "Ohio", "text": "Draw 2 cards from your Draw Deck. Discard 1 card and play the other card for its event immediately." }, { "id": 125, "type": "states", "title": "Pennsylvania", "text": "Add 6 :pink_yellow_cube or 6 :red_cube in the Atlantic & Appalachia region, no more than 2 per state." }, { "id": 126, "type": "states", "title": "Virginia", "text": "Draw 2 cards from your Draw Deck. Discard 1 card and play the other card for its event immediately." }, { "id": 127, "type": "states", "title": "New York", "text": "Add 6 :pink_yellow_cube or 6 :red_cube in the Northeast region, no more than 2 per state." }, { "id": 128, "type": "states", "title": "New Jersey", "text": "Receive 2 :badge." }]
+
+// :r !python3 tools/genlayout.py
+const LAYOUT = {
+ "NorthEast": [914, 190],
+ "AtlanticAppalachia": [797, 366],
+ "MidWest": [612, 298],
+ "South": [574, 505],
+ "Plains": [406, 236],
+ "West": [127, 300],
+ "NJ": [960, 277],
+ "CT": [1019, 237],
+ "RI": [1036, 165],
+ "MA": [1014, 74],
+ "ME": [963, 119],
+ "NH": [889, 96],
+ "VT": [817, 157],
+ "NY": [863, 207],
+ "DE": [997, 345],
+ "MD": [952, 404],
+ "NC": [864, 385],
+ "VA": [861, 332],
+ "PA": [849, 257],
+ "WV": [811, 314],
+ "KY": [743, 351],
+ "TN": [716, 401],
+ "OH": [762, 287],
+ "IN": [708, 285],
+ "IL": [663, 333],
+ "MI": [724, 228],
+ "WI": [639, 198],
+ "MO": [601, 357],
+ "IA": [563, 256],
+ "MN": [561, 163],
+ "FL": [835, 572],
+ "SC": [828, 433],
+ "GA": [779, 465],
+ "AL": [715, 470],
+ "MS": [662, 477],
+ "LA": [623, 544],
+ "AR": [605, 436],
+ "TX": [482, 516],
+ "OK": [519, 417],
+ "KS": [497, 348],
+ "NE": [477, 273],
+ "SD": [471, 205],
+ "ND": [468, 134],
+ "CO": [374, 331],
+ "WY": [341, 229],
+ "MT": [335, 133],
+ "NM": [351, 440],
+ "AZ": [245, 432],
+ "UT": [264, 310],
+ "NV": [180, 290],
+ "ID": [233, 203],
+ "CA": [126, 367],
+ "OR": [135, 173],
+ "WA": [158, 97],
+}
+
+function is_action(action) {
+ if (view.actions && view.actions[action])
+ return true
+ return false
+}
+
+function is_card_action(action, card) {
+ if (view.actions && view.actions[action] && view.actions[action].includes(card))
+ return true
+ return false
+}
+
+function is_piece_action(i) {
+ if (view.actions && view.actions.piece && view.actions.piece.includes(i))
+ return true
+ return false
+}
+
+function is_space_action(i) {
+ if (view.actions && view.actions.space && view.actions.space.includes(i))
+ return true
+ return false
+}
+
+function on_blur(evt) {
+ document.getElementById("status").textContent = ""
+}
+
+function on_focus_space(evt) {
+ document.getElementById("status").textContent = evt.target.my_name
+}
+
+function on_focus_piece(evt) {
+ if (evt.target.my_name)
+ document.getElementById("status").textContent = evt.target.my_name
+}
+
+function on_click_card(evt) {
+ if (evt.button === 0) {
+ if (send_action('card', evt.target.my_card))
+ evt.stopPropagation()
+ }
+}
+
+function on_click_space(evt) {
+ if (evt.button === 0) {
+ if (send_action('space', evt.target.my_space))
+ evt.stopPropagation()
+ }
+}
+
+function on_click_cube(evt) {
+ if (evt.button === 0) {
+ if (send_action('piece', evt.target.my_cube))
+ evt.stopPropagation()
+ }
+}
+
+function create(t, p, ...c) {
+ let e = document.createElement(t)
+ Object.assign(e, p)
+ e.append(c)
+ return e
+}
+
+function build_user_interface() {
+ let elt
+
+ for (let c = 1; c <= 128; ++c) {
+ elt = ui.cards[c] = create("div", {
+ className: `card card_${c}`,
+ my_card: c,
+ onmousedown: on_click_card
+ })
+ }
+
+}
+
+function on_focus_card_tip(card_number) {
+ document.getElementById("tooltip").className = "card card_" + card_number
+}
+
+function on_blur_card_tip() {
+ document.getElementById("tooltip").classList = "card hide"
+}
+
+function sub_card_name(match, p1, offset, string) {
+ let c = p1 | 0
+ let n = CARDS[c].title
+ return `<span class="tip" onmouseenter="on_focus_card_tip(${c})" onmouseleave="on_blur_card_tip()">${n}</span>`
+}
+
+function on_log(text) {
+ let p = document.createElement("div")
+
+ if (text.match(/^>/)) {
+ text = text.substring(1)
+ p.className = 'i'
+ }
+
+ text = text.replace(/&/g, "&amp;")
+ text = text.replace(/</g, "&lt;")
+ text = text.replace(/>/g, "&gt;")
+ text = text.replace(/C(\d+)/g, sub_card_name)
+
+ if (text.match(/^\.h1/)) {
+ text = text.substring(4)
+ p.className = 'h1'
+ }
+
+ if (text.match(/^\.h2/)) {
+ text = text.substring(4)
+ p.className = 'h2'
+ }
+
+ if (text.match(/^\.h3/)) {
+ text = text.substring(4)
+ p.className = 'h3'
+ }
+
+ p.innerHTML = text
+ return p
+}
+
+function support_info() {
+ if (view.support_hand === 1)
+ return "1 card in hand";
+ return view.support_hand + " cards in hand";
+}
+
+function opposition_info() {
+ if (view.opposition_hand === 1)
+ return "1 card in hand";
+ return view.opposition_hand + " cards in hand";
+}
+
+function on_update() {
+ console.log("VIEW", view)
+
+ ui.player[SUF].classList.toggle("active", view.active === SUF_NAME)
+ ui.player[OPP].classList.toggle("active", view.active === OPP_NAME)
+
+ document.getElementById("support_info").textContent = support_info()
+ document.getElementById("opposition_info").textContent = opposition_info()
+
+ document.getElementById("hand").replaceChildren()
+ document.getElementById("states_draw").replaceChildren()
+ document.getElementById("strategy_draw").replaceChildren()
+
+ if (view.hand) {
+ document.getElementById("hand_panel").classList.remove("hide")
+ for (let c of view.hand)
+ document.getElementById("hand").appendChild(ui.cards[c])
+ } else {
+ document.getElementById("hand_panel").classList.add("hide")
+ }
+
+ for (let c of view.states_draw)
+ document.getElementById("states_draw").appendChild(ui.cards[c])
+ for (let c of view.strategy_draw)
+ document.getElementById("strategy_draw").appendChild(ui.cards[c])
+
+ action_button("draw", "Draw")
+
+ action_button("skip", "Skip")
+ action_button("pass", "Pass")
+ action_button("done", "Done")
+ action_button("undo", "Undo")
+
+ // XXX
+ action_button("restart", "Restart")
+}
+
+build_user_interface()
diff --git a/rules.js b/rules.js
index 6f0e966..dd802ae 100644
--- a/rules.js
+++ b/rules.js
@@ -59,15 +59,22 @@ exports.setup = function (seed, _scenario, _options) {
}
log_h1("Votes for Women")
+ setup_game()
+ start_turn()
+ return game
+}
+function setup_game() {
// init card decks & shuffle
game.support_deck = init_player_cards(first_support_card)
game.support_hand.push(first_support_card)
game.opposition_deck = init_player_cards(first_opposition_card)
game.opposition_hand.push(first_opposition_card)
- for (let c = first_strategy_card; c <= last_strategy_card; ++c)
+ for (let c = first_strategy_card; c <= last_strategy_card; ++c) {
+ console.log("PUSH", c)
game.strategy_deck.push(c)
+ }
for (let c = first_states_card; c <= last_states_card; ++c)
game.states_draw.push(c)
@@ -75,11 +82,14 @@ exports.setup = function (seed, _scenario, _options) {
shuffle(game.strategy_deck)
game.states_draw.splice(-3) // 3 states card aren't used
- game.strategy_draw = game.strategy_deck.splice(-3) // draw 3 strategy cards
+ log_h2("States Cards")
+ for (let c of game.states_draw)
+ log(`C${c}`)
- game.active = SUF
- start_turn()
- return game
+ game.strategy_draw = game.strategy_deck.splice(-3) // draw 3 strategy cards
+ log_h2("Strategy Cards")
+ for (let c of game.strategy_draw)
+ log(`C${c}`)
}
function init_player_cards(first_card) {
@@ -103,6 +113,7 @@ function start_turn() {
game.turn += 1
log_h1("Turn " + game.turn)
+ game.active = SUF
goto_planning_phase()
}
@@ -241,6 +252,7 @@ exports.view = function(state, player) {
view = {
log: game.log,
+ active: game.active,
prompt: null,
actions: null,
diff --git a/tools/gencards.py b/tools/gencards.py
new file mode 100644
index 0000000..1d22e87
--- /dev/null
+++ b/tools/gencards.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+
+import json
+import re
+
+cards = [None]
+
+# global card object
+card = {
+ 'id': 1,
+ 'type': "",
+ 'title': "",
+ 'era': "",
+ 'text': [],
+ 'attrs': {}
+}
+
+kv_pattern = r'<!--\s*(?P<key>[^:]+):\s*(?P<value>[^->]+)\s*-->'
+file_format = "tools/{}_cards.md"
+
+def flush():
+ if card['title']:
+ output = card.copy()
+ # Combine text into a single string
+ output['text'] = " ".join(output['text'])
+
+ # Integrate attrs into the card object and then clear attrs
+ for key, value in output['attrs'].items():
+ output[key] = value
+ output.pop('attrs')
+
+ # Add era only if it's a non-empty string
+ if not output['era']:
+ output.pop('era')
+
+ cards.append(output)
+
+ # Reset card attributes for the next entry
+ card['title'] = ""
+ card['text'] = []
+ card['attrs'] = {}
+ card['id'] += 1
+
+def read_cards(_card_type):
+ card['type'] = _card_type
+ card['era'] = ""
+ filename = file_format.format(_card_type)
+
+ with open(filename) as fp:
+ for line in fp:
+ line = line.rstrip()
+ if line.startswith("# "):
+ flush()
+ card['era'] = line[2:].strip()
+ elif line.startswith("## "):
+ flush()
+ card['title'] = line[3:].strip()
+ elif match := re.match(kv_pattern, line):
+ key = match.group('key').strip()
+ value = match.group('value').strip()
+ card['attrs'][key] = value
+ elif line:
+ card['text'].append(line)
+ flush()
+
+if __name__ == "__main__":
+ read_cards("support")
+ read_cards("opposition")
+ read_cards("strategy")
+ read_cards("states")
+
+ print("const CARDS = " + json.dumps(cards))