Zonet
Zonet

Reputation: 302

Tic-Tac-Toe: checking to see if a player has won

I am currently in the middle of building a replica of the ever so popular Tic-Tac-Toe game, built using pure ruby & tested TDD style.

The only issue I'm having is that I cannot, for the life of me, figure out how to check when a player has won. I know this is a relatively simple issue, but I'm just having one of those days - and I truly do only post here as a last resort.

Any help is massively appreciated - and feel free to critique my current code! I can handle it. :)

My code:

class TicTacToe

WINNING_COMBINATIONS = [[0, 1, 2], [3, 4, 5], [6, 7, 8], #Horizontal
                      [0, 3, 6], [1, 4, 7], [2, 5, 8], #Vertical
                      [0, 4, 8], [2, 4, 6]] #Diagonal    

def initialize
  @board = ["", "", "", "", "", "", "", "", ""]
  @players = ['player_one', 'player_two']
  @current_player = 'player_one'
end

def player_1
  @players.first
end

def player_2
  @players.last
end

def switch
  @current_player = opponent_of(@current_player)
end

def display_board
  puts " #{@board[0]} | #{@board[1]} | #{@board[2]} "
  puts "-----------"
  puts " #{@board[3]} | #{@board[4]} | #{@board[5]} "
  puts "-----------"
  puts " #{@board[6]} | #{@board[7]} | #{@board[8]} "
end

def move(position)
  fail "Please select a space within range." if position < 1 || position > 9
  fail "That space is already taken!" unless @board[position-1].empty?
if @current_player == player_1
  @board[position-1] = 'o'
else
  @board[position-1] = 'x'
end
  switch
end

def check_for_winner
  #Help!
end

private

def opponent_of(player)
  @players.select { |p| p != player }.first
  end
end

Upvotes: 3

Views: 1278

Answers (4)

Muhammad Mudasir
Muhammad Mudasir

Reputation: 11

Using if elsif else (:Tic Tac Toe)  *Game*" )
------------------------------------------------
a=['','','','','','','','','']

puts "(Tic Tac Toe)  *Game*"
puts ""
puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                            "
a.each_with_index do |n,index|
val=''
puts "Enter your Sign:"
val=gets.chomp
loc=''
puts "Enter location:"
loc=gets.to_i
if loc == 1
 a[0]=val
 puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                             "
end
# check posible condition to win loction (1)
if   (a[0] !="") && (a[0] == a[1]) && (a[0] == a[2])
  puts "You are win"
break
elsif  (a[0] !="") && (a[0] == a[3]) && (a[0] == a[6])
  puts "You are win"
break
elsif (a[0] !="") && (a[0] == a[4]) && (a[0] == a[8])
  puts "You are win"
break
else
end
if loc == 02
 a[1]=val
  puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                             "
end
# check posible condition to win loction (2)
if   (a[1] !="") && (a[0] == a[1]) && (a[0] == a[2])
  puts "You are win"
break
elsif (a[1] !="") && (a[1] == a[4]) && (a[1] == a[7])
  puts "You are win"
break
else
end
if loc == 3
a[2]=val
 puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                             "
end
# check posible condition to win loction (3)
if   (a[2] !="") && (a[2] == a[1]) && (a[2] == a[0])
  puts "you are win"
break
elsif (a[2] !="") && (a[2] == a[4]) && (a[2] == a[6])
  puts "You are win"
break
elsif (a[2] !="") && (a[2] == a[5]) && (a[2] == a[8])
  puts "You are win"
break
else
end
# End win posible conditions
if loc == 4
 a[3]=val
  puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                             "
end
# check posible condition to win loction (4)
if   (a[3] !="") && (a[3] == a[4]) && (a[3] == a[5])
  puts "you are win"
break
elsif  (a[3] !="") && (a[3] == a[0]) && (a[3] == a[6])
  puts "You are win"
