Non repeatable strings (code example here)

I’m having trouble with…
appling loops to game Xperience

The error I’m getting is:…

Well Its not like a error. Is more a ask for input…

I’ve been coding a snipet that grants you the Ability to generate ‘arrays’ of no repeatable letters. I’m asking for you opinion about how to use this solution in a game. For example. I evision this kind of code as a way for, at the begin of each game, a set of scenes would be sorted.

Each scene will an independent event that must occur just once in each session. My idea is that way you can add replayability to your game.

Other thing I was thinking is a set of events. Both good or bad. That is sorted into a pile and each time a certain point of the game you “pull” one event from this pile and shove it at the user. Surprise! You got a random non repeatable event. (probably there is easier ways to do that kind of thing using choicescript… )

Thoughts?

link : https://dashingdon.com/go/2943

My code looks like this:

Startup.txt:

 *title Test_code
*author Victor Silva
*comment your code goes here

*scene_list
  startup
  
*comment =========== Variables ==========

*create Attrib0 1
*create Attrib1 1
*create Attrib2 "@"
*create Attrib3 ""

*create var_int 0







This is a test for my code. It will generate a sequence of non repeatable letters in an 'array'.

*label init

Please enter the size of your 'array' (1-10)

*input_number var_int 1 10

*gosub_scene routines draw1

so…

Is this good?

*choice
  #yes.
    *goto fill
  #No.
    *goto init
    
*label fill

Now, let's fill it with ${var_int} nom repeatable values!

*choice
  #DO IT!
    
    *if (var_int=1)
      *gosub_scene routines gen_letter
      *set Attrib3 (Attrib3&Attrib2)
      *goto label3
    *else
      *gosub_scene routines for_each2
      *goto label3


*label label2
*gosub_scene routines gen_letter

*label label3

The generated sequence is 
*gosub_scene routines draw2

String: ${Attrib3}



So that's it! Now if you please can help-me with ideas for using or implementing its use in choicescripting… I already have a couple ideas, for example, we could use that for sorting which cards were draw in a card game were each card is unique and can not be draw twice in the same hand. Or perhaps a "table" of events were each event is sorted to occur in a random order but without repeating in each iteration… thoughts?




*finish  

routines.txt:


*comment cap_stats is a sub routine that receive a number and writes one "star" *for_each value pick Attrib1 devolve into Attrib2.

*label cap_stats
*set Attrib0 0
*set Attrib2 ""
*gosub for_each
*return

*label for_each
*if (Attrib0 < Attrib1)
  *set Attrib2&"* "
  *set Attrib0 +1
  *goto for_each
*return





*label for_each2

*if (length(Attrib3)<var_int)
  *gosub gen_letter
  *gosub init_loop3
  *gosub for_each2
  *return
*else
  *return

*return

    
*label init_loop3
*if (length(Attrib3)>0)
  *set Attrib0 1
  *gosub for_each3
  *return

*else
  *set Attrib3 (Attrib3&Attrib2)
  *return
  
*return
    




*comment ==============================================
*comment =================== Test! ====================
*comment ==============================================
*comment 
*comment Atrib3 has the random event letters by now.

*label for_each3

*if (Attrib0<=length(Attrib3))
    *gosub do_while_2
    *return
*else
  *return
    
    
    
    
    
    
    
*comment do_while_2 checks if a value is already sorted.
 
*label do_while_2


*if ((Attrib3#Attrib0)=Attrib2)
  Ops, thats a repeat! (erasing letter)
  *page_break
  *gosub init_loop1
  *gosub init_loop3
  *return
*else
  *set Attrib0 +1
  *if (Attrib0<=(length(Attrib3)))
    *gosub do_while_2
    *return
  *else
    *set Attrib3 (Attrib3&Attrib2)
    *return
  *return
TESTDEBUG do_While_2: ${Attrib3}
*return














*comment This is a funny code for non-repeat generation
*comment ==============================================
*comment =================== Test! ====================
*comment ==============================================

*comment generate random non repeated letters
*label gen_letter




*label init_loop1
*comment this '*if' breaks the loop

*comment *if (Attrib0>var_int)
*comment   *return    

*temp die 0
*temp letter ""

*rand die 1 15

*if (die = 1 )
  *set letter "a"
  
*if (die = 2 )
  *set letter "b"

*if (die = 3 )
  *set letter "c"

*if (die = 4 )
  *set letter "d"

*if (die = 5 )
  *set letter "e"

*if (die = 6 )
  *set letter "f"

*if (die = 7 )
  *set letter "g"

*if (die = 8 )
  *set letter "h"
  
*if (die = 9 )
  *set letter "i"

*if (die = 10 )
  *set letter "j"

*if (die = 11 )
  *set letter "k"

*if (die = 12)
  *set letter "l"

*if (die = 13)
  *set letter "m"

*if (die = 14)
  *set letter "n"

*if (die = 15 )
  *set letter "o"

*set Attrib2 letter

Test Letter generated: ${Attrib2}


*return

Test: ${Attrib3}

*goto init_loop1




*label do_while_1

*if (aux < var_int)
  
  [b]position_${aux}[/b],
  
  *set aux +1
  *gosub do_while_1
  *return
*if (aux = var_int)
  
  [b]position_${aux}[/b]
  
  ];
  *return


*comment === draw1 ===
*comment is a nice little thing it 
*comment simply 'draw' a array in the
*comment browseru-desu

*label draw1

*if (var_int > 0)
  My_array = [  
  *if (var_int = 1)
    
    [b]position_1[/b] 
    
    ];
    *return
  *else
    
    [b]position_1[/b],
    
  *temp aux 2
  *gosub do_while_1
  *return
  
  
*label draw2
*if (var_int=1)
  My_Array = [ [b]$!{(Attrib3#Attrib0)}[/b] ]
  *return
  
My_Array = [
*set Attrib0 1
*label draw2_loop

*if (var_int > Attrib0)
  
  [b] $!{(Attrib3#Attrib0)}[/b], 
  *set Attrib0 +1
  *gosub draw2_loop
  *return
*else
  [b]$!{(Attrib3#Attrib0)}[/b] 
  ];
  *return
*return
1 Like

That makes my head spin.

Here’s how I would make random non-repeatable events:

*create event0 false
*create event1 false
*create event2 false
*create event3 false
*create event4 false
*create random_event 0

...

*label new_event

*rand random_event 0 4

*if (random_event = 0)
  *if (event0 = false)
    *set event0 true
    *gosub_scene event0
    *finish
  *else
    *goto new_event

*if (random_event = 1)
  *if (event1 = false)
    *set event1 true
    *gosub_scene event1
    *finish
  *else
    *goto new_event

*if (random_event = 2)
  *if (event2 = false)
    *set event2 true
    *gosub_scene event2
    *finish
  *else
    *goto new_event

*if (random_event = 3)
  *if (event3 = false)
    *set event3 true
    *gosub_scene event3
    *finish
  *else
    *goto new_event

*if (random_event = 4)
  *if (event4 = false)
    *set event4 true
    *gosub_scene event4
    *finish
  *else
    *goto new_event

It’s super boring, but it’s pretty clear what’s happening!

(by the way, it’d crash if you do it six times, so I would also probably include an *if statement for if all the events have already triggered, as well).

Another way I can think of, not sure if it would actually work:

*create cards 0
*create opponent_cards 0
*create card_name ""
*create opponent_card_name ""
...

*label new_game
*rand cards 0 53
*gosub assign_cards

You've just drawn the ${card_name}! Do you think you have a higher card than your opponent?

*choice
  # Yes!
    *if (cards > opponent_cards)
      You win!
      *goto play_again
    *else
      Eat shit! Your opponent drew the ${opponent_card_name}!
      *goto play_again
  # No! Fold!
    You get nothing.
    *goto play_again

*label play_again
Play again?
*choice
  # Yes.
    *goto new_game
  # No.
    *finish

*label assign_cards
*rand opponent_cards 0 53
*if (cards = opponent_cards)
  *goto assign_cards
*if cards = 0
  *set card_name "Ace of Spades"
...
*if opponent_cards = 0
  *set opponent_card_name "Ace of Spades"
...
*return

A bit laborious to do all the card name strings, but you’d have to do that for your version as well. Mine’s just a simple check of whether the two cards drawn are the same. I think trying to code more complex games like poker or crazy eights or whatever is probably a bad idea in ChoiceScript.

4 Likes

Thanks for the feedback Will. Sorry the messy cody. You see I was trying to use a ‘for each’ likey using the gosub loops of choicescript. That’s why I create a scene named ‘routines’ believe or not, I did this way because sounded a good idea at the time meh.

You first example does the same thing with much less complexity… he he

I did like your second example. Code a game like black jack must be possible in choicescript but… yeah that would be a nightmare of a code… But the idea of a card minigame inside a choicescript game do sounds interesting for me, even if a simplified one. Or a well of fortune perhaps… hummm

You should check out Missing Wings when it comes out! Apparently it has some card game minigames :slight_smile:

2 Likes

@Nahim_Kerman @will I realize I had to solve a similar problem for my games, I wanted to share the solution hoping it’s useful (2 years later :grinning:). BTW, I am still amazed by the complexity of Missing Wings, it would be cool to hear from @Carlos.R how he achieved some of his tricks.

Anyway, the idea is not too complex: you create the ordered list, scan it, possibly swapping an event with a random one from what follows. See below in my own CS metalanguage.

Algorithm outline, 25 lines
*define MAX 20
*array list MAX
*create num_to_alpha "abcdefghijklmnopqrstuvwxyz"

*for i 0 MAX
  *set list[i] num_to_alpha#(i+1)
  
*temp dieroll  
*for i 0 MAX
  *rand dieroll (i) (MAX-1)
  *gosub swap i dieroll
  
*comment This shows the final list.
*for i 0 MAX
  ${list[i]}

*finish

*label swap
*params swap_from swap_to
*temp buffer list[swap_from]
*set list[swap_from] list[swap_to]
*set list[swap_to] buffer
*return

Unfortunately, to do it for real you have to manually create every array entry, and simulate the loop with a goto. It becomes this confusing thing.

Generated Choicescript, 69 lines
*create list_0 0
*create list_1 0
*create list_2 0
*create list_3 0
*create list_4 0
*create list_5 0
*create list_6 0
*create list_7 0
*create list_8 0
*create list_9 0
*create list_10 0
*create list_11 0
*create list_12 0
*create list_13 0
*create list_14 0
*create list_15 0
*create list_16 0
*create list_17 0
*create list_18 0
*create list_19 0
*create num_to_alpha "abcdefghijklmnopqrstuvwxyz"

*comment Generated loop with *for command, line 5: *for i 0 20
*temp i 0
*label loop_999
*if i >= 20
  *goto done_999
*set list[i] num_to_alpha#(i+1)

*set i + 1
*goto loop_999 
*label done_999
*comment End of loop, line 7
*temp dieroll  
*comment Generated loop with *for command, line 9: *for i 0 20
*temp i 0
*label loop_1000
*if i >= 20
  *goto done_1000
*rand dieroll (i) (20-1)
*gosub swap i dieroll

*set i + 1
*goto loop_1000 
*label done_1000
*comment End of loop, line 12
*comment Generated loop with *for command, line 14: *for i 0 20
*temp i 0
*label loop_1001
*if i >= 20
  *goto done_1001
${list[i]}
*set i + 1
*goto loop_1001 
*label done_1001
*comment End of loop, line 16
*finish

*label swap
*params swap_from swap_to
*temp buffer list[swap_from]
*set list[swap_from] list[swap_to]
*set list[swap_to] buffer
*return
  


*finish



1 Like

All of this could hypothetically be made much easier if you knew Javascript and could divine how *script actually works…

Let me know if you can figure that out! I can learn Javascript easily enough but I really don’t quite understand how the Choicescript tie-in is supposed to function.

Yes, it’s much shorter. If you want to use *script to replace the central part, concatenate all this in one line.

*script for (var i =0; i< MAX; i ++) {
   var dice = Math.floor(i + Math.random() * (MAX - i));
   var tmp = this.stats["list_" + i];
   this.stats["list_" + i] = this.stats["list_" + dice];
   this.stats["list_" + dice] = tmp;
 }

The idea is that CS variables are all visible as this.stats[“name”] (or this.stats.name).

3 Likes

Is this syntax actually working for you or are you using it on one line? Because any function that line breaks gives me an error.

Yes, you would have to concatenate everything on one line. In other words:

*create MAX 20
*script for (var i =0; i< MAX; i ++) {var dice = Math.floor(i + Math.random() * (MAX - i)); var tmp = this.stats["list_" + i]; this.stats["list_" + i] = this.stats["list_" + dice]; this.stats["list_" + dice] = tmp;}

If it still doesn’t work, feel free to post the error here or in a private message.

2 Likes

Yes that was what I was wondering. Im already familiar how any JS stuff works on one line. I just noticed you mentioned that before but I just didn’t read it properly, sorry.

1 Like

Have a look at Game of Set for an application.