how to randomize the assigned values of an array in x86

Started by jhang, September 30, 2011, 12:23:19 PM

Previous topic - Next topic

jhang

this code runs properly, but we just want to randomize the values of the array1, so that the when the player wants a new game , new set of pairs will be available..




%include "asm_io.inc"

segment .data
title      db   "         -oOo- PAIRS II -oOo-   ", 0   
partition   db   "********************************************************************************", 0
instruct   db   "Instructions: ", 0
instruct1   db   "The squares are arranged row-wise on the grid and are numbered from 0 to 15.", 0
instruct2   db   "To choose the square you want to open, indicate its number (refer to legend).", 0
instruct3   db   "Find every (number) pattern's pair in the grid.", 0
ready      db   "Are you ready?", 0
new_game    db    "To play, press [1].",0
quit_game   db   "To quit, press any key.", 0
choice      db   "Choice: ", 0
open_square    db    "Enter square number: ", 0
legend      db   "      Legend: ", 0
grid      db   "      Pairs: ", 0
invalid_input   db   "Invalid input. The squares range from 0 to 15.", 0
repeat_input   db   "You already chose this number.", 0
opened_input   db   "You already opened this square.", 0
pick_again   db   "Choose another square.", 0
win_prompt   db   "         -oOo-    YOU WIN!    -oOo-", 0
congrats   db   "           -oOo-   CONGRATULATIONS!  -oOo-", 0   

row_sep      db      "          +----+----+----+----+",0
col_sep0   db   "         |  ", 0
col_sep    db    " |  ",0

legend_r1   db   "         |  0 |  1 |  2 |  3 |", 0
legend_r2   db   "         |  4 |  5 |  6 |  7 |", 0
legend_r3   db   "         |  8 |  9 | 10 | 11 |", 0
legend_r4   db   "         | 12 | 13 | 14 | 15 |", 0

array0      dd   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
array1      dd   3,8,1,8,4,7,2,5,1,2,6,5,7,4,3,6
array2      dd   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
checker      dd   0
counter      dd   0

segment   .bss
input1      resd 1
input2      resd 1

segment   .text
   global    asm_main

asm_main:
   enter   0, 0
   pusha

   call    print_nl
   mov    eax, title
   call    print_string
   call    print_nl
   call    print_nl
   mov    eax, instruct
   call    print_string
   call    print_nl
   mov    eax, instruct1
   call    print_string
   call    print_nl
   mov    eax, instruct2
   call    print_string
   call    print_nl
   mov    eax, instruct3
   call    print_string
   call    print_nl
   mov    eax, ready
   call    print_string
   call    print_nl
   call    print_nl   
   mov    eax, new_game
   call    print_string
   call    print_nl
   mov    eax, quit_game
   call    print_string
   call    print_nl
   call    print_nl
   mov    eax, choice   
   call    print_string
   call    read_int
   call    print_nl

   cmp    eax, 1
   jne   quit
   push   dword array0
   call   print_table
   add   esp, 4

fir_choice:
   mov    eax, open_square
   call    print_string
   call    read_int
   mov   [input1], eax   
   cmp   dword [array2+4*eax], 1            ;functions as a boolean, 1 if true, 0 if false. 1 means the square is opened.
   jne   f_allowed
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   mov   eax,opened_input
   call   print_string
   call   print_nl
   mov   eax, pick_again
   call   print_string
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl   
   jmp   fir_choice

f_allowed:
   mov   eax, [input1]
   cmp   eax, 0
   je   square_zero
   cmp   eax, 1
   je   square_one
   cmp   eax, 2
   je   square_two
   cmp   eax, 3
   je   square_three
   cmp   eax, 4
   je   square_four
   cmp   eax, 5
   je   square_five
   cmp   eax, 6
   je   square_six
   cmp   eax, 7
   je   square_seven
   cmp   eax, 8
   je   square_eight
   cmp   eax, 9
   je   square_nine
   cmp   eax, 10
   je   square_ten
   cmp   eax, 11
   je   square_eleven
   cmp   eax, 12
   je   square_twelve
   cmp   eax, 13
   je   square_thirteen
   cmp   eax, 14
   je   square_fourteen
   cmp   eax, 15
   je   square_fifteen
   call   print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   mov   eax, invalid_input
   call   print_string
   call   print_nl
   mov   eax, pick_again
   call   print_string
   call   print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   jne    fir_choice

square_zero:
   mov   eax, 0
   cmp   eax,[checker]            ;checks if this is the first input or second input
   jne   square_zerosec
   mov   eax, [array1]
   mov   [array0], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker], 1         ;adds 1 to checker to signify that first input has already a value
   jmp   sec_choice
