0

Say I have an array:

array = [6, 6, 6, 4, 4, 6, 4, 4]

and I have another array of strings:

quadrant = ["upper_left", "upper_right", "lower_left", "lower_right"]

and I have a 8 x 8 2-d array consisting of board locations(@board) that are either nil or Checker objects.

My goal is to create a hash such:

hash = { "upper_left" => @board[array[0]][array[1]] ,
         "upper_right" => @board[array[2]][array[3]] ,
         "lower_left" => @board[array[4]][array[5]] ,
         "lower_left" => @board[array[6]][array[7]] }

I have the following code:

jump_positions = {}
QUADRANTS.each do |quad|
        array.each_slice(2) do |coord|
          jump_positions[quad] = @board[coord[0]][coord[1]]
        end

And then the test:

it "should assign board locations as adjacent positions and deliver that info as a whole" do
    @bs.board = board.create_board
    x_coord = 3
    y_coord = 1
    jump_assignments = @bs.assign_adjacent_positions(x_coord, y_coord)
    jump_assignments["upper_left"].class.should == nil
    jump_assignments["upper_right"].class.should == nil
    jump_assignments["lower_left"].class.should == Checker
    jump_assignments["lower_right"].class.should == Checker 
end

fails because all the assignments are of class 'Checker' and turns out they're all the same 'Checker' object. I know its doing this because the loops are nested so all the 'quad' keys are getting initialize to the last board location.

Is there a way I can assign the value to the key with a value from the 'array' in one pass so that they get assigned correctly? Does this question even make sense?

steve_gallagher
  • 3,778
  • 8
  • 33
  • 51
  • Can you post the `assign_adjacent_positions` method please? – Batkins Dec 02 '11 at 23:43
  • Does this end being almost the same as [this question](http://stackoverflow.com/q/8332807/479863)? Just a slight modification is needed to use the 2 element arrays as indices in `@board`. – mu is too short Dec 03 '11 at 00:57
  • @mu is too short It is similar, but there are some key differences: I'm not just zipping the the array values with the strings, I have to include those values as indices of the board attribute (which is a 2d array), ultimately the end result is an object contained in the board 2d array that is indicated by the coordinates delivered by the array.each_slice method Sorry if this is a bit convoluted and thanks much for responding. – steve_gallagher Dec 05 '11 at 16:28
  • @mu is too short So I realized my algoritm design was bad: there was no need to have the hash contain the actual board object, the coords were sufficient, in which case the fairly awesome zip method you explained to me in the other question worked quite nicely. Thanks for making me reconsider my question, which is probably better than answering it. Hope the season starts soon in Whistler! – steve_gallagher Dec 05 '11 at 17:52
  • I adjusted my other answer to extract the `@board` positions anyway. I was setting it up while you were commenting so we missed each other. I won't mind if you delete this question, no big deal. – mu is too short Dec 05 '11 at 18:03

2 Answers2

1

I think you just need to add a little map to my answer to your other similar question:

hash = Hash[quadrant.zip(array.each_slice(2).map { |a| @board[a.first][a.last] })]

Given a board like this:

@board = [
    ['11', '12', ... '18'],
    ['21', '22', ... '28'],
    ...
    ['81', '82', ... '88']
]

the above construct gives me a hash like this:

{
    "upper_left"  => "77",
    "upper_right" => "75",
    "lower_left"  => "57",
    "lower_right" => "55"
}

and that seems to be what you're looking for.

Community
  • 1
  • 1
mu is too short
  • 426,620
  • 70
  • 833
  • 800
0

mu too short made me reconsider my question, and I believe my algorithm was broken. I actually ended up breaking this method down into three interdependent methods:

def deltas_to_board_locations(deltas, x, y)
    board_coords = []
    deltas.each_slice(2) do |slice|
      board_coords << x + slice[0] 
      board_coords << y + slice[1]
    end
    board_coords
  end    

  def assign_adjacent_board_coords(x, y) 
    jump_positions = Hash[QUADRANTS.zip(deltas_to_board_locations(normal_deltas, x, y).each_slice(2))]    
  end

  def determine_adjacent_positions_content(board, board_coords)
    adjacent_content = {}
    board_coords.each_pair { |quad, coords| adjacent_content[quad] = board[coords[0]][coords[1]] }
    adjacent_content
  end  

which worked out quite nicely.

steve_gallagher
  • 3,778
  • 8
  • 33
  • 51