diff --git a/bin/tictactoe b/bin/tictactoe index 7ddd394b19b..c3da781a44d 100755 --- a/bin/tictactoe +++ b/bin/tictactoe @@ -1,3 +1,27 @@ #!/usr/bin/env ruby require_relative '../config/environment' + + + puts "Hey, there! Let's play some 'Toe!" + puts "\nPlease choose player mode: + 0 + 1 + 2\n" + player_mode = gets.strip + + + if player_mode == "0" + Game.new(Players::Computer.new("X"), Players::Computer.new("O"), Board.new).play + + elsif player_mode == "1" + puts "Do you want to go first? [y/ n]" + if gets.strip == "y" + Game.new(Players::Human.new("X"), Players::Computer.new("O"), Board.new).play + else + Game.new(Players::Computer.new("X"), Players::Human.new("O"), Board.new).play + end + + elsif player_mode == "2" + Game.new(Players::Human.new("X"), Players::Human.new("O"), Board.new).play + end diff --git a/lib/board.rb b/lib/board.rb index e69de29bb2d..6bc721be83b 100644 --- a/lib/board.rb +++ b/lib/board.rb @@ -0,0 +1,47 @@ +require 'pry' + +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 position(input) + cells[input.to_i-1] + end + + def full? + !cells.include?(" ") + end + + def turn_count + cells.count("X") + cells.count("O") + end + + def taken?(input) + position(input) != " " + 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 +end diff --git a/lib/game.rb b/lib/game.rb index e69de29bb2d..8581e74ec7e 100644 --- a/lib/game.rb +++ b/lib/game.rb @@ -0,0 +1,64 @@ +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], + [2,4,6] + ] + + 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 current_player + @board.turn_count % 2 == 0 ? @player_1 : @player_2 + end + + def won? + WIN_COMBINATIONS.detect do |combo| + @board.cells[combo[0]] == @board.cells[combo[1]] && @board.cells[combo[0]] == @board.cells[combo[2]] && @board.taken?(combo[0] + 1) + end + end + + def draw? + @board.full? && !won? + end + + def over? + won? || draw? + end + + def winner + if won? + @board.cells[won?[0]] + end + end + + def turn + input = current_player.move(board) + if !@board.valid_move?(input) + turn + else + @board.update(input, current_player) + end + end + + def play + turn until over? + if won? + puts "Congratulations #{winner}!" + elsif draw? + puts "Cat's Game!" + end + end + + +end diff --git a/lib/player.rb b/lib/player.rb index e69de29bb2d..c2c7537c360 100644 --- a/lib/player.rb +++ b/lib/player.rb @@ -0,0 +1,8 @@ +class Player + attr_reader :token + + def initialize(token) + @token = token + end + +end diff --git a/lib/players/computer.rb b/lib/players/computer.rb index e69de29bb2d..1f4e4c061bc 100644 --- a/lib/players/computer.rb +++ b/lib/players/computer.rb @@ -0,0 +1,96 @@ +class Players::Computer < Player + + def move(board) + move = nil + if board.turn_count == 0 + move = [1,3,7,9].sample.to_s + # elsif board.turn_count == 1 && [1,3,7,9].all?{|cell| !board.taken?(cell.to_s)} + # move = [1,3,7,9].sample.to_s +elsif board.turn_count == 1 && board.taken?("5") + move = [1,3,7,9].sample.to_s + elsif board.turn_count >= 1 && board.turn_count < 6 && !board.taken?("5") + move = "5" + # elsif board.turn_count == 2 && board.taken?("5") && [1,3,7,9].all?{|cell| !board.taken?(cell.to_s)} + # move = [1,3,7,9].sample.to_s + elsif board.turn_count == 2 && board.turn_count < 6 && board.taken?("5") && ([1,3,7,9].select{|cell| board.position("#{cell}") == self.token}) + if board.position("1") == self.token + move = [3,7].sample + elsif board.position("3") == self.token + move = [1,9].sample + elsif board.position("7") == self.token + move = [1,9].sample + elsif board.position("9") == self.token + move = [3,7].sample + end + elsif (board.turn_count > 2 && board.turn_count < 6 && ((board.position("1") != " " && board.position("2") != " " && board.position("1") == board.position("2") && !board.taken?("3")) || (board.position("2") != " " && board.position("3") != " " && board.position("2") == board.position("3") && !board.taken?("1")) || (board.position("4") != " " && board.position("5") != " " && board.position("4") == board.position("5") && !board.taken?("6")) || (board.position("5") != " " && board.position("6") != " " && board.position("5") == board.position("6") && !board.taken?("4")) || (board.position("7") != " " && board.position("8") != " " && board.position("7") == board.position("8") && !board.taken?("9")) || (board.position("8") != " " && board.position("9") != " " && board.position("8") == board.position("9") && !board.taken?("7")) || (board.position("1") != " " && board.position("4") != " " && board.position("1") == board.position("4") && !board.taken?("7")) || (board.position("4") != " " && board.position("7") != " " && board.position("4") == board.position("7") && !board.taken?("1")) || (board.position("2") != " " && board.position("5") != " " && board.position("2") == board.position("5") && !board.taken?("8")) || (board.position("5") != " " && board.position("8") != " " && board.position("5") == board.position("8") && !board.taken?("2")) || (board.position("3") != " " && board.position("6") != " " && board.position("3") == board.position("6") && !board.taken?("9")) || (board.position("6") != " " && board.position("9") != " " && board.position("6") == board.position("9") && !board.taken?("3")) || (board.position("1") != " " && board.position("5") != " " && board.position("1") == board.position("5") && !board.taken?("9")) || (board.position("5") != " " && board.position("9") != " " && board.position("5") == board.position("9") && !board.taken?("1")) || (board.position("7") != " " && board.position("5") != " " && board.position("7") == board.position("5") && !board.taken?("3")) || (board.position("5") != " " && board.position("3") != " " && board.position("5") == board.position("3") && !board.taken?("7")))) || (board.turn_count > 3 && board.turn_count < 7 && ((board.position("1") != " " && board.position("3") != " " && board.position("1") == board.position("3") && !board.taken?("2")) || (board.position("7") != " " && board.position("9") != " " && board.position("7") == board.position("9") && !board.taken?("8")) || (board.position("1") != " " && board.position("7") != " " && board.position("1") == board.position("7") && !board.taken?("4")) || (board.position("3") != " " && board.position("9") != " " && board.position("3") == board.position("9") && !board.taken?("6")))) + if board.position("1") != " " && board.position("2") != " " && board.position("1") == board.position("2") && !board.taken?("3") + move = "3" + elsif board.position("2") != " " && board.position("3") != " " && board.position("2") == board.position("3") && !board.taken?("1") + move = "1" + elsif board.position("4") != " " && board.position("5") != " " && board.position("4") == board.position("5") && !board.taken?("6") + move = "6" + elsif board.position("5") != " " && board.position("6") != " " && board.position("5") == board.position("6") && !board.taken?("4") + move = "4" + elsif board.position("7") != " " && board.position("8") != " " && board.position("7") == board.position("8") && !board.taken?("9") + move = "9" + elsif board.position("8") != " " && board.position("9") != " " && board.position("8") == board.position("9") && !board.taken?("7") + move = "7" + elsif board.position("1") != " " && board.position("4") != " " && board.position("1") == board.position("4") && !board.taken?("7") + move = "7" + elsif board.position("4") != " " && board.position("7") != " " && board.position("4") == board.position("7") && !board.taken?("1") + move = "1" + elsif board.position("2") != " " && board.position("5") != " " && board.position("2") == board.position("5") && !board.taken?("8") + move = "8" + elsif board.position("5") != " " && board.position("8") != " " && board.position("5") == board.position("8") && !board.taken?("2") + move = "2" + elsif board.position("3") != " " && board.position("6") != " " && board.position("3") == board.position("6") && !board.taken?("9") + move = "9" + elsif board.position("6") != " " && board.position("9") != " " && board.position("6") == board.position("9") && !board.taken?("3") + move = "3" + elsif board.position("1") != " " && board.position("5") != " " && board.position("1") == board.position("5") && !board.taken?("9") + move = "9" + elsif board.position("5") != " " && board.position("9") != " " && board.position("5") == board.position("9") && !board.taken?("1") + move = "1" + elsif board.position("7") != " " && board.position("5") != " " && board.position("7") == board.position("5") && !board.taken?("3") + move = "3" + elsif board.position("5") != " " && board.position("3") != " " && board.position("5") == board.position("3") && !board.taken?("7") + move = "7" + elsif board.position("1") != " " && board.position("3") != " " && board.position("1") == board.position("3") && !board.taken?("2") + move = "2" + elsif board.position("1") != " " && board.position("7") != " " && board.position("1") == board.position("7") && !board.taken?("4") + move = "4" + elsif board.position("3") != " " && board.position("9") != " " && board.position("3") == board.position("9") && !board.taken?("6") + move = "6" + elsif board.position("9") != " " && board.position("7") != " " && board.position("9") == board.position("7") && !board.taken?("8") + move = "8" + end +# elsif board.turn_count > 3 && board.turn_count < 7 && ((board.position("1") != " " && board.position("3") != " " && board.position("1") == board.position("3") && !board.taken?("2")) || (board.position("7") != " " && board.position("9") != " " && board.position("7") == board.position("9") && !board.taken?("8")) || (board.position("1") != " " && board.position("7") != " " && board.position("1") == board.position("7") && !board.taken?("4")) || (board.position("3") != " " && board.position("9") != " " && board.position("3") == board.position("9") && !board.taken?("6"))) +# if board.position("1") != " " && board.position("3") != " " && board.position("1") == board.position("3") && !board.taken?("2") +# move = "2" +# elsif board.position("1") != " " && board.position("7") != " " && board.position("1") == board.position("7") && !board.taken?("4") +# move = "4" +# elsif board.position("3") != " " && board.position("9") != " " && board.position("3") == board.position("9") && !board.taken?("6") +# move = "6" +# elsif board.position("9") != " " && board.position("7") != " " && board.position("9") == board.position("7") && !board.taken?("8") +# move = "8" +# end + elsif board.turn_count > 2 && board.turn_count < 6 && board.position("5") == self.token && [1,3,7,9].none?{|cell| board.position("#{cell}") == self.token} + move = [1,3,7,9].detect{|cell| !board.taken?("#{cell}")}.to_s + elsif board.turn_count > 2 && board.turn_count < 6 && board.position("5") == self.token && ((board.position("1") == self.token && !board.taken?("9")) || (board.position("3") == self.token && !board.taken?("7")) || (board.position("7") == self.token && !board.taken?("3")) || (board.position("9") == self.token && !board.taken?("1"))) + if board.position("1") == self.token && !board.taken?("9") + move = "9" + elsif board.position("3") == self.token && !board.taken?("7") + move = "7" + elsif board.position("7") == self.token && !board.taken?("3") + move = "3" + elsif board.position("9") == self.token && !board.taken?("1") + move = "1" + end + # elsif board.turn_count >= 3 + else + move = [1,2,3,4,5,6,7,8,9].detect{|cell| board.taken?(cell.to_s) == false}.to_s + end + move + end + +end diff --git a/lib/players/human.rb b/lib/players/human.rb index e69de29bb2d..e4cbf84463d 100644 --- a/lib/players/human.rb +++ b/lib/players/human.rb @@ -0,0 +1,13 @@ +module Players + + class Human < Player + + def move(board) + puts "Please enter 1-9" + puts "#{board.display}" + gets.strip + end + + end + +end