diff --git a/Gemfile.lock b/Gemfile.lock index c66f69eb343..6e823785950 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -31,4 +31,5 @@ DEPENDENCIES rspec BUNDLED WITH - 2.0.1 + 2.1.4 + diff --git a/lib/board.rb b/lib/board.rb index e69de29bb2d..674d36a617f 100644 --- a/lib/board.rb +++ b/lib/board.rb @@ -0,0 +1,43 @@ +class Board + attr_accessor :cells + def initialize + reset! + end + + def reset! + @cells = Array.new(9, " ") + 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 full? + cells.all?{|token| token == "X" || token == "O"} + end + + def turn_count + cells.count{|token| token == "X" || token == "O"} + end + + def valid_move?(input) + input.to_i.between?(1,9) && !taken?(input) + end + + def update(input, player) + cells[input.to_i-1] = player.token + end + + def position(input) + cells[input.to_i-1] + end + + def taken?(input) + !(position(input) == " " || position(input) == "") + end +end + diff --git a/lib/game.rb b/lib/game.rb index e69de29bb2d..7ab0dd43038 100644 --- a/lib/game.rb +++ b/lib/game.rb @@ -0,0 +1,71 @@ +class Game + attr_accessor :board, :player_1, :player_2 + WIN_COMBINATIONS = [ + [0,1,2], + [3,4,5], + [6,7,8], + [0,3,6], + [1,4,7], + [2,5,8], + [0,4,8], + [6,4,2] + ] + + def initialize(player_1 = Players::Human.new("X"), player_2 = Players::Human.new("O"), board = Board.new) + @board = board + @player_1 = player_1 + @player_2 = player_2 + end + + def over? + won? || draw? + end + + def current_player + @board.turn_count % 2 == 0 ? @player_1 : @player_2 + end + + def winner + if winning_combo = won? + @winner = @board.cells[winning_combo.first] + end + end + + def turn + player = current_player + current_move = player.move(@board) + if !@board.valid_move?(current_move) + turn + else + puts "Turn #: #{@board.turn_count+1}\n" + @board.display + @board.update(current_move, player) + puts "#{player.token}: moved #{current_move}" + @board.display + puts "\n\n" + end + end + + def play + while !over? + turn + end + if won? + puts "Congratulations #{winner}!" + elsif draw? + puts "Cat's Game!" + end + end + + def won? + WIN_COMBINATIONS.detect do |combo| + @board.cells[combo[0]] == @board.cells[combo[1]] && + @board.cells[combo[1]] == @board.cells[combo[2]] && + @board.taken?(combo[0]+1) + end + end + + def draw? + @board.full? && !won? + end +end \ No newline at end of file diff --git a/lib/player.rb b/lib/player.rb index e69de29bb2d..77530d483ec 100644 --- a/lib/player.rb +++ b/lib/player.rb @@ -0,0 +1,7 @@ +class Player + attr_reader :token + + 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..dfaef4d52d9 100644 --- a/lib/players/computer.rb +++ b/lib/players/computer.rb @@ -0,0 +1,27 @@ +module Players + class Computer < Player + def move(board) + move = nil + + if !board.taken?(5) + move = "5" + elsif board.turn_count == 1 + move = "1" + elsif board.turn_count == 2 + move = [1, 3, 7, 9].detect{|i| !board.taken?(i)}.to_s + elsif board.turn_count == 3 && (board.position(1) == board.position(9) || board.position(3) == board.position(7)) + move = "2" + + Game::WIN_COMBINATIONS.detect do |combo| + if combo.select{|i| board.position(i+1) == token}.size == 2 && combo.any?{|i| board.position(i+1) == " "} + move = combo.select{|i| !board.taken?(i+1)}.first.to_i.+(1).to_s + elsif combo.select{|i| board.position(i+1) != " " && board.position(i+1) != token}.size == 2 && combo.any?{|i| board.position(i+1) == " "} + move = combo.select{|i| !board.taken?(i+1)}.first.to_i.+(1).to_s + end + end + move = [1, 3, 7, 9, 2, 4, 6, 8].detect{|i| !board.taken?(i)}.to_s if move == nil + end + move + end + end +end \ No newline at end of file diff --git a/lib/players/human.rb b/lib/players/human.rb index e69de29bb2d..c2f76bae49d 100644 --- a/lib/players/human.rb +++ b/lib/players/human.rb @@ -0,0 +1,9 @@ + +module Players + class Human < Player + def move(board) + puts "Please enter a number between 1 - 9:" + gets.strip + end + end +end \ No newline at end of file