【问题标题】:Datatype for accessing data in multidimensional arrays用于访问多维数组中数据的数据类型
【发布时间】:2015-02-24 20:39:52
【问题描述】:

我有一个数组如下:

@spaces = []
def make_board
  7.times do |x|
    x += 1
    6.times do |y|
      y += 1
      @spaces << [x," "]
    end
  end
end

...以及一系列所需的组合:

def winners 
    #V row 1 
    [ [[0][1], [1][1], [2][1], [3][1]], 
    [[1][1], [2][1], [3][1], [4][1]], 
    [[2][1], [3][1], [4][1], [5][1]],
    #V row 2
    [[6][1], [7][1], [8][1], [9][1]],
    [[7][1], [8][1], [9][1], [10][1]],
    [[8][1], [9][1], [10][1], [11][1]],
    #V row 3
    [[12][1], [13][1], [14][1], [15][1]],
    [[13][1], [14][1], [15][1], [16][1]],
    [[14][1], [15][1], [16][1], [17][1]] ]
end

在程序的其余部分,@spaces 数组中的“”可以更改为“X”或“O”。我正在尝试编写一种方法来检测任何组合何时不是“”并且都具有相同的值。

def @win? = false
def success
  winners.each do |x|
    fours = [ @spaces[x[0]], @spaces[x[1]], @spaces[x[2]], @spaces[x[3]] ]
    if fours.each{|x| x[1] != " "}
      if @spaces[x[0]] == @spaces[x[1]] && @spaces[x[1]] == @spaces[x[2]] && @spaces[x[2]] == @spaces[x[3]]
        @win = true
      end
    end
  end
end

它不喜欢从#winners 数组传递的数据类型#success 方法来搜索@spaces 数组。它将其读取为 nil 并需要一个整数,但添加 .to_i 会导致所有内容都为 0。添加括号、“”以及响应错误消息的任何其他内容的变化和分类组合只会导致更多的 nil 和 0 . 要使该方法有效,需要什么数据类型? 或者,在可能的情况下,我会以一种特别愚蠢的方式来处理它,只是还没有意识到 有人可以建议实现相同目标的替代方法?

6X7 网格是“连接四”板。 @sample 数组中的每个子数组[0] 都是列,用于程序的其他部分。每个子数组[1] 是“X”、“O”或“”(未使用)。该程序是用于学习目的的“连接四个”游戏

【问题讨论】:

  • @spaces 是一个由 42 个元素组成的数组,形式为 [i,s],其中 i 是介于 17(含)之间的数字,而 s 最初是 @987654330 @,但可以更改为 "X""O"@spacesjth元素是什么意思?
  • 你从哪里得到jth 元素?
  • j 引用@spaces 在位置(或索引或​​偏移)j 处的元素,其中j041 之间的任意数字。例如,j=21
  • 啊。在这些术语中,每个元素 j 代表 6X7 网格上的一个空间。 j[0] 是列,用于程序的其他部分。 j[1] 是“X”、“O”或“”(未使用)。该程序是一个用于学习目的的“连接四个”游戏。

标签: ruby arrays multidimensional-array


【解决方案1】:

我认为您对winners 的定义有点偏离。特别是

[0][1] # => nil

因为您实际上是在创建一个数组[0],然后立即要求位置 1 中的元素,即 nil(该数组只有位置 0 中的元素)。由于所有数组都是单个元素,因此获胜者看起来像这样

[ [nil, nil, nil, nil], 
[nil, nil, nil, nil], 
[nil, nil, nil, nil],
# etc

认为你想要的是这个

[ [0, 1, 2, 3], 
[1, 2, 3, 4], 
[2, 3, 4, 5],

这将使这条线

fours = [ @spaces[x[0]], @spaces[x[1]], @spaces[x[2]], @spaces[x[3]] ]

所以,对于winners中的第一个数组

fours = [ @spaces[0], @spaces[1], @spaces[2], @spaces[3] ]

可能看起来像

# the first 6 elements of spaces have x = 1, so all 1's here
fours = [ [1, " "], [1, " "], [1, " "], [1, " "] ]

...取决于游戏的状态。在那之后,你的代码会有点偏离。看起来您正在尝试检查所有四个 fours 在空间中是否具有相同的值,并且该值不为空。使用您拥有的结构:

if fours.all? { |space| space[1] != " " }
  if fours[0][1] == fours[1][1] &&
       fours[1][1] == fours[2][1] &&
       fours[2][1] == fours[3][1]
    @win = true
  end
end

如果我正确理解您的结构,那应该可以,或者至少可以接近。

话虽如此,如果可以的话,我会非常显着地改变这里的结构。首先,我将板表示为一个数组数组,您可以在其中仅使用 x、y 坐标访问任何位置,就像这样

board = 7.times.map { Array.new(6, " ") }
board[0][0] # => " "

您可以使用基于 0 或 1 的坐标,但如果您使用 1,则每次访问数组时都必须减去 1。

填充一个正方形很容易

board[x][y] = "O"

您可以将所有获胜者枚举为坐标对(注意使用常量,因为它永远不会改变):

WINNERS = [
  [[0,0], [1,0], [2,0], [3,0]], # horizontal win
  [[0,0], [1,1], [2,2], [3,3]], # diagonal win
  # etc
]

然后检查那些

WINNERS.each do |win_row|
  if win_row.all? { |x, y| board[x][y] == "X" } || win_row.all? { |x, y| board[x][y] == "O" }
    @win = true
    break
  end
end

如果您不想构造和存储获胜者数组,也可以通过算法确定获胜者。

【讨论】:

  • 成功了!那就是票......现在我意识到还有其他问题,但那部分现在很有意义并且起作用了。谢谢。
【解决方案2】:

这是第一个问题... [0] 是一个只有一个元素的数组。 [0][1] 说“获取数组的第二个元素”(索引 1)但没有第二个元素,因此返回 nil。

我认为你真正想做的不是[0][1],而是0,等等。

def winners 

    #V row 1 
    [ 
      [0, 1, 2, 3], 
      [1, 2, 3, 4], 
      [2, 3, 4, 5],
    #V row 2
      [6, 7, 8, 9],
      [7, 8, 9, 10],
      [8, 9, 10, 11],
    #V row 3
      [12, 13, 14, 15],
      [13, 14, 15, 16],
      [14, 15, 16, 17]
    ]
end

下一个问题是这一行...

if fours.each{|x| x[1] != " "}

... 并没有按照你的想法去做。 each 块返回迭代数组,而不是 truefalse。你想要的是……

if fours.select{|x| x[1] == " "}.empty?

如果第二个元素中没有带有“”的单元格,它将返回true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    • 2023-03-24
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多