Script-Problem: How do I create random menu items?

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

Post Reply
User avatar
marionline
Metal Slime
Posts: 673
Joined: Sat Feb 26, 2011 9:23 pm

Script-Problem: How do I create random menu items?

Post by marionline »

Good evening!

I'd appriciate some help and hints how to write a plotscript that creates a menu.
The menu items should be ordered randomly.

I try to use globals to keep track of how much of the menu is filled, because there is no arrays.
This is how far I got:

Code: Select all

   
global variable (0,random1_used) # keeps track id slot 1 is filled with a menu 
global variable (1,random2_used)
global variable (2,random3_used)
global variable (3,random4_used)
global variable (5,random_used_counter) # keeps tack how many of the globals from 0-3 are set

plotscript, test2, begin 
    variable(mymenu, mi, slot)
    mymenu := open menu(1)
 
    variable(c)
    c := 0

    # Do I need to add the menu handles extra like this? 
    # Or are they created futher down in the for loop already?
    while&#40; c < 4&#41; do&#40; 
        add menu item&#40;mymenu&#41;
        c&#58;=c+1
    &#41;
    variable&#40;i&#41;
    i &#58;= 0
    while&#40;read global&#40;5&#41; < 4&#41; do &#40;
        
        # choose a position
        variable &#40;choice, pos_choice&#41;
        pos_choice &#58;= random&#40;1, 5&#41;
        i&#58; = i+1
        
        # menu item handles as variables
        variable&#40;mi1, mi2, mi3, mi4&#41;
        
        if &#40;&#40;pos_choice == 1&#41; AND &#40;read global&#40;0&#41; == FALSE&#41;&#41; then &#40;  
            $1 = "one"
            mi1 &#58;= menu item by true slot&#40;mymenu, 1&#41;
            set menu item caption&#40;mi1, 1&#41;
            set menu item type&#40;mi1, menutype&#58;label&#41;
            set menu item bit&#40;mi1, menu item bit&#58;Close menu when selected&#41;
            set menu item togtag&#40;mi1, 3&#41;
            &#41; 
        else if &#40;&#40;pos_choice == 2&#41; AND &#40;read global&#40;1&#41; == FALSE&#41;&#41; then &#40; 
            $2 = "two"
            mi2 &#58;=  menu item by true slot&#40;mymenu, 2&#41;
            set menu item caption&#40;mi2, 2&#41;
            set menu item type&#40;mi2, menutype&#58;label&#41;
            set menu item bit&#40;mi2, menu item bit&#58;Close menu when selected&#41;
            set menu item togtag&#40;mi2, 3&#41;
            &#41; 
        else if &#40;&#40;pos_choice == 3&#41; AND &#40;read global&#40;2&#41; == FALSE&#41;&#41; then &#40;
            $3 = "three"
            mi3 &#58;= menu item by true slot&#40;mymenu, 3&#41;
            set menu item caption&#40;mi3, 3&#41;
            set menu item type&#40;mi3,menutype&#58;label&#41;
            set menu item bit&#40;mi3, menu item bit&#58;Close menu when selected&#41;
            set menu item togtag&#40;mi3, 3&#41;
            &#41; 
        else if &#40;&#40;pos_choice == 4&#41; AND &#40;read global&#40;3&#41; == FALSE&#41;&#41; then &#40; 
            $4 = "four"
            mi4 &#58;= menu item by true slot&#40;mymenu, 4&#41;
            set menu item caption&#40;mi4, 4&#41;
            set menu item type&#40;mi4,menutype&#58;label&#41;
            set menu item bit&#40;mi4, menu item bit&#58;Close menu when selected&#41;
            set menu item togtag&#40;mi4, 3&#41;
            &#41; 
        else &#40; 
           #nothing
           &#41;

        # count how  many are set&#58;
        write global&#40;5, 0&#41;  # set global 5 to 0
        variable &#40;myvar&#41;

        if &#40;read global&#40;0&#41; == 0&#41; then &#40;
            myvar &#58;= read global&#40;5&#41; 
            myvar &#58;= myvar + 1
            show value &#40;myvar&#41;
            write global&#40;5, myvar&#41;
            write global&#40;0, TRUE&#41;
            &#41;

        if &#40;read global&#40;1&#41; == 0&#41; then &#40;
            myvar &#58;= read global&#40;5&#41; 
            myvar &#58;= myvar + 1
            show value &#40;myvar&#41;
            write global&#40;5, myvar&#41;
            write global&#40;1, TRUE&#41;
            &#41; 

        if &#40;read global&#40;2&#41; == 0&#41; then &#40;
            myvar &#58;= read global&#40;5&#41; 
            myvar &#58;= myvar + 1
            show value &#40;myvar&#41;
            write global&#40;5, myvar&#41;
            write global&#40;2, TRUE&#41;
            &#41; 

        if &#40;read global&#40;3&#41; == 0&#41; then &#40;
            myvar &#58;= read global&#40;5&#41; 
            myvar &#58;= myvar + 1
            write global&#40;5, myvar&#41;
            write global&#40;3, TRUE&#41;
            &#41;              
        show value &#40;myvar&#41;
    &#41;   
