Let's Party with Stacks and Queues! Pt 2
Tags: beginners, webdev, ruby
Published: 2019-04-30 18:19:27

---
title: Let's Party with Stacks and Queues! Pt 2
published: true 
cover_image: https://thepracticaldev.s3.amazonaws.com/i/i5hiamwbabnhomcb50k2.jpg
tags: #beginner #webdev #ruby
series: "Let's Party with Stacks and Queues"
---


In Part 1, we configured classes for our stack of meals, and queue of guests. Now let's setup our Party class, which accepts our arrays of meals & guests, and initializes instances of MealStack and GuestQueue.

```ruby
class Party
  attr_accessor :meals, :guests
  
  def initialize(meals_array, guest_array)
    self.meals = MealStack.new(meals_array)
    self.guests = GuestQueue.new(guest_array)
  end
end
```

It would be nice to view the meals and guests at any point during the party, so let's create a `view_party` method for that:

```ruby
def view_party
    puts "Party Status:\n Meals: #{meals.display_meals}\n Guests: #{guests.display_queue}\n\n"
end
```

For a guest to be properly served, the meal at the top of the stack has to match the meal preference of the first guest in the queue. So we create a method `match?` that checks for this:

```ruby
def match?
    meals.top_meal == guests.first_guest
end
```

Next we create a `move_queue` method that does three things:
- Shows us the party status
- Removes guests that have been served successfully
- Moves guests in front of the queue to the back when the top meal doesn't match their preference

We're also including some statements to clue us in to what is happening.

For a meal-guest match, the top meal is removed and the first guest leaves the queue. For a mismatch, the first guest moves to the back of the queue and the `move_queue` method is called again for the updated first guest:

```ruby
def move_queue
    view_party

    if match?
      meals.take_meal
      served = guests.leave_queue
      puts "Guest wanting a #{served} meal has been served\n\n"
    else
      guests.rejoin_queue
      puts "No one was served the last round\n\n"
      move_queue
    end
end
```

Finally, we'll create a `meal_service` method that sets everything in motion. The meal service will run until either all meals are gone, or all guests have been served. A cute "party report" is generated after the meal service concludes:

```ruby
def meal_service
    until meals.stack_empty? || guests.queue_empty?
      move_queue
    end
    puts "Meals Left: #{meals.display_meals}\nUnserved Guests: #{guests.display_queue}"
end
```

Awesome! Let's build a party with the following meals and guests:

```ruby
my_party = Party.new(%w[vegetarian vegan normal paleo], %w[normal paleo vegan vegetarian])

my_party.meal_service
```

And here's the complete file:

```ruby
class MealStack
  attr_accessor :meals
  
  def initialize(meals_array)
    self.meals = meals_array
  end

  def top_meal
    meals.last
  end

  def take_meal
    meals.pop
  end

  def stack_empty?
    meals.empty?
  end

  def display_meals
    meals.reverse.inspect
  end

  def size
    meals.length
  end
end

class GuestQueue
  attr_accessor :guests

  def initialize(guest_array)
      self.guests = guest_array
  end

  def first_guest
      guests.first
  end

  def join_queue(guest)
      guests.push(guest)
  end

  def leave_queue
      guests.shift
  end

  def rejoin_queue
      join_queue(leave_queue)
  end

  def queue_empty?
      guests.empty?
  end

  def display_queue
      guests.inspect
  end

  def size
      guests.length
  end
end

class Party
  attr_accessor :meals, :guests
  
  def initialize(meals_array, guest_array)
    self.meals = MealStack.new(meals_array)
    self.guests = GuestQueue.new(guest_array)
  end

  def view_party
    puts "Party Status:\n Meals: #{meals.display_meals}\n Guests: #{guests.display_queue}\n\n"
  end

  def match?
    meals.top_meal == guests.first_guest
  end

  def move_queue
    view_party

    if match?
      meals.take_meal
      served = guests.leave_queue
      puts "Guest wanting a #{served} meal has been served\n\n"
    else
      guests.rejoin_queue
      puts "No one was served the last round\n\n"
      move_queue
    end
  end

  def meal_service
    until meals.stack_empty? || guests.queue_empty?
      move_queue
    end
    puts "Meals Left: #{meals.display_meals}\nUnserved Guests: #{guests.display_queue}"
  end
end

my_party = Party.new(%w[vegetarian vegan normal paleo], %w[normal paleo vegan vegetarian])

my_party.meal_service
```

Here is my output after running my program's file in Terminal:

```
Party Status:
 Meals: ["paleo", "normal", "vegan", "vegetarian"]
 Guests: ["normal", "paleo", "vegan", "vegetarian"]

No one was served the last round

Party Status:
 Meals: ["paleo", "normal", "vegan", "vegetarian"]
 Guests: ["paleo", "vegan", "vegetarian", "normal"]

Guest wanting a paleo meal has been served

Party Status:
 Meals: ["normal", "vegan", "vegetarian"]
 Guests: ["vegan", "vegetarian", "normal"]

No one was served the last round

Party Status:
 Meals: ["normal", "vegan", "vegetarian"]
 Guests: ["vegetarian", "normal", "vegan"]

No one was served the last round

Party Status:
 Meals: ["normal", "vegan", "vegetarian"]
 Guests: ["normal", "vegan", "vegetarian"]

Guest wanting a normal meal has been served

Party Status:
 Meals: ["vegan", "vegetarian"]
 Guests: ["vegan", "vegetarian"]

Guest wanting a vegan meal has been served

Party Status:
 Meals: ["vegetarian"]
 Guests: ["vegetarian"]

Guest wanting a vegetarian meal has been served

Meals Left: []
Unserved Guests: []
```

YAY! Everyone was served, and our shindig was a success! But let's think for a minute: even though some of our guests had to rejoin the queue due to meal mismatches, everyone eventually got served because there was 1 meal present for every guest.

What if there was a meal on our stack that nobody wanted? Well, due to how stacks work, we can't access any meals under the unwanted meal until we get rid of said meal. However, we don't want to trash any top meal until we *know for sure* that no guests want it. That's what we'll be looking at in Part 3...