Question on String comparison in Inform6

I am having trouble with comparing a string in an if-clause that is itself returned from a function.

The comparing takes places here:

if (TimeOfDay() == “Dawn”) { print “The sun is rising.^”; }

The problem ist, that TimeOfDay() does not return a String like “Dawn” or “Night” but rather a number.
I can see that, if I print the returned value to the screen with “print TimeOfDay()”. Of course I can simple fix this, if I do it like this “print (string)TimeOfDay()”.

But if I try to compare the returned value of TimeOfDay() with (string) in front of it, my code won’t compile.

line 61: Error: Expected ‘)’ but found TimeOfDay

> if ((string)TimeOfDay

line 61: Warning: Logical expression has no side-effects

> if ((string)TimeOfDay() == “Dawn”)

line 61: Error: Expected ‘;’ but found )

> if ((string)TimeOfDay() == “Dawn”)

line 61: Error: Expected expression but found )

> if ((string)TimeOfDay() == “Dawn”)

line 61: Error: Expected expression with side-effects but found

> if ((string)TimeOfDay() == “Dawn”)

line 61: Error: Expected expression but found }

> if ((string)TimeOfDay() == “Dawn”) { print "The sun is rising. …etc

line 61: Error: Expected expression with side-effects but found

> if ((string)TimeOfDay() == “Dawn”) { print "The sun is rising. …etc

line 62: Error: Expected expression but found }

> else if (TimeOfDay() == “Morning”) { print "The sun has rise …etc

line 62: Error: Expected expression with side-effects but found

> else if (TimeOfDay() == “Morning”) { print "The sun has rise …etc

Compiled with 8 errors and 1 warning (no output)

Constant Story "Aventurien Time Test";
Constant Headline "^a test for showing Avanturian time in Inform6^";

Replace DrawStatusLine;

Include "Parser";
Include "VerbLib";
Include "Infglk";

Global minutes = 15;
Global hours = 5;
Global day = 12;
Global month = 5;
Global year = 998;

[ AdvanceTime;
   minutes = minutes + 15;
   if (minutes >= 60) {
      minutes = 0;
      hours++;
      if (hours >= 24) {
         hours = 0;
         day++;
         if (day > 30) {
            day = 1;
            month++;
            if (month > 12) {
               month = 1;
               year++;
            }
         }
      }
   }
];

Array month_names --> 
    "Praiosmoon" "Rondramoon" "Efferdmoon" "Traviamoon"
    "Boronmoon" "Hesindemoon" "Firunmoon" "Tsamoon"
    "Phexmoon" "Perainemoon" "Ingerimmmoon" "Rahjamoon";

Array hour_names --> 
    "Praioshour" "Rondrahour" "Efferdhour" "Traviahour"
    "Boronhour" "Hesindehour" "Firunhour" "Tsahour"
    "Phexhour" "Perainehour" "Ingerimmhour" "Rahjahour";


Object testRaum "TESTROOM"
   with description
      "This is the test room.",
   daemon [;
      AdvanceTime();
      DrawStatusLine();
      glk_set_window(gg_mainwin);
      print "TIME ", hours, " hours and ", minutes, " minutes on ", day, ". ", month, ". ", year, " BF.^";

      ! debug start
      print TimeOfDay(), "^";
      print (string)TimeOfDay(), "^";
      !debug end
      if ((string)TimeOfDay() == "Dawn") { print "The sun is rising.^"; }
        else if ((string)TimeOfDay() == "Morning") { print "The sun has risen and another day is about to begin.^"; };
       

      rtrue;
   ],
   has light;
   


[ Initialise;
   location = testRaum;   
   StartDaemon(testRaum);  
   rtrue;   
];

[ DrawStatusLine;
   glk_set_window(gg_statuswin);
   glk_window_clear(gg_statuswin);
   glk_window_move_cursor(gg_statuswin, 5, 0);
   PrintAventurianDateTime();
   glk_set_window(gg_mainwin);
];

[ PrintAventurianDateTime;
   print day, ". ", (string) month_names--> (month - 1), " ", year, " BF - ";
   print (string) hour_names-->(hours / 2), " ";
   print " (", (string) TimeOfDay(), ")";
];

[ TimeOfDay total;
   ! Convert to minutes since midnight for easy comparisons
   total = hours * 60 + minutes;
   ! Mitternacht spans 23:30 - 01:00; handle wrap-around first
   if (total >= (23*60 + 30) || total < (1*60)) return "Midnight";
   ! Nacht: 01:00 - 04:30
   if (total >= (1*60) && total < (4*60 + 30)) return "Night";
   ! Morgendämmerung: 04:30 - 06:30
   if (total >= (4*60 + 30) && total < (6*60 + 30)) return "Dawn";
   ! Morgen: 06:30 - 08:00
   if (total >= (6*60 + 30) && total < (8*60)) return "Morning";
   ! Vormittag: 08:00 - 11:30
   if (total >= (8*60) && total < (11*60 + 30)) return "Noon";
   ! Mittag: 11:30 - 13:30
   if (total >= (11*60 + 30) && total < (13*60 + 30)) return "Midday";
   ! Nachmittag: 13:30 - 16:30
   if (total >= (13*60 + 30) && total < (16*60 + 30)) return "Afternoon";
   ! Spätnachmittag: 16:30 - 18:30
   if (total >= (16*60 + 30) && total < (18*60 + 30)) return "Late Afternoon";
   ! Abenddämmerung: 18:30 - 20:00
   if (total >= (18*60 + 30) && total < (20*60)) return "Nightfall";
   ! Nacht: 20:00 - 23:30
   if (total >= (20*60) && total < (23*60 + 30)) return "Night";
   ! Fallback
   return "";
];

Include "Grammar";


The fundamental problem here is that Inform 6 does not have a string type. Any time you use a string in your program, it’s represented by a number which is converted to the address of the string constant in your z-code or Glulx file. That’s why TimeOfDay() appears to be returning a number. I believe that if you have two occurrences of the string “Dawn” in your program, they will not generally be assigned the same address, which is why your comparison (without “(string)”) doesn’t work.

It looks like you’re just using strings to represent which of a small set of values is the current time, so you should be able to do Constant DAWN 1 etc. and use those values instead of strings?

3 Likes

You may need to use constants instead of strings, for example:

Constant TOD_MIDNIGHT = 1;
Constant TOD_DAWN = 2;
! etc...

and return one of these constants.

If you want to print the time, then one way is to create a function and use a switch statement:

[ PrintMyTime tod;
    switch (tod) {
    TOD_MIDNIGHT: print "Midnight";
    TOD_DAWN: print "Dawn";
    ! etc...
    }
];
4 Likes

as jwalrus correctly says, there’s no string comparison per se built in. if you absolutely have to, you would typically do so by looping through character array ‘A’ while comparing each character to reference character array ‘B’. if you get to the end then they match.

it’s not too hard to do but andrewj’s suggestion would be faster.

1 Like

Thanks folks, andrewjs solution worked pretty well for me…
Jens

3 Likes