Building & Scripting > Scripting Board

A room counter

(1/2) > >>

erwin:
Suppose you want to give a player a challenge to explore the entire zone, and tell the player how many rooms he or she has yet to find. This is not easy to script, because a zone with 100 rooms might necessitate 100 (different) flags on the player.

It is possible to make a script (using the following outline shown) to reduce the worst case scenario of the number of flags to {Number of rooms /2} by considering the vnums in binary. However, it might be possible to reduce this number further - unfortunately I don't know what (other) commands I can use in scripting.

Therefore, here is a test case by considering vnums in base 10. While this is inefficient (it's not in base 2), the outline of the code is relatively easier to follow.

I would also like to know whether it's possible to create for loops in scripts - then the following code can be further compacted.

I have resorted to a hack - putting this as a room enter trigger, so this necessitates that *every* room have this trigger. Ideally, I'd like to have this trigger on an object in the player's inventory - so that if the player moves, then the object will trigger, and tally the number of rooms.

If anyone has any suggestions for improvements, or any shortcuts which I have overlooked, do post here, so everyone can benefit :)


--- Code: ---*Code works like this:
*Every 10vnums are grouped together, from 00-09, 10-19, 20-29, .., 90-99
*Flags are labelled africanexplored0, africanexplored1, .. africanexplored99
*But if you have a group of 10, say africanexplored0, .. africanexplored9
*then you'll get the flag africanexploredtens0 (the tens0 denotes the tens
*position as 0). So here, the worst case scenario is the player gets 9 of each
*group, and has 90 extra flags. The 91st flag would mean the player completes
*one group of 10, and hence reduce the number of flags from 90 to 81.
*Of course, we can group 2 vnums together, to reduce the worst case scenarion
*to 50. I think this can be even reduced further, but I'm not sure what
*commands I'm able to use.

*For the code below, you can see I've only been using "if" statements, as
*I'm not sure if for loops, etc exists.

if %actor.is_pc%
if !%actor.varexists(africanexploredall)%
*The flag africanexploredall means you've been to all the rooms
*So suppose you haven't
eval NUM %actor.room.vnum%
eval ABSNUM %NUM% -33700
                *We want the last two digits of the vnum - we're assuming the zone has 100 rooms, and given zone 337
eval TENS %ABSNUM%/10
                *We want the digit in the 10s place
eval TENSVAR africanexploredtens%TENS%
                *Create the variable which corresponds to the 10sdigit
eval ABSNUMVAR africanexplored%ABSNUM%
                *Create the variable which corresponds to the last two digits of the vnum
%echo% My room number is %NUM%
%echo% My tens is %TENS%
%echo% I belong to %TENSVAR%
%echo% and %ABSNUMVAR%
%echo% My absolute number is %ABSNUM%
*TENS will be from 00-09
if  !%actor.varexists(%TENSVAR%)% && !%actor.varexists(%ABSNUMVAR%)%
%echo% I haven't been in this room yet%
set %ABSNUMVAR% 1
remote %ABSNUMVAR% %actor.id%
                                *Put your room counter here and make it increase by 1
endif
*check per 10 rooms
                        *A for loop would be nice here (needless to say, for binary case
                        *it's somewhat easier as we can look at %NUM%/2, %NUM%+1/2
                        *etc)
