首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在组件中同时生成2个随机整数

在组件中同时生成2个随机整数
EN

Stack Overflow用户
提问于 2020-06-09 22:01:56
回答 1查看 315关注 0票数 2

背景

函数rollCubes在一个棋盘游戏的每回合中滚动2个立方体。

问题

运行时:rollCubes总是返回2-2, 4-46-6

编辑

调试时(在turbo debugger__中执行每一行):函数设法生成两个不同的随机整数,但多维数据集1从未滚动。

这让我想知道,在运行可执行文件时,是什么阻止了rollCubes产生随机整数。

源码

代码语言:javascript
复制
proc rollCubes
    xor cx, cx
    mov [hicube], 0 
    mov [locube], 0
    mov cx, 2
    addAgainHigh:
        ; Random number [0, 3] --> two rolls [0, 6]
        mov ax, 40h
        mov es, ax
        mov ax, es:6Ch ;Random number
        and al, 00000011b
        cmp al, 0 ;Make sure al isn't 0
        je addAgainHigh ;If 0, roll again
        add [hicube], al ;add to cube value
        loop addAgainHigh
    mov cx, 2
    addAgainLow:
    ; Random number [0, 3] --> two rolls [0, 6]
        mov ax, 40h
        mov es, ax
        mov ax, es:6Ch
        and al, 00000011b
        cmp al, 0
        je addAgainLow
        add [locube], al
        loop addAgainLow
    mov al, [locube]
    mov ah, [hicube]
    ret 
endp rollCubes
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-14 21:48:48

您的代码读取一些数字(BIOS.Timer),并且只保留可能值{1,2,3}的子集。重复之后,你得到{2,3,4,5,6}。你永远不能以这种方式滚动1

一卷骰子应该产生一个从1到6的数字。

代码语言:javascript
复制
call myRandom    ; -> AX = [0,65535]
xor  dx, dx
mov  cx, 6
div  cx          ; -> Remainder DX = [0,5]
inc  dx          ; -> Dice is [1,6]
...

; IN () OUT (ax)
proc myRandom
    imul ax, [NextRandom], 25173
    add  ax, 13849
    xor  ax, 62832
    mov  [NextRandom], ax
    ret
endp myRandom

这个myRandom proc中的代码是一个伪随机数发生器,它将在重复之前产生65536个唯一的16位数字。它很快就会输出相同的数字。

当我运行上面的代码80次(NextRandom从0开始)时,我得到了掷骰子的数字:

代码语言:javascript
复制
4,5,6,1,2,3,2,3,4,3, 2,3,6,5,6,3,4,3,4,1
6,5,6,5,4,3,6,1,2,5, 4,5,2,3,6,5,2,1,6,3
6,3,6,3,2,3,2,1,2,5, 2,1,2,3,4,1,6,5,4,1
4,5,4,5,4,1,2,1,2,3, 6,3,6,1,4,1,6,3,6,1

这些数字的分布情况很好:

代码语言:javascript
复制
1 ~ 13
2 ~ 13
3 ~ 16
4 ~ 12
5 ~ 11
6 ~ 15

编辑

运行时: rollCubes总是返回2-2、4-4或6-6。这让我想知道,在运行可执行文件时,是什么原因阻止了rollCubes生成随机图。

线性地址0040h:006Ch处的BIOS.TimerTick每55 ms递增一次。这在计算机中是很长的时间,而且由于您的rollCubes过程连续4次快速读取计数器(),您几乎总是从它得到相同的值。

这是大多数情况下发生的情况:

  • 如果TimerTick碰巧以00b结尾 addAgainHigh: 00b重读直到它变为01b 01b=1 hicube =0+1+1=2 addAgainLow: 01b=1蝗虫=0+1+1=2
  • 如果TimerTick碰巧以01b结尾 addAgainHigh: 01b=1 hicube =0+1+1=2 addAgainLow: 01b=1蝗虫=0+1+1=2
  • 如果TimerTick碰巧以10b结尾 addAgainHigh: 10b=2 hicube =0+2+2=4 addAgainLow: 10b=2蝗虫=0+2+2=4
  • 如果TimerTick碰巧以11b结尾 addAgainHigh: 11b=3 hicube =0+3+3=6 addAgainLow: 11b=3蝗虫=0+3+3=6

在调试(在turbo调试器中执行每一行):时,该函数设法按原样生成随机滚动

事实上,不再存在快速继承的问题了!从Turbo内部执行程序需要时间。线性地址0040h:006Ch的BIOS.TimerTick (很可能)在从程序读取之间增加了。

调试时(在turbo调试器中执行每一行):该函数设法生成随机滚动,这应该是

不怎么有意思!正如我在最早的回答中所说,你永远不能这样滚动1。

由于您的程序抛出了零,下面是代码通过加法组合这两个集合{1,2,3}所能产生的所有和:

代码语言:javascript
复制
1 + 1 = 2
1 + 2 = 3
1 + 3 = 4
2 + 1 = 3
2 + 2 = 4
2 + 3 = 5
3 + 1 = 4
3 + 2 = 5
3 + 3 = 6

请注意,通过这种方式,这些数字的概率非常不同。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62292592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档