GraphGists


Inspiration

I came across this post on Reddit where user /u/Bobdor posted a really awesome diagram of catchable Pokémon in the X & Y games. Click here for the high-resolution image. I encourage you to keep the diagram open in a second tab or on a second monitor so you can follow along!


Model

The graph consists of the following types of nodes:

  • Pokémon

  • Cities

  • Caves

  • Forests

  • Routes

  • Points of Interest

  • Attractions

And the following relationships:

  • CONNECTS_TO

  • CAUGHT_IN

  • HAS

The model is best illustrated through the diagram created by Bobdor:

x3V0mjw

But the relationships between nodes are summarized below:

Note that Caves, Forests, and Points of Interest are not shown in my diagram but are similar to Routes.

Attractions include things like surfing, fishing, using rock smash to find items, or whether or not the place has a Pokémon Center or gym.

The CAUGHT_IN relationship has a property catch_type that indicates what is needed for the catch, e.g., if you need to be surfing to catch the Pokémon, if catching the Pokémon requires a fishing rod, etc. These are summarized below, with descriptions from Bobdor’s map key:

catch_typeDescription
StandardStandard Catch (Bushes, Walking, etc.)
SpecialSpecial Catch (Shaking Bushes, etc.)
Shallow WaterCatchable in Shallow Water
Rock SmashCatchable Using Rock Smash
HordesCatchable in Hordes
SurfCatchable Using Surf
Old RodCatchable Fishing with an Old Rod
Good RodCatchable Fishing with a Good Rod
Super RodCatchable Fishing with a Super Rod
InteractionCatching Requires an Interaction
GiftPokémon Received as a Gift

Setup


Trip Planning

Let’s say you’ve just started the game and you’re in Vaniville Town. You’re about to set out on your journey and you want to know which Routes with wild Pokémon you will have to traverse between Vaniville Town and the nearest city or town with a Pokémon Center.

Routes with Wild Pokémon Between Vaniville Town and the Nearest City or Town with a Pokémon Center

MATCH x = shortestPath((o:City)-[*]-(a:Attraction))
WHERE o.name = "Vaniville Town" AND a.name = "Pokemon Center"
WITH NODES(x) AS stops
MATCH (p:Pokemon)-[:CAUGHT_IN]->(r:Route)
WHERE r IN stops
RETURN r.name AS `Route`, COLLECT(p.name) AS `Wild Pokemon`
ORDER BY r.name

You will encounter wild Pokémon on Routes 2 and 3 on your way from Vaniville Town to the nearest city or town with a Pokémon Center. We should also query the graph for visual directions:

Visual Directions

MATCH x = shortestPath((o:City)-[*]-(a:Attraction))
WHERE o.name = "Vaniville Town" AND a.name = "Pokemon Center"
RETURN x

With the visualization, we can see that we will pass through Aquacorde Town and Santalune Forest before we get to Santalune City, which is the nearest city or town with a Pokémon Center. We also know that Route 1 apparently has no wild Pokémon, since it was not returned in our earlier query.


Now, let’s say you’ve found your way to Lumiose City, a hub city, and can’t decide which route you should take to leave. We can find which routes leave Lumiose city, the Pokémon you can catch on each route, and the routes' destinations all in one query:

Routes Leaving Lumiose City, Catchable Pokémon on Each Route, and the Routes' Destinations

MATCH (o:City)<-[:CONNECTS_TO]-(r:Route)-[:CONNECTS_TO]->(d:City)
WHERE o.name = "Lumiose City"
WITH r, d
MATCH (p:Pokemon)-[:CAUGHT_IN]->(r)
RETURN r.name AS Route, COLLECT(p.name) AS `Catchable Pokemon`, d.name AS Destination

Now we have a better idea of what our options are.

Again, we should also query for visual directions:

Visual Directions

MATCH x = (o:City)<-[:CONNECTS_TO]-(r:Route)-[:CONNECTS_TO]->(d:City), y = (p:Pokemon)-[:CAUGHT_IN]->(r:Route)
WHERE o.name = "Lumiose City"
RETURN x, y

