bbuchalter/tictactoe_core

View on GitHub
lib/tictactoe/board.rb

Summary

Maintainability
A
0 mins
Test Coverage
require 'tictactoe/position'
require 'tictactoe/tuple'

module TicTacToe
  class Board
    include Enumerable

    def initialize
      @board = Array.new(9) { |i| ::TicTacToe::Position.new((i + 1), nil) }
    end

    def each(&block)
      board.each(&block)
    end

    def length
      board.length
    end

    def at(position)
      board[index_for(position)]
    end

    def index_for(position)
      position.to_i - 1
    end

    def new_move_for(position, value)
      fail InvalidPosition unless position.to_i.between?(1, 9)
      fail PositionTaken unless board[index_for(position)].empty?
      board[index_for(position)] = value
    end

    def tuples
      (row_tuples + column_tuples + diagonal_tuples).flatten
    end

    def corners
      [at(1), at(3), at(7), at(9)]
    end

    def sides
      [at(2), at(4), at(6), at(8)]
    end

    private

    attr_reader :board

    def row_tuples
      [
          tuple_for(1, 2, 3),
          tuple_for(4, 5, 6),
          tuple_for(7, 8, 9)
      ]
    end

    def column_tuples
      [
          tuple_for(1, 4, 7),
          tuple_for(2, 5, 8),
          tuple_for(3, 6, 9)
      ]
    end

    def diagonal_tuples
      [
          tuple_for(1, 5, 9),
          tuple_for(3, 5, 7)
      ]
    end

    def tuple_for(one, two, three)
      ::TicTacToe::Tuple.new([at(one), at(two), at(three)])
    end

    class PositionTaken < RuntimeError
    end
    class InvalidPosition < RuntimeError
    end
  end
end