Skip to content

Instantly share code, notes, and snippets.

@ready4god2513
Created October 3, 2014 22:24
Show Gist options
  • Select an option

  • Save ready4god2513/d6fc51a1188fa1ae2b56 to your computer and use it in GitHub Desktop.

Select an option

Save ready4god2513/d6fc51a1188fa1ae2b56 to your computer and use it in GitHub Desktop.

Revisions

  1. ready4god2513 renamed this gist Oct 3, 2014. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. ready4god2513 created this gist Oct 3, 2014.
    85 changes: 85 additions & 0 deletions tictactoe
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,85 @@
    require 'set'

    class TicTacToe

    WINNING_LINES = [
    Set.new([0, 1, 2]),
    Set.new([0, 3, 6]),
    Set.new([0, 4, 8]),
    Set.new([1, 4, 7]),
    Set.new([2, 5, 8]),
    Set.new([2, 4, 6]),
    Set.new([3, 4, 5]),
    Set.new([6, 7, 8])
    ].freeze

    attr_reader :players
    Player = Struct.new(:name, :moves)

    def initialize(player1, player2)
    @players = []
    @players << Player.new(player1, Set.new)
    @players << Player.new(player2, Set.new)
    end

    def move(position)
    return puts 'Move taken or invalid' unless available_move?(position)

    take_turn do |player|
    player.moves.add(position)
    determine_game_standing
    end

    puts "#{current_player.name}'s turn"
    end

    def available_moves
    Set[*(0..8).to_a] - taken_moves
    end

    private

    def tie?
    available_moves.empty? && !winner?
    end

    def determine_game_standing
    notify_winner if winner?
    notify_of_tie if tie?
    reset if (tie? || winner?)
    end

    def available_move?(position)
    available_moves.include?(position)
    end

    def notify_winner
    puts "#{current_player.name} wins!"
    end

    def notify_tie
    puts 'It\'s a tie!'
    end

    def taken_moves
    players[0].moves | players[1].moves
    end

    def reset
    players.each { |p| p.moves.clear }
    end

    def winner?
    WINNING_LINES.any? { |l| l == current_player.moves }
    end

    def current_player
    players.first
    end

    def take_turn
    yield current_player
    players.rotate!
    end

    end