Class: Monotony::Game
- Inherits:
-
Object
- Object
- Monotony::Game
- Defined in:
- lib/monotony/game.rb
Overview
Contains the main game engine logic.
Instance Attribute Summary collapse
-
#available_properties ⇒ Array<Purchasable>
Properties yet to be purchased by players.
-
#bank_balance ⇒ Object
Returns the value of attribute bank_balance.
-
#board ⇒ Array<Square>
The current game board.
-
#chance ⇒ String
Draws a chance card from the pile.
-
#community_chest ⇒ String
Draws a community chest card from the pile.
-
#completed ⇒ Boolean
Whether or not the game has been completed.
-
#die_size ⇒ Object
Returns the value of attribute die_size.
-
#free_parking_balance ⇒ Object
Returns the value of attribute free_parking_balance.
-
#go_amount ⇒ Object
Returns the value of attribute go_amount.
-
#hits ⇒ Hash
Returns a hash containing the number of times each Square has been landed on.
-
#last_roll ⇒ Object
Returns the value of attribute last_roll.
-
#max_turns_in_jail ⇒ Object
Returns the value of attribute max_turns_in_jail.
-
#num_dice ⇒ Object
Returns the value of attribute num_dice.
-
#num_hotels ⇒ Object
Returns the value of attribute num_hotels.
-
#num_houses ⇒ Object
Returns the value of attribute num_houses.
-
#player_starting_balance ⇒ Object
Returns the value of attribute player_starting_balance.
-
#players ⇒ Boolean
Players registered to the game.
-
#starting_currency ⇒ Object
Returns the value of attribute starting_currency.
-
#turn ⇒ Integer
The current turn number.
Instance Method Summary collapse
-
#active_players ⇒ Array<Player>
An array of players who have not yet been eliminated from the game.
-
#all_sets_owned ⇒ Array<Symbol>
The names of completed property sets currently owned by players.
-
#initialize(opts) ⇒ String
constructor
Creates a new Monopoly game.
-
#pay_player(player, amount, reason = nil) ⇒ Boolean
Transfers money from the bank to a player.
-
#payout_free_parking(player) ⇒ Integer
Pays the contents of the free parking square to a player.
-
#play(turns = 100000) ⇒ self
Play through a given number of turns of the game as configured.
-
#register_player(player) ⇒ Array<Player>
Add a player to the game.
-
#summary ⇒ String
Produces a colourful ASCII representation of the state of the game board to standard output.
Constructor Details
#initialize(opts) ⇒ String
Creates a new Monopoly game
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/monotony/game.rb', line 32 def initialize(opts) opts = { free_parking_balance: 0, bank_balance: 12755, max_turns_in_jail: 3, go_amount: 200, num_dice: 2, die_size: 6, num_houses: 48, num_hotels: 12, starting_currency: 1500, players: 4, variant: Monotony::DefaultLayout }.merge(opts) random_player_names = %w{Andy Brian Katie Cathy Tine Jody James Ryan Lucy Pierre George Gregor Tracy Lia Andoni Ralph San} @board = opts[:variant]::BOARD @chance_all = opts[:variant]::CHANCE @community_chest_all = opts[:variant]::COMMUNITY_CHEST @hits = {} @turn = 0 @bank_balance = opts[:bank_balance] @free_parking_balance = opts[:free_parking_balance] @max_turns_in_jail = opts[:max_turns_in_jail] @last_roll = 0 @go_amount = opts[:go_amount] @initial_board = @board @available_properties = @board @chance = @chance_all.shuffle @community_chest = @community_chest_all.shuffle @num_dice = opts[:num_dice] @num_houses = opts[:num_houses] @num_hotels = opts[:num_hotels] @die_size = opts[:die_size] @starting_currency = opts[:starting_currency] @variant = opts[:variant] case opts[:players] when Integer @players = [] opts[:players].times do @players << Monotony::Player.new(name: random_player_names.sample) end when Array @players = opts[:players] end @completed = false @board.each do |square| @hits[square] = 0 end @players.each do |player| player.board = @board.clone player.currency = opts[:starting_currency] player.game = self end self end |
Instance Attribute Details
#available_properties ⇒ Array<Purchasable>
Returns properties yet to be purchased by players.
14 15 16 |
# File 'lib/monotony/game.rb', line 14 def available_properties @available_properties end |
#bank_balance ⇒ Object
Returns the value of attribute bank_balance.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def bank_balance @bank_balance end |
#board ⇒ Array<Square>
Returns the current game board.
7 8 9 |
# File 'lib/monotony/game.rb', line 7 def board @board end |
#chance ⇒ String
Draws a chance card from the pile. If the pile is empty, resets and reshuffles the deck.
157 158 159 |
# File 'lib/monotony/game.rb', line 157 def chance @chance end |
#community_chest ⇒ String
Draws a community chest card from the pile. If the pile is empty, resets and reshuffles the deck.
195 196 197 |
# File 'lib/monotony/game.rb', line 195 def community_chest @community_chest end |
#completed ⇒ Boolean
Returns whether or not the game has been completed.
12 13 14 |
# File 'lib/monotony/game.rb', line 12 def completed @completed end |
#die_size ⇒ Object
Returns the value of attribute die_size.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def die_size @die_size end |
#free_parking_balance ⇒ Object
Returns the value of attribute free_parking_balance.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def free_parking_balance @free_parking_balance end |
#go_amount ⇒ Object
Returns the value of attribute go_amount.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def go_amount @go_amount end |
#hits ⇒ Hash
Returns a hash containing the number of times each Square has been landed on.
5 6 7 |
# File 'lib/monotony/game.rb', line 5 def hits @hits end |
#last_roll ⇒ Object
Returns the value of attribute last_roll.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def last_roll @last_roll end |
#max_turns_in_jail ⇒ Object
Returns the value of attribute max_turns_in_jail.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def max_turns_in_jail @max_turns_in_jail end |
#num_dice ⇒ Object
Returns the value of attribute num_dice.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def num_dice @num_dice end |
#num_hotels ⇒ Object
Returns the value of attribute num_hotels.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def num_hotels @num_hotels end |
#num_houses ⇒ Object
Returns the value of attribute num_houses.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def num_houses @num_houses end |
#player_starting_balance ⇒ Object
Returns the value of attribute player_starting_balance.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def player_starting_balance @player_starting_balance end |
#players ⇒ Boolean
Returns players registered to the game.
9 10 11 |
# File 'lib/monotony/game.rb', line 9 def players @players end |
#starting_currency ⇒ Object
Returns the value of attribute starting_currency.
10 11 12 |
# File 'lib/monotony/game.rb', line 10 def starting_currency @starting_currency end |
#turn ⇒ Integer
Returns the current turn number.
17 18 19 |
# File 'lib/monotony/game.rb', line 17 def turn @turn end |
Instance Method Details
#active_players ⇒ Array<Player>
Returns an array of players who have not yet been eliminated from the game.
163 164 165 |
# File 'lib/monotony/game.rb', line 163 def active_players @players.reject{ |p| p.is_out? } end |
#all_sets_owned ⇒ Array<Symbol>
Returns the names of completed property sets currently owned by players.
93 94 95 |
# File 'lib/monotony/game.rb', line 93 def all_sets_owned @board.select{ |p| p.is_a? BasicProperty }.select { |p| p.set_owned? }.group_by { |p| p.set }.keys end |
#pay_player(player, amount, reason = nil) ⇒ Boolean
Transfers money from the bank to a player. If the bank does not have sufficient funds, transfers as much as possible.
169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/monotony/game.rb', line 169 def pay_player(player, amount, reason = nil) if @bank_balance > amount @bank_balance = @bank_balance - amount player.currency = player.currency + amount puts '[%s] Received £%d from bank%s (balance: £%d, bank balance: £%d)' % [ player.name, amount, (reason ? ' for %s' % reason : '' ), player.currency, bank_balance ] true else player.currency = player.currency + bank_balance puts '[%s] Unable to receive £%d from bank! Received £%d instead (balance: £%d)' % [ player.name, amount, bank_balance, player.currency ] @bank_balance = 0 false end end |
#payout_free_parking(player) ⇒ Integer
Pays the contents of the free parking square to a player.
185 186 187 188 189 190 191 |
# File 'lib/monotony/game.rb', line 185 def payout_free_parking(player) payout = @free_parking_balance player.currency = player.currency + payout puts '[%s] Landed on free parking! £%d treasure found' % [player.name, @free_parking_balance] unless @free_parking_balance == 0 @free_parking_balance = 0 payout end |
#play(turns = 100000) ⇒ self
Play through a given number of turns of the game as configured.
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/monotony/game.rb', line 214 def play(turns = 100000) if @completed puts 'Game is complete!' return false end turns.to_i.times do @turn = @turn + 1 puts '- Turn %d begins!' % @turn @players.each do |turn| if turn.is_out? puts '[%s] Is sitting out' % turn.name next end puts '[%s] Go begins on %s (balance: £%d)' % [ turn.name , turn.current_square.name, turn.currency ] turn.properties.each do |property| case property when Station if property.is_mortgaged? turn.behaviour[:unmortgage_possible].call(self, turn, property) if turn.currency > property.cost end when Utility if property.is_mortgaged? turn.behaviour[:unmortgage_possible].call(self, turn, property) if turn.currency > property.cost end when BasicProperty if property.is_mortgaged? turn.behaviour[:unmortgage_possible].call(self, turn, property) if turn.currency > property.cost else if property.set_owned? case property.num_houses when 0..3 turn.behaviour[:houses_available].call(self, turn, property) unless property.num_hotels > 0 when 4 turn.behaviour[:hotel_available].call(self, turn, property) end end end end end turn.behaviour[:trade_possible].call(self, turn) if not turn.properties.empty? turn.behaviour[:use_jail_card].call(self, turn) if turn.in_jail? and turn.jail_free_cards > 0 result = turn.roll double = (result.uniq.length == 1) move_total = result.inject(:+) @last_roll = move_total puts '[%s] Rolled %s (total: %d)' % [ turn.name, result.join(', '), move_total ] puts '[%s] Rolled a double' % turn.name if double if turn.in_jail? if double puts '[%s] Got out of jail! (rolled double)' % turn.name turn.in_jail = false else turn.turns_in_jail = turn.turns_in_jail + 1 puts '[%s] Is still in jail (turn %d)' % [ turn.name, turn.turns_in_jail ] if turn.turns_in_jail >= @max_turns_in_jail turn.in_jail = false turn.pay(:free_parking, 50) puts '[%s] Got out of jail (paid out)' % turn.name else next end end end square = turn.move(move_total) puts '[%s] Moved to %s' % [ turn.name, square.name ] square.action.call(self, square.owner, turn, square) puts '[%s] Next throw' % turn.name if double redo if double puts '[%s] Ended go on %s (balance: £%d)' % [ turn.name, turn.current_square.name, turn.currency ] end still_in = @players.reject{ |p| p.is_out? } if active_players.count == 1 winner = still_in.first puts '[%s] Won the game! Final balance: £%d, Property: %s' % [ winner.name, winner.currency, winner.properties.collect {|p| p.name} ] @completed = true break end end self end |
#register_player(player) ⇒ Array<Player>
Add a player to the game.
202 203 204 |
# File 'lib/monotony/game.rb', line 202 def register_player(player) @players << player end |
#summary ⇒ String
Produces a colourful ASCII representation of the state of the game board to standard output. The string produced contains ANSI colours.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/monotony/game.rb', line 102 def summary summary = Array.new(6) { '' } position = 0 header = '' worth = @players.collect { |p| '%s: £%d' % [ p.name, p.currency ]} header << 'Balances: %s' % worth.join(', ') puts header puts @board.each do |property| if position % 10 == 0 and position > 0 puts summary.collect! { |s| s << "\n" } puts summary.collect! { '' } end if property.owner owner_string = ( '%7s ' % property.owner.name ).colorize(:color => :black, :background => :light_white) else owner_string = ' '.colorize(:background => :white) end summary[0] << ( '%-11s' % property.name[0..9] ).colorize(:color => :light_white, :background => property.colour) + ' '.colorize(:color => :default) summary[1] << ( '%11s' % ' ' ).colorize(:color => :light_white, :background => :white) + ' '.colorize(:color => :default) summary[3] << ( '%11s' % ' ' ).colorize(:color => :light_white, :background => :white) + ' '.colorize(:color => :default) summary[4] << ( '%3s' % ' ' ).colorize(:color => :light_white, :background => :white) + owner_string + ' '.colorize(:color => :default) this_space = @players.select { |p| p.current_square == property } if this_space.length > 0 summary[2] << ' '.colorize(:background => :white) + ( ' %-6s ' % this_space.collect(&:name).first.upcase ).colorize(:color => :black, :background => :white) summary[2] << ( ' ' * 2 ) .colorize(:background => :white) + ' '.colorize(:color => :default) else summary[2] << ( '%11s' % ' ' ).colorize(:color => :light_white, :background => :white) + ' '.colorize(:color => :default) end if property.is_a? PurchasableProperty and property.is_mortgaged? summary[5] << ' MORTGAGED '.colorize(:background => :light_black, :color => :white) + ' '.colorize(:color => :default) elsif property.is_a? BasicProperty summary[5] << property.display_house_ascii else summary[5] << ( '%11s' % ' ' ).colorize(:background => :white) + ' '.colorize(:color => :default) end position = position + 1 end summary_out = summary.collect! { |s| s << "\n" } puts summary_out puts return summary_out end |