# Help me understand this Infocom code

Have just found myself baffled by this seemingly innocuous code in Seastalker, which seems at though it ought to do the opposite of what it actually does. Clearly I am missing something:

<ROUTINE STARBOARD-OF-THORPE? (X Y)
<COND (<NOT <G? 0 <- <* ,THORPE-HLAT <- .X ,THORPE-LON>>
<* ,THORPE-HLON <- .Y ,THORPE-LAT>>>>>
<RTRUE>)
(T <RFALSE>)>>

For context, THORPE-HLAT and THORPE-HLON are integers from -1 to 1, which describe which direction Thorpe’s submarine is facing. South and west are -1, and north and east are 1, in latitude and longitude respectively, with 0 meaning the submarine is perpendicular to that particular axis. THORPE-LON and THORPE-LAT are what they look like, and this routine would usually be called with the player’s own longitude and latitude as arguments.

Now, I observe:

1. The expression <- .X ,THORPE-LON> is positive if the player is to the east of Thorpe and negative if they are to the west.

2. The expression <- .Y ,THORPE-LAT> is positive if the player is to the north of Thorpe and negative if they are to the south.

3. The expression <* ,THORPE-HLAT <...>> reverses the sign of the included expression if the submarine is facing south, and similarly the expression <* ,THORPE-HLON <...>> reverses the sign if the submarine is facing west.

4. However, the expression <* ,THORPE-HLON <...>> is the subtrahend in a subtraction operation, and we can think of this as one more sign reversal. If Thorpe is facing northwest (which he is at the start) and we are to the northeast of him, the core operation <- <* ,THORPE-HLAT <...>> <* ,THORPE-HLON <...>>> is effectively the addition of two positive numbers.

5. If Thorpe is facing northwest and we are to the northeast of him, we are to starboard of Thorpe. If we were to the southwest of him, we would be to port of Thorpe.

6. As we have seen, the central operation necessarily produces a positive number if Thorpe is facing northwest and we are northeast of him. If Thorpe is facing northwest and we are southwest of him, it would necessarily produce a negative number.

7. This routine returns false if the central operation produces a positive number. It returns true if the central operation produces a negative number. (I don’t care about the zero case at the moment.) Therefore this routine must return false if we are to starboard of Thorpe and true if we are to port of Thorpe.

8. Except the above is wrong, because if you play the compiled game it is easy to verify that the routine returns true if you are to starboard of Thorpe and false if you are to port of him, as the name of the routine would suggest.

I must be misunderstanding something, but I genuinely can’t tell what.

If I understand correctly, I think this might be where you go wrong. I guess you might either have overlooked the NOT or you might have read “G? 0 EXPRESSION” as something like “greater-than-zero? EXPRESSION”.

But “G? OP1 OP2” is to be understood as “is OP1 greater than OP2?”, so “G? 0 EXPRESSION” evaluates to true if 0 is greater than EXPRESSION, so “NOT (G? 0 EXPRESSION)” will evaluate to false if 0 is greater than EXPRESSION, i.e. if EXPRESSION is negative; whereas it will evaluate to true otherwise.

Sorry if I’m overlooking something in turn, but that’s my impression after an admittedly cursory look.

3 Likes

Doh! This isn’t even the first time the G? operator has tripped me up. Thanks for the help!

1 Like

Yeah, I think this is an occasion where the prefix notation unfortunately trips people up easily (me too, almost), because it just jumps quite naturally into the mind as “greater-than zero …”.

1 Like

I analyzed before as well (put into a wiki). The formula used by the routine calculates the difference between two products (First is the Seacat’s heading latitude times the longitude distance from the Seacat to the Sub. Second is the Seacat’s heading longitude times the latitude distance from the Seacat to the Sub.). In an expanded form:

(Sub Lon - Seacat Lon) * Seacat Lat Heading - (Sub Lat - Seacat Lat) * Seacat Lon Heading

If this value is positive or zero, then the Sub is starboard to the Seacat. Another way of viewing this is:

Seacat Lat Heading     (Sub Lat - Seacat Lat)
------------------  ?  ----------------------
Seacat Lon Heading     (Sub Lon - Seacat Lon)

Each fraction calculates a slope. So if the slope of the Seacat heading vector is bigger than the slope of the vector to the Sub, then the Sub is on the starboard side of the Seacat.

1 Like