Class: Upwords::Game
- Inherits:
-
Object
- Object
- Upwords::Game
- Defined in:
- lib/upwords/game.rb
Instance Attribute Summary collapse
-
#board ⇒ Object
readonly
Returns the value of attribute board.
-
#cursor ⇒ Object
readonly
Returns the value of attribute cursor.
-
#players ⇒ Object
readonly
Returns the value of attribute players.
Instance Method Summary collapse
- #add_player(name = nil, cpu = false) ⇒ Object
- #add_players(player_names = nil) ⇒ Object
- #clear_message ⇒ Object
- #confirm_action?(question_text) ⇒ Boolean
-
#current_player ⇒ Object
Player Methods =========================================.
- #display_on? ⇒ Boolean
- #exit_game(need_confirm = true) ⇒ Object
- #game_over ⇒ Object
-
#init_window ⇒ Object
Graphics Methods =========================================.
-
#initialize(display_on = true, max_players = 4) ⇒ Game
constructor
A new instance of Game.
- #max_players ⇒ Object
-
#modify_letter_input(letter) ⇒ Object
Capitalize letters, and convert ‘Q’ and ‘q’ to ‘Qu’.
- #next_turn ⇒ Object
- #pending_result ⇒ Object
- #player_count ⇒ Object
- #read_input(key) ⇒ Object
- #refresh_graphics ⇒ Object
- #run ⇒ Object
-
#running? ⇒ Boolean
Game Loops & Non-Input Procedures =========================================.
- #skip_turn(need_confirm = true) ⇒ Object
- #standard_message ⇒ Object
- #submit_moves(need_confirm = true) ⇒ Object
-
#swap_letter(need_confirm = true) ⇒ Object
TODO: Test this method…
- #toggle_rack_visibility ⇒ Object
-
#undo_moves ⇒ Object
Game Procedures Bound to some Key Input =========================================.
- #update_message(msg) ⇒ Object
Constructor Details
#initialize(display_on = true, max_players = 4) ⇒ Game
Returns a new instance of Game.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/upwords/game.rb', line 5 def initialize(display_on = true, max_players = 4) @max_players = max_players @display_on = display_on @board = Board.new(10, 5) @letter_bank = LetterBank.new(ALL_LETTERS.dup) @cursor = Cursor.new(@board.num_rows, @board.num_columns, *@board.middle_square[0]) @dict = Dictionary.import(OSPD_FILE) @moves = MoveManager.new(@board, @dict) @players = [] @running = false @submitted = false end |
Instance Attribute Details
#board ⇒ Object (readonly)
Returns the value of attribute board.
3 4 5 |
# File 'lib/upwords/game.rb', line 3 def board @board end |
#cursor ⇒ Object (readonly)
Returns the value of attribute cursor.
3 4 5 |
# File 'lib/upwords/game.rb', line 3 def cursor @cursor end |
#players ⇒ Object (readonly)
Returns the value of attribute players.
3 4 5 |
# File 'lib/upwords/game.rb', line 3 def players @players end |
Instance Method Details
#add_player(name = nil, cpu = false) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/upwords/game.rb', line 36 def add_player(name = nil, cpu = false) if player_count >= max_players raise StandardError, "No more players can join" else if name.nil? || name.size == 0 name = "Player #{player_count + 1}" end @players << Player.new(name, rack_capacity=7, cpu) end @players.each {|p| p.refill_rack(@letter_bank) } end |
#add_players(player_names = nil) ⇒ Object
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 |
# File 'lib/upwords/game.rb', line 48 def add_players(player_names = nil) print "\n" num_players = 0 # Select how many players will be in the game # TODO: Add a command-line flag to allow players to skip this step until (1..@max_players).include?(num_players) do print "How many players will play? (1-#{@max_players})\n" num_players = gets.chomp.to_i print "\n" if !(1..@max_players).include?(num_players) print "Invalid selection: #{num_players}\n\n" end end # Name each player and choose if they are humans or computers # TODO: Add a command-line flag to set this (1..num_players).each do |idx| print "What is Player #{idx}'s name?\n" name = gets.chomp print "Is Player #{idx} or a computer? (y/n)\n" cpu = gets.chomp add_player(name, cpu.upcase == "Y") print "\n" end end |
#clear_message ⇒ Object
106 107 108 |
# File 'lib/upwords/game.rb', line 106 def end |
#confirm_action?(question_text) ⇒ Boolean
231 232 233 234 235 236 237 238 239 240 |
# File 'lib/upwords/game.rb', line 231 def confirm_action?(question_text) if display_on? "#{question_text} (y/n)" inp = @win.getch inp == 'y' || inp == 'Y' else true # Never ask for confirm if the display_on is off end end |
#current_player ⇒ Object
Player Methods
24 25 26 |
# File 'lib/upwords/game.rb', line 24 def current_player @players.first end |
#display_on? ⇒ Boolean
89 90 91 |
# File 'lib/upwords/game.rb', line 89 def display_on? @display_on end |
#exit_game(need_confirm = true) ⇒ Object
291 292 293 294 295 296 |
# File 'lib/upwords/game.rb', line 291 def exit_game(need_confirm=true) if !need_confirm || (confirm_action? "Are you sure you want to exit the game?") @running = false @win.close if display_on? end end |
#game_over ⇒ Object
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/upwords/game.rb', line 302 def game_over "The game is over. Press any key to continue to see who won..." @win.getch if display_on? # Subtract 5 points for each tile remaining @players.each do |p| p.score -= p.letters.size * 5 end top_score = @players.map {|p| p.score}.max winners = @players.select{|p| p.score == top_score}.map{|p| p.name} if winners.size == 1 "And the winner is... #{winners[0]} with #{top_score} points!" else "We have a tie! #{winners.join(', ')} all win with #{top_score} points!" end @win.getch if display_on? exit_game(need_confirm=false) end |
#init_window ⇒ Object
Graphics Methods
79 80 81 82 83 84 85 86 87 |
# File 'lib/upwords/game.rb', line 79 def init_window Curses.noecho Curses.curs_set(0) Curses.init_screen # Curses.start_color @win = Graphics.new(self) @win.keypad(true) end |
#max_players ⇒ Object
28 29 30 |
# File 'lib/upwords/game.rb', line 28 def max_players @max_players end |
#modify_letter_input(letter) ⇒ Object
Capitalize letters, and convert ‘Q’ and ‘q’ to ‘Qu’
223 224 225 226 227 228 229 |
# File 'lib/upwords/game.rb', line 223 def modify_letter_input(letter) if letter =~ /[Qq]/ 'Qu' else letter.capitalize end end |
#next_turn ⇒ Object
211 212 213 214 215 216 |
# File 'lib/upwords/game.rb', line 211 def next_turn @players.rotate! @win.hide_rack if display_on? @submitted = false end |
#pending_result ⇒ Object
114 115 116 117 118 119 120 121 122 |
# File 'lib/upwords/game.rb', line 114 def pending_result new_words = @moves.pending_words unless new_words.empty? new_words.map do |w| "#{w} (#{w.score})" end.join(", ") + " (Total = #{@moves.pending_score(current_player)})" end end |
#player_count ⇒ Object
32 33 34 |
# File 'lib/upwords/game.rb', line 32 def player_count player_count = @players.size end |
#read_input(key) ⇒ Object
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/upwords/game.rb', line 183 def read_input(key) case key when 'Q' exit_game when SPACE toggle_rack_visibility when DELETE undo_moves when ENTER submit_moves when Curses::KEY_UP @cursor.up when Curses::KEY_DOWN @cursor.down when Curses::KEY_LEFT @cursor.left when Curses::KEY_RIGHT @cursor.right when '+' swap_letter when '-' skip_turn when /[[:alpha:]]/ @moves.add(current_player, modify_letter_input(key), @cursor.y, @cursor.x) end end |
#refresh_graphics ⇒ Object
93 94 95 96 97 |
# File 'lib/upwords/game.rb', line 93 def refresh_graphics if display_on? && running? @win.refresh end end |
#run ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/upwords/game.rb', line 132 def run @running = true # Add players add_players # Start graphics init_window if @display_on # Start main loop while running? do begin # ------ CPU MOVE -------- if current_player.cpu? "#{current_player.name} is thinking..." cpu_move = current_player.cpu_move(@board, @dict, 50, 10) if !cpu_move.nil? cpu_move.each do |posn, letter| @moves.add(current_player, letter, *posn) end submit_moves(need_confirm=false) else skip_turn(need_confirm=false) end else read_input(@win.getch) end if @submitted # TODO: remove magic string from last move message if @players.all? {|p| p.last_turn == "skipped turn"} || @letter_bank.empty? && current_player.rack_empty? game_over @running = false else next_turn end end refresh_graphics rescue IllegalMove => exception "#{exception.} (press any key to continue...)" @win.getch if display_on? end end end |
#running? ⇒ Boolean
Game Loops & Non-Input Procedures
128 129 130 |
# File 'lib/upwords/game.rb', line 128 def running? @running end |
#skip_turn(need_confirm = true) ⇒ Object
281 282 283 284 285 286 287 288 289 |
# File 'lib/upwords/game.rb', line 281 def skip_turn(need_confirm=true) if !need_confirm || (confirm_action? "Are you sure you want to skip your turn?") @moves.undo_all(current_player) @submitted = true # TODO: remove magic string from last move message current_player.last_turn = "skipped turn" end end |
#standard_message ⇒ Object
110 111 112 |
# File 'lib/upwords/game.rb', line 110 def "#{current_player.name}'s pending words: #{pending_result}" end |
#submit_moves(need_confirm = true) ⇒ Object
251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/upwords/game.rb', line 251 def submit_moves(need_confirm=true) if !need_confirm || (confirm_action? "Are you sure you want to submit?") @moves.submit(current_player) current_player.refill_rack(@letter_bank) @submitted = true # TODO: remove magic string from last move message current_player.last_turn = "played word" end end |
#swap_letter(need_confirm = true) ⇒ Object
TODO: Test this method…
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/upwords/game.rb', line 264 def swap_letter(need_confirm=true) "Pick a letter to swap... " letter = @win.getch if letter =~ /[[:alpha:]]/ letter = modify_letter_input(letter) if !need_confirm || (confirm_action? "Swap '#{letter}' for another?") @moves.undo_all(current_player) current_player.swap_letter(letter, @letter_bank) @submitted = true # TODO: remove magic string from last move message current_player.last_turn = "swapped letter" end end end |
#toggle_rack_visibility ⇒ Object
298 299 300 |
# File 'lib/upwords/game.rb', line 298 def toggle_rack_visibility @win.toggle_rack_visibility end |
#undo_moves ⇒ Object
Game Procedures Bound to some Key Input
246 247 248 249 |
# File 'lib/upwords/game.rb', line 246 def undo_moves @moves.undo_last(current_player) end |
#update_message(msg) ⇒ Object
99 100 101 102 103 104 |
# File 'lib/upwords/game.rb', line 99 def msg if display_on? @win. = msg refresh_graphics end end |