App Academy

New and improved Tic Tac Toe project in additional project

Hey after doing the tic tac toe project, I decided to make a version of it that I think is a little more efficient, and can be easier for the user to select a value. Instead of them having to put the row and col, they only have to select a number in the column, so if it’s a 3x3 it would look something like this

1 2 3
4 5 6
7 8 9
#if they select let's say 6 it would then print out a new board like this
1 2 3 
4 5 X
7 8 9

Making it more user friendly. Not only is it more user friendly, but it can also just be ran by just doing ruby game.rb, and it is also shorter by 20 lines of code, and can be reduced even further. Try it out and see what you think guys!

class Player
    attr_reader :players, :count
    def initialize
        @players = Array.new(2)
        @count =  0
        playable_chooses  = ["x","o"]
        @players[0] = playable_chooses.sample
         if @players[0] == playable_chooses[0]
            @players[1] = playable_chooses[1]
    else
        @players[1] = playable_chooses[0]
    end
end 
def place 
            return "Player 1 is #{@players[0]} \nPlayer 2 is #{@players[1]}"
        end
     def  players_move
    if @count % 2 == 0  
                return @players[0]   
            else  
                return @players[1]
        end
    end
        def next_turn
            @count += 1
        end
end
class Board
    def self.print_grid(arr)
        arr.each do |row|
            puts row.join(" ") 
#do puts row.join("\t") if you're doing anything greater then 3x3 fyi
#it's gonna look a little weird if you don't 
        end
    end   
    def initialize
        count,x,i = 0
        @grid = Array.new(3){Array.new(3)}
            (0...@grid.length).each do |x|
                (0...@grid.length).each do |i|
                    @grid[x][i] =  count  += 1
                end
            end
        end
       def     valid?(position)
            @grid.flatten.include?(position)
    end
        def make_move(position, mark)
            if valid?(position) 
                (0...@grid.length).each do |x|
                    (0...@grid.length).each do |i|
                        if @grid[i][x]  == position
                            @grid[i][x] =  mark.upcase
                            return true
                        end
                    end
                end
            else
                false
            end
        end
        def win?
            return true if @grid.any? { |row| row.uniq.length == 1 }
    return true if @grid.transpose.any? { |col| col.uniq.length == 1 }
            main_diagonal, anti_diagonal = [], []
    (0...@grid.length).each do |i|
        main_diagonal << @grid[i][i]
        anti_diagonal << @grid[i][-i - 1]
    end
    main_diagonal.uniq.length == 1 || anti_diagonal.uniq.length == 1
end
    def  lose?
        @grid.flatten.all?{|ele| ele.is_a?(String)}
    end
    def print
        Board.print_grid(@grid)
    end
end
require_relative  'board.rb'
require_relative  'player.rb'
 board = Board.new
players = Player.new
puts players.place
until board.win? || board.lose?
    board.print
    puts "select a number on the board"
   if  players.count % 2 == 0 
    puts "It is Player 1 turn"
   else puts "It is players 2 turn"
   end
    position = gets.chomp.to_i
 players.next_turn if board.make_move(position, players.players_move)
end
board.print
players.next_turn
winner = ""
if  players.count %  2 == 0  
    winner << "Player 1"
else
    winner <<   "Player 2"
end
puts "#{winner} won!" if  board.win? == true
puts "no one won :'(" if board.lose? == true