summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2023-09-21 09:22:07 +0200
committerJérémy Zurcher <jeremy@asynk.ch>2023-09-21 09:22:07 +0200
commitca128a74ae0f238b9ba81df68ed26e3b9a223e1e (patch)
treee5985c9eda5527a394e70f344a881f2920b47144
parent6da1db151f295b910cc7244ba0211b438a914514 (diff)
downloadcolonial-twilight-ca128a74ae0f238b9ba81df68ed26e3b9a223e1e.zip
colonial-twilight-ca128a74ae0f238b9ba81df68ed26e3b9a223e1e.tar.gz
Cards : set attributes with specs
-rw-r--r--lib/colonial_twilight/card_attributes.rb97
-rw-r--r--lib/colonial_twilight/cards.rb164
-rw-r--r--lib/colonial_twilight/deck.rb128
-rw-r--r--spec/cards_spec.rb69
4 files changed, 294 insertions, 164 deletions
diff --git a/lib/colonial_twilight/card_attributes.rb b/lib/colonial_twilight/card_attributes.rb
new file mode 100644
index 0000000..bf339d8
--- /dev/null
+++ b/lib/colonial_twilight/card_attributes.rb
@@ -0,0 +1,97 @@
+#! /usr/bin/env ruby
+# frozen_string_literal: true
+
+# rubocop:disable Style/Documentation
+
+module ColonialTwilight
+ module CardAttributes
+ MAX_CARD_NUM = 71
+ SINGLE = 1
+ FLN_MARKED = 2
+ FLN_SPECIAL = 4
+ FLN_CAPABILITY = 8
+ FLN_MOMENTUM = 16
+ GOV_CAPABILITY = 32
+ GOV_MOMENTUM = 64
+ DUAL_CAPABILITY = 128
+ DUAL_MOMENTUM = 256
+
+ class << self
+ attr_reader :cards
+ end
+
+ @cards = {
+ 1 => ['Quadrillage', 0],
+ 2 => ['Balky Conscripts', 0 | FLN_MOMENTUM],
+ 3 => ['Leadership Snatch', 0 | FLN_MARKED],
+ 4 => ['Oil & Gas Discoveries', 0 | SINGLE],
+ 5 => ['Peace of the Brave', 0 | GOV_MOMENTUM],
+ 6 => ['Factionalism', 0],
+ 7 => ['5th Bureau', 0 | FLN_MARKED],
+ 8 => ['Cross-border air strike', 0 | FLN_MOMENTUM],
+ 9 => ['Beni-Oui-Oui', 0 | SINGLE | FLN_MARKED],
+ 10 => ['Moudjahidine', 0 | FLN_MARKED | FLN_MOMENTUM],
+ 11 => ['Bananes', 0 | FLN_MARKED | GOV_MOMENTUM],
+ 12 => ['Ventilos', 0 | FLN_MARKED | FLN_SPECIAL | GOV_MOMENTUM],
+ 13 => ['SAS', 0 | GOV_CAPABILITY],
+ 14 => ['Protest in Paris', 0 | SINGLE | FLN_MARKED],
+ 15 => ['Jean-Paul Sarte', 0],
+ 16 => ['NATO', 0],
+ 17 => ['Commandos', 0 | FLN_CAPABILITY],
+ 18 => ['Torture', 0 | SINGLE | FLN_MARKED | DUAL_CAPABILITY],
+ 19 => ['General Strike', 0 | FLN_MARKED],
+ 20 => ['Sauve qui peut', 0 | SINGLE | FLN_MARKED | FLN_SPECIAL],
+ 21 => ['UN Resolution', 0],
+ 22 => ['The Government of USA is Convinced...', 0 | FLN_MARKED],
+ 23 => ['Diplomatic Leanings', 0 | FLN_MARKED],
+ 24 => ['Economic Development', 0 | FLN_MARKED],
+ 25 => ['Purge', 0 | SINGLE],
+ 26 => ['Casbah', 0 | FLN_MARKED],
+ 27 => ['Covert Movement', 0 | FLN_CAPABILITY],
+ 28 => ['Atrocities and Reprisals', 0 | SINGLE | FLN_MARKED],
+ 29 => ['The Call Up', 0 | FLN_MOMENTUM],
+ 30 => ['Change in Tactics', 0 | SINGLE],
+ 31 => ['Intimidation', 0 | FLN_MARKED | GOV_MOMENTUM],
+ 32 => ['Teleb the Bomb-maker', 0 | FLN_CAPABILITY],
+ 33 => ['Overkill', 0 | FLN_MARKED | FLN_CAPABILITY],
+ 34 => ['Elections', 0 | FLN_MARKED],
+ 35 => ['Napalm', 0 | FLN_MARKED | GOV_CAPABILITY],
+ 36 => ['Assassination', 0 | FLN_MARKED],
+ 37 => ['Integration', 0],
+ 38 => ['French Economic Crisis', 0],
+ 39 => ['Retreat into Djebel', 0],
+ 40 => ['Strategic Movement', 0 | FLN_MOMENTUM],
+ 41 => ['Egypt', 0 | FLN_MARKED],
+ 42 => ['Czech Arms Deal', 0 | FLN_MARKED],
+ 43 => ['Refugees', 0 | FLN_MARKED],
+ 44 => ['Paranoia', 0 | GOV_MOMENTUM],
+ 45 => ['Challe Plan', 0 | GOV_MOMENTUM | FLN_MOMENTUM],
+ 46 => ['Moghazni', 0 | GOV_MOMENTUM],
+ 47 => ['Third Force', 0 | FLN_MARKED],
+ 48 => ['Ultras', 0 | FLN_MARKED],
+ 49 => ['Factional Plot', 0 | FLN_MARKED | FLN_SPECIAL],
+ 50 => ['Bleuite', 0],
+ 51 => ['Stripey Hole', 0 | FLN_MARKED | FLN_SPECIAL],
+ 52 => ['Cabinet Shuffle', 0 | SINGLE],
+ 53 => ['Population Control', 0 | FLN_MARKED | GOV_MOMENTUM],
+ 54 => ['Operation 744', 0 | SINGLE | FLN_MARKED | FLN_SPECIAL],
+ 55 => ['Development', 0 | FLN_MARKED],
+ 56 => ['Hardened Attitudes', 0 | SINGLE | FLN_MARKED | FLN_SPECIAL | DUAL_MOMENTUM],
+ 57 => ['Peace Talks', 0 | SINGLE | FLN_MARKED | DUAL_MOMENTUM],
+ 58 => ['Army in Waiting', 0],
+ 59 => ['Bandung Conference', 0 | FLN_MARKED],
+ 60 => ['Soummam Conference', 0 | FLN_MARKED],
+ 61 => ['Morocco and Tunisia Independent', 0 | SINGLE],
+ 62 => ['Suez Crisis', 0 | SINGLE],
+ 63 => ['OAS', 0 | SINGLE],
+ 64 => ['Mobilization', 0 | SINGLE],
+ 65 => ['Recall De Gaulle', 0 | SINGLE],
+ 66 => ['Coup d\'etat', 0 | SINGLE],
+ 67 => ['Propaganda!', 0 | SINGLE],
+ 68 => ['Propaganda!', 0 | SINGLE],
+ 69 => ['Propaganda!', 0 | SINGLE],
+ 70 => ['Propaganda!', 0 | SINGLE],
+ 71 => ['Propaganda!', 0 | SINGLE]
+ }
+ end
+end
diff --git a/lib/colonial_twilight/cards.rb b/lib/colonial_twilight/cards.rb
deleted file mode 100644
index de962c0..0000000
--- a/lib/colonial_twilight/cards.rb
+++ /dev/null
@@ -1,164 +0,0 @@
-#! /usr/bin/env ruby
-# frozen_string_literal: true
-
-# rubocop:disable Style/Documentation
-
-module ColonialTwilight
- CARD_SINGLE = 1
- CARD_FLN_MARKED = 2
- CARD_ALWAYS_PLAY = 4
-
- class Card
- attr_reader :num, :title
-
- def initialize(num, title, attr, act0 = nil, act1 = nil)
- @num = num
- @title = title
- @attributes = attr
- @act0 = act0
- @act1 = act1
- end
-
- def dual?
- @attributes & CARD_SINGLE.zero?
- end
-
- def single?
- @attributes & CARD_SINGLE == CARD_SINGLE
- end
-
- def fln_marked?
- @attributes & CARD_FLN_MARKED == CARD_FLN_MARKED
- end
-
- def always_play?
- @attributes & CARD_ALWAYS_PLAY == CARD_ALWAYS_PLAY
- end
-
- def capability?
- false
- end
-
- def fln_effective?
- false
- end
-
- def fln_effectiveness
- 0
- end
-
- def fln_playable?
- # reduce GOV support or resources or commitment
- # shift France Track toward F
- # place FLN base or increase FLN resources
- false
- end
-
- def check
- # @attributes.each do |attr| raise "unknown attribute : #{attr}" if attr not in ATTRS end
- # puts single?
- # puts dual?
- # puts flnmarked?
- # puts alwaysplay?
- end
- end
-
- class CardAction
- def initialize(txt, cond)
- @txt = txt
- @condition = cond
- end
- end
-
- class Deck
- attr_reader :cards
-
- def initialize
- @cards = {}
- add_card 0, 'None', nil, nil
- add_card 1, 'Quadrillage', 0, CardAction.new('Place up to all French Police in Available in up to 3 spaces', { what: :french_police, from: :available })
- end
-
- def pull(num)
- @cards[num.positive? ? 1 : 0] # FIXME
- end
-
- private
-
- def add_card(num, title, attrs, _action)
- @cards[num] = Card.new num, title, attrs
- @cards[num].check
- end
- end
-end
-
- # 'Balky Conscripts'
- # 'Leadership Snatch'
- # 'Oil & Gas Discoveries'
- # 'Peace of the Brave'
- # 'Factionalism'
- # '5th Bureau'
- # 'Cross-border air strike'
- # 'Beni-Oui-Oui'
- # 'Moudjahidine'
- # 'Bananes'
- # 'Ventilos'
- # 'SAS'
- # 'Protest in Paris'
- # 'Jean-Paul Sarte'
- # 'NATO'
- # 'Commandos'
- # 'Torture'
- # 'General Strike'
- # 'Sauve qui peut'
- # 'United Nations Resolution'
- # 'The Government of USA is Convinced...'
- # 'Diplomatic Leanings'
- # 'Economic Development'
- # 'Purge'
- # 'Casbah'
- # 'Covert Movement'
- # 'Atrocities and Reprisals'
- # 'The Call Up'
- # 'Change in Tactics'
- # 'Intimidation'
- # 'Teleb the Bomb-maker'
- # 'Overkill'
- # 'Elections'
- # 'Napalm'
- # 'Assassination'
- # 'Integration'
- # 'Economic Crisis in France'
- # 'Retreat into Djebel'
- # 'Strategic Movement'
- # 'Egypt'
- # 'Czech Arms Deal'
- # 'Refugees'
- # 'Paranoia'
- # 'Challe Plan'
- # 'Moghazni'
- # 'Third Force'
- # 'Ultras'
- # 'Factional Plot'
- # 'Bleuite'
- # 'Stripey Hole'
- # 'Cabinet Shuffle'
- # 'Population Control'
- # 'Operation 744'
- # 'Development'
- # 'Hardened Attitudes'
- # 'Peace Talks'
- # 'Army in Waiting'
- # 'Bandung Conference'
- # 'Soummam Conference'
- # 'Morocco and Tunisia Independent'
- # 'Suez Crisis'
- # 'OAS'
- # 'Mobilization'
- # 'Recall De Gaulle'
- # "Coup d'etat"
- # "Propaganda!"
- # "Propaganda!"
- # "Propaganda!"
- # "Propaganda!"
- # "Propaganda!"
diff --git a/lib/colonial_twilight/deck.rb b/lib/colonial_twilight/deck.rb
new file mode 100644
index 0000000..747cb2f
--- /dev/null
+++ b/lib/colonial_twilight/deck.rb
@@ -0,0 +1,128 @@
+#! /usr/bin/env ruby
+# frozen_string_literal: true
+
+# rubocop:disable Style/Documentation
+
+require 'colonial_twilight/card_attributes'
+module ColonialTwilight
+ class Card
+ include ColonialTwilight::CardAttributes
+
+ attr_reader :num, :title
+
+ def set(num)
+ raise "card #{num} is out of range [1; #{MAX_CARD_NUM}]" if !num.positive? || num > MAX_CARD_NUM
+
+ @num = num
+ card = ColonialTwilight::CardAttributes.cards[num] || [nil, nil]
+ @title = card[0]
+ @attributes = card[1]
+ self
+ end
+
+ def propaganda?
+ @num >= 67
+ end
+
+ def dual?
+ (@attributes & SINGLE).zero?
+ end
+
+ def single?
+ (@attributes & SINGLE) == SINGLE
+ end
+
+ def fln_marked?
+ (@attributes & FLN_MARKED) == FLN_MARKED
+ end
+
+ def special?
+ (@attributes & FLN_SPECIAL) == FLN_SPECIAL
+ end
+
+ def fln_capability?
+ (@attributes & FLN_CAPABILITY) == FLN_CAPABILITY
+ end
+
+ def gov_capability?
+ (@attributes & GOV_CAPABILITY) == GOV_CAPABILITY
+ end
+
+ def dual_capability?
+ (@attributes & DUAL_CAPABILITY) == DUAL_CAPABILITY
+ end
+
+ def fln_momentum?
+ (@attributes & FLN_MOMENTUM) == FLN_MOMENTUM
+ end
+
+ def gov_momentum?
+ (@attributes & GOV_MOMENTUM) == GOV_MOMENTUM
+ end
+
+ def dual_momentum?
+ (@attributes & DUAL_MOMENTUM) == DUAL_MOMENTUM
+ end
+
+ def fln_effective?
+ # FIXME: todo
+ false
+ end
+
+ def fln_effectiveness
+ # FIXME: todo
+ 0
+ end
+
+ def fln_playable?
+ # reduce GOV support or resources or commitment
+ # shift France Track toward F
+ # place FLN base or increase FLN resources
+ false
+ end
+
+ def inspect
+ s = @num < 10 ? ' ' : ''
+ t = title + ' ' * (38 - title.size)
+ s += "#{@num} - #{single? ? 'Single' : 'Dual '} : #{t} : #{_capability} : #{_momentum}"
+ s
+ end
+
+ def _capability
+ s = ''
+ s += ' FLN-capability' if fln_capability?
+ s += ' GOV-capability' if gov_capability?
+ s += 'DUAL-capability' if dual_capability?
+ s = ' ' * 15 if s.empty?
+ s
+ end
+
+ def _momentum
+ s = ''
+ s += ' FLN-momentum ' if fln_momentum?
+ s += ' GOV-momentum ' if gov_momentum?
+ s += 'DUAL-momentum ' if dual_momentum?
+ s
+ end
+ end
+
+ # class CardAction
+ # def initialize(txt, cond)
+ # @txt = txt
+ # @condition = cond
+ # end
+ # end
+
+ class Deck
+ attr_reader :card
+
+ def initialize
+ @card = Card.new
+ end
+
+ def pull(num)
+ @card.set(num)
+ end
+ end
+ # 1.upto(71) { |n| puts Deck.new.pull(n).inspect }
+end
diff --git a/spec/cards_spec.rb b/spec/cards_spec.rb
new file mode 100644
index 0000000..12ffb24
--- /dev/null
+++ b/spec/cards_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require './lib/colonial_twilight/deck'
+
+describe ColonialTwilight::Card do
+ describe 'Propaganda' do
+ deck = ColonialTwilight::Deck.new
+ s = [67, 68, 69, 70, 71]
+ 1.upto(71) do |n|
+ it "is flags right #{n}" do expect(deck.pull(n).propaganda?).to be s.include?(n) end
+ end
+ end
+
+ describe 'Single or Dual' do
+ deck = ColonialTwilight::Deck.new
+ s = [4, 9, 14, 18, 20, 25, 28, 30, 52, 54, 56, 57, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71]
+ 1.upto(71) do |n|
+ it "is flags right #{n}" do expect(deck.pull(n).single?).to be s.include?(n) end
+ end
+ end
+
+ describe 'FLN capability' do
+ deck = ColonialTwilight::Deck.new
+ s = [17, 27, 32, 33]
+ 1.upto(71) do |n|
+ it "is flags right #{n}" do expect(deck.pull(n).fln_capability?).to be s.include?(n) end
+ end
+ end
+
+ describe 'GOV capability' do
+ deck = ColonialTwilight::Deck.new
+ s = [13, 35]
+ 1.upto(71) do |n|
+ it "is flags right #{n}" do expect(deck.pull(n).gov_capability?).to be s.include?(n) end
+ end
+ end
+
+ describe 'DUAL capability' do
+ deck = ColonialTwilight::Deck.new
+ s = [18]
+ 1.upto(71) do |n|
+ it "is flags right #{n}" do expect(deck.pull(n).dual_capability?).to be s.include?(n) end
+ end
+ end
+
+ describe 'FLN momentum' do
+ deck = ColonialTwilight::Deck.new
+ s = [2, 8, 10, 29, 40, 45]
+ 1.upto(71) do |n|
+ it "is flags right #{n}" do expect(deck.pull(n).fln_momentum?).to be s.include?(n) end
+ end
+ end
+
+ describe 'GOV momentum' do
+ deck = ColonialTwilight::Deck.new
+ s = [5, 11, 12, 31, 44, 45, 46, 53]
+ 1.upto(71) do |n|
+ it "is flags right #{n}" do expect(deck.pull(n).gov_momentum?).to be s.include?(n) end
+ end
+ end
+
+ describe 'DUAL momentum' do
+ deck = ColonialTwilight::Deck.new
+ s = [56, 57]
+ 1.upto(71) do |n|
+ it "is flags right #{n}" do expect(deck.pull(n).dual_momentum?).to be s.include?(n) end
+ end
+ end
+end