我目前正在尝试实现一个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
我知道这可能是一个愚蠢的错误但是,我真的想明确我未来代码的错误。非常感谢!
答案 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