Ruby Tic Tac toe feedback


Hi everyone,

I i just finished this exercise, i was able to get it working properly but i was wondering if i this is good enough?
I’m pretty sure its possible to do it with less lines of code but I’m having a hard time figuring out how.

  def player_a_won?
    #checks horizontal
    if @@board[0..2].all? { |i| i == "X"} ||
       @@board[3..5].all? { |i| i == "X"} || 
       @@board[6..8].all? { |i| i == "X"}
      return true
    #checks vertical 
    elsif (@@board[0] == "X" && @@board[3] == "X" && @@board[6] == "X") || 
          (@@board[1] == "X" && @@board[4] == "X" && @@board[7] == "X") || 
          (@@board[2] == "X" && @@board[5] == "X" && @@board[8] == "X") 
      return true
    #check slash?
    elsif (@@board[0] == "X" && @@board[4] == "X" && @@board[8] == "X") ||
          (@@board[2] == "X" && @@board[4] == "X" && @@board[6] == "X")
      return true
      return false

This is what I’m least happy about and would really like some input on how i can refactor it.


Duplicate code is a big code smell. In your case you have two methods that operate exactly the same with the only difference being the piece they check.

The simplest way to handle that is to make the piece an argument to the method and then check against that argument.

  def player_a_won?(piece)
    #checks horizontal
    if @@board[0..2].all? { |i| i == piece} ||
       @@board[3..5].all? { |i| i == piece} || 
       @@board[6..8].all? { |i| i == piece}
      return true


That way you can use the same method for both players and rename it to winner? or player_won? or whatever you need.

The other way I’ve seen it done is to store all the winning combinations in an array and iterate that looking for a winner although your code is probably good enough for now that I wouldn’t worry about that change now. I just wanted to present an alternative way to handle it that I’ve seen.

Otherwise it’s pretty good going. Nice work.