News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Generating Random Values

Started by cbjunior, October 17, 2011, 12:50:21 AM

Previous topic - Next topic

cbjunior

I created this guessing game in order to give myself an exercise in Assembly programming:

.386
.MODEL FLAT, STDCALL
OPTION CASEMAP :NONE

INCLUDE \MASM32\INCLUDE\WINDOWS.INC
INCLUDE \MASM32\INCLUDE\KERNEL32.INC
INCLUDE \MASM32\INCLUDE\MASM32.INC

INCLUDELIB \MASM32\LIB\KERNEL32.LIB
INCLUDELIB \MASM32\LIB\MASM32.LIB

.DATA
   
    GreetString BYTE "Welcome to the Guessing Game!", 0Ah, 0
    GreetStringTwo BYTE "I'm thinking of a number between 1 and 100...", 0Ah, 0
    GuessString BYTE "Guess a number between 1 and 100: ", 0
    HighString BYTE "Your guess was too high.", 0Ah, 0
    LowString BYTE "Your guess was too low.", 0Ah, 0
    RightString BYTE "You guessed the number!", 0

.DATA?

    Guess BYTE ?
    ToGuess BYTE ?

.CODE

START:

    INVOKE StdOut, ADDR GreetString
    INVOKE StdOut, ADDR GreetStringTwo

    _startGuess:
        INVOKE StdOut, ADDR GuessString
        INVOKE StdIn, ADDR Guess, 100

        INVOKE szTrim, ADDR Guess
        INVOKE atodw, ADDR Guess

        CMP eax, 23
        JA _highGuess
        JB _lowGuess

        INVOKE StdOut, ADDR RightString
        INVOKE StdIn, ADDR Guess, 100  ;; just for pausing the program before exiting
        INVOKE ExitProcess, 0

    _highGuess:
        INVOKE StdOut, ADDR HighString
        JMP _startGuess

    _lowGuess:
        INVOKE StdOut, ADDR LowString
        JMP _startGuess

END START


I was wondering if there was any way to assign ToGuess to a random value between 1 and 100, so that the line
CMP eax, 23
would become
CMP eax, ToGuess
and every time the program was executed it would be a different value.
Ash nazg durbatuluk
Ash nazg gimpatul
Ash nazg thrakatuluk
Agh burzum ishi krimpatul

Gunner

ToGuess    DWORD ?



invoke GetTickCount
invoke nseed, eax
invoke nrandom, 100
mov ToGuess, eax


Do this at the start of your app.  You can search for these functions with the search tool above
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

dedndave

 :P
        INVOKE  GetTickCount
        ror     eax,5
        mov     ecx,100
        mul     ecx
        mov     ToGuess,edx

cbjunior

I tried that before, but it always ends up screwing up the comparisons.
Ash nazg durbatuluk
Ash nazg gimpatul
Ash nazg thrakatuluk
Agh burzum ishi krimpatul

Gunner

try changing to this:
Guess byte 100 dup  (?)
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

cbjunior

It works! What exactly does that do? :eek
Ash nazg durbatuluk
Ash nazg gimpatul
Ash nazg thrakatuluk
Agh burzum ishi krimpatul

Gunner

Magic?  Look at the masm32.chm in your \masm32\help directory  a lot of good info there  :bg
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

cbjunior

Sorry, I didn't mean to sound like too much of a newbie  :lol. I understand what the actual operation does, but why does declaring Guess as an array fix the problem?
Ash nazg durbatuluk
Ash nazg gimpatul
Ash nazg thrakatuluk
Agh burzum ishi krimpatul

dedndave

it should be a dword, probably
on a 32-bit machine, everyone goes smoother with dwords   :P
but, it could be a byte, really, because your values are 100 or less
the problem is - what if the user enters 101 - or even 70000
you have no checks to make sure the byte value isn't exceeded

now, if you put a test in there that limits user entry to values 100 or below, then ToGuess could be a byte
then, using either Rob's or my random generator code, modify the last instruction to only store a byte
for mine...
        INVOKE  GetTickCount
        ror     eax,5
        mov     ecx,100
        mul     ecx
        mov     ToGuess,dl

Geryon

As you predicted it's impolisble to generate random numbers with a deterministic machine such as a computer. However some peope use " pseudorandom number generators". The result is exactly random but looks like it :P
http://en.wikipedia.org/wiki/Linear_congruential_generator
"Some people have got a mental horizon of radius zero and call it their point of view." --D.Hilbert

qWord

hi,
The following function produces 'good' values in the range 0...255:
badRandom256 proc uses esi edi
LOCAL qw:QWORD
    rdtsc
    and eax,0ffh
    push eax
    mov esi,eax
    xor edi,edi
    .while esi
        xor edi,rv(GetTickCount)
        dec esi
    .endw
    rdtsc
    pop edx
    mul edx
    xor eax,edi
    push eax
    invoke QueryPerformanceCounter,ADDR qw
    pop eax
    xor eax,DWORD ptr qw[0]
    and eax,0ffh

    ret
   
badRandom256 endp


qWord
FPU in a trice: SmplMath
It's that simple!