eval T1 %TENS% * 10
eval T1VAR africanexplored%T1%
eval T2 %T1% + 1
eval T2VAR africanexplored%T2%
eval T3 %T1% + 2
eval T3VAR africanexplored%T3%
eval T4 %T1% + 3
eval T4VAR africanexplored%T4%
eval T5 %T1% + 4
eval T5VAR africanexplored%T5%
eval T6 %T1% + 5
eval T6VAR africanexplored%T6%
eval T7 %T1% + 6
eval T7VAR africanexplored%T7%
eval T8 %T1% + 7
eval T8VAR africanexplored%T8%
eval T9 %T1% + 8
eval T9VAR africanexplored%T9%
eval T10 %T1% + 9
eval T10VAR africanexplored%T10%
%echo% My 10 variables are
%echo% %T1VAR%
%echo% %T2VAR%
%echo% %T3VAR%
%echo% %T4VAR%
%echo% %T5VAR%
%echo% %T6VAR%
%echo% %T7VAR%
%echo% %T8VAR%
%echo% %T9VAR%
%echo% %T10VAR%
if %actor.varexists(%T1VAR%)% && %actor.varexists(%T2VAR%)% && %actor.varexists(%T3VAR%)% && %actor.varexists(%T4VAR%)% && %actor.varexists(%T5VAR%)% && %actor.varexists(%T6VAR%)% && %actor.varexists(%T7VAR%)% && %actor.varexists(%T8VAR%)% && %actor.varexists(%T9VAR%)% && %actor.varexists(%T10VAR%)%
%echo% I've been in a set of 10 rooms
%echo% so I'm adding %TENSVAR% to me
%echo% Check to see I have this
set %TENSVAR% 1
remote %TENSVAR% %actor.id%
rdelete %T1VAR% %actor.id%
rdelete %T2VAR% %actor.id%
rdelete %T3VAR% %actor.id%
rdelete %T4VAR% %actor.id%
rdelete %T5VAR% %actor.id%
rdelete %T6VAR% %actor.id%
rdelete %T7VAR% %actor.id%
rdelete %T8VAR% %actor.id%
rdelete %T9VAR% %actor.id%
rdelete %T10VAR% %actor.id%
endif
*check all rooms
if %actor.varexists(africanexploredtens0)% && %actor.varexists(africanexploredtens1)% && %actor.varexists(africanexploredtens2)% && %actor.varexists(africanexploredtens3)% && %actor.varexists(africanexploredtens4)% && %actor.varexists(africanexploredtens5)% && %actor.varexists(africanexploredtens6)% && %actor.varexists(africanexploredtens7)% && %actor.varexists(africanexploredtens8)% && %actor.varexists(africanexploredtens9)%
%echo% If I am triggered, I have explored everywhere
%echo% Check to see if I have the complete flag!
set africanexploredall 1
remote africanexploredall %actor.id%
rdelete africanexploredtens0 %actor.id%
rdelete africanexploredtens1 %actor.id%
rdelete africanexploredtens2 %actor.id%
rdelete africanexploredtens3 %actor.id%
rdelete africanexploredtens4 %actor.id%
rdelete africanexploredtens5 %actor.id%
rdelete africanexploredtens6 %actor.id%
rdelete africanexploredtens7 %actor.id%
rdelete africanexploredtens8 %actor.id%
rdelete africanexploredtens9 %actor.id%
endif
endif
endif

--- End code ---

Now, it just suffices to put a counter whenever the player enters a new room to increase the rooms explored by 1! Tada!

erwin:
I can bring this down to 2-3 flags in worst case scenario, as opposed to 50 flags - I have the outline of the script (hint - it uses the charat function), so I'll do it in the weekend. Here's a short exercise for all of you.

Q1: What is the maximum string length a flag can hold? [5 marks]
Q2: Suppose a zone has seven rooms. Using the string 1100011, we can say that the first 2 rooms have been explored, the next three rooms have not, and the last two have. With this idea, write code to improve the previous script for the worse case scenario of flags [20 marks]

Jaros:
loops:
while %var%
  < blah >
done

eval flag 0000000...000  * 110 digits.  I don't know what the max length of a flag is but i suspect it is more than 110.

eval tens %self.room.vnum.charat(4)%
eval tens_check 100 + %tens%
eval ones %self.room.vnum.charat(5)%
eval ones_check %tens% * 10 + %ones%
if %flag.charat(%tens_check%)% == 0 && %flag.charat(%ones_check%)% == 0
  %echo% this room is new to me
  eval i 1
  eval newflag
  while %i% < 101
    if %i% == %ones_check%
      eval digit 1
    else
      eval digit %flag.charat(%i)%
    end
    eval newflag %newflag%%digit%
    eval i %i% + 1
  done
  eval flag %newflag%
end

plus another loop in there to check if all the ones in the relevant 10-digit bracket == 1 and if so set the tens place (100 + tens) to 1.

are you doing something like that?

erwin:
My script would be just putting the flag

0000..0000000

on the player.

When the relevant room, say k is entered, we'll check if the kth position is a 0 or a 1.

If it is a 0, we change it to a 1. Update counter by 1.

This is the problem I have. How do we change the kth position of a flag? eg, suppose I have the flag value 123, and I want to change it to 143. Apart from adding 20 to it, how do I change the 2 to a 4?

Furthermore, expressions like 10^2 isn't recognized - the output will be 10^2 instead of 100, so even a workaround by adding would be a pain.[/i]

If the kth position is a 1, check if the flag is 111..1111.

If it is 111....111, we give player a new flag - explored, and delete the messy 111...111 flag.

I'll look through the above script later when I'm at the office.

Jaros:
The while loop in that script above builds a new flag the same as the old one updated at k.  I'm pretty sure something like that could be made to work.  You could use another loop if k == 1 to check the digits from tens*10 to tens*10+9.  If they all == 1, build a new flag updated at tens_check position.

Not ideal having to loop through ~100 characters every time you want to update the flag but I'm not sure how else you could do it.  I don't think there's a way to change a character at an index?  Does anyone know if there is?

Navigation

[0] Message Index

[#] Next page

Go to full version