diff --git a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb index a3287c1..a9bd88e 100644 --- a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb +++ b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb @@ -35,7 +35,7 @@ Then /^the computer prints "(.*?)"$/ do |arg1| @game.should_receive(:puts).with(arg1) - @game.indicate_palyer_turn + @game.indicate_player_turn end Then /^waits for my input of "(.*?)"$/ do |arg1| diff --git a/week7/homework/features/tic-tac-toe.rb b/week7/homework/features/tic-tac-toe.rb new file mode 100644 index 0000000..dd83639 --- /dev/null +++ b/week7/homework/features/tic-tac-toe.rb @@ -0,0 +1,131 @@ +class TicTacToe + attr_accessor :player, :player_symbol, :computer_symbol, :board + SYMBOLS = [:X, :O] + + @game_over + @current + + + def welcome_player + current_state + "Welcome #{@player}" + end + + def current_player + @current ||= [@player, "Computer"].sample + if @current == @player + @current = "Computer" + else + @current = @player + end + end + + def initialize *name + @current ||= name[0] + name[1] ||= SYMBOLS.sample + @player_symbol = (SYMBOLS.reject {|s| s != name[1]}).first + @computer_symbol = (SYMBOLS.reject {|s| s == @player_symbol}).first + @player = name.first.to_s.capitalize + @board = {A1: ' ', A2: ' ', A3: ' ', + B1: ' ', B2: ' ', B3: ' ', + C1: ' ', C2: ' ', C3: ' '} + end + + def indicate_player_turn + puts "#{@player}'s Move:" + end + + def get_player_move + gets.chomp.upcase + end + + def computer_move + move = open_spots.sample + @board[move] = @computer_symbol.to_s + move + end + + def player_move + entered_move = get_player_move.to_sym + if open_spots.include? entered_move + move = entered_move + else + puts "Sorry, that spot isn't available." + move = player_move + end + @board[move] = @player_symbol.to_s + move + end + + def open_spots + @board.inject(Array.new) do |remaining, (spot, fill)| + remaining << spot if fill == ' ' + remaining + end + end + + def current_state + #current state is a display method, building a string that pleasingly displays the @board + <<-board + 1 2 3 + A #{@board[:A1]} | #{@board[:A2]} | #{@board[:A3]} + --- --- --- + B #{@board[:B1]} | #{@board[:B2]} | #{@board[:B3]} + --- --- --- + C #{@board[:C1]} | #{@board[:C2]} | #{@board[:C3]} + board + end + + def determine_winner + @winner = false + winner_hash = {@player_symbol=>@player, @computer_symbol=>"Computer"} + winner_hash.each do |symbol, winner| + winning_play = winning_lines symbol + @winner = winner if winning_play + @game_over = (@game_over or winning_play) + end + if spots_open? == false and @winner == false + @game_over = true + end + end + + def player_won? + @winner == @player + end + + def computer_won? + @winner == "Computer" + end + + def over? + @game_over + end + + def draw? + (@game_over == true) and (@winner == false) + end + + def spots_open? + @board.has_value?(' ') + end + + private + def winning_lines symbol + winning_lines = [[:A1, :A2, :A3], + [:B1, :B2, :B3], + [:C1, :C2, :C3], + [:A1, :B1, :C1], + [:A2, :B2, :C2], + [:A3, :B3, :C3], + [:A3, :B2, :C1], + [:A1, :B2, :C3]] + winning_lines.inject(false) do |won, line| + line_wins = line.inject(true) do |winning, spot| + # A single false creates a false value + winning = (winning and @board[spot].to_sym == symbol) + end + # A single true creates a true value + won = (won or line_wins) + end + end +end \ No newline at end of file diff --git a/week7/homework/play_game.rb b/week7/homework/play_game.rb index 0535830..a28dc5c 100644 --- a/week7/homework/play_game.rb +++ b/week7/homework/play_game.rb @@ -1,4 +1,4 @@ -require './features/step_definitions/tic-tac-toe.rb' +require './features/tic-tac-toe.rb' @game = TicTacToe.new puts "What is your name?" @@ -10,7 +10,7 @@ when "Computer" @game.computer_move when @game.player - @game.indicate_palyer_turn + @game.indicate_player_turn @game.player_move end puts @game.current_state