diff --git a/bin/tictactoe b/bin/tictactoe index 7ddd394b19b..94d00a89192 100755 --- a/bin/tictactoe +++ b/bin/tictactoe @@ -1,3 +1,5 @@ #!/usr/bin/env ruby require_relative '../config/environment' + +Game.new.start \ No newline at end of file diff --git a/lib/board.rb b/lib/board.rb index e69de29bb2d..02f60d2da9d 100644 --- a/lib/board.rb +++ b/lib/board.rb @@ -0,0 +1,45 @@ +require 'pry' +class Board + attr_accessor :cells + + def initialize + @cells = Array.new(9, " ") + end + + def reset! + initialize + end + + def display + puts " #{@cells[0]} | #{@cells[1]} | #{@cells[2]} " + puts "-----------" + puts " #{@cells[3]} | #{@cells[4]} | #{@cells[5]} " + puts "-----------" + puts " #{@cells[6]} | #{@cells[7]} | #{@cells[8]} " + end + + def position(pos) + @cells[pos.to_i - 1] + end + + def full? + @cells.none?(" ") + end + + def turn_count + 9 - @cells.count(" ") + end + + def taken?(pos) + position(pos) == " " ? false : true + end + + def valid_move?(pos) + !taken?(pos) && pos.to_i.between?(1, 9) + end + + def update(pos, token) + turn_count.even? ? token = "X" : token = "O" + @cells[pos.to_i - 1] = token if valid_move?(pos) + end +end \ No newline at end of file diff --git a/lib/game.rb b/lib/game.rb index e69de29bb2d..78fae89bc55 100644 --- a/lib/game.rb +++ b/lib/game.rb @@ -0,0 +1,97 @@ +require 'pry' +class Game + WIN_COMBINATIONS = [ + [0,1,2], [3,4,5], [6,7,8], + [0,3,6], [1,4,7], [2,5,8], + [0,4,8], [2,4,6] + ] + + attr_accessor :player_1, :player_2, :board + + def initialize(player_1 = nil, player_2 = nil, board = nil) + player_1 == nil ? @player_1 = Players::Human.new("X") : @player_1 = player_1 + player_2 == nil ? @player_2 = Players::Human.new("O") : @player_2 = player_2 + board == nil ? @board = Board.new : @board = board + end + + def current_player + @board.cells.count(" ").odd? ? @player_1 : @player_2 + end + + def won? + WIN_COMBINATIONS.detect {|win| + @board.cells[win[0]] == "X" && + @board.cells[win[1]] == "X" && + @board.cells[win[2]] == "X" || + @board.cells[win[0]] == "O" && + @board.cells[win[1]] == "O" && + @board.cells[win[2]] == "O" + } + end + + def draw? + won? == nil && @board.full? + end + + def over? + won? != nil || draw? + end + + def winner + won?.nil? ? nil : @board.cells[won?[0]] + end + + def turn + valid = false + until valid == true + pos = current_player.move(@board) + valid = @board.valid_move?(pos) + end + @board.update(pos, current_player.token) + end + + def play + until over? + turn + @board.display + end + if won? + puts "Congratulations #{winner}!" + elsif draw? + puts "Cat's Game!" + end + end + + def start + puts "Welcome to Tic-Tac-Toe!" + puts "Select a game:" + puts " - Make the computer play itself, click '0'." + puts " - Play versus the computer, click '1'." + puts " - Play against a friend, click '2'." + @game_type = gets.chomp.to_i + case @game_type + when 0 #computer vs computer + @player_1 = Players::Computer.new("X") + @player_2 = Players::Computer.new("O") + play + when 1 #player vs computer + @player_1 = Players::Human.new("X") + @player_2 = Players::Computer.new("O") + play + when 2 #player vs player + puts "Great! Who wants to go first and be 'X'?" + play + end + end +end + + + + + + + + + + + diff --git a/lib/player.rb b/lib/player.rb index e69de29bb2d..e8f32ee9ece 100644 --- a/lib/player.rb +++ b/lib/player.rb @@ -0,0 +1,9 @@ +class Player + attr_reader :token + + @@board_pos = ["1", "2", "3", "4", "5", "6", "7", "8", "9"] + + def initialize(token) + @token = token + end +end \ No newline at end of file diff --git a/lib/players/computer.rb b/lib/players/computer.rb index e69de29bb2d..e4018a9ab50 100644 --- a/lib/players/computer.rb +++ b/lib/players/computer.rb @@ -0,0 +1,83 @@ +require 'pry' +module Players + class Computer < Player + def move(board) + puts "Computer: Select a number 1-9." + if board.cells.count(" ") == 9 + @@board_pos.delete(@@board_pos.sample) + #center + elsif board.cells[4] == " " + @@board_pos.delete("5") #center + elsif board.cells[4] == "X" + @@board_pos.delete("8") #bottom-center, counter to X in center position + #top-center + elsif board.cells[4] == "X" && board.cells[7] == "X" && board.cells[1] == " " || + board.cells[0] == "X" && board.cells[2] == "X" && board.cells[1] == " " || + board.cells[4] == "O" && board.cells[7] == "O" && board.cells[1] == " " || + board.cells[0] == "O" && board.cells[2] == "O" && board.cells[1] == " " + @@board_pos.delete("2") #top-center + #left-center + elsif board.cells[4] == "X" && board.cells[5] == "X" && board.cells[3] == " " || + board.cells[0] == "X" && board.cells[6] == "X" && board.cells[3] == " " || + board.cells[4] == "O" && board.cells[5] == "O" && board.cells[3] == " " || + board.cells[0] == "O" && board.cells[6] == "O" && board.cells[3] == " " + @@board_pos.delete("4") #left-center + #right-center + elsif board.cells[4] == "X" && board.cells[3] == "X" && board.cells[5] == " " || + board.cells[2] == "X" && board.cells[5] == "X" && board.cells[5] == " " || + board.cells[4] == "O" && board.cells[3] == "O" && board.cells[5] == " " || + board.cells[2] == "O" && board.cells[5] == "O" && board.cells[5] == " " + @@board_pos.delete("6") #right- + #bottom-center + elsif board.cells[4] == "X" && board.cells[1] == "X" && board.cells[7] == " " || + board.cells[6] == "X" && board.cells[8] == "X" && board.cells[7] == " " || + board.cells[4] == "O" && board.cells[1] == "O" && board.cells[7] == " " || + board.cells[6] == "O" && board.cells[8] == "O" && board.cells[7] == " " + @@board_pos.delete("8") #bottom-center + #top-left + elsif board.cells[1] == "X" && board.cells[2] == "X" && board.cells[0] == " " || + board.cells[3] == "X" && board.cells[6] == "X" && board.cells[0] == " " || + board.cells[4] == "X" && board.cells[8] == "X" && board.cells[0] == " " || + board.cells[1] == "X" && board.cells[3] == "X" && board.cells[0] == " " || + board.cells[1] == "O" && board.cells[2] == "O" && board.cells[0] == " " || + board.cells[3] == "O" && board.cells[6] == "O" && board.cells[0] == " " || + board.cells[4] == "O" && board.cells[8] == "O" && board.cells[0] == " " || + board.cells[1] == "X" && board.cells[3] == "X" && board.cells[0] == " " + @@board_pos.delete("1") #top-left + #top-right + elsif board.cells[0] == "X" && board.cells[1] == "X" && board.cells[2] == " " || + board.cells[5] == "X" && board.cells[8] == "X" && board.cells[2] == " " || + board.cells[4] == "X" && board.cells[6] == "X" && board.cells[2] == " " || + board.cells[1] == "X" && board.cells[5] == "X" && board.cells[2] == " " || + board.cells[0] == "O" && board.cells[1] == "O" && board.cells[2] == " " || + board.cells[5] == "O" && board.cells[8] == "O" && board.cells[2] == " " || + board.cells[4] == "O" && board.cells[6] == "O" && board.cells[2] == " " || + board.cells[1] == "O" && board.cells[5] == "O" && board.cells[2] == " " + @@board_pos.delete("3") #top-right + #bottom-left + elsif board.cells[7] == "X" && board.cells[8] == "X" && board.cells[6] == " " || + board.cells[0] == "X" && board.cells[3] == "X" && board.cells[6] == " " || + board.cells[2] == "X" && board.cells[4] == "X" && board.cells[6] == " " || + board.cells[3] == "X" && board.cells[7] == "X" && board.cells[6] == " " || + board.cells[7] == "O" && board.cells[8] == "O" && board.cells[6] == " " || + board.cells[0] == "O" && board.cells[3] == "O" && board.cells[6] == " " || + board.cells[2] == "O" && board.cells[4] == "O" && board.cells[6] == " " || + board.cells[3] == "O" && board.cells[7] == "O" && board.cells[6] == " " + @@board_pos.delete("7") #bottom-left + #bottom-right + elsif board.cells[6] == "X" && board.cells[7] == "X" && board.cells[8] == " " || + board.cells[2] == "X" && board.cells[5] == "X" && board.cells[8] == " " || + board.cells[0] == "X" && board.cells[4] == "X" && board.cells[8] == " " || + board.cells[5] == "X" && board.cells[7] == "X" && board.cells[8] == " " || + board.cells[6] == "O" && board.cells[7] == "O" && board.cells[8] == " " || + board.cells[2] == "O" && board.cells[5] == "O" && board.cells[8] == " " || + board.cells[0] == "O" && board.cells[4] == "O" && board.cells[8] == " " || + board.cells[5] == "O" && board.cells[7] == "O" && board.cells[8] == " " + @@board_pos.delete("9") #bottom-right + #random + else + @@board_pos.delete(@@board_pos.sample) + end + end + end +end \ No newline at end of file diff --git a/lib/players/human.rb b/lib/players/human.rb index e69de29bb2d..42db9658b62 100644 --- a/lib/players/human.rb +++ b/lib/players/human.rb @@ -0,0 +1,11 @@ +require 'pry' +module Players + class Human < Player + def move(board) + puts "Select a number 1-9." + pos = gets.chomp + @@board_pos.delete(pos) + pos + end + end +end \ No newline at end of file diff --git a/spec/02_player_spec.rb b/spec/02_player_spec.rb index cafa7c3e94b..54d82612c55 100644 --- a/spec/02_player_spec.rb +++ b/spec/02_player_spec.rb @@ -18,4 +18,4 @@ expect(player).to_not respond_to(:token=) end end -end +end \ No newline at end of file diff --git a/spec/03_human_player_spec.rb b/spec/03_human_player_spec.rb index 4c9878da817..ad5ff7029f0 100644 --- a/spec/03_human_player_spec.rb +++ b/spec/03_human_player_spec.rb @@ -15,4 +15,4 @@ expect(human.move(Board.new)).to eq("1") end end -end +end \ No newline at end of file diff --git a/spec/04_game_spec.rb b/spec/04_game_spec.rb index 1dd2f1e3d25..cce932f7c0a 100644 --- a/spec/04_game_spec.rb +++ b/spec/04_game_spec.rb @@ -348,4 +348,4 @@ describe 'start' do end -end +end \ No newline at end of file diff --git a/spec/05_computer_player_spec.rb b/spec/05_computer_player_spec.rb index fb8adba9edb..d22b3ee1a14 100644 --- a/spec/05_computer_player_spec.rb +++ b/spec/05_computer_player_spec.rb @@ -17,4 +17,4 @@ expect(valid_moves).to include(computer_move) end end -end +end \ No newline at end of file