Finding Pokémon & More Trip Planning

Let’s say we’re not very impressed with the list of Pokémon we saw in the queries above. In fact, we have a specific Pokémon in mind: Mr. Mime. We can find all locations where a Mr. Mime can be caught and what you might need to catch it:

Find Where to Catch a Mr. Mime

MATCH (p:Pokemon)-[c:CAUGHT_IN]->(d)
WHERE p.name = "Mr. Mime"
RETURN d.name AS Destination, c.catch_type AS `Catch Type`

It looks like the only place where we can catch a Mr. Mime is Reflection Cave. Luckily, it’s a standard catch so we don’t need to bring anything special. Now, where is Reflection Cave?! How do we get there from Lumiose City?

Get Shortest Path Directions from Lumiose City to Reflection Cave

MATCH x = shortestPath((o:City)-[:CONNECTS_TO*]-(d:Cave))
WHERE o.name = "Lumiose City" AND d.name = "Reflection Cave"
RETURN EXTRACT(n IN NODES(x) | n.name) AS Directions

Visual Directions

MATCH x = shortestPath((o:City)-[:CONNECTS_TO*]-(d:Cave))
WHERE o.name = "Lumiose City" AND d.name = "Reflection Cave"
RETURN x

Now that we have our trip planned, let’s figure out what we can do along the way. If we really enjoy fishing, for example, we can find where we should stop along the way to go fishing. Specifically, let’s say we are interested in the stops between Lumiose City and Reflection Cave where we can use our Super Rod to catch Pokémon, and what these Pokémon are:

Stops Between Lumiose City and Reflection Cave Where We Can Go Fishing with a Super Rod

MATCH x = shortestPath((o:City)-[:CONNECTS_TO*]-(d:Cave))
WHERE o.name = "Lumiose City" AND d.name = "Reflection Cave"
WITH NODES(x) AS stops
MATCH (p:Pokemon)-[c:CAUGHT_IN]->(s)
WHERE c.catch_type = "Super Rod" AND (s IN stops)
WITH s, COLLECT(p.name) AS pokemon
RETURN s.name AS Stop, pokemon AS `Pokemon Catchable with a Super Rod`
ORDER BY Stop

Thus, we can plan to stop on Route 12 and in Shalour City to go fishing with our Super Rod and we know which Pokémon we can catch at each stop.

Visual Directions

MATCH x = shortestPath((o:City)-[:CONNECTS_TO*]-(d:Cave))
WHERE o.name = "Lumiose City" AND d.name = "Reflection Cave"
WITH x
MATCH y = (p:Pokemon)-[c:CAUGHT_IN]->(s)
WHERE (s IN NODES(x)) AND c.catch_type = "Super Rod"
RETURN x, y

Console

Use the console below to answer your own questions. Here are some templates to get started:

Find where you can catch a specific Pokémon and what type of catch it is

Replace POKEMON_NAME with the Pokémon’s name:

MATCH (p:Pokemon)-[c:CAUGHT_IN]->(d)
WHERE p.name = "POKEMON_NAME"
RETURN d.name AS Destination, c.catch_type AS `Catch Type`

Find all locations with a certain attraction

Replace ATTRACTION_NAME with the name of the attraction.

MATCH (d)-[:HAS]->(a:Attraction)
WHERE a.name = "ATTRACTION_NAME"
RETURN d.name AS Destination

Get shortest path directions from one place to another

Replace ORIGIN_NAME with the name of the origin City / Route / Cave / Forest / Point of Interest and replace DESTINATION_NAME with the name of the destination City / Route / Cave / Forest / Point of Interest:

MATCH x = shortestPath((o)-[:CONNECTS_TO*]-(d))
WHERE o.name = "ORIGIN_NAME" AND d.name = "DESTINATION_NAME"
RETURN EXTRACT(n IN NODES(x) | n.name) AS Directions

All Pokémon names, Attraction names, and City / Route / Cave / Forest / Point of Interest names can be found by expanding the data initilization query under Setup.


About Me