Class: SplendorGame::CLI

Inherits:
Object show all
Defined in:
lib/splendor_game/cli.rb

Constant Summary collapse

@@cli =
HighLine.new

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeCLI

Returns a new instance of CLI.



9
10
11
12
13
# File 'lib/splendor_game/cli.rb', line 9

def initialize
  @g = SplendorGame::Game.new Hash[*ARGV]
  choose_players
  main
end

Instance Attribute Details

#colourObject (readonly)

Returns the value of attribute colour.



7
8
9
# File 'lib/splendor_game/cli.rb', line 7

def colour
  @colour
end

#costObject (readonly)

Returns the value of attribute cost.



7
8
9
# File 'lib/splendor_game/cli.rb', line 7

def cost
  @cost
end

#levelObject (readonly)

Returns the value of attribute level.



7
8
9
# File 'lib/splendor_game/cli.rb', line 7

def level
  @level
end

#pointsObject (readonly)

Returns the value of attribute points.



7
8
9
# File 'lib/splendor_game/cli.rb', line 7

def points
  @points
end

Instance Method Details

#bank_detailsObject



154
155
156
157
158
159
160
# File 'lib/splendor_game/cli.rb', line 154

def bank_details
  str = "Bank tokens = "
  @g.bank.tokens.sort.to_h.each do |colour, count|
    str << "#{colour}=#{count} " if count > 0
  end
  str
end

#card_display(card) ⇒ Object



117
118
119
120
121
122
123
124
# File 'lib/splendor_game/cli.rb', line 117

def card_display(card)
  text = "#{card.points}pts "
  text << "(#{card.colour}) => " if card.instance_variable_defined?(:@colour)
  card.cost.each do |k,v|
    text << "#{v} x #{k}, "
  end
  text[0..-3]
end

#choose_card(mode, player = nil) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/splendor_game/cli.rb', line 162

def choose_card(mode, player = nil)
  displayed_cards_list = @g.all_displayed_cards.collect { |c| [card_display(c),c] }.to_h
  if mode==:reserve
    (1..3).each { |i| displayed_cards_list["Reserve mystery level #{i} card"]= i }
  end
  if mode==:buy
    player.tableau.reserved_cards.each_with_index do |card, index| 
      displayed_cards_list["R#{index+1} - #{card_display(card)}"]= card
    end
  end
  @@cli.choose do |menu|
    menu.prompt = "Which card do you want to #{mode}? "
    menu.choices(*displayed_cards_list.keys) do |chosen|
      @@cli.say "Nice, you chose #{chosen}."
      displayed_cards_list[chosen]
    end
    menu.choice(:cancel) { return false }
  end
end

#choose_playersObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/splendor_game/cli.rb', line 15

def choose_players
  count = 1 
  @@cli.say "Name all the players. Input 'done' when you are done."
  loop do
    pname = @@cli.ask("Enter name of player #{count} > ") do |q| 
      q.validate = lambda { |a| a.length >= 1 && a.length <= 19 }
    end
    if pname.downcase == 'done'
      break if count > MIN_PLAYER_COUNT
      @@cli.say "You need to input at least 2 players!"
    elsif @g.add_player(pname)== true
      count += 1
      @@cli.say "*** #{pname} successfully added"
    else
      @@cli.say "*** Sorry, there was a problem adding player #{pname}"
    end
    break if count > MAX_PLAYER_COUNT
  end
  @@cli.say "Succesfully added #{count-1} players. Game is ready to start."
end

#consider_nobles(turn) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/splendor_game/cli.rb', line 201

def consider_nobles(turn)
  possibles = turn.claimable_nobles
  return false if possibles.empty?
  return assign_only_valid_noble(turn, possibles) if possibles.count==1
  displayed_nobles_list = possibles.collect { |c| [card_display(c),c] }.to_h
  @@cli.choose do |menu|
    menu.prompt = "You qualify for multiple nobles! Pick one... "
    menu.choices(*displayed_nobles_list.keys) do |chosen|
      turn.claim_noble(displayed_nobles_list[chosen])
      @@cli.say "Nice, you chose #{chosen}."
    end
  end
  
end

#display_noblesObject



216
217
218
219
220
# File 'lib/splendor_game/cli.rb', line 216

def display_nobles
  @g.nobles.each do |noble|
    @@cli.say "NOBLE - #{card_display(noble)}"
  end
end

#do_turn(turn) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/splendor_game/cli.rb', line 76

def do_turn(turn)
  while turn.action_done == false
    output_all_player_details(turn.player)
    input = @@cli.ask "What do you want to do, <%= color('#{turn.player.name}', BOLD) %>? "
    command_result = process_command(input.downcase, turn)
    if !command_result
      @@cli.say "Sorry, I did not understand that. Press h for help"
    elsif command_result==:exit
      break
    end
  end
  consider_nobles(turn)
  turn.end_turn
  @@cli.say "*** END OF TURN***"
  command_result==:exit ? false : true
end

#end_game_detailObject



222
223
224
225
226
# File 'lib/splendor_game/cli.rb', line 222

