Advertisement
Guest User

Untitled

a guest
Jan 24th, 2019
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.64 KB | None | 0 0
  1. #!/usr/bin/env ruby
  2.  
  3. # Class to play the game of Tic-Tac-Toe
  4. class TicTacToe
  5.  
  6. # Initialize an instance of this class
  7. def initialize
  8. initialize_game
  9. end
  10.  
  11. # Play tic-tac-toe as long as user wants
  12. def play
  13. while true
  14. play_game
  15. break unless play_again?
  16. end
  17. puts "Thanks for playing...come back soon :-)"
  18. end
  19.  
  20. # *********************************************
  21. # ************ PRIVATE METHODS **************
  22. # *********************************************
  23. private
  24.  
  25. # Reset instance variable to begin a new game
  26. def initialize_game
  27. @moves = 0
  28. @player = PIECE[:x]
  29. @board = []
  30. 9.times { @board << PIECE[:blank] }
  31. end
  32.  
  33. # play a game of tic-tac-toe
  34. def play_game
  35. initialize_game
  36. puts HOW_TO_PLAY_TEXT
  37.  
  38. while true
  39. display_board
  40. set_move get_valid_move
  41. @moves += 1
  42. break if game_over?
  43. switch_player
  44. end
  45. end
  46.  
  47. # Display current state of the game board
  48. def display_board
  49. print "\t"
  50. @board.each_with_index do |piece, index|
  51. display_piece_by_location(piece, index)
  52. end
  53. end
  54.  
  55. # Display a game piece and separators between game pieces
  56. # based on the location of the piece on the game board
  57. def display_piece_by_location(piece, location)
  58. if location == 2 || location == 5
  59. print_piece(piece, "\n\t")
  60. print_separator_line
  61. elsif location == 8
  62. print_piece(piece, "\n")
  63. else
  64. print_piece(piece, SEPARATOR[:vertical])
  65. end
  66. end
  67.  
  68. # Display a single game piece and separator(s) around it
  69. def print_piece(piece, separator)
  70. print " #{ piece } #{ separator }"
  71. end
  72.  
  73. # Display the line that separates two game board rows
  74. def print_separator_line
  75. line = ""
  76. 3.times do
  77. 3.times { line << SEPARATOR[:horizontal] }
  78. line << SEPARATOR[:cross]
  79. end
  80. puts line[0...line.length - 1]
  81. print "\t"
  82. end
  83.  
  84. # Set location specified by move to the current player's piece
  85. def set_move move
  86. @board[move] = @player
  87. end
  88.  
  89. # Get a move that is valid
  90. def get_valid_move
  91. while true
  92. move = get_move
  93. if valid_move?(move)
  94. return move
  95. else
  96. puts "Position #{ move + 1 } is occupied...Enter a free position"
  97. end
  98. end
  99. end
  100.  
  101. # Get a position to place a new piece
  102. def get_move
  103. while true
  104. question = "Player #{ @player }, Enter play position (1 - 9)"
  105. move = (get_response_for question).to_i
  106. if move.between?(1, 9)
  107. return move - 1
  108. else
  109. puts "Invalid input...Enter a number between 1 and 9"
  110. end
  111. end
  112. end
  113.  
  114. # Get the response to a question from the player
  115. def get_response_for question
  116. print question + ": "
  117. gets.chomp
  118. end
  119.  
  120. # Check if a move is valid
  121. def valid_move? move
  122. @board[move] == PIECE[:blank]
  123. end
  124.  
  125. # Determine if game is over.
  126. # Display appropriate message if the game is over.
  127. def game_over?
  128. win_formations = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 4, 8],
  129. [2, 4, 6], [0, 3, 6], [1, 4, 7], [2, 5, 7] ]
  130. win_formations.each do |win_formation|
  131. if formation_met?(win_formation)
  132. end_game_message "Player #{ @player } Won."
  133. return true
  134. end
  135. end
  136. draw?
  137. end
  138.  
  139. # Determine if a player has pieces in a certain formation
  140. def formation_met? formation
  141. pieces = [@board[formation[0]], @board[formation[1]], @board[formation[2]]]
  142. pieces.uniq.length == 1 && (pieces[0] != PIECE[:blank])
  143. end
  144.  
  145. # Display relevant message when the game is over
  146. def end_game_message(message)
  147. system "clear"
  148. puts "GAME OVER: #{ message }"
  149. display_board
  150. end
  151.  
  152. # Determine if game ended in a draw; display message if so
  153. def draw?
  154. if @moves >= 9
  155. end_game_message "Game Ended in a draw."
  156. true
  157. else
  158. false
  159. end
  160. end
  161.  
  162. # Switch the current player
  163. def switch_player
  164. if @player == PIECE[:x]
  165. @player = PIECE[:o]
  166. else
  167. @player = PIECE[:x]
  168. end
  169. end
  170.  
  171. # Determine if user what to play another tic-tac-toe game
  172. def play_again?
  173. while true
  174. play_again = (get_response_for "Play again (y/n)").downcase
  175. case play_again
  176. when 'y', 'yes' then return true
  177. when 'n', 'no' then return false
  178. end
  179. end
  180. end
  181.  
  182.  
  183. PIECE = { x: 'X', o: 'O', blank: ' ' }
  184. SEPARATOR = { vertical: "\u2503", horizontal: "\u2501", cross: "\u254b" }
  185. HOW_TO_PLAY_TEXT = <<-END.gsub(/^\s+\|/, '')
  186. |
  187. | 1 | 2 | 3 The positions to play on the tic-tac-toe board are
  188. |---+---+--- represented by the numbers 1 - 9 as shown in the
  189. | 4 | 5 | 6 figure at the left.
  190. |---+---+--- To place an 'X' or 'O' in a certain position, simply
  191. | 7 | 8 | 9 enter the number corresponding to that position.
  192. |
  193. |
  194. END
  195. end
  196.  
  197. if $PROGRAM_NAME == __FILE__
  198. tic_tac_toe = TicTacToe.new
  199. tic_tac_toe.play
  200. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement