Module: TextPlayer::Commands
- Defined in:
- lib/text_player/commands.rb,
lib/text_player/commands/quit.rb,
lib/text_player/commands/save.rb,
lib/text_player/commands/score.rb,
lib/text_player/commands/start.rb,
lib/text_player/commands/action.rb,
lib/text_player/commands/restore.rb
Constant Summary collapse
- Quit =
Command for quitting the game
Data.define do def input "quit" end def execute(game) begin game.write(input) sleep(0.2) game.write("y") rescue Errno::EPIPE # Expected when process exits - ignore ensure game.terminate end CommandResult.new( input: input, operation: :quit, success: true, message: "Game quit successfully" ) end end
- Save =
Command for saving game state
Data.define(:savefile) do def input "save" end def execute(game) # Note: we could check if the file exists and delete it here, but # instead we will let dfrotz handle it in case the save fails. game.write(input) game.read_until(TextPlayer::FILENAME_PROMPT_REGEX) game.write(savefile.filename) result = game.read_until(/Overwrite existing file\? |Ok\.|Failed\.|>/i) if result.include?("Overwrite existing file?") game.write("y") result += game.read_until(/Ok\.|Failed\.|>/i) end success = result.include?("Ok.") = if success "[#{savefile.slot}] Game saved successfully" else "Save operation failed" end CommandResult.new( input: input, raw_output: result, operation: :save, success: success, message: , slot: savefile.slot, filename: savefile.filename ) end end
- Score =
Command for getting game score
Data.define do def input "score" end def execute(game) game.write(input) raw_output = game.read_until(TextPlayer::PROMPT_REGEX) score, out_of = nil if TextPlayer::SCORE_REGEX =~ raw_output score, out_of = $1, $2 end # Some games give dialog instead of score # We will return what the game says as a success # whether or not we find a score. CommandResult.new( input:, raw_output:, operation: :score, success: true, score:, out_of: ) end end
- Start =
Command for starting the game This is used to start the game and is not accessible by the user.
Data.define do def input nil end def execute(game) raw_output = game.read_until(TextPlayer::PROMPT_REGEX) # Handle "Press any key" prompts - be more specific max_iterations = 5 lines = raw_output.lines while /\A\W*(Press|Hit|More)\s+.*\z/i.match?(lines.last) # if last line is a continuation prompt lines.pop game.write(" ") lines.concat game.read_until(TextPlayer::PROMPT_REGEX).lines max_iterations -= 1 break if max_iterations.zero? end raw_output = lines.join # Skip introduction if offered if raw_output.include?("introduction") game.write("no") raw_output += game.read_until(TextPlayer::PROMPT_REGEX) end CommandResult.new( input: input, raw_output: raw_output, operation: :start, success: true ) end end
- Action =
Command for generic game actions (look, go north, take sword, etc.)
Data.define(:input) do def execute(game) game.write(input) raw_output = game.read_until(TextPlayer::PROMPT_REGEX) CommandResult.new( input: input, raw_output: raw_output, operation: :action, success: !failure_detected?(raw_output) ) end def failure_detected?(output) TextPlayer::FAILURE_PATTERNS.any? { |pattern| output.match?(pattern) } end end
- Restore =
Command for restoring game state
Data.define(:savefile) do def input "restore" end def execute(game) unless savefile.exist? return CommandResult.new( input: input, operation: :restore, success: false, message: "Restore failed - file not found", slot: savefile.slot, filename: savefile.filename ) end game.write(input) game.read_until(TextPlayer::FILENAME_PROMPT_REGEX) game.write(savefile.filename) result = game.read_until(/Ok\.|Failed\.|not found|>/i) success = result.include?("Ok.") = if success "Game restored successfully" elsif result.include?("Failed") || result.include?("not found") "Restore failed - file not found by dfrotz process even though it existed before running this command" else "Restore operation completed" end CommandResult.new( input: input, raw_output: result, operation: :restore, success: success, message: , slot: savefile.slot, filename: savefile.filename ) end end
Class Method Summary collapse
Class Method Details
.create(input, game_name: nil) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/text_player/commands.rb', line 12 def self.create(input, game_name: nil) case input.strip.downcase when "score" Commands::Score.new when /^save\s*(\S+)/ # no end anchor to catch all save commands that have args Commands::Save.new(savefile: Savefile.new(game_name:, slot: Regexp.last_match(1))) when "save" Commands::Save.new(savefile: Savefile.new(game_name:)) when /^restore\s*(\S+)/ # no end anchor to catch all restore commands that have args Commands::Restore.new(savefile: Savefile.new(game_name:, slot: Regexp.last_match(1))) when "restore" Commands::Restore.new(savefile: Savefile.new(game_name:)) when "quit" Commands::Quit.new else Commands::Action.new(input:) end end |