 
 // LOGIC FOR GEAR STUFF
 
-// Takes in photoresistor_history, which must be filled in entirely, and sets
-// gear_orientations and gear_types.
-// Returns true for success, false if there was an issue.
-boolean computeGearPositions()
-{
-  // TODO(benkraft)
+// Reads photoresistor_history[i][], which must be filled in entirely, and sets
+// gear_types[i] and gear_orientations[i].
+// Returns true for success, false if there was an issue (in which case output
+// arrays may not be set).
+boolean computeGearPosition(int i)
+{
+  // Hold on tight; this is kinda bespoke and messy.
+  int positions_white = 0;
+  for (int j=0; j<7; j++)
+  {
+    positions_white += photoresistor_history[i][j]
+  }
+
+  // If we saw 2 white, they should be in 1, 4 or 2, 5, and that means we have
+  // gear 1, in positions 2 or 1 respectively.
+  if (positions_white == 2)
+  {
+    gear_types[i] = 1;
+    if (photoresistor_history[i][1] && photoresistor_history[i][4])
+    {
+      gear_orientations[i] = 2;
+      return true;
+    }
+    else if (photoresistor_history[i][2] && photoresistor_history[i][5])
+    {
+      gear_orientations[i] = 1;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // If we saw 3 white, they should be in 0, 3, 6, and that means we have gear
+  // 1, in position 0.
+  else if (positions_white == 3)
+  {
+    if (photoresistor_history[i][0] && photoresistor_history[i][3]
+        && photoresistor_history[i][6])
+    {
+      gear_types[i] = 1;
+      gear_orientations[i] = 0;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // If we saw 3 black, they should be in 0, 3, 6, and that means we have gear
+  // 0 in position 1.
+  else if (positions_white == 4)
+  {
+    if (!photoresistor_history[i][0] && !photoresistor_history[i][3]
+        && !photoresistor_history[i][6])
+    {
+      gear_types[i] = 0;
+      gear_orientations[i] = 1;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // If we saw 2 black, we could have them in 1, 4 or 2, 5, in which case we
+  // have gear 0 in positions 0 or 2 respectively; or they could be in 0, 4 or
+  // 1, 5 or 2, 6, in which case we have gear 2 in positions 2, 1, or 0
+  // respectively.
+  else if (positions_white == 5)
+  {
+    if (!photoresistor_history[i][1] && !photoresistor_history[i][4])
+    {
+      gear_types[i] = 0;
+      gear_orientations[i] = 0;
+      return true;
+    }
+    else if (!photoresistor_history[i][2] && !photoresistor_history[i][5])
+    {
+      gear_types[i] = 0;
+      gear_orientations[i] = 2;
+      return true;
+    }
+    else if (!photoresistor_history[i][0] && !photoresistor_history[i][4])
+    {
+      gear_types[i] = 2;
+      gear_orientations[i] = 2;
+      return true;
+    }
+    else if (!photoresistor_history[i][1] && !photoresistor_history[i][5])
+    {
+      gear_types[i] = 2;
+      gear_orientations[i] = 1;
+      return true;
+    }
+    else if (!photoresistor_history[i][2] && !photoresistor_history[i][6])
+    {
+      gear_types[i] = 2;
+      gear_orientations[i] = 0;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // If we saw 1 black, it should be in 3, and we have gear 2 in position 3.
+  else if (positions_white == 6)
+  {
+    if (!photoresistor_history[i][3])
+    {
+      gear_types[i] = 2;
+      gear_orientations[i] = 3;
+      return true;
+      
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // Otherwise, something is wrong.
+  else
+  {
+    return false;
+  }
 }
 
 // True if positions pos1 and pos2 are connected on gear_num.

      {
        state = 2;
        // This fills in gear_types and gear_orientations.
        if (!computeGearPositions())
        {
          // Or should we say you failed calibration?
          sendCastleErrorMessage();
          state = 0;
          resetLights();
        }

        for (int i=0; i<7; i++)
        {
          correct_positions[i] = false;
        }
      }
    }

  // TODO(bhomberg): close all solenoids (??)
}

// Tell the user they have won!
void sendCastleSuccessMessage() 
{
  // 20's -- 2nd puzzle message
