HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyModerate

Checking for a win in TicTacToe

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
wincheckingtictactoefor

Problem

It looks like it should be shortened but I can't see how.

I have my methods <= 5 lines but that's as far as I got:

def check_lines
  if horizontal?(@player) || vertical?(@player) || diagonal?(@player)
    @win=@player
  end
end

def horizontal?(player)
  ((@squares[0] == player) && (@squares[1] == player) && (@squares[2] == player)) ||
  ((@squares[3] == player) && (@squares[4] == player) && (@squares[5] == player)) ||
  ((@squares[6] == player) && (@squares[7] == player) && (@squares[8] == player))
end

def vertical?(player)
  ((@squares[0] == player) && (@squares[3] == player) && (@squares[6] == player)) ||
  ((@squares[1] == player) && (@squares[4] == player) && (@squares[7] == player)) ||
  ((@squares[2] == player) && (@squares[5] == player) && (@squares[8] == player))
end

def diagonal?(player)
  ((@squares[0] == player) && (@squares[4] == player) && (@squares[8] == player)) ||
  ((@squares[2] == player) && (@squares[4] == player) && (@squares[6] == player))
end

Solution

When all of your code is the same, just with different numbers, you want to use data-directed programming.

WINS = [
  [0, 1, 2], [3, 4, 5], [6, 7, 8],  # <-- Horizontal wins
  [0, 3, 6], [1, 4, 7], [2, 5, 8],  # <-- Vertical wins
  [0, 4, 8], [2, 4, 6],             # <-- Diagonal wins
]

def check_lines
  if WINS.any? { |line| line.all? { |square| @squares[square] == @player } }
    @win = @player
  end
end

Code Snippets

WINS = [
  [0, 1, 2], [3, 4, 5], [6, 7, 8],  # <-- Horizontal wins
  [0, 3, 6], [1, 4, 7], [2, 5, 8],  # <-- Vertical wins
  [0, 4, 8], [2, 4, 6],             # <-- Diagonal wins
]

def check_lines
  if WINS.any? { |line| line.all? { |square| @squares[square] == @player } }
    @win = @player
  end
end

Context

StackExchange Code Review Q#48902, answer score: 12

Revisions (0)

No revisions yet.