Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB6 > Неправильная работа exe


Автор: neiron 29.4.2007, 23:09
Написал незатейливую программулину... 
Есть форма, есть классмодуль, есть файл ресурсов, есть обычный модуль.

На форме поле 10*10. Каждая клетка в зависимости от значения объекта в массиве имеет определёный рисунок. 
При этом в форме происходит прорисовка, в классмодуле по сути ничего интересного не происходит, в ьодуле происходит следующее:

Код

Option Explicit
Dim i As Integer, j As Integer, k As Integer

Const ColKl As Integer = 50
Public Gr(1 To ColKl, 1 To ColKl) As New Ground

Public Sub Generation()
Dim per As Double
Randomize Timer
    For i = 1 To ColKl
        For j = 1 To ColKl
            Gr(i, j).X = i
            Gr(i, j).Y = j
            per = Rnd(1)
            If per < 0.25 Then
                Gr(i, j).GrType = 2    
                Gr(i, j).DopType = Int(Rnd(1) * 3) + 1
                Select Case Gr(i, j).DopType
                    Case 1
                        Gr(i, j).DobMet = 0
                        Gr(i, j).DobGl = 0
                        Gr(i, j).DobFor = 25
                        Gr(i, j).DobZer = 0
                    Case 2
                        Gr(i, j).DobMet = 25
                        Gr(i, j).DobGl = 0
                        Gr(i, j).DobFor = 0
                        Gr(i, j).DobZer = 0
                    Case 3
                        Gr(i, j).DobMet = 0
                        Gr(i, j).DobGl = 0
                        Gr(i, j).DobFor = 0
                        Gr(i, j).DobZer = 25
                End Select
            Else
                If per < 0.65 Then
                    Gr(i, j).GrType = 1 
                    Gr(i, j).DopType = Int(Rnd(1) * 10) + 1
                        Gr(i, j).DobZer = CByte(Rnd(1) * 8)
                        Gr(i, j).DobMet = CByte(Rnd(1) * (18 - Gr(i, j).DobZer) / 2)
                        Gr(i, j).DobGl = CByte(Rnd(1) * (18 - Gr(i, j).DobZer - Gr(i, j).DobMet) * 2 / 3)
                        Gr(i, j).DobFor = 18 - Gr(i, j).DobZer - Gr(i, j).DobMet - Gr(i, j).DobGl
                Else
                    Gr(i, j).GrType = 0     
                    Gr(i, j).DopType = 1
                    Gr(i, j).DobMet = 4
                    Gr(i, j).DobGl = 4
                    Gr(i, j).DobFor = 4
                    Gr(i, j).DobZer = 6
                End If
            End If
        Next j
    Next i
End Sub


В общем, создаётся массив 50*50 объектов моего класса. Рэндомно определяются свойства. 

В чём проблема (быть может зря так много расписывал):
запускаю из среды: всё работает как надо - рэндомная генерация, правильное отображение клеток на форме.
делаю экзешник, запускаю - 
Gr(i, j).GrType = 1 только для первого столбца массива. Т.е. в только Gr(1, n) может иметь GrType равный единице, при этом не все объекты первого столбца имеют GrType=1... Соответствено, неправильно отображаются клетки... 
В чём может быть беда?

Автор: neiron 29.4.2007, 23:56
Вместо if...end if заюзал select...end select и всё заработало как надо.
Кто-нибудь может сказать в чём дело было?

Автор: Tectoder 30.4.2007, 09:43
neiron, к слову, соврешенно незачем передавать в Rnd все время число 1 этим ты только "ухудшаешь" случайность чисел. Ты, вероятно, полагаешь что 1 - это верхняя граница для rnd? Нет, это совсем другое.

Автор: neiron 30.4.2007, 10:11
Tectoder, насколько я помню из школьного курса QB, 1 как раз определяет предел... Или быть может нам неправильно объясняли... Но её оттуда у меня привычка ставить везде rnd(1)... Прочитал доки:

Цитата

Если параметр number        То функцией Rnd генерируется 
Меньше нуля       Каждый раз одно и то же число, при этом аргумент number используется как начальное значение. 
Больше нуля        Следующее случайное число в последовательности. 
Равно нулю          Последнее сгенерированное случайное число. 
Не задается         Следующее случайное число в последовательности. 



Примечания
Функция Rnd возвращает значение, которое меньше единицы, но больше или равно нулю.

Cпособ генерации случайного числа в функции Rnd определяется значением параметра number:

Для любого заданного начального числа генерируется одна и та же последовательность чисел, поскольку при каждом последующем вызове в функции Rnd при генерации следующего числа последовательности в качестве начального используется ранее сгенерированное число.

Перед вызовом Rnd для инициализации генератора случайных чисел с начальным значением на основе системного таймера воспользуйтесь оператором Randomize без указания аргументов.


