ruby中的随机对象,需要异常处理的帮助

时间:2014-06-05 20:46:39

标签: ruby object random minesweeper

我正在尝试编写扫雷游戏以获得乐趣。到目前为止,我正在制作一块板子和我的物体,最终会在板上留下胡须。目前,当我为测试目的制作一个5×5板并将其加载到我的矿物对象中以便它可以选择随机列行时,它会在一段时间内出错。这是代码,我运行的内容以及我得到的错误:

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 Mine
  attr_accessor :proxi, :row, :col

  def initialize(proxi)
    @proxi = proxi
    @row = Random.rand(1..@proxi.board.length)
    @col = Random.rand(1..@proxi.board[0].length)
    check_position
  end

  def check_position
    if @proxi.board[@row - 1][@col - 1] != "L"
      initialize
    else
      map_position
    end
  end

  def map_position
    @proxi.board[@row - 1][@col - 1] = "*"
  end
end

b = Board.new(5)

=> #<Board:0x000000024cbb50 @size=5, @board=[["L", "L", "L", "L", "L"], ["L", "L", "L", "L", "L"], ["L", "L", "L", "L", "L"], ["L", "L", "L", "L", "L"], ["L", "L", "L", "L", "L"]]> 

m = Mine.new(b)

 => #<Mine:0x000000024ae9d8 @proxi=#<Board:0x000000024cbb50 @size=5, @board=[["L", "L", "L", "L", "L"], ["L", "L", "L", "L", "L"], ["L", "L", "*", "L", "L"], ["L", "L", "L", "L", "L"], ["L", "L", "L", "L", "L"]]>, row3, col3 

m = Mine.new(b)

 => #<Mine:0x00000002487888 @proxi=#<Board:0x000000024cbb50 @size=5, @board=[["L", "L", "L", "L", "L"], ["L", "L", "L", "L", "L"], ["L", "L", "*", "L", "L"], ["*", "L", "L", "L", "L"], ["L", "L", "L", "L", "L"]]>, row4, col1 

m = Mine.new(b)

 => #<Mine:0x000000024758b8 @proxi=#<Board:0x000000024cbb50 @size=5, @board=[["L", "L", "L", "L", "L"], ["L", "L", "L", "L", "L"], ["L", "L", "*", "L", "L"], ["*", "L", "*", "L", "L"], ["L", "L", "L", "L", "L"]]>, row4, col3 

m = Mine.new(b)

 => #<Mine:0x000000024211a0 @proxi=#<Board:0x000000024cbb50 @size=5, @board=[["L", "L", "L", "*", "L"], ["L", "L", "L", "L", "L"], ["L", "L", "*", "L", "L"], ["*", "L", "*", "L", "L"], ["L", "L", "L", "L", "L"]]>, row1, col4 

m = Mine.new(b)

 => #<Mine:0x000000023b37e0 @proxi=#<Board:0x000000024cbb50 @size=5, @board=[["L", "L", "L", "*", "L"], ["L", "L", "L", "L", "L"], ["*", "L", "*", "L", "L"], ["*", "L", "*", "L", "L"], ["L", "L", "L", "L", "L"]]>, row3, col1 

m = Mine.new(b)

 => #<Mine:0x0000000235ed08 @proxi=#<Board:0x000000024cbb50 @size=5, @board=[["L", "L", "L", "*", "L"], ["L", "L", "L", "*", "L"], ["*", "L", "*", "L", "L"], ["*", "L", "*", "L", "L"], ["L", "L", "L", "L", "L"]]>, row2, col4 

m = Mine.new(b)

 => #<Mine:0x00000002310888 @proxi=#<Board:0x000000024cbb50 @size=5, @board=[["L", "L", "L", "*", "L"], ["L", "L", "L", "*", "L"], ["*", "L", "*", "L", "*"], ["*", "L", "*", "L", "L"], ["L", "L", "L", "L", "L"]]>, row3, col5 

m = Mine.new(b)

 ArgumentError: wrong number of arguments (0 for 1)
     from (irb):16:in `initialize'
     from (irb):25:in `check_position'
     from (irb):20:in `initialize'
     from (irb):43:in `new'
     from (irb):43
     from /home/ubuntu/.rvm/rubies/ruby-2.0.0-p353/bin/irb:12:in `<main>'

所以最终当我向一个新的对象实例提供它不需要的修改过的板子实例时。我不知道为什么会这样,但希望有人能引导我朝着正确的方向前进,这样我就可以继续自动化了。谢谢!

以下是我采用的解决方案:

class Mine
  attr_accessor :proxi, :row, :col

  def initialize(proxi)
    @proxi = proxi
    @row = 0
    @col = 0
    @random = Random.new
    check_position
  end

  def check_position
    if @proxi.board[@row - 1][@col - 1] != "L"
      @row = @random.rand(1..@proxi.board.length)
      @col = @random.rand(1..@proxi.board[0].length)
      check_position
    else
      map_position
    end
  end

  def map_position
    @proxi.board[@row - 1][@col - 1] = "*"
  end
end

1 个答案:

答案 0 :(得分:0)

如果已经采取了排名,check_position方法会尝试回拨initialize,但无法传递所需的proxi参数。

我觉得重复调用initialize方法是不明智的(如果可能的话),因为那是你班级的构造函数。

我更愿意提取与找到一组辅助方法的开放位置相关的逻辑。以下内容将帮助您实现目标:

private

  def find_open_position
    x = 0
    y = 0

    begin
      x, y = random_position
    while position_taken?(x, y)

    [x, y]
  end

  def random_position
    [Random.rand(1..@proxi.board.length), @col = Random.rand(1..@proxi.board[0].length)]
  end

  def position_taken?(x, y)
    @proxi.board[x - 1][x - 1] != "L"
  end

然后您的initialize只需要包含

 @row, @col = find_open_position