end
What happens is that the first time the script is triggered it shows a menu with severly slots, only one of them displaying test. :(
The next time I start the script no text at all is displayed, I guess, I still need to reset some values after the menu is close.

Can you help me fix this script?
Is there an easier way to create random menus (for "choose the right answer"-type of questions)?

Thanks in advance for your help! :)
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Oops, I overlooked this thread.

The reason you saw only one menu item with text is that at the bottom of the script you set all the global variables random1_used - random4_used to true, so that all the "read global(X) == FALSE" checks at the top of the script will be false from then on.

Why are you using global variables? You have just the one script, which is only called once, so there is no use to using globals, but maybe you wanted to read those globals in another script. Why are you using "read global" and "write global"? There is no point doing that in this script, it just creates a mess. Only use read/write global when you don't know which global the code will operate on, otherwise use the name of the global.

If you want to rearrange the items in a menu randomly here is the easy way. I recommend defining the menu in Custom because creating menus with script commands is tedious. But since you already have code to create a menu, you can use that. Then after opening or creating the menu, run this "randomise menu" script:

Code: Select all

# We forgot to add a command to get the number of menu items!
script, menu item count, menu, begin
  variable&#40;num, item&#41;
  item &#58;= first menu item&#40;menu&#41;
  while &#40;item&#41; do &#40;
    num += 1
    item &#58;= next menu item&#40;item&#41;
  &#41;
  return&#40;num&#41;
end

# This script randomly rearranges the items in the top menu
plotscript, randomise menu, begin
  variable&#40;i, j, last, mi1, mi2&#41;
  last &#58;= menu item count&#40;top menu&#41; -- 1
  for &#40;i, 0, last&#41; do &#40;
    j &#58;= random&#40;i, last&#41;
    mi1 &#58;= menu item by true slot&#40;top menu, i&#41;
    mi2 &#58;= menu item by true slot&#40;top menu, j&#41;
    swap menu items&#40;mi1, mi2&#41;
  &#41;
end
I've tested this script and discovered that there is a bug in swap menu items which causes this script to not work very well. It still randomises the menu items a bit, but not completely randomly. You can get a complete mix by running the script say 5 times in a row. I'll try to fix that bug soon.
User avatar
marionline
Metal Slime
Posts: 673
Joined: Sat Feb 26, 2011 9:23 pm

Post by marionline »

Hey TMC.
Thanks a lot for your help! :D

Qhen I decided to write the script I was thinking about registries and bits, something like this: "Why are there no arrays?" And then I told myself that computers do not have arrays in first place, and one could program array-like-behavior. . . I should have realized, i do not need global variables, thanks for pointing that out. :o

I couldn't really figure out how to make your scripts run, how to use them.
Just making a menu by plotscript was difficult for me... So, I guess I should change my plans and try something more easy, like creating some non-randomized menus in the editor (and randomly choose them) or something like this.

(( Still, I would suggest to add some easy examples on menus (with some comments) to either the wiki or inside the plotscripting dictionary. ))

And thanks again for your help! :)
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

To use it, assuming you've created a menu in the editor, just do this:

Code: Select all

plotscript, test2, begin
  open menu&#40;1&#41;  # change menu id here

  # repeat a few times to mix well
  randomise menu
  randomise menu
  randomise menu
  randomise menu
  randomise menu
end
Yes, the plot dictionary could always do with more examples, or we could put fleshed out examples on the wiki and link to them from the dictionary. It would be nice to have an 'overview' example for each topic of the wiki.
Last edited by TMC on Wed Jun 22, 2016 4:10 am, edited 2 times in total.
Post Reply