break
else
end
# End win posible conditions
if loc == 5
 a[4]=val
  puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                             "
end
# check posible condition to win loction (5)
if   (a[4] !="") && (a[4] == a[1]) && (a[4] == a[7])
  puts "You are win"
break
elsif (a[4] !="") && (a[4] == a[3]) && (a[4] == a[5])
  puts "You are win"
break
elsif (a[4] !="") && (a[4] == a[2]) && (a[4] == a[6])
  puts "You are win"
break
else
end
if loc == 6
  a[5]=val
   puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                             "
end
# check posible condition to win loction (6)
if   (a[5] !="") && (a[5] == a[2]) && (a[5] == a[8])
  puts "You are win"
break
elsif  (a[5] !="") && (a[5] == a[3]) && (a[5] == a[4])
  puts "You are win"
break
else
end
if loc == 7
 a[6]=val
  puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                             "
end
# check posible condition to win loction (7)
if   (a[6] !="") && (a[6] == a[1]) && (a[6] == a[3])
  puts "You are win"
break
elsif (a[6] !="") && (a[6] == a[7]) && (a[6] == a[8])
  puts "You are win"
break
elsif (a[6] !="") && (a[6] == a[4]) && (a[6] == a[2])
   puts "You are win"
break
else
end
if loc == 8
a[7]=val
 puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                             "
end
# check posible condition to win loction (8)
if   (a[7] !="") && (a[7] == a[6]) && (a[7] == a[8])
   puts "You are win"
break
elsif  (a[7] !="") && (a[7] == a[4]) && (a[7] == a[1])
   puts "You are win"
break
else
end
if loc == 9
 a[8]=val
  puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                             "
end
# check posible condition to win loction (9)
if   (a[8] !="") && (a[8] == a[7]) && (a[8] == a[6])
   puts "You are win"
break
elsif (a[8] !="") && (a[8] == a[4]) && (a[8] == a[0])
  puts  puts "You are win"
break
elsif (a[8] !="") && (a[8] == a[5]) && (a[8] == a[2])
  puts "you are win"
break
else
  puts "Again play No winner"
end
end
puts "=============================="
puts "Game Preview"

puts " #{a[0]} | #{a[1]} | #{a[2]} "
puts "-----------"
puts " #{a[3]} | #{a[4]} | #{a[5]} "
puts "-----------"
puts " #{a[6]} | #{a[7]} | #{a[8]} "
puts "                             "

Upvotes: 1

SteveTurczyn
SteveTurczyn

Reputation: 36860

This is a problem of determining if a small array (winning set) is completely a subset of a larger array (board). You can do that with simple array subtraction.

def has_winner(board)
  WINNING_COMBINATIONS.each do |line|
    return true if (line - board) == []
  end
  return false
end

To incorporate @Stefan 's excellent suggestion in another answer...

def has_winner(board)
   WINNING_COMBINATIONS.any? {|line| (line - board) == [] }
end

Upvotes: 2

spickermann
spickermann

Reputation: 106972

I would start with something like this:

def check_for_winner
  WINNING_COMBINATIONS.each do |combination|
    case board.values_at(*combination)
    when %w(o o o)
      return 'Player 1 wins'
    when %w(x x x)
      return 'Player 2 wins'
    end
  end
end

Upvotes: 3

Ray Toal
Ray Toal

Reputation: 88418

You are very close. I don't want to write your code for you, but I'll give you some pseudocode from which you should recognize the correct algorithm to apply:

def has_winner(board)
  WINNING_COMBINATIONS.each do |i, j, k|
    return true if board[i] == board[j] && board[i] == board[k]
  end
  false
end

Integrate as needed, then maybe dabble in trying to get all fancy with some higher order functions.

By the way, there are some really fancy and much faster ways to compute winning based on bit masks and summing powers of two and the like, but I'm guessing going with what is the most readable is fine.

Upvotes: 1

Related Questions