From ff1ef5d3ccaee2ab50cae56a4afc42506ef0de0b Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Fri, 30 Nov 2012 18:58:28 -0800 Subject: [PATCH 01/11] 3 passing steps tic_tac_toe game --- .../features/step_definitions/tic-tac-toe-steps.rb | 3 +++ week7/homework/lib/tic_tac_toe.rb | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 week7/homework/lib/tic_tac_toe.rb 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 b353120..1212fb1 100644 --- a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb +++ b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb @@ -1,5 +1,8 @@ require 'rspec/mocks/standalone' +current_dir = File.expand_path(File.dirname(__FILE__)) +require "#{current_dir}/../../lib/tic_tac_toe.rb" + Given /^I start a new Tic\-Tac\-Toe game$/ do @game = TicTacToe.new end diff --git a/week7/homework/lib/tic_tac_toe.rb b/week7/homework/lib/tic_tac_toe.rb new file mode 100644 index 0000000..74a1848 --- /dev/null +++ b/week7/homework/lib/tic_tac_toe.rb @@ -0,0 +1,7 @@ +class TicTacToe + attr_accessor :player + def welcome_player + "Welcome #{player}" + end + +end \ No newline at end of file From 854a7e0731200aaf479bac90c78d99d1fefe8edd Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Fri, 30 Nov 2012 20:16:29 -0800 Subject: [PATCH 02/11] first scenario passing tests for tictactoe --- week7/homework/lib/tic_tac_toe.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/week7/homework/lib/tic_tac_toe.rb b/week7/homework/lib/tic_tac_toe.rb index 74a1848..252805f 100644 --- a/week7/homework/lib/tic_tac_toe.rb +++ b/week7/homework/lib/tic_tac_toe.rb @@ -1,7 +1,20 @@ class TicTacToe + attr_accessor :player + + def initialize + @players = ["Computer", @player] + @player_index = rand(2) + end + def welcome_player "Welcome #{player}" end + def current_player + @players[@player_index] + end + + + end \ No newline at end of file From 46f36b0c93b64b6b8cf2ec78ac27ab080be9515a Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Sun, 2 Dec 2012 14:06:31 -0800 Subject: [PATCH 03/11] refactored code for tictactoe --- .../step_definitions/tic-tac-toe-steps.rb | 2 +- week7/homework/lib/tic_tac_toe.rb | 39 +++++++++++++++---- week7/homework/play_game.rb | 2 +- 3 files changed, 34 insertions(+), 9 deletions(-) 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 1212fb1..1efb36b 100644 --- a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb +++ b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb @@ -16,7 +16,7 @@ end Then /^randomly chooses who goes first$/ do - [@game.player, "Computer"].should include @game.current_player + [@game.player, "Computer"].should include @game.current_player.name end Then /^who is X and who is O$/ do diff --git a/week7/homework/lib/tic_tac_toe.rb b/week7/homework/lib/tic_tac_toe.rb index 252805f..4f5b278 100644 --- a/week7/homework/lib/tic_tac_toe.rb +++ b/week7/homework/lib/tic_tac_toe.rb @@ -1,20 +1,45 @@ +class Player + + attr_accessor :name, :symbol + +end + + + class TicTacToe - attr_accessor :player + SYMBOLS = ["X", "O"] def initialize - @players = ["Computer", @player] - @player_index = rand(2) + @computer_player = Player.new + @computer_player.name = "Computer" + + @human_player = Player.new + + @players = [@computer_player, @human_player].shuffle + + @players.each_with_index do |player, index| + player.symbol = SYMBOLS[index] + end + + @current_player_index = 0 end - def welcome_player - "Welcome #{player}" + def player=(name) + @human_player.name = name end - def current_player - @players[@player_index] + def player + @human_player.name end + def welcome_player + "Welcome #{@human_player.name}" + end + + def current_player + @players[@current_player_index] + end end \ No newline at end of file diff --git a/week7/homework/play_game.rb b/week7/homework/play_game.rb index cf7847f..f64b949 100644 --- a/week7/homework/play_game.rb +++ b/week7/homework/play_game.rb @@ -8,7 +8,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 From 205a90c3eb24b4225bcd3010df1087c08303aff2 Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Sun, 2 Dec 2012 14:48:31 -0800 Subject: [PATCH 04/11] more passing tests, computer knows whose turn it is. --- .../step_definitions/tic-tac-toe-steps.rb | 6 +-- week7/homework/lib/tic_tac_toe.rb | 37 +++++++++++++++---- 2 files changed, 33 insertions(+), 10 deletions(-) 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 1efb36b..07e82bc 100644 --- a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb +++ b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb @@ -29,7 +29,7 @@ end Given /^it is my turn$/ do - @game.current_player.should eq "Renee" + @game.current_player.name.should eq "Renee" end Given /^the computer knows my name is Renee$/ do @@ -38,7 +38,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| @@ -48,7 +48,7 @@ Given /^it is the computer's turn$/ do @game = TicTacToe.new(:computer, :O) - @game.current_player.should eq "Computer" + @game.current_player.name.should eq "Computer" end Then /^the computer randomly chooses an open position for its move$/ do diff --git a/week7/homework/lib/tic_tac_toe.rb b/week7/homework/lib/tic_tac_toe.rb index 4f5b278..5a4d965 100644 --- a/week7/homework/lib/tic_tac_toe.rb +++ b/week7/homework/lib/tic_tac_toe.rb @@ -5,21 +5,37 @@ class Player end - class TicTacToe SYMBOLS = ["X", "O"] - def initialize + def initialize(first_player = nil, first_symbol = nil) @computer_player = Player.new @computer_player.name = "Computer" @human_player = Player.new - @players = [@computer_player, @human_player].shuffle + @players = {:player => @human_player, :computer => @computer_player} + + # player_order is an array like [:player, :computer] + if first_player + @player_order = [] + player_names = @players.keys + + @player_order << player_names.delete(first_player) + @player_order << player_names[0] + else + @player_order = @players.keys.shuffle + end + + symbols = SYMBOLS.dup.shuffle - @players.each_with_index do |player, index| - player.symbol = SYMBOLS[index] + if first_symbol + @players[first_player].symbol = symbols.delete + end + + @players.values.select { |player| !player.symbol }.each_with_index do |player, index| + player.symbol = symbols[index] end @current_player_index = 0 @@ -33,13 +49,20 @@ def player @human_player.name end + def player_symbol + @human_player.symbol + end + + def computer_symbol + @computer_player.symbol + end def welcome_player "Welcome #{@human_player.name}" end def current_player - @players[@current_player_index] + key = @player_order[@current_player_index] + @players[key] end - end \ No newline at end of file From 8833395b18a4fb495781171a316d1234edc4a554 Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Sun, 2 Dec 2012 15:03:45 -0800 Subject: [PATCH 05/11] player and computer x and o assignment tests passing --- .../step_definitions/tic-tac-toe-steps.rb | 2 +- week7/homework/lib/tic_tac_toe.rb | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) 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 07e82bc..d2f1add 100644 --- a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb +++ b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb @@ -81,7 +81,7 @@ end Then /^it is now the computer's turn$/ do - @game.current_player.should eq "Computer" + @game.current_player.name.should eq "Computer" end When /^there are three X's in a row$/ do diff --git a/week7/homework/lib/tic_tac_toe.rb b/week7/homework/lib/tic_tac_toe.rb index 5a4d965..a1bc10b 100644 --- a/week7/homework/lib/tic_tac_toe.rb +++ b/week7/homework/lib/tic_tac_toe.rb @@ -7,9 +7,9 @@ class Player class TicTacToe - SYMBOLS = ["X", "O"] + SYMBOLS = [:X, :O] - def initialize(first_player = nil, first_symbol = nil) + def initialize(first_player = nil, player_symbol = nil) @computer_player = Player.new @computer_player.name = "Computer" @@ -30,8 +30,8 @@ def initialize(first_player = nil, first_symbol = nil) symbols = SYMBOLS.dup.shuffle - if first_symbol - @players[first_player].symbol = symbols.delete + if player_symbol + @players[:player].symbol = symbols.delete(player_symbol) end @players.values.select { |player| !player.symbol }.each_with_index do |player, index| @@ -65,4 +65,12 @@ def current_player key = @player_order[@current_player_index] @players[key] end + + def indicate_player_turn + puts "#{@human_player.name}'s Move:" + end + + def get_player_move + gets.chomp + end end \ No newline at end of file From 4354ee7f39142cf80cc91dfec86b6cad4e9b4c51 Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Sun, 2 Dec 2012 17:18:42 -0800 Subject: [PATCH 06/11] passing tests for computer move and board visualization. --- week7/homework/lib/tic_tac_toe.rb | 36 ++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/week7/homework/lib/tic_tac_toe.rb b/week7/homework/lib/tic_tac_toe.rb index a1bc10b..c7b5b44 100644 --- a/week7/homework/lib/tic_tac_toe.rb +++ b/week7/homework/lib/tic_tac_toe.rb @@ -9,6 +9,8 @@ class TicTacToe SYMBOLS = [:X, :O] + attr_accessor :board + def initialize(first_player = nil, player_symbol = nil) @computer_player = Player.new @computer_player.name = "Computer" @@ -31,7 +33,7 @@ def initialize(first_player = nil, player_symbol = nil) symbols = SYMBOLS.dup.shuffle if player_symbol - @players[:player].symbol = symbols.delete(player_symbol) + @players[:player].symbol = symbols.delete(player_symbol ) end @players.values.select { |player| !player.symbol }.each_with_index do |player, index| @@ -39,6 +41,12 @@ def initialize(first_player = nil, player_symbol = nil) end @current_player_index = 0 + + @board = { + :A1 => nil, :A2 => nil, :A3 => nil, + :B1 => nil, :B2 => nil, :B3 => nil, + :C1 => nil, :C2 => nil, :C3 => nil + } end def player=(name) @@ -73,4 +81,30 @@ def indicate_player_turn def get_player_move gets.chomp end + + def open_spots + @board.keys.select { |key| @board[key] == nil } + end + + def computer_move + position = open_spots.shuffle.first # :A2 + + @board[position] = computer_symbol + + position + end + + def current_state +<<-BOARD + A B C + ------------- +1 | #{@board[:A1]} | #{@board[:B1]} | #{@board[:C1]} | + ------------- +2 | #{@board[:A2]} | #{@board[:B2]} | #{@board[:C2]} | + ------------- +3 | #{@board[:A3]} | #{@board[:B3]} | #{@board[:C3]} | + ------------- + +BOARD + end end \ No newline at end of file From cddceba360b7f15554a9f90428a93475081d613d Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Sun, 2 Dec 2012 21:00:38 -0800 Subject: [PATCH 07/11] passing tests for taken position by player. --- .../step_definitions/tic-tac-toe-steps.rb | 2 +- week7/homework/lib/tic_tac_toe.rb | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) 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 d2f1add..c234225 100644 --- a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb +++ b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb @@ -121,7 +121,7 @@ end Then /^computer should ask me for another position "(.*?)"$/ do |arg1| - @game.board[arg1.to_sym] = ' ' + @game.board[arg1.to_sym] = nil @game.should_receive(:get_player_move).twice.and_return(@taken_spot, arg1) @game.player_move.should eq arg1.to_sym end diff --git a/week7/homework/lib/tic_tac_toe.rb b/week7/homework/lib/tic_tac_toe.rb index c7b5b44..4d44c3f 100644 --- a/week7/homework/lib/tic_tac_toe.rb +++ b/week7/homework/lib/tic_tac_toe.rb @@ -1,3 +1,5 @@ +require 'pry' + class Player attr_accessor :name, :symbol @@ -86,6 +88,14 @@ def open_spots @board.keys.select { |key| @board[key] == nil } end + def open?(position) + open_spots.include?(position) + end + + def taken?(position) + !open?(position) + end + def computer_move position = open_spots.shuffle.first # :A2 @@ -94,6 +104,24 @@ def computer_move position end + def player_move + position = nil + + begin + if position + puts "That spot is taken, please choose another:" + else + puts "It's your turn, please make a move:" + end + + position = get_player_move.to_sym + end until open?(position) + + @board[position] = player_symbol + + position + end + def current_state <<-BOARD A B C From 9a3518973705145d704bb2b9d5040b4dce47b40a Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Sun, 2 Dec 2012 21:05:31 -0800 Subject: [PATCH 08/11] Modify .rvmrc to reflect 1.9.3-head --- .rvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rvmrc b/.rvmrc index 10e469b..753f1b5 100644 --- a/.rvmrc +++ b/.rvmrc @@ -6,7 +6,7 @@ # First we specify our desired [@], the @gemset name is optional, # Only full ruby name is supported here, for short names use: # echo "rvm use 1.9.3" > .rvmrc -environment_id="1.9.3@rubyfall2012" +environment_id="1.9.3-head@rubyfall2012" # Uncomment the following lines if you want to verify rvm version per project # rvmrc_rvm_version="1.13.5 (stable)" # 1.10.1 seams as a safe start From 41d746046c893f8ca176dccc3a4e72a87e1b70bc Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Sun, 2 Dec 2012 21:06:19 -0800 Subject: [PATCH 09/11] Revert "Modify .rvmrc to reflect 1.9.3-head" This reverts commit 9a3518973705145d704bb2b9d5040b4dce47b40a. --- .rvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rvmrc b/.rvmrc index 753f1b5..10e469b 100644 --- a/.rvmrc +++ b/.rvmrc @@ -6,7 +6,7 @@ # First we specify our desired [@], the @gemset name is optional, # Only full ruby name is supported here, for short names use: # echo "rvm use 1.9.3" > .rvmrc -environment_id="1.9.3-head@rubyfall2012" +environment_id="1.9.3@rubyfall2012" # Uncomment the following lines if you want to verify rvm version per project # rvmrc_rvm_version="1.13.5 (stable)" # 1.10.1 seams as a safe start From 8e79565460a0fbc29ac4414e99144e858ffd50d3 Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Mon, 3 Dec 2012 19:54:29 -0800 Subject: [PATCH 10/11] all passing tests for tic tac toe feature --- .../step_definitions/tic-tac-toe-steps.rb | 2 +- week7/homework/lib/tic_tac_toe.rb | 60 +++++++++++++++++-- 2 files changed, 56 insertions(+), 6 deletions(-) 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 c234225..6a6f7b4 100644 --- a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb +++ b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb @@ -77,7 +77,7 @@ end When /^"(.*?)" is not taken$/ do |arg1| - @old_pos.should eq " " + @old_pos.should eq nil end Then /^it is now the computer's turn$/ do diff --git a/week7/homework/lib/tic_tac_toe.rb b/week7/homework/lib/tic_tac_toe.rb index 4d44c3f..61746cf 100644 --- a/week7/homework/lib/tic_tac_toe.rb +++ b/week7/homework/lib/tic_tac_toe.rb @@ -1,9 +1,7 @@ require 'pry' class Player - - attr_accessor :name, :symbol - + attr_accessor :name, :symbol, :winner end @@ -32,12 +30,14 @@ def initialize(first_player = nil, player_symbol = nil) @player_order = @players.keys.shuffle end + # Randomize the symbol order symbols = SYMBOLS.dup.shuffle if player_symbol - @players[:player].symbol = symbols.delete(player_symbol ) + @players[:player].symbol = symbols.delete(player_symbol) end + # Iterate over all the players that don't yet have symbols, and assign them one @players.values.select { |player| !player.symbol }.each_with_index do |player, index| player.symbol = symbols[index] end @@ -51,6 +51,10 @@ def initialize(first_player = nil, player_symbol = nil) } end + def player_for_symbol(symbol) + @players.values.find { |player| player.symbol == symbol } + end + def player=(name) @human_player.name = name end @@ -106,7 +110,7 @@ def computer_move def player_move position = nil - + begin if position puts "That spot is taken, please choose another:" @@ -122,6 +126,52 @@ def player_move position end + def determine_winner + win_scenarios = [ + %w[A1 A2 A3], + %w[B1 B2 B3], + %w[C1 C2 C3], + %w[A1 B1 C1], + %w[A2 B2 C2], + %w[A3 B3 C3], + %w[A3 B2 C1], + %w[A1 B2 C3] + ].map { |array| array.map(&:to_sym) } + + # Find the winning scenenario + win = win_scenarios.find do |scenario| + board_state = scenario.map { |c| @board[c] } + + board_state.all? { |i| i == :O } || board_state.all? { |i| i == :X } + end + + # Figure out which player won + if win + # [:B1, :B2, :B3] + winning_symbol = @board[win.first] + winning_player = player_for_symbol(winning_symbol) + winning_player.winner = true + @winner = winning_player + end + + end + + def player_won? + @human_player.winner + end + + def spots_open? + open_spots.any? + end + + def over? + @winner || !spots_open? + end + + def draw? + over? && !@winner + end + def current_state <<-BOARD A B C From 0b4422b5ddecfe14ade02aec66692a773f34ad01 Mon Sep 17 00:00:00 2001 From: Karen Caplan Date: Mon, 3 Dec 2012 20:28:08 -0800 Subject: [PATCH 11/11] working tic tac toe game --- week7/homework/lib/tic_tac_toe.rb | 27 ++++++++++++++++++++++++--- week7/homework/play_game.rb | 13 +++++++++++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/week7/homework/lib/tic_tac_toe.rb b/week7/homework/lib/tic_tac_toe.rb index 61746cf..c550b13 100644 --- a/week7/homework/lib/tic_tac_toe.rb +++ b/week7/homework/lib/tic_tac_toe.rb @@ -80,6 +80,10 @@ def current_player @players[key] end + def advance_player + @current_player_index = (@current_player_index + 1) % 2 + end + def indicate_player_turn puts "#{@human_player.name}'s Move:" end @@ -101,10 +105,17 @@ def taken?(position) end def computer_move + + puts "Computer's Move:" + position = open_spots.shuffle.first # :A2 + puts position + @board[position] = computer_symbol + advance_player + position end @@ -123,6 +134,8 @@ def player_move @board[position] = player_symbol + advance_player + position end @@ -160,6 +173,10 @@ def player_won? @human_player.winner end + def computer_won? + @computer_player.winner + end + def spots_open? open_spots.any? end @@ -176,13 +193,17 @@ def current_state <<-BOARD A B C ------------- -1 | #{@board[:A1]} | #{@board[:B1]} | #{@board[:C1]} | +1 | #{present_board_at(:A1)} | #{present_board_at(:B1)} | #{present_board_at(:C1)} | ------------- -2 | #{@board[:A2]} | #{@board[:B2]} | #{@board[:C2]} | +2 | #{present_board_at(:A2)} | #{present_board_at(:B2)} | #{present_board_at(:C2)} | ------------- -3 | #{@board[:A3]} | #{@board[:B3]} | #{@board[:C3]} | +3 | #{present_board_at(:A3)} | #{present_board_at(:B3)} | #{present_board_at(:C3)} | ------------- BOARD end + + def present_board_at(slot) + @board[slot] || " " + end end \ No newline at end of file diff --git a/week7/homework/play_game.rb b/week7/homework/play_game.rb index f64b949..75824e5 100644 --- a/week7/homework/play_game.rb +++ b/week7/homework/play_game.rb @@ -1,15 +1,24 @@ -require './features/step_definitions/tic-tac-toe.rb' +current_dir = File.expand_path(File.dirname(__FILE__)) +require "#{current_dir}/lib/tic_tac_toe.rb" @game = TicTacToe.new + +puts "What's your name player?" + +name = gets.chomp +@game.player = name + puts @game.welcome_player until @game.over? - case @game.current_player + case @game.current_player.name when "Computer" @game.computer_move when @game.player @game.indicate_player_turn @game.player_move + else + raise "It's nobody's move!" end puts @game.current_state @game.determine_winner