Т.е. как я понимаю задавать 1 или оставлять пустым без разницы... Но если это плохо, то тогда надо 0 задавать? И что это даст?
Стартовое число получается всегда 1... Но из-за Randomize Timer (как я понимаю, можно просто randomize?) принцип генерации всё время разный, т.е. тут тогда вообще нет смысла ставить какой-либо аргумент в rnd()?



ЗЫ. Извиняюсь за 2 вопроса в одной теме, но всё же))

Автор: Tectoder 30.4.2007, 12:43
Цитата(neiron @  30.4.2007,  10:11 Найти цитируемый пост)
т.е. тут тогда вообще нет смысла ставить какой-либо аргумент в rnd()?
Да, просто rnd() и все
Цитата(neiron @  30.4.2007,  10:11 Найти цитируемый пост)
как я понимаю, можно просто randomize?
Да
Цитата(neiron @  30.4.2007,  10:11 Найти цитируемый пост)
Т.е. как я понимаю задавать 1 или оставлять пустым без разницы
Глянул в MSDN и прадва, значение большее нуля игнорируется. Короче, лучше писать просто rnd без параметров

Автор: neiron 30.4.2007, 22:09
Нет, ну не зря же придумывали параметр... Видимо, где-то когда-то он применяется? Кто-нибудь знает где и когда?

И что же всё-таки с if и selecct case? В чём причина ошибки?

Автор: bom 1.5.2007, 10:58
Цитата(neiron @  1.5.2007,  01:09 Найти цитируемый пост)
 не зря же придумывали параметр...  где-то когда-то он применяется? Кто-нибудь знает где и когда?

Я знаю кто это может быть.

Обычный чел, каждый день ходит на неинтересную, выматывающую работу, помогает выносить мусор соседям по лестничной клетке, а ночью, устав от трудов праведных, спит, сидя у домашнего компа, положив голову на клавиатуру вместо подушки. Знания, информация беспрепятственно, неконтролируемо перетекают из клавы непосредственно в моск нашего кролика, находящегося в безсознательном состоянии. 
Так продолжалось какое то время, пока согласно глобальным законам, количество не переросло в качество. Не написав ни строчки кода, не прочитав ни страницы мануала, он становится Избранным. Теперь ему известно все и подвластно - все!


Сорри за оффтоп, навеяно известным фильмом smile
Открыл учебник и скопировал тебе следующую инфу:
Код

Синтаксис

Rnd[(число)]

Необязательный аргумент число представляет значение типа Single или любое допустимое числовое выражение.

Возвращаемые значения

Если число:     Rnd возвращает:

Меньше нуля     Каждый раз одно и то же число, используя аргумент число в качестве опорного числа.
Больше нуля     Следующее случайное число в последовательности.
Равняется нулю     Случайное число, возвращенное при предыдущем вызове этой функции.
Не указано     Следующее случайное число в последовательности.

Дополнительные сведения

Функция Rnd возвращает значение, меньшее 1 и большее или равное нулю.
Аргумент число определяет способ генерации случайного числа функцией Rnd:
При использовании одинаковых опорных чисел получаются одинаковые последовательности случайных чисел, поскольку при генерации каждого следующего члена последовательности используется предыдущий член.
Перед вызовом функции Rnd используйте инструкцию Randomize без аргумента для инициализации генератора случайных чисел значением, возвращаемым системным таймером.

Ниже приведена формула, предназначенная для получения случайных целых чисел в заданном диапазоне:

Int((верхняяГраница - нижняяГраница+ 1) * Rnd + нижняяГраница)

Здесь верхняяГраница представляет максимальное число в диапазоне, а нижняяГраница минимальное число в диапазоне.

Примечание.   Для повторения последовательности случайных чисел следует вызвать функцию Rnd с отрицательным аргументом сразу после использования инструкции Randomize с числовым аргументом.  Повторное использование инструкции Randomize с тем же числовым аргументом не приведет к повторению предыдущей последовательности случайных чисел.

Автор: neiron 1.5.2007, 22:22
bom, хм... и?

если аргумент меньше 0, то последовательность будет типа 
0.34363 0.34363 0.34363 0.34363 0.34363 0.34363 
если ставить Randomize 1 всегда

а если =0? Будет возвращено число вызванное именно в этой строчке ранее? или вообще хоть где в коде? 
Ничего не понимаю(с)  smile 


И в чём всё же тайна if...select?)))

Автор: bom 2.5.2007, 03:22
Цитата(neiron @  2.5.2007,  01:22 Найти цитируемый пост)
хм... и?

По моему, там все понятно написано... Не знаю, что и как тут можно еще дополнительно разжевывать.
Создай процедуру типа:
Код

Private Sub Command1_Click()
Debug.Print Rnd(число)
End Sub

и долби ее, меняя число, до полного просветления.



Автор: Tectoder 2.5.2007, 11:51
Или вообще, нажми Ctrl+L и напиши там 
Код
? rnd(2)
 smile 

Автор: neiron 2.5.2007, 12:17
теперь понятно))) спасибо

и что же всё же с главным вопросом темы?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)