Tic-tac-toe 'winner' method doesn't not returning expected values

I need to create a method that returns “X” if X won, “O” if O won,

and ‘nil’ if no win.

board = [“O”, “X”, “O”, “X”, “X”, “O”, “X”, “O”, “X”]

WIN_COMBINATIONS =
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 4, 8],
[2, 4, 6],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8]]

def won?(board)
combo = 0
while combo < WIN_COMBINATIONS.length
current_combo = WIN_COMBINATIONS[combo]

win1 = current_combo.all? { |position| board[position] == "X" }
win2 = current_combo.all? { |position| board[position] == "O" }

if win1 == true || win2 == true
  return current_combo
else
  false
end
combo += 1

end
end

def winner(board)
#need to figure out who won
#need to know if a game was won
#won?(board) will return the winning combo
#we can check the combo against the board and see if they’re X’s or
O’s
#we really need to only check if the first one is an X

won = won?(board)
type = won[0]

if won == true
return board[type]
else nil
end

endboard = [“O”, “X”, “O”, “X”, “X”, “O”, “X”, “O”, “X”]

WIN_COMBINATIONS =
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 4, 8],
[2, 4, 6],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8]]

def won?(board)
combo = 0
while combo < WIN_COMBINATIONS.length
current_combo = WIN_COMBINATIONS[combo]

win1 = current_combo.all? { |position| board[position] == "X" }
win2 = current_combo.all? { |position| board[position] == "O" }

if win1 == true || win2 == true
  return current_combo
else
  false
end
combo += 1

end
end

def winner(board)
won = won?(board)
type = won[0]

if won == true
return board[type]
else nil
end

end

Basically, the method returns ‘nil’ when won?(board) is true. If I write
the method in the following manner, however…

def winner(board)
won = won?(board)
type = won[0]
return board[type]
end

The first 2 parts of the methods work. But it doesn’t return ‘nil’ when
it’s supposed to, obviously.

if won == true
return board[type]
else nil
end

I feel like it’s not understanding the first line of the above block,
but can’t figure out why.

Thank you ahead of time for you time!

Basically, the method returns
‘nil’ when won?(board) is true.

The problem here is that won?(board) is not true (but a truthy-value).

If there is a winning combination, won? returns an array representing
the winning combbination.

An array is not a boolean, so the comparison won==true evaluates to
false.

In ruby, only nil and false and falsey-values. You can do the check like
this:

if won
board[type]
else
nil
end

And make sure won? actually returns false when there is no winning
combination by adding an explicit return value. Currently it returns
what “while” returns, which is nil.

def won?(board)
combo = 0
while combo < WIN_COMBINATIONS.length
current_combo = WIN_COMBINATIONS[combo]

win1 = current_combo.all? { |position| board[position] == "X" }
win2 = current_combo.all? { |position| board[position] == "O" }

if win1 == true || win2 == true
  return current_combo
end
combo += 1

end
false
end

So here was the working solution for this method:

def winner(board)
won = won?(board)
if won != nil
return board[won[0]]
end
end

When I try to simplify the code by substituting a variable for won[0]
like so…

def winner(board)
won = won?(board)
type = won[0]
if won != nil
return board[type]
end
end

I get the following error…

Failure/Error: expect(winner(board)).to be_nil
NoMethodError:
undefined method `[]’ for nil:NilClass

why ?

nvm…figured it out…can’t index into nil.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs