【问题标题】:minesweeper ruby detector arrays indexes out of扫雷红宝石探测器阵列索引出
【发布时间】:2014-06-07 04:12:48
【问题描述】:

所以我正在用 ruby​​ 制作一个扫雷游戏,只是为了好玩。我已经完成了大部分工作,但是我的检测器对象在处理电路板边缘时遇到了问题。 board 对象由一个大小 int 和一个由 row..col 组成的 3d 数组组成。我的检测器对象必须忽略我设置的超出范围的索引,除非有条件处理。然后问题是当它检查地雷时,它可以总计它将计算顶部或底部阵列上的东西的数量。如果它在板的底部,它将从顶部等开始计数。还有一些地雷到右边的边界似乎没有检测到任何东西。董事会中间阵列中的地雷似乎工作正常。我一直在尝试很多不同的配置,却不知所措。这是板子和探测器对象:

class Board
  attr_accessor :size, :board

  def initialize(size = gets.chomp.to_i)
    @size = size
    @board = (1..@size).map { |x| ["L"] * @size }
  end

  def print_board
    @board.map { |row| puts row.join }
  end
end

class Detector
  attr_accessor :proxi, :row, :col, :value

  def initialize(proxi)
    @proxi = proxi
    @row = 0
    @col = 0
    @value = 0
  end

  def mine?
    if @proxi.board[@row - 1][@col - 1] == "*"
      true
    else
      false
    end
  end

  def detect
    unless (@row < 0 || @row > @proxi.size - 1) || (@col < 0 || @col > @proxi.size - 1)
      @value += 1 if @proxi.board[@row - 2][@col - 1] == "*"
      @value += 1 if @proxi.board[@row - 2][@col - 2] == "*"
      @value += 1 if @proxi.board[@row - 1][@col - 2] == "*"
      @value += 1 if @proxi.board[@row][@col - 2] == "*"
      @value += 1 if @proxi.board[@row][@col - 1] == "*"
      @value += 1 if @proxi.board[@row][@col] == "*"
      @value += 1 if @proxi.board[@row - 1][@col] == "*"
      @value += 1 if @proxi.board[@row - 2][@col] == "*"
    end
  end

  def map_position
    @proxi.board[@row - 1][@col - 1] = @value
    @row = 0
    @col = 0
    @value = 0
  end
end

为了时间,我一直在对小板进行测试。我注意到底部面板在应该说 5 时给出了 0。顶部的 6 反映了它们周围的地雷以及板的底部。所以我如何管理我的 3d 数组。在较大的板上,我注意到中间物体检测良好,当它们位于边缘时,它们要么检测到另一侧,要么它们是哑弹和假 0。

这是一个带有调试的游戏的输出:

Minefield size:
3
Lets play minesweeper!
LL*
***
*L*
LLL
LLL
LLL
pick a row:
1
pick a col:
1
flag position? (y/n)
n
6L*
***
*L*
6LL
LLL
LLL
pick a row:
1
pick a col:
2
flag position? (y/n)
n
66*
***
*L*
66L
LLL
LLL
pick a row:
1
pick a col:
3
flag position? (y/n)
y
66*
***
*L*
66!
LLL
LLL
pick a row:
2
pick a col:
1
flag position? (y/n)
y
66*
***
*L*
66!
!LL
LLL
pick a row:
2
pick a col:
2
flag position? (y/n)
y
66*
***
*L*
66!
!!L
LLL
pick a row:
2
pick a col:
3
flag position? (y/n)
y
66*
***
*L*
66!
!!!
LLL
pick a row:
3
pick a col:
1
flag position? (y/n)
y
66*
***
*L*
66!
!!!
!LL
pick a row:
3
pick a col:
2
flag position? (y/n)
n
66*
***
*0*
66!
!!!
!0L
pick a row:
3
pick a col:
3
flag position? (y/n)
y
66*
***
*0*
you win
continue? (y/n)

感谢您的任何建议和帮助!

【问题讨论】:

  • 太长了。很少有人愿意免费阅读您的问题。
  • 别担心,打扰您了!

标签: ruby arrays indexing minesweeper


【解决方案1】:

你为什么不考虑让你的董事会课程更聪明一点。

我建议首先创建一个函数来测试任何位置是否有效。例如:

  def valid?(row,col)
    !(row < 1 || row > @size - 1) || (col < 1 || col > @size - 1)
  end

我还建议添加一个函数来获取或设置任何单元格。例如:

def get (row,col)
   @board[row -1][col-1] if valid?(row,col)
end

def set (row,col,val)
   @board[row -1][col -1] = val if valid?(row,col)
end

那么您就不必再担心事情的去向了。

您可以添加一个迭代器函数,让您查看一个点“周围”的所有单元格。 请注意它是如何盲目地循环遍历一系列单元格并让有效的?函数担心边缘..

例如:

 def around(row,col)
   (row-1 .. row+1).each do |r|
     (col-1 .. col+1).each do |c|
       if valid?(r,c)
         yield r,c
       end
     end
   end
 end

然后,如果您想实现“检测”之类的功能,您只需要担心如何处理每个单元格,例如:

def detect(row,col)
  around(row,col) do |r,c|
    puts "boom at #{r},#{c}" if get(r,c) == '*'
  end
end

您可以更改此逻辑以将分数相加或您需要做的任何事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多