Вот решил побаловаться и проверить рандомный ли рандом в java :)
Сделаю тоже самое, что сделали ребята на пхп, только на Clojure, то есть сгенерирую (x * y) вариантов рандома (0 или 1), и, если выпадет 1, то нарисую точку на экране с координатой (x, y).
Для начала определю функцию, которая будет считать рандомы.
(defn rands [max-x max-y] (for [x (range max-x) y (range max-y) :let [rnd (cond (< (rand 1) 0.5) 0 :else 1)] :when (= rnd 1) ] [x y rnd]))
Что здесь:
- Входные параметры max-x и max-y
- Перебераем все сочетания (0..max-x : 0..max-y) и отбераем только те значения, рандом которых вернет 1. Выражение (cond (< (rand 1) 0.5) 0 :else 1) должно вернуть нам 1 или 0 с вероятностью 50%
- Возвращаем последовательность из векторов, состоящих из x, y, rnd. Где x, y - переменные, по которым итерируемся, rnd - рандомное значение (уже отфильтрованное ограничением :when)
Проверяю. Запускаю в REPL:
Вроде похоже на правду - возвращает значения x и y только для рандома, равному 1.
Теперь выведем на экран (по примеру, взятому из книжки Joy of Clojure). Запускаю в REPLe команды:
(def frame (java.awt.Frame.)) (.setSize frame 512 512) (.setVisible frame true)Что здесь:
- Определяем переменную frame, которой присвоится значение нового экземпляра java.awt.Frame. На Java это выглядело бы как Frame frame = new java.awt.Frame();
- Устанавливаем размер frame 512 x 51. Java: frame.setSize(512, 512);
- Делаем фрейм видимым. Java: frame.setVisible(true);
Крутизна в том, что не надо перекомпиливать приложение! Результат выполнения команд виден сразу же.
Вот как это выглядит из Идеевской консоли REPL. Я использую плагин La Closure для IDEA.
Появилось пустое awt-шное окошко, в котором и будем рисовать:
Теперь осталось совсем малость - нарисовать. Опять же в REPLe запускаю такие команды:
(def gfx (.getGraphics frame)) (doseq [[x y rnd] (rands 512 512)] (.fillRect gfx x y 1 1))Что здесь:
- Определили gfx, который равен graphics у frame. Java: Graphics gfx = frame.getGraphics();
- Проитерировались по списку, который нам вернет вызов функции (rands 512 512)
- Помним, что rands возвращает вектор из переменных [x, y и значение рандома rnd]. Значения x,y и рандома присвоятся в локальные переменные x,y,rnd соответственно. Такая форма в Clojure называется деструктуризация (destructuring).
- Для каждого элемента списка заполним единичный rectangle в координате x, y
Вот что получилось на экране:
Важно помнить, что изображение в awt-шном окошке "одноразовое". То есть оно исчезнет как только мы перекроем awt-шный фрейм другим окном или же свернем/развернем его.
Так что псевдорандом в Java похож на рандом. А Clojure + REPL - прикольная вещь!
Весь код целиком ниже. Тоже самое на Java наверняка потребовало бы чуть больше кода, но повторять это на Java уже не хочется :)
(defn rands [max-x max-y] (for [x (range max-x) y (range max-y) :let [rnd (cond (< (rand 1) 0.5) 0 :else 1)] :when (= rnd 1) ] [x y rnd])) (def frame (java.awt.Frame.)) (.setSize frame 512 512) (.setVisible frame true) (def gfx (.getGraphics frame)) (doseq [[x y rnd] (rands 512 512)] (.fillRect gfx x y 1 1))
No comments:
Post a Comment