square_zerosec:
   mov   eax, [array1]
   mov   [array0], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_one:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_onesec
   mov   eax, [array1+4]
   mov   [array0+4], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_onesec:
   mov   eax, [array1+4]
   mov   [array0+4], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_two:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_twosec
   mov   eax, [array1+8]
   mov   [array0+8], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_twosec:
   mov   eax, [array1+8]
   mov   [array0+8], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_three:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_threesec
   mov   eax, [array1+12]
   mov   [array0+12], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_threesec:
   mov   eax, [array1+12]
   mov   [array0+12], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_four:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_foursec
   mov   eax, [array1+16]
   mov   [array0+16], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_foursec:
   mov   eax, [array1+16]
   mov   [array0+16], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_five:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_fivesec
   mov   eax, [array1+20]
   mov   [array0+20], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_fivesec:
   mov   eax, [array1+20]
   mov   [array0+20], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_six:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_sixsec
   mov   eax, [array1+24]
   mov   [array0+24], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_sixsec:
   mov   eax, [array1+24]
   mov   [array0+24], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_seven:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_sevensec
   mov   eax, [array1+28]
   mov   [array0+28], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_sevensec:
   mov   eax, [array1+28]
   mov   [array0+28], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_eight:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_eightsec
   mov   eax, [array1+32]
   mov   [array0+32], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_eightsec:
   mov   eax, [array1+32]
   mov   [array0+32], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_nine:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_ninesec
   mov   eax, [array1+36]
   mov   [array0+36], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_ninesec:
   mov   eax, [array1+36]
   mov   [array0+36], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_ten:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_tensec
   mov   eax, [array1+40]
   mov   [array0+40], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_tensec:
   mov   eax, [array1+40]
   mov   [array0+40], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_eleven:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_elevensec
   mov   eax, [array1+44]
   mov   [array0+44], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_elevensec:
   mov   eax, [array1+44]
   mov   [array0+44], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_twelve:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_twelvesec
   mov   eax, [array1+48]
   mov   [array0+48], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_twelvesec:
   mov   eax, [array1+48]
   mov   [array0+48], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_thirteen:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_thirteensec
   mov   eax, [array1+52]
   mov   [array0+52], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_thirteensec:
   mov   eax, [array1+52]
   mov   [array0+52], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_fourteen:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_fourteensec
   mov   eax, [array1+56]
   mov   [array0+56], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_fourteensec:
   mov   eax, [array1+56]
   mov   [array0+56], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

square_fifteen:
   mov   eax,0
   cmp   eax,[checker]
   jne   square_fifteensec
   mov   eax, [array1+60]
   mov   [array0+60], eax
   push   dword array0
   call   print_table
   pop   ecx
   mov   dword [checker],1
   jmp   sec_choice
square_fifteensec:
   mov   eax, [array1+60]
   mov   [array0+60], eax
   push   dword array0
   call   print_table
   pop   ecx
   jmp   compare

sec_choice:
   mov    eax, open_square
   call    print_string
   call    read_int
   cmp   eax,15
   jg   not_allowed
   mov   [input2], eax
   mov   ebx, [input1]
   cmp   eax, ebx
   jne   allowed
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   mov   eax, repeat_input
   call   print_string
   call   print_nl
   mov   eax, pick_again
   call   print_string
   call   print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   jmp   sec_choice

not_allowed:
   call   print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   mov   eax, invalid_input
   call   print_string
   call   print_nl
   mov   eax, pick_again
   call   print_string
   call   print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   jmp   sec_choice

allowed:
   mov   eax,[input2]
   cmp   dword [array2+4*eax],1
   jne   s_allowed
   call   print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   mov   eax, opened_input
   call   print_string
   call   print_nl
   mov   eax, pick_again
   call   print_string
   call   print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   call    print_nl
   jmp   sec_choice

s_allowed:   
   mov   eax, [input2]
   cmp   eax, 0
   je   square_zero
   cmp   eax, 1
   je   square_one
   cmp   eax, 2
   je   square_two
   cmp   eax, 3
   je   square_three
   cmp   eax, 4
   je   square_four
   cmp   eax, 5
   je   square_five
   cmp   eax, 6
   je   square_six
   cmp   eax, 7
   je   square_seven
   cmp   eax, 8
   je   square_eight
   cmp   eax, 9
   je   square_nine
   cmp   eax, 10
   je   square_ten
   cmp   eax, 11
   je   square_eleven
   cmp   eax, 12
   je   square_twelve
   cmp   eax, 13
   je   square_thirteen
   cmp   eax, 14
   je   square_fourteen
   cmp   eax, 15
   je   square_fifteen

compare:
   mov   dword [checker], 0
   mov   eax, [input1]
   mov   eax, [array0+4*eax]
   mov   ebx, [input2]
   mov   ebx, [array0+4*ebx]
   cmp   eax, ebx

   je   pairs
   mov   eax,[input1]
   mov   dword [array0+4*eax],0         ;returns the value to zero if they are not pairs
   
   mov   eax,[input2]
   mov   dword [array0+4*eax],0
   jmp   fir_choice

pairs:
   mov   eax,[input1]
   mov   dword [array2+4*eax],1
   mov   ebx,[input2]
   mov   dword [array2+4*ebx],1

   add   dword [counter], 1         ;counts the number of pairs created   
   mov   eax, [counter]
   cmp   eax, 8
   jne   cont
   call   print_nl
   call   print_nl
   call   print_nl
   call   print_nl
   call   print_nl
   mov   eax, win_prompt
   call   print_string
   call   print_nl
   mov   eax, congrats
   call   print_string
   call   print_nl
   call   print_nl
   call   print_nl
   call   print_nl
   call   print_nl
   jmp   quit

