如何在井字棋盘中找到第一个获胜组合?

问题描述 投票:0回答:2

Ruby的新功能,请原谅可怜的代码。我想遍历多维数组WIN_COMBINATIONS,并检查至少一个数组的所有元素是否等于'X'或全部等于'O'。如果是这样,则返回匹配的数组。这是通过won?函数完成的,但似乎只返回了整个多维数组。任何帮助,将不胜感激。

class TicTacToe
  WIN_COMBINATIONS = [ 
[0,1,2], # top_row 
[3,4,5], # middle_row 
[6,7,8], # bottom_row 
[0,3,6], # left_column 
[1,4,7], # center_column 
[2,5,8], # right_column 
[0,4,8], # left_diagonal 
[6,4,2] # right_diagonal 
]

  def initialize
    @board = Array.new(9, " ")
  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 input_to_index(board_position)
    user_input = board_position.to_i
    user_input - 1
  end

  def move(board_index, player_token = 'X')
    @board[board_index] = player_token
  end

  def position_taken?(board_position)
    if @board[board_position] == ' '
      false
    else
      true
    end
  end

  def valid_move?(board_position)
    if board_position >= 0 and board_position <= 8
      if @board[board_position] == ' '
        true
      end
    else
      false
    end
  end

  def current_player
    turn_count % 2 == 0 ? "X" : "O"
  end

  def turn_count
    @board.count{|token| token == "X" || token == "O"}
  end

  def turn
    puts "Select your move (1-9)\n"
    move = gets.chomp
    move_index = input_to_index(move)
    if valid_move?(move_index)
      token = current_player
      move(move_index, token)
      display_board
    else
      puts "Select your move (1-9)\n"
      move = gets.chomp
    end
  end

  def won?
    WIN_COMBINATIONS.each do |combinations|
      if combinations.all? {|combination| combination == 'X' or combination == 'O'}
        combinations
      else
        false
      end
    end
  end

  def draw?
    if full? and !won?
      true
    elsif won?
      false
    else
      false
    end
  end

  def over?

  end

  def winner

  end

  def play

  end
end
ruby tic-tac-toe
2个回答
1
投票

[...]似乎只返回整个多维数组。

您尝试的解决方案有几个问题:

  1. WIN_COMBINATIONS是一个索引数组。这些索引是数字,因此它们永远不会是'X''O'。您必须检查其对应值'X'还是'O'

  2. or是用于do_this or fail场景的控制流运算符布尔值“或”运算符||。使用or代替|| might可以工作,但由于precedence较低,可能会产生意想不到的结果。您几乎总是想要||

  3. 表达式array.all? { |element| element == 'X' || element == 'O' }检查所有元素是任一个>] 'X'还是'O'true['X','O','O']false['X',' ','O']。那是因为您将条件放在块中。您要检查的元素是全部为'X'还是全部为'O'

    array.all?('X') || array.all?('O')
    
  4. 您的方法的返回值是WIN_COMBINATIONS.each { ... }的结果,并且Array#each始终返回数组本身,即Array#each。要获取与条件匹配的第一个元素,请使用WIN_COMBINATIONS

  5. 让我们将所有这些应用于您的代码。鉴于此板:

find

您可以通过以下方式获得第一个匹配的组合:

find

@board = %w[ X - O O X - - - X ] 返回相应索引的值(WIN_COMBINATIONS.find do |indices| values = @board.values_at(*indices) values.all?('X') || values.all?('O') end #=> [0, 4, 8] values_at数组转换为参数列表,因此values_at变为*)。然后,该块的第二行检查这些值是全部为indices还是全部为values_at(*[0,1,2])。一旦计算结果为values_at(0,1,2),循环就会中断,'X'返回找到的元素。 (如果没有匹配项,则为'O'


0
投票

这是解决问题的方法:

© www.soinside.com 2019 - 2024. All rights reserved.