def end_game_detail
  @@cli.say "The game consisted of #{@g.turns.count} turns"
  @@cli.ask "It's the end of the game. Press enter to end the program."
  @@cli.say "Goodbye!"
end

#full_displayObject



46
47
48
49
50
51
52
53
# File 'lib/splendor_game/cli.rb', line 46

def full_display
  @g.display.each do |row, deck|
    @@cli.say "ROW #{row}"
    deck.each do |card| 
      @@cli.say card_display(card)
    end
  end
end

#mainObject



229
230
231
232
233
234
235
236
237
238
239
# File 'lib/splendor_game/cli.rb', line 229

def main
  @g.start_game
  catch :exit do
    loop do
      turn = @g.next_turn
      throw :exit if turn===false # or @exit_flag==true ??
      throw :exit if !do_turn(turn) 
    end #end of the game - only reachable by throwing an :exit
  end
  end_game_detail
end

#output_all_player_details(highlighted_player = nil) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/splendor_game/cli.rb', line 126

def output_all_player_details(highlighted_player=nil)
  @g.players.each do |p|
    if p==highlighted_player
      str = "<%= color('"
      str << player_details(p)
      str << "', BOLD) %>"
    else
      str = player_details(p)
    end
    @@cli.say str
  end
end

#player_details(player) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/splendor_game/cli.rb', line 139

def player_details(player)
  str = "#{player.name.ljust(19)}: #{player.points.to_s.ljust(2)}pts. "
  reserved_card_count = player.tableau.reserved_cards.count
  str << "(#{reserved_card_count}R) " if reserved_card_count > 0
  str << "Cards (#{player.tableau.cards.count}): "
  player.tableau.all_colours_on_cards.sort.to_h.each do |colour, count|
    str << "#{colour}=#{count} " if count > 0
  end
  str << "Tokens: "
  player.tableau.tokens.sort.to_h.each do |colour,count|
    str << "#{colour}=#{count} " if count > 0
  end
  str[0..-2]
end

#process_command(input, turn) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/splendor_game/cli.rb', line 93

def process_command(input, turn)
  case
  when input[0]=='b'
    card = choose_card(:buy, turn.player)
    purchase_card(:card => card, :turn => turn) if card
  when input[0]=='r'
    card = choose_card(:reserve, turn.player)
    reserve_card(:card => card, :turn => turn) if card
  when input[0]=='h'
    puts_help
  when input[0]=='n'
    display_nobles
  when input[0]=='t'
    @@cli.say bank_details + " "
    take_tokens(turn)
  when input[0]=='x'
    return :exit
  else
    return false
  end
  true
end

#purchase_card(args) ⇒ Object

practicing using args rather than fixed list of parameters



56
57
58
59
60
61
62
63
64
# File 'lib/splendor_game/cli.rb', line 56

def purchase_card(args)
  #if args[:turn].player.tableau.reserved_cards.include?(args[:card])
  #  args[:turn].reserve_card
  if args[:turn].purchase_card(args[:card])
    true
  else
    @@cli.say "Oops, you can't afford that"
  end
end

#puts_helpObject



36
37
38
39
40
41
42
43
44
# File 'lib/splendor_game/cli.rb', line 36

def puts_help
  @@cli.say "************************ HELP! ************************"
  @@cli.say "<%= color('(b)uy', BOLD) %> = Buy a card"
  @@cli.say "<%= color('(r)eserve', BOLD) %> = Reserve a card"
  @@cli.say "<%= color('(t)okens', BOLD) %> = Pick up tokens from the bank"
  @@cli.say "<%= color('(n)obles', BOLD) %> = Look at the available nobles"
  @@cli.say "<%= color('(h)elp', BOLD) %> = This help page"
  @@cli.say "<%= color('e(x)it', BOLD) %> = Exit the program"
end

#reserve_card(args) ⇒ Object



66
67
68
69
70
71
72
73
74
# File 'lib/splendor_game/cli.rb', line 66

def reserve_card(args)
  if args[:card].is_a?(SplendorGame::Card) && args[:turn].reserve_displayed_card(args[:card])
    true
  elsif args[:card].is_a?(Integer) && args[:turn].reserve_random_card(args[:card])
    true
  else
    @@cli.say "Sorry, you can't reserve that (maybe you have reserved too many cards)"
  end
end

#take_tokens(turn) ⇒ Object

def validate_token_choice(t)

return false if [2,3].include?(t.count)
t.each { |c| return false if !VALID_COLOUR_SYMBOLS.include?(c.upcase) || c==:gold}
return false if t.count==2 && t[0] != t[1]
true

end



189
190
191
192
193
194
195
196
197
198
199
# File 'lib/splendor_game/cli.rb', line 189

def take_tokens(turn)
  input = @@cli.ask "Which tokens would you like (CSV format)? "
  requested_tokens = input.split(",")
  #return false if !validate_token_choice(requested_tokens)
  if requested_tokens.count==2
    response = turn.take_two_tokens_same_colour(requested_tokens[0])
  elsif requested_tokens.count==3
    response = turn.take_different_tokens(requested_tokens)
  end
  @@cli.say "Oops, that's not a valid selection" if !response
end