diff --git a/bin/tictactoe b/bin/tictactoe index 7ddd394b19b..b2cd1975da6 100755 --- a/bin/tictactoe +++ b/bin/tictactoe @@ -1,3 +1,6 @@ #!/usr/bin/env ruby require_relative '../config/environment' + +puts "Welcome to Tic Tac Toe!" +Game.start diff --git a/lib/board.rb b/lib/board.rb index e69de29bb2d..3ebdafb22e4 100644 --- a/lib/board.rb +++ b/lib/board.rb @@ -0,0 +1,61 @@ +require 'pry' + +class Board + + attr_accessor :cells + + def initialize + reset! + end + + def display + puts " #{@cells[0]} | #{@cells[1]} | #{@cells[2]} \n-----------\n #{@cells[3]} | #{@cells[4]} | #{@cells[5]} \n-----------\n #{@cells[6]} | #{@cells[7]} | #{@cells[8]} " + end + + def position(input) + @input = input.to_i - 1 + @cells[@input] + end + + def full? + if @cells.include? " " + false + else + true + end + end + + def turn_count + @cells.count {|position| position != " "} + end + + def taken?(position) + @position = position.to_i - 1 + if ((@position >=0 && @position <= 8) && @cells[@position] != " ") + true + else + false + end + end + + def valid_move?(position) + @position_taken = taken?(position) + @position = position.to_i - 1 + if ((@position >=0 && @position <= 8) && !@position_taken) + true + else + false + end + end + + def update(position,player) + @position = position.to_i - 1 + @cells[@position] = player.token + end + + def reset! + @cells = [] + @cells = [" "," "," "," "," "," "," "," "," "] + end + +end diff --git a/lib/game.rb b/lib/game.rb index e69de29bb2d..1565412f885 100644 --- a/lib/game.rb +++ b/lib/game.rb @@ -0,0 +1,146 @@ +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=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 board + @board + end + + def current_player + @board.turn_count % 2 == 0 ? @player_1 : @player_2 + end + + def won? + winner_found = false + WIN_COMBINATIONS.each do |combo| + tokens_played = combo.collect {|position| @board.cells[position]} + winner_found = combo if (tokens_played.all?("X") || tokens_played.all?("O")) + end + winner_found + end + + def draw? + @board.full? && !won? + end + + def over? + draw? || won? + end + + def winner + if won? + @board.cells.count {|position| position == "X"} > @board.cells.count {|position| position == "O"} ? "X" : "O" + end + end + + def turn + loop do + move = current_player.move(@board) + + if move != "invalid" + @board.update(move, current_player) + move + break + end + end + end + + def board_display + puts "Current board" + + index = 0 + board_string = "" + + while index < 10 + board_string += "| #{@board.cells[index]} " + board_string += "|\n" if index == 2 || index == 5 + index += 1 + end + + puts board_string + + end + + def request_position + position_req = "Select an open square" + position_req += ", #{current_player.name}" if current_player.name != nil + position_req += ":" + puts position_req if current_player.class == Players::Human + end + + def play + + while !over? + request_position + board_display if current_player.class == Players::Human + turn + end + if winner != nil + puts "Congratulations #{winner}!" + elsif draw? + puts "Cat's Game!" + end + end + + def self.start + puts "Please enter the number of players (0, 1, 2):" + player_count = gets.chomp + + game_count = 1 + won_count = 0 + + if player_count == "wargames" + puts "Thermonuclear War" + game_count = 100 + @player_1 = Players::Computer.new("X") + @player_2 = Players::Computer.new("O") + + elsif player_count == "0" + puts "You have asked for 2 Computer players." + @player_1 = Players::Computer.new("X") + @player_2 = Players::Computer.new("O") + + elsif player_count == "1" + puts "You have asked for 1 Human player and 1 Computer player. Do you want X (Player 1) or 0 (Player 2)?" + human_token = gets.chomp + + if human_token == "X" + @player_1 = Players::Human.new("X") + @player_2 = Players::Computer.new("O") + elsif human_token == "O" + @player_1 = Players::Computer.new("X") + @player_2 = Players::Human.new("O") + end + + elsif player_count == "2" + puts "You have asked for a 2 Human player game. Who will be X (Player 1)?" + name1 = gets.chomp + puts "Who will be O (Player 2)?" + name2 = gets.chomp + + @player_1 = Players::Human.new("X",name1) + @player_2 = Players::Human.new("O",name2) + + end + + while (game_count > 0 ) + game = self.new(@player_1,@player_2) + game.play + + won_count += 1 if game.winner != nil + game_count -= 1 + end + + puts "Outcome: #{won_count} games won." + + end + +end diff --git a/lib/player.rb b/lib/player.rb index e69de29bb2d..ccb4a36fef9 100644 --- a/lib/player.rb +++ b/lib/player.rb @@ -0,0 +1,10 @@ +class Player + + attr_reader :token, :name + + def initialize(token, name=nil) + @token = token + @name = name + end + +end diff --git a/lib/players/computer.rb b/lib/players/computer.rb index e69de29bb2d..947ea12ffed 100644 --- a/lib/players/computer.rb +++ b/lib/players/computer.rb @@ -0,0 +1,25 @@ +module Players + + class Computer < Player + + def move(board) + + input = "" + + if board.cells[4] == " " && board.cells.count {|cell| cell == " "} == 9 #middle square is empty and game is new + input = "5" + else + input = rand(1..9) + end + + if !board.valid_move?(input) + input = "invalid" + end + + input + + end + + end + +end diff --git a/lib/players/human.rb b/lib/players/human.rb index e69de29bb2d..dd8e0308df8 100644 --- a/lib/players/human.rb +++ b/lib/players/human.rb @@ -0,0 +1,17 @@ +module Players + + class Human < Player + + def move(board) + + input = gets.chomp + if !board.valid_move?(input) + input = "invalid" + end + + input + end + + end + +end