首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在python中生成超出范围的随机数

在python中生成超出范围的随机数
EN

Stack Overflow用户
提问于 2015-11-23 01:30:19
回答 1查看 2.4K关注 0票数 18

我目前正在开发一个pygame游戏,我需要在屏幕上随机放置对象,除非它们不能在指定的矩形内。有没有一种简单的方法可以做到这一点,而不是不断地生成一对随机的坐标,直到它在矩形之外?

这里有一个粗略的例子,展示了屏幕和矩形的样子。

代码语言:javascript
复制
 ______________
|      __      |
|     |__|     |
|              |
|              |
|______________|

其中屏幕尺寸为1000x800,矩形为x: 500,y: 250,width: 100,height: 75

一种更面向代码的方式来看待它

代码语言:javascript
复制
x = random_int
0 <= x <= 1000
    and
500 > x or 600 < x

y = random_int
0 <= y <= 800
    and
250 > y or 325 < y
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-23 01:43:24

在这些约束下生成一个均匀的随机点需要一些思考。我能想到的最简单的暴力方式是生成所有有效点的列表,并使用random.choice()从该列表中进行选择。这使用了几MB内存来存储列表,但是生成点的速度非常快:

代码语言:javascript
复制
import random

screen_width = 1000
screen_height = 800
rect_x = 500
rect_y = 250
rect_width = 100
rect_height = 75

valid_points = []
for x in range(screen_width):
    if rect_x <= x < (rect_x + rect_width):
        for y in range(rect_y):
            valid_points.append( (x, y) )
        for y in range(rect_y + rect_height, screen_height):
            valid_points.append( (x, y) )
    else:
        for y in range(screen_height):
            valid_points.append( (x, y) )

for i in range(10):
    rand_point = random.choice(valid_points)
    print(rand_point)

可以生成随机数并将其映射到屏幕上的有效点,这使用较少的内存,但它有点混乱,并且需要更多时间来生成点。可能有一种更干净的方法来做到这一点,但这里有一种使用与上面相同的屏幕大小变量的方法:

代码语言:javascript
复制
rand_max = (screen_width * screen_height) - (rect_width * rect_height) 
def rand_point():
    rand_raw = random.randint(0, rand_max-1)
    x = rand_raw % screen_width
    y = rand_raw // screen_width
    if rect_y <= y < rect_y+rect_height and rect_x <= x < rect_x+rect_width:
        rand_raw = rand_max + (y-rect_y) * rect_width + (x-rect_x)
        x = rand_raw % screen_width
        y = rand_raw // screen_width
    return (x, y)

这里的逻辑与在旧的8位和16位微处理器上根据x和y坐标计算屏幕地址的方式相反。变量rand_max等于有效屏幕坐标的数量。计算像素的x和y坐标,如果它在矩形内,则将像素推到rand_max上方,进入第一次调用无法生成的区域。

如果你不太关心点是均匀随机的,这个解决方案很容易实现,而且非常快。X值是随机的,但如果所选的X在包含矩形的列中,则Y值会受到约束,因此矩形上方和下方的像素被选中的概率将高于矩形左侧和右侧的像素:

代码语言:javascript
复制
def pseudo_rand_point():        
    x = random.randint(0, screen_width-1)
    if rect_x <= x < rect_x + rect_width: 
        y = random.randint(0, screen_height-rect_height-1)
        if y >= rect_y:
            y += rect_height
    else:
        y = random.randint(0, screen_height-1)
    return (x, y)

另一个答案是计算像素位于屏幕特定区域的概率,但他们的答案还不太正确。这是一个使用类似思想的版本,计算像素在给定区域中的概率,然后计算它在该区域中的位置:

代码语言:javascript
复制
valid_screen_pixels = screen_width*screen_height - rect_width * rect_height
prob_left = float(rect_x * screen_height) / valid_screen_pixels
prob_right = float((screen_width - rect_x - rect_width) * screen_height) / valid_screen_pixels
prob_above_rect = float(rect_y) / (screen_height-rect_height)
def generate_rand():
    ymin, ymax = 0, screen_height-1
    xrand = random.random()
    if xrand < prob_left:
        xmin, xmax = 0, rect_x-1
    elif xrand > (1-prob_right):
        xmin, xmax = rect_x+rect_width, screen_width-1
    else:
        xmin, xmax = rect_x, rect_x+rect_width-1
        yrand = random.random()
        if yrand < prob_above_rect:
            ymax = rect_y-1
        else:
            ymin=rect_y+rect_height
    x = random.randrange(xmin, xmax)
    y = random.randrange(ymin, ymax)
    return (x, y)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33857855

复制
相关文章

相似问题

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