Are we asking the right question?
It would certainly be interesting to know the earliest location where we can get a monster with a given ability, but we have access to more data than that, so we could actually answer a bigger question with the same effort. How about, "what are the locations where I can get a monster with the Auto-Bravery ability, sorted from earliest to latest?" We still need to find the earliest location where a tamable monster has the Auto-Bravery ability, but we can find out more this way. We've transformed the question from a linear search through the locations from earliest to latest into a filter-and-sort query, which is easy for a database to do.This filter-and-sort query is still more complex than previous questions because we're taking into account more types of data. Instead of just filtering monsters by ability, we also need to sort them by location, and to do that sorting, we need to know the order of the locations. We do have a complete ordering in the database table because the locations were added to the table in such a way that dependent locations were added after their source locations were added. 
That's not the only valid ordering of the locations, though. Sometimes the game path forks, and in those cases the locations that both have the same source can be reached in either order. Since the locations make a tree graph with New Bodhum 003 AF at the root, we can add a depth attribute to the location table and assign each location a depth value based on how far it is away from the root. This depth value represents how many areas must be visited if we headed straight for the area in question. We could do this algorithmically, but the table only has 30 locations, so it's easy enough to assign by hand. We've added attributes to tables and views a half dozen times now, so I'll assume it's obvious how to do this and move on.
Sorting by Location Depth
Sorting by location depth isn't as hard as it may appear. We already have the filtering done between the links in the location table and the filter parameter processing in the monster controller, and we have the filtered list of monsters in the monster controller. All we have to do is sort that list by the location depth for where we can find each monster. Also, remember that a monster can be found in up to three different locations, so we're going to have to handle that detail as well. First, let's go ahead and add the sorting by location depth to the monster controller in app/controllers/monster_controller.rb:
class MonsterController < ApplicationController
  def index
    if params[:filter]
      location = Location.find_by(name: params[:filter])
      @monsters = location.location_monsters +
                  location.location2_monsters +
                  location.location3_monsters
    elsif params[:ability_filter]
      ability = Ability.find_by(name: params[:ability_filter])
      @monsters = ability.get_all_monsters.sort_by { |monster| monster.first_location_depth }
    elsif params[:skill_filter]
      ability = RoleAbility.find_by(name: params[:skill_filter])
      @monsters = ability.get_all_monsters.sort_by { |monster| monster.first_location_depth }
    else
      @monsters = Monster.all
    end
  end
  def show
    @monster = Monster.find(params[:id])
  end
endclass Monster < ApplicationRecord
  # ... A whole mess of belongs_to macros ...
  def first_location_depth
    [location&.depth, location2&.depth, location3&.depth].compact.min
  end
endWhat's Left?
Trying to automate this question of finding the strongest monsters also adds its own complications. What should we sort by, base strength, max level, or some combination of them? What if it's not what the user wants? Should we give the user the option? The solution to these questions will necessarily add complexity to the user interface that we should prefer to avoid. Side-stepping the issue and just not trying to do something for the user that is easier for them to do for themselves ends up being the better solution. We should always watch out for that simple case when designing a user interface.
Since we already have the feature of finding strong monsters in each location, the only things remaining are the two tables that we haven't connected: monster materials and monster characteristics. Monster materials is an interesting table that we can use to figure out how quickly we can level up the monsters we've tamed because we need to find the monsters that drop those materials that are used to level up our tamed monsters. However, enabling that feature is going to take a bit of work because the material table doesn't currently have the info for which monsters drop each material. We'll add that missing data and connect up that table next time.


 

No comments:
Post a Comment