Skip to content

Instantly share code, notes, and snippets.

@ready4god2513
Created October 3, 2014 22:24
Show Gist options
  • Save ready4god2513/d6fc51a1188fa1ae2b56 to your computer and use it in GitHub Desktop.
Save ready4god2513/d6fc51a1188fa1ae2b56 to your computer and use it in GitHub Desktop.
Simple game of tictactoe
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment