Could you help me with this if statement?

Posted by Errigour on Tue 31 May 2011 03:32 AM — 15 posts, 47,264 views.

USA #0
This doesn't work it says error near ! line 16 which is the
if statement line


one = math.random(80)
two = math.random(80)
three = math.random(80)
four = math.random(80)
five = math.random(80)
six = math.random(80)
seven = math.random(80)
eight = math.random(80)
nine = math.random(80)
ten = math.random(80)
eleven = math.random(80)
twelve = math.random(80)
thirteen = math.random(80)
fourteen = math.random(80)
fifteen = math.random(80)
if one != two != three != four != five != sixe != seven != eight != nine != ten != eleven != twelve != thirteen != fourteen != fifteen then 
Note("bet 100 multiticket 10 ", one, " ", two, " ", three, " ", four, " ", five, " ", six, " ", seven, " ", eight, " ", nine, " ", ten, " ", eleven, " ", twelve, " ", thirteen, " ", fourteen, " ", fifteen)
do
Australia Forum Administrator #1
Hmm. Comparing not equal in Lua uses ~= rather than != (that is from C).

However you can't compare a sequence like that. I am guessing you are trying to generate 15 numbers with no repeats. This should do it:



local bets = {}

for i = 1, 15 do
  local bet
  while true do
    bet = math.random (80)
    if not bets [bet] then
      break  -- don't have him already
    end -- if
  end -- while
  bets [bet] = true
end -- for

local betline = "bet 100 multiticket 10 "

for bet in pairs (bets) do
  betline = betline .. bet .. " "
end -- for
  
print (betline)


Example output:


bet 100 multiticket 10 24 63 26 74 41 45 71 9 49 19 53 11 42 6 77 
bet 100 multiticket 10 70 50 1 54 56 43 31 32 64 10 9 40 57 49 41 
bet 100 multiticket 10 63 5 27 3 29 30 60 11 49 51 15 40 31 45 77 
bet 100 multiticket 10 48 50 70 2 26 58 28 14 18 68 6 11 57 69 52 
bet 100 multiticket 10 73 33 35 6 69 30 11 43 49 51 53 21 65 12 64 
bet 100 multiticket 10 46 25 50 70 29 69 60 9 64 19 72 11 65 23 44 
bet 100 multiticket 10 12 7 35 11 4 8 72 75 5 19 20 21 42 44 79 
bet 100 multiticket 10 77 35 27 74 56 67 47 32 5 68 20 76 1 21 43 
bet 100 multiticket 10 1 63 35 53 7 34 31 47 49 18 72 76 21 12 55 
bet 100 multiticket 10 63 7 70 57 56 43 52 3 59 6 53 55 65 69 12 

USA #2
I didn't have enough time to tell you I figured a way out.
Mines a little bit different though. If your' still
watching this post I was wondering if you could help me
with alter a string and then send the string to the mud. I
basically want to take the following code and change the
note statement to a send statement.


number = {}
function kenonumbers(number)
  local start, fin, s, f = 1, 15, 1, %2
  local t, n, a, h = 1, 15, 1 ,15
  local step, tep, ep, p = 1, 1, 1, 1
  if start > fin then step = -1 end
  if s > f then tep = -1 end
  for i = s,f,tep do
    for m = start,fin,step do
      number[m] = math.random(80)
    end
  
    if t > n then ep = -1 end  
    for x = t,n,ep do
      if a > h then p = -1 end
      for y = a,h,p do
        if number[x] == number[y] and x ~= y then
          number[x] = math.random(80)
          x, y = 1, 1
        end
      end
    end

    Note("bet", %1, " multiticket 10 ", number[1], " ", number[2], " ", number[3], " ", number[4], " ", number[5], " ", number[6], " ", number[7], " ", number[8], " ", number[9], " ", number[10], " ", number[11], " ", number[12], " ", number[13], " ", number[14], " ", number[15])
  end
end
kenonumbers(number)
USA #3
Well I'm looking at the function list for string and I think I may have found the answer I need. string.format. But I am not sure yet because I haven't tried using it to Send("") a mud command yet.
USA #4
Ok string.format works but there is still a problem with the code I used to send numbers that work. there will still be double numbers after changing the numbers array after the check.

I don't think x, y = 1, 1 restarts the loop. Do I have to make them local functions for x, y = 1, 1 to start the function at one again till math.random(80) generates all fifteen numbers that aren't the same as each other?

here is the loop that doesn't restart after assigning
x, y = 1, 1 to it

    if t > n then ep = -1 end  
    for x = t,n,ep do
      if a > h then p = -1 end
      for y = a,h,p do
        if number[x] == number[y] and x ~= y then
          number[x] = math.random(80)
          x, y = 1, 1
        end
      end
    end
USA #5
It almost works accept that the loop that makes sure there
are no random numbers has to be re run every time number[x]
and number[y] are equal and x and y are not. I can't seem
figure out how to start the loop over until all numbers are
original.

Below is the loop that I can't seem to restart
until all the numbers are original.

    if t > n then ep = -1 end  
    for x = t,n,ep do
      if a > h then p = -1 end
      for y = a,h,p do
        if number[x] == number[y] and x ~= y then
          number[x] = math.random(80)
          t, a, x, y = 1, 1, 1, 1
        end
      end
    end



Below is the entire piece of code I put together right before nick gammon gave me a smaller piece of code.

number = {}
function kenonumbers(number)
  local start, fin, s, f = 1, 15, 1, %3
  local t, n, a, h = 1, 15, 1 ,15
  local step, tep, ep, p = 1, 1, 1, 1
  if start > fin then step = -1 end
  if s > f then tep = -1 end
  for i = s,f,tep do
    for m = start,fin,step do
      number[m] = math.random(80)
    end
    if t > n then ep = -1 end  
    for x = t,n,ep do
      if a > h then p = -1 end
      for y = a,h,p do
        if number[x] == number[y] and x ~= y then
          number[x] = math.random(80)
          t, a, x, y = 1, 1, 1, 1
        end
      end
    end
    Note("bet ", %1, " multiticket ", %2, " ", number[1], " ", number[2], " ", number[3], " ", number[4], " ", number[5], " ", number[6], " ", number[7], " ", number[8], " ", number[9], " ", number[10], " ", number[11], " ", number[12], " ", number[13], " ", number[14], " ", number[15])
    Send(string.format("bet %d multiticket %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", %1, %2, number[1], number[2], number[3], number[4], number[5], number[6], number[7], number[8], number[9], number[10], number[11], number[12], number[13], number[14], number[15]))

  end
end
kenonumbers(number)
#6

  local step, tep, ep, p = 1, 1, 1, 1
  if start > fin then step = -1 end
  if s > f then tep = -1 end


You're going to hate yourself later for not differentiating the names of these variables a bit more.

It's not only bad form but I believe it breaks looping guarantees to modify looping variables inside the loop itself. That is, you the coder have no way of knowing what will happen (and it might not happen consistently over several program runs) if you modify your start, finish or indexor variables while your loop it running.

So, an easy way to fix your problem is to wrap your number selection routine with a "repeat, until" loop. Like this:


success = true
guess = -1

repeat
   guess = (make a guess)

   (loop to make sure it's unique; set "success" to false if it's not so the loop will restart)
until success


By the way, the "break" statement will leave a for loop prematurely if you find that useful.

You'll also find this function useful. Sparrows and pigeons will hate you for it because you'll destroy all of their nesting ground, but your eyes will simply fly over your code with its newfound simplicity...


function isunique(newmember, array, length)
   for i=1, length do
      if newmember == array[i] then return false end
   end

   return true
end



   numbers[1] = (make a guess)
   for i=2, 15 do
      guess = -1

      repeat
         guess = (make a guess)
      until isunique(guess, numbers, i-1)

      numbers[i] = guess
   end
Australia Forum Administrator #7
Can we stick to this thread please? You (Errigour) started a new thread just to ask people to "check your code". It is confusing to have to jump back and forwards between threads to see what you are talking about.

I moved your post into this thread.
Australia Forum Administrator #8
Errigour said:

Below is the loop that I can't seem to restart
until all the numbers are original.

    if t > n then ep = -1 end  
    for x = t,n,ep do
      if a > h then p = -1 end
      for y = a,h,p do
        if number[x] == number[y] and x ~= y then
          number[x] = math.random(80)
          t, a, x, y = 1, 1, 1, 1
        end
      end
    end



This code is very hard to read. Single-letter variables, and no comments, make us have to try to read your mind to see what your intentions are.

As for why it doesn't work. From the Programming in Lua online book:

http://www.lua.org/pil/4.3.4.html

In there it says:

Quote:

Third, you should never change the value of the control variable: The effect of such changes is unpredictable. If you want to break a for loop before its normal termination, use break.


(my emphasis).

You should not attempt to make the loop "restart" by changing the loop variables.

My method was simpler, rather than restarting the loop, you simply (for each number) have an inner loop that keeps getting random numbers until you find one that isn't used.
Australia Forum Administrator #9
By the way, Manacle was basically saying the same thing as me.

Good explanation. :)
USA #10
So then there is no way to make that loop restart from the beginning every time this if statement.

if number[x] == number[y] and x ~= y then
  number[x] = math.random(80)
end
USA #11
I would really like to know how to restart that loop above
when that if statement is called.
#12
Yes, there is.

You want to repeatstart your loop over and over again until that if statement never returns true, right?


local success = true

repeat
   number[x] = math.random(80)
   success = true  --assume that the number is unique

   for {however your for statement is set up with those variables}
      if number[x] == number[y] and x ~= y then
         success = false -- notify the repeat loop to repeat
         break
      end
   end
until success --repeat this whole loop until success is true at the end of the loop


http://www.lua.org/pil/
http://www.lua.org/pil/4.3.html
Amended on Wed 01 Jun 2011 04:43 PM by Manacle
Australia Forum Administrator #13
Errigour said:

I would really like to know how to restart that loop above
when that if statement is called.


Loops, by design, are not supposed to "restart". They start at one end and go to the other. You can however exit them early by using "break".

What was wrong with the code I posted above? That output the random numbers with no repeats.
USA #14
Nothing I just came up with some code that I was wondering if you could correct. And Manacle I'll use yours for this subject since I'm using Nick Gammons' for my numbers alias but I would really like to know if there is a way to make that function repeat or if it is just not possible.