Author Topic: Randomnize table ?  (Read 125 times)

MetalZelda

  • Hero Member
  • *****
  • Posts: 518
    • View Profile
Randomnize table ?
« on: December 10, 2017, 02:31:53 pm »
Hello

Today I am mostly programming minigames, one of which is based on ALTTP.
But, I have taken another view of how the minigame would work.
Winnable items are shown before the game starts like so



Then a movement starts on winnable item's entity and the minigame starts.

This leads me to this question to make the minigame more dependant of an RNG (Random Number Generator) to make the minigame a bit more difficult
Winnable items are stored in a table

Code: Lua
  1. local minigame_prices = {
  2.   {"rupee", 0},
  3.   {"amber_counter", 0},
  4.   {"green_chuchu_counter", 0},
  5.   {"heart_piece", 0},
  6.   {"arrow", 0},
  7.   {"rupee", 3},
  8.   {"heart", 0},
  9.   {"rupee", 5},
  10.   {"rupee", 2},
  11. }

Basically, it is

[chest 1] treasure = rupee, variant = 0

All I want is

[chest (random 1 - 9)] treasure = rupee, variant = 0

Any idea of how to make it happen ?
« Last Edit: December 10, 2017, 02:34:51 pm by MetalZelda »

Diarandor

  • Hero Member
  • *****
  • Posts: 814
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Randomnize table ?
« Reply #1 on: December 10, 2017, 05:13:24 pm »
That depends on what you want to do.

1) If you want to show only the treasure of the chest you opened and not the others, then you only need a random number between 1 and #minigame_prizes (remember to rename your list "minigame_prices" to "minigame_priZes", because it's not the same thing). You can use:
Code: [Select]
local index = math.random(1, #minigame_prizes)
local prize = minigame_prizes[index]

2) If you want to show where all prizes are after you open the chest, then you need to code a random permutation. I would use the "Knuth shuffles" permutation algorithm (it is very simple and the code is short); you can adapt the code from here:
https://en.wikipedia.org/wiki/Random_permutation
You can either permute the prizes list directly, or permute a list with numbers from 1 to #minigame_prizes and then use the permuted indices list to associate the prizes to the corresponding chests.

We all enjoy games with chests. Does that mean we are all perverts?  :o
“If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you.”

MetalZelda

  • Hero Member
  • *****
  • Posts: 518
    • View Profile
Re: Randomnize table ?
« Reply #2 on: December 10, 2017, 05:33:28 pm »
That depends on what you want to do.

1) If you want to show only the treasure of the chest you opened and not the others, then you only need a random number between 1 and #minigame_prizes (remember to rename your list "minigame_prices" to "minigame_priZes", because it's not the same thing). You can use:
Code: [Select]
local index = math.random(1, #minigame_prizes)
local prize = minigame_prizes[index]

2) If you want to show where all prizes are after you open the chest, then you need to code a random permutation. I would use the "Knuth shuffles" permutation algorithm (it is very simple and the code is short); you can adapt the code from here:
https://en.wikipedia.org/wiki/Random_permutation
You can either permute the prizes list directly, or permute a list with numbers from 1 to #minigame_prizes and then use the permuted indices list to associate the prizes to the corresponding chests.

We all enjoy games with chests. Does that mean we are all perverts?  :o

Yes, that's the way I wanna go
I did found some workaround by setting a random treasure at chest opening sequence

Code: Lua
  1. -- Define what happen when the player tries to open a chest
  2. -- Since chests are empty (no treasure), that makes things easier
  3. for chests in map:get_entities_by_type("chest") do
  4.   chests.on_opened = function()
  5.     if minigame_state == "end" then
  6.       sol.audio.play_sound("error")
  7.       game:start_dialog("minigame.chest.need_pay", function()
  8.         sol.audio.play_sound("objects/minecart/landing")
  9.         chests:set_open(false)
  10.         hero:unfreeze()
  11.       end)
  12.     else
  13.       local rng = math.random(1, #minigame_prizes)
  14.       rng = minigame_prizes[rng]
  15.  
  16.       local treasure, variant, savegame = rng[1], rng[2], rng[3]
  17.       hero:start_treasure(treasure, variant + 1, savegame, function()
  18.         game:start_dialog("minigame.chest.finished")
  19.       end)
  20.       minigame_state = "end"
  21.      
  22.     end
  23.   end
  24. end

I don't know if there's a better way to do so, since rng only applies when the choosen chest has been opened
Oh well, it does what I wanted

Y'all love chests chest is love chest is life :o
« Last Edit: December 10, 2017, 05:39:52 pm by MetalZelda »

Diarandor

  • Hero Member
  • *****
  • Posts: 814
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Randomnize table ?
« Reply #3 on: December 10, 2017, 05:46:42 pm »
Remember to initialize a random seed once, and only once (the recommended way is to use the time as seed). This could be done in your main script.
“If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you.”