cont:
   mov   dword [checker], 0
   jmp   fir_choice

quit:
   popa
   leave
   ret

print_table:
   enter   0,0
   push   ebp
   mov   ebp, esp

   mov   eax, partition
   call    print_string
   call   print_nl
   mov   eax, legend
   call    print_string
   call   print_nl
   mov   eax, row_sep
   call    print_string
   call   print_nl
   mov   eax, legend_r1
   call    print_string
   call   print_nl
   mov   eax, row_sep
   call    print_string
   call   print_nl
   mov   eax, legend_r2
   call    print_string
   call   print_nl
   mov   eax, row_sep
   call    print_string
   call   print_nl
   mov   eax, legend_r3
   call    print_string
   call   print_nl
   mov   eax, row_sep
   call    print_string
   call   print_nl
   mov   eax, legend_r4
   call    print_string
   call   print_nl
   mov   eax, row_sep
   call    print_string
   call   print_nl
   call   print_nl

   mov   eax, grid
   call    print_string
   call   print_nl   
   mov    eax, row_sep
   call    print_string
   call   print_nl
   mov    eax, col_sep0
   call    print_string

   mov   ebx, [ebp+12]
   mov   eax,[ebx]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax,[ebx+4]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+8]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+12]
   call   print_int
   mov   eax, col_sep
   call   print_string
   call   print_nl
   
   mov    eax, row_sep
   call    print_string
   call   print_nl
   mov    eax, col_sep0
   call    print_string

   mov   eax, [ebx+16]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+20]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+24]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+28]
   call   print_int
   mov   eax, col_sep
   call   print_string
   call   print_nl

   mov    eax, row_sep
   call    print_string
   call   print_nl
   mov    eax, col_sep0
   call    print_string

   mov   eax, [ebx+32]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+36]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+40]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+44]
   call   print_int
   mov   eax, col_sep
   call   print_string
   call   print_nl

   mov    eax, row_sep
   call    print_string
   call   print_nl
   mov    eax, col_sep0
   call    print_string

   mov   eax, [ebx+48]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+52]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+56]
   call   print_int
   mov   eax, col_sep
   call   print_string
   mov   eax, [ebx+60]
   call   print_int
   mov   eax, col_sep
   call   print_string
   call   print_nl

   mov    eax, row_sep
   call    print_string
   call   print_nl
   call   print_nl
   
   pop   ebp
   pop   ebp
   ret

hutch--

jhang,

If you have the current version of MASM32, have a look at the example "sa.asm" which has the following algorithm in it.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

shuffle_array proc arr:DWORD,cnt:DWORD

    LOCAL lcnt  :DWORD

    mov eax, cnt            ; copy cnt to lcnt
    mov lcnt, eax

    push ebx
    push esi
    push edi

    mov esi, arr
    mov edi, arr
    xor ebx, ebx

  @@:
    invoke nrandom, cnt     ; get the random number within "cnt" range
    mov ecx, [esi+ebx*4]    ; get the incremental pointer
    mov edx, [edi+eax*4]    ; get the random pointer
    mov [esi+ebx*4], edx    ; write random pointer back to incremental location
    mov [edi+eax*4], ecx    ; write incremental pointer back to random location
    add ebx, 1              ; increment the original pointer
    sub lcnt, 1             ; decrement the loop counter
    jnz @B

    pop edi
    pop esi
    pop ebx

    ret

shuffle_array endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤


The "nrandom" procedure is in the MASM32 library. This is basically a card shuffling algorithm but you can use if for any count you like.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jhang

hutch,

thanks.. but i'm using NASM because this is what we are using in class.. i'm just hoping that there's anyone here knows or have any idea about assembly code using NASM..

i appreciated your help. thanks again ;)

hutch--

You should be able to code a similar algorithm in NASM but the advantage is this type of algo is both very simple and very fast. You need an external random algo that performs OK but the basic idea is to swap pairs starting from the beginning of the array and swapping each item with a randomly selected second item. Its a standard way to shuffle cards in a pack but it can be used to randomise any array for purposes like building balanced trees.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

#4
for a simple random generator, you can use the lower bits of QueryPerformanceCounter or GetTickCount and scale the output (or RDTSC, i suppose)

EDIT:
if you give us some criteria, we can show better examples:

1) what is the range of values ?
2) may values be repeated ?
3) anything else that describes behviour

in the list you show, i see values 1-8 with repeats

juzi


RandNum proc uses ecx edx num1:dword,num2:dword

rdtsc ; rdtsc needs .586
mov ecx,num2
sub ecx,num1
inc ecx
xor edx,edx
div ecx
add edx,num1
mov eax,edx
ret

RandNum endp
not native English speaker, sorry for my English, hope you understand what I'm saying.

dedndave

well - you can use RDTSC once during program initialization to seed the generator
after that, you shouldn't need it any more - it really isn't random by itself