Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Но природные процессы считаются истинно случайными. Поэтому при розыгрыше призов в лотерее счастливчики определяются лототроном, который хаотично выбрасывает шары. Другие источники случайности — радиоактивный распад или атмосферный шум.
Есть источники случайных чисел и в Web. Один из них — сайт www.random.org, который мы задействуем в следующем примере.
Программа в листинге 18.4 имитирует подбрасывание пяти обычных (шестигранных) костей. Конечно, игровые фанаты могли бы увеличить число граней до 10 или 20, но тогда стало бы сложно рисовать ASCII-картинки.
require 'net/http'HOST = "www.random.org"RAND_URL = "/cgi-bin/randnum?col=5&"def get_random_numbers(count=1, min=0, max=99) path = RAND_URL + "num=#{count}&min=#{min}&max=#{max}" connection = Net::HTTP.new(HOST) response, data = connection.get(path) if response.code == "200" data.split.collect { |num| num.to_i } else [] endendDICE_LINES = [ "+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ ", "| | | * | | * | | * * | | * * | | * * | ", "| * | | | | * | | | | * | | * * | ", "| | | * | | * | | * * | | * * | | * * | ", "+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ "DIE_WIDTH = DICE_LINES[0].length/6def draw_dice(values) DICE_LINES.each do | line | for v in values print line[(v-1)*DIE_WIDTH, DIE_WIDTH] print " " end puts endenddraw_dice(get_random_numbers(5, 1, 6))Здесь мы воспользовались классом
Net::НТТРПосмотрим на вариацию этой идеи. Что если вы захотели бы применить случайные числа в каком-нибудь приложении? Поскольку обслуживающая программа на стороне сервера позволяет указать количество возвращаемых чисел, то было бы логично сохранить их в буфере. Учитывая, что при обращении к удаленному серверу задержки неизбежны, следует сразу заполнить буфер во избежание лишних запросов по сети.
В листинге 18.5 эта мысль реализована. Буфер заполняется отдельным потоком и совместно используется всеми экземплярами класса. Размер буфера и «нижняя отметка» (
@slackrequire "net/http"require "thread"class TrueRandom def initialize(min=nil,max=nil,buff=nil,slack=nil) @buffer = [] @site = "www.random.org" if ! defined? @init_flag # Принять умолчания, если они не были заданы явно И # это первый созданный экземпляр класса... @min = min || 0 @max = max || 1 @bufsize = buff || 1000 @slacksize = slack || 300 @mutex = Mutex.new @thread = Thread.new { fillbuffer } @init_flag = TRUE # Значение может быть любым. else @min = min || @min @max = max || @max @bufsize = buff || @bufsize @slacksize = slack || @slacksize end @url = "/cgi-bin/randnum" + "?num=#@bufsize&min=#@min&max=#@max&col=1" end def fillbuffer h = Net::HTTP.new(@site, 80) resp, data = h.get(@url, nil) @buffer += data.split end def rand num = nil @mutex.synchronize { num = @buffer.shift } if @buffer.size < @slacksize if ! @thread.alive? @thread = Thread.new { fillbuffer } end end if num == nil if @thread.alive? @thread.join else @thread = Thread.new { fillbuffer }
