条件,红宝石。井字游戏

时间:2018-02-11 00:22:48

标签: ruby rspec

我目前正在尝试实现一个tic tac toe console-version。我有一套规范来指导我完成我需要编写的方法等。目前,我正在研究我的“赢家”方法,该方法确定:X或:O是否赢得了比赛。我知道我的实现到目前为止非常昂贵,因为我使用了很多循环来检查每种可能性。我完全让我的功能工作后,我会尝试重构它。如果没有满足任何条件,我很难在最后使我的函数返回“nil”并且我没有碰巧找到它的原因!!有人能发现我的错误吗?这是我的代码:

    class Board

  attr_reader :grid, :marks

  def self.grid
    (Array.new(3) { Array.new(3) })
  end

  def initialize(grid = Board.grid)
    @grid = grid
    @marks = [:X, :O]
  end

  def [](pos)
    row, col = pos
    @grid[row][col]
  end

  def []=(pos, value)
    row, col = pos
    @grid[row][col] = value
  end

  def empty?(pos)
    self[pos].nil?
  end

  def place_mark(pos, mark)
    self[pos] = mark
  end

  def winner
    @grid.each do |row|
      return :X if row.each.all? { |mark| mark == :X }
    end
    @grid.transpose.each do |col|
      return :X if col.each.all? { |mark| mark == :X }
    end
    @grid.each do |row|
      return :O if row.each.all? { |mark| mark == :O }
    end
    @grid.transpose.each do |col|
      return :O if col.each.all? { |mark| mark == :O }
    end
    if @grid[0, 0] = :X && @grid[1, 1] = :X && @grid[2, 2] = :X &&
       @grid[2, 2] = :X
      return :X
    elsif @grid[0, 0] = :O && @grid[1, 1] = :O && @grid[2, 2] = :O &&
       @grid[2, 2] = :O
      return :O
    end
    nil   # HERE! I can't make this run! :/ 
  end

  def over?
    @grid.flatten.none?{|sqr| sqr.nil?} || self.winner != :X
    return true if self.winner == :X
  end
end

这是我对该功能的规范

describe "winner" do
    context "when :X has won" do
      context "on a row" do
        it "returns :X" do
          place_marks([[0, 0], [0, 1], [0, 2]], :X)

          expect(board.winner).to be :X
        end
      end

      context "on the left diagonal" do
        it "returns :X" do
          place_marks([[0, 0], [1, 1], [2, 2]], :X)

          expect(board.winner).to be :X
        end
      end

      context "on the right diagonal" do
        it "returns :X" do
          place_marks([[0, 2], [1, 1], [2, 0]], :X)

          expect(board.winner).to be :X
        end
      end
    end

    context "when :O has won a column" do
      it "returns :O" do
        place_marks([[0, 2], [1, 2], [2, 2]], :O)

        expect(board.winner).to be :O
      end
    end

    context "when there is no winner" do
      it "returns nil" do
        expect(board.winner).to be nil

        fill_cats_game

        expect(board.winner).to be nil
      end
    end
  end

我知道这可能是一个愚蠢的错误但是,我真的想明确我未来代码的错误。非常感谢!

1 个答案:

答案 0 :(得分:0)

首先,根据@Simple Lime提供的解释,你应该在winner方法中使用如下的条件语句,并且nested array应该如下访问:

if @grid[0][0] == :X && @grid[1][1] == :X && @grid[2][2] == :X
  return :X
elsif @grid[0][0] == :O && @grid[1][1] == :O && @grid[2][2] == :O
  return :O
end

您的方法如下所示:

  def winner
    @grid.each do |row|
      return :X if row.each.all? { |mark| mark == :X }
    end
    @grid.transpose.each do |col|
      return :X if col.each.all? { |mark| mark == :X }
    end
    @grid.each do |row|
      return :O if row.each.all? { |mark| mark == :O }
    end
    @grid.transpose.each do |col|
      return :O if col.each.all? { |mark| mark == :O }
    end
    if @grid[0][0] == :X && @grid[1][1] == :X && @grid[2][2] == :X
      return :X
    elsif @grid[0][0] == :O && @grid[1][1] == :O && @grid[2][2] == :O
      return :O
    end
  end

x_board = Board.new([[:O,:X,:X],[:O,:X,:O],[:O,:X,:X]])

x_board.winner
=> :X

o_board = Board.new([[:O,:X,:X],[:O,:O,:X],[:X,:O,:O]])

o_board.winner
=> :O

nil_board = Board.new

nil_board.winner
=> nil