Pseudorandom number generator image: Difference between revisions
(→{{header|Wren}}: Updated preamble and changed to Wren S/H) |
|||
(36 intermediate revisions by 21 users not shown) | |||
Line 2: | Line 2: | ||
;Task: |
;Task: |
||
Write a program that creates an image from |
Write a program that creates an image from a Pseudorandom Number Generator (PRNG) algorithm's output. |
||
The image can have the following dimensions: |
The image can have the following dimensions: |
||
::# 250px by 250px : If the algorithm requires the use of prime numbers, use 8-15 bit primes. |
::# 250px by 250px : If the algorithm requires the use of prime numbers, use 8-15 bit primes. |
||
Line 10: | Line 10: | ||
;Possible Output: |
;Possible Output: |
||
https://www.random.org/analysis/randbitmap-rdo.png |
|||
[[File:PsuedoRandomAlgorithm.png|500px|thumb|left]] |
|||
<br><br><br><br><br><br> |
|||
https://ibb.co/ZJPS16j |
|||
;See also: |
;See also: |
||
* Blum Blum Shub [https://en.wikipedia.org/wiki/Blum_Blum_Shub]. |
* Blum Blum Shub [https://en.wikipedia.org/wiki/Blum_Blum_Shub]. |
||
* Blum-Micali Algorithm: [https://en.wikipedia.org/wiki/Blum%E2%80%93Micali_algorithm]. |
* Blum-Micali Algorithm: [https://en.wikipedia.org/wiki/Blum%E2%80%93Micali_algorithm]. |
||
* Linear congruential generator [https://en.wikipedia.org/wiki/Linear_congruential_generator]. |
* Linear congruential generator [https://en.wikipedia.org/wiki/Linear_congruential_generator]. |
||
<br><br> |
<br><br> |
||
=={{header|6502 Assembly}}== |
|||
===6502js/easy6502=== |
|||
The "hardware" gives us a memory-mapped port at address $00FE which contains a different random number every clock cycle. We can use this to write to video memory (there are only 16 colors so the top 4 bits of the random value are ignored.) |
|||
<syntaxhighlight lang="6502asm">define vramPtr $00 |
|||
define vramPtrHi $01 |
|||
main: |
|||
;we're guaranteed to start off with all registers zeroed. |
|||
STA vramPtr |
|||
LDA #$02 |
|||
STA vramPtrHi |
|||
LDX #4 |
|||
loop: |
|||
LDA $FE ;read a random byte from the port |
|||
STA (vramPtr),y |
|||
INY |
|||
BNE loop |
|||
INC vramPtrHi |
|||
DEX |
|||
bne loop |
|||
brk ;end program</syntaxhighlight> |
|||
Output can be seen by copying/pasting the above code [https://skilldrick.github.io/easy6502/ here.] |
|||
=={{header|Ada}}== |
|||
<syntaxhighlight lang="ada"> |
|||
-- Generate a (pseudo)random image |
|||
-- J. Carter 2023 Apr |
|||
-- Uses Ada_GUI (https://github.com/jrcarter/Ada_GUI) |
|||
with Ada.Numerics.Discrete_Random; |
|||
with Ada_GUI; |
|||
procedure Random_Image is |
|||
package Color_Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Ada_GUI.RGB_Value); |
|||
Gen : Color_Random.Generator; |
|||
Image : Ada_GUI.Widget_ID; |
|||
Event : Ada_GUI.Next_Result_Info; |
|||
use type Ada_GUI.Event_Kind_ID; |
|||
begin -- Random_Image |
|||
Color_Random.Reset (Gen => Gen); |
|||
Ada_GUI.Set_Up (Title => "Random Image"); |
|||
Image := Ada_GUI.New_Graphic_Area (Width => 250, Height => 250); |
|||
All_X : for X in 0 .. 249 loop |
|||
All_Y : for Y in 0 .. 249 loop |
|||
Image.Set_Pixel (X => X, Y => Y, Color => (Red => Color_Random.Random (Gen), |
|||
Green => Color_Random.Random (Gen), |
|||
Blue => Color_Random.Random (Gen), |
|||
Alpha => 1.0) ); |
|||
end loop All_Y; |
|||
end loop All_X; |
|||
Wait : loop |
|||
Event := Ada_GUI.Next_Event; |
|||
exit Wait when not Event.Timed_Out and then Event.Event.Kind = Ada_GUI.Window_Closed; |
|||
end loop Wait; |
|||
Ada_GUI.End_GUI; |
|||
end Random_Image; |
|||
end.</syntaxhighlight> |
|||
{{out}} |
|||
[[Media:Random_Image.png]] |
|||
=={{header|Delphi}}== |
|||
{{libheader| System.SysUtils}} |
|||
{{libheader| vcl.Graphics}} |
|||
{{libheader| Vcl.Imaging.PngImage}} |
|||
<syntaxhighlight lang="delphi"> |
|||
program Pseudorandom_number_generator_image; |
|||
{$APPTYPE CONSOLE} |
|||
uses |
|||
System.SysUtils, |
|||
vcl.Graphics, |
|||
Vcl.Imaging.PngImage; |
|||
type |
|||
TRGBTriple = packed record |
|||
b: Byte; |
|||
g: Byte; |
|||
r: Byte; |
|||
end; |
|||
PRGBTripleArray = ^TRGBTripleArray; |
|||
TRGBTripleArray = array[0..999] of TRGBTriple; |
|||
function Noise(cWidth, cHeight: Integer; Color: boolean = True): TBitmap; |
|||
const |
|||
Seed = 2147483647; |
|||
var |
|||
Pixels: PRGBTripleArray; |
|||
begin |
|||
RandSeed := Seed; |
|||
Result := TBitmap.Create; |
|||
with Result do |
|||
begin |
|||
SetSize(cWidth, cHeight); |
|||
PixelFormat := pf24bit; |
|||
for var row := 0 to cHeight - 1 do |
|||
begin |
|||
Pixels := ScanLine[row]; |
|||
for var col := 0 to cWidth - 1 do |
|||
begin |
|||
if Color then |
|||
begin |
|||
Pixels[col].r := random(255); |
|||
Pixels[col].g := random(255); |
|||
Pixels[col].b := random(255); |
|||
end |
|||
else |
|||
begin |
|||
var Gray := Round((0.299 * random(255)) + (0.587 * random(255)) + (0.114 |
|||
* random(255))); |
|||
Pixels[col].r := Gray; |
|||
Pixels[col].g := Gray; |
|||
Pixels[col].b := Gray; |
|||
end; |
|||
end; |
|||
end; |
|||
end; |
|||
end; |
|||
const |
|||
cWidth = 1000; |
|||
cHeight = 1000; |
|||
begin |
|||
// Color noise |
|||
var bmp := Noise(cWidth, cHeight); |
|||
bmp.SaveToFile('randbitmap-rdo.bmp'); |
|||
// to Png |
|||
with TPngImage.create do |
|||
begin |
|||
Assign(bmp); |
|||
SaveToFile('randbitmap-rdo.png'); |
|||
free; |
|||
end; |
|||
bmp.Free; |
|||
// Gray noise |
|||
bmp := Noise(cWidth, cHeight, False); |
|||
bmp.SaveToFile('randbitmap-rdo_g.bmp'); |
|||
// to Png |
|||
with TPngImage.create do |
|||
begin |
|||
Assign(bmp); |
|||
SaveToFile('randbitmap-rdo_g.png'); |
|||
free; |
|||
end; |
|||
bmp.Free; |
|||
end.</syntaxhighlight> |
|||
{{out}} |
|||
[https://ibb.co/d6hwX1Y randbitmap-rdo.png]. |
|||
=={{header|Factor}}== |
|||
Factor's default PRNG is Mersenne Twister, but it can be easily swapped out for others like Drand, Xoroshiro, Blum Blum Shub, lagged Fibonnaci, system RNGs, and more. |
|||
{{works with|Factor|0.99 2021-02-05}} |
|||
<syntaxhighlight lang="factor">USING: accessors images.testing images.viewer literals math |
|||
random sequences ; |
|||
CONSTANT: size 500 |
|||
<rgb-image> |
|||
${ size size } >>dim |
|||
size sq 3 * [ 256 random ] B{ } replicate-as >>bitmap |
|||
image-window</syntaxhighlight> |
|||
=={{header|Forth}}== |
|||
{{works with|gforth|0.7.3}} |
|||
Uses gforth random generator to create PBM portable pixmap image file. |
|||
<syntaxhighlight lang="forth">require random.fs |
|||
: prngimage |
|||
outfile-id >r |
|||
s" prngimage.pbm" w/o create-file throw to outfile-id |
|||
s\" P1\n500 500\n" type |
|||
500 0 do |
|||
500 0 do |
|||
2 random 48 + emit |
|||
loop #lf emit |
|||
loop |
|||
outfile-id close-file throw |
|||
r> to outfile-id ; |
|||
prngimage</syntaxhighlight> |
|||
=={{header|FreeBASIC}}== |
|||
<syntaxhighlight lang="freebasic">Windowtitle "Pseudorandom number generator image" |
|||
Dim As Integer w = 500, h = w, x, y |
|||
Screenres w, h, 16 |
|||
For x = 0 To w-1 |
|||
For y = 0 To h-1 |
|||
Pset(x, y), Rgb(Rnd * 255, Rnd * 255, Rnd * 255) |
|||
Next y |
|||
Next x |
|||
Bsave "Pseudo-Random-Algorithm.bmp",0</syntaxhighlight> |
|||
[https://www.dropbox.com/s/xsj4y5rnwlid6r4/Pseudo-Random-Algorithm.bmp?dl=0 image500.png] (sample image, offsite) |
|||
=={{header|Go}}== |
|||
The math/rand package uses a custom algorithm attributed to D.P.Mitchell and J.A.Reeds. It doesn't need to be seeded by a prime number. Typically (as here) the seed is generated from the current time. |
|||
The image is saved to a .png file which can then be viewed with a utility such as EOG. |
|||
<syntaxhighlight lang="go">package main |
|||
import ( |
|||
"image" |
|||
"image/color" |
|||
"image/png" |
|||
"log" |
|||
"math/rand" |
|||
"os" |
|||
"time" |
|||
) |
|||
func main() { |
|||
rand.Seed(time.Now().UnixNano()) |
|||
img := image.NewNRGBA(image.Rect(0, 0, 1000, 1000)) |
|||
for x := 0; x < 1000; x++ { |
|||
for y := 0; y < 1000; y++ { |
|||
col := color.RGBA{uint8(rand.Intn(256)), uint8(rand.Intn(256)), uint8(rand.Intn(256)), 255} |
|||
img.Set(x, y, col) |
|||
} |
|||
} |
|||
fileName := "pseudorandom_number_generator.png" |
|||
imgFile, err := os.Create(fileName) |
|||
if err != nil { |
|||
log.Fatal(err) |
|||
} |
|||
defer imgFile.Close() |
|||
if err := png.Encode(imgFile, img); err != nil { |
|||
imgFile.Close() |
|||
log.Fatal(err) |
|||
} |
|||
}</syntaxhighlight> |
|||
=={{header|Java}}== |
|||
Following implementation generates images from java.util.Random(uses linear congruential generator [https://en.wikipedia.org/wiki/Linear_congruential_generator].) and Blum Blum Shub Algorithm with least significant bit method and even bit parity method[https://en.wikipedia.org/wiki/Blum_Blum_Shub]. |
|||
<syntaxhighlight lang="java"> |
|||
import javax.imageio.ImageIO; |
|||
import java.awt.*; |
|||
import java.awt.image.BufferedImage; |
|||
import java.io.File; |
|||
import java.io.IOException; |
|||
import java.math.BigInteger; |
|||
import java.security.SecureRandom; |
|||
import java.util.Random; |
|||
import java.util.Scanner; |
|||
/* |
|||
* Numbers to try: |
|||
* p = 11 or BigInteger.probablePrime(BIT1_LENGTH, rand) |
|||
* q = 23 or BigInteger.probablePrime(BIT_LENGTH, rand) |
|||
* seed = 3 or BigInteger.probablePrime(BIT_LENGTH,rand) |
|||
* */ |
|||
public class csprngBBS { |
|||
public static Scanner input = new Scanner(System.in); |
|||
private static final String fileformat = "png"; |
|||
private static String bitsStri = ""; |
|||
private static String parityEven = ""; |
|||
private static String leastSig = ""; |
|||
private static String randomJavaUtil = ""; |
|||
private static int width = 0; |
|||
private static int BIT_LENGTH = 0; |
|||
private static final Random rand = new SecureRandom(); |
|||
private static BigInteger p = null; // 11 |
|||
private static BigInteger q = null; // 23 |
|||
private static BigInteger m = null; |
|||
private static BigInteger seed = null; // 3 |
|||
private static BigInteger seedFinal = null; |
|||
private static final Random randMathUtil = new SecureRandom(); |
|||
public static void main(String[] args) throws IOException { |
|||
System.out.print("Width: "); |
|||
width = input.nextInt(); |
|||
System.out.print("Bit-Length: "); |
|||
BIT_LENGTH = input.nextInt(); |
|||
System.out.print("Generator format: "); |
|||
String useGenerator = input.next(); |
|||
p = BigInteger.probablePrime(BIT_LENGTH, rand); |
|||
q = BigInteger.probablePrime(BIT_LENGTH, rand); |
|||
m = p.multiply(q); |
|||
seed = BigInteger.probablePrime(BIT_LENGTH,rand); |
|||
seedFinal = seed.add(BigInteger.ZERO); |
|||
if(useGenerator.contains("parity") && useGenerator.contains("significant")) { |
|||
findLeastSignificant(); |
|||
findBitParityEven(); |
|||
createImage(parityEven, "parityEven"); |
|||
createImage(leastSig, "significant"); |
|||
} |
|||
if(useGenerator.contains("parity") && !useGenerator.contains("significant")){ |
|||
findBitParityEven(); |
|||
} |
|||
if(useGenerator.contains("significant") && !useGenerator.contains("parity")){ |
|||
findLeastSignificant(); |
|||
createImage(leastSig, "significant"); |
|||
} |
|||
if(useGenerator.contains("util")){ |
|||
findRandomJava(randMathUtil); |
|||
createImage(randomJavaUtil, "randomUtilJava"); |
|||
} |
|||
} |
|||
public static void findRandomJava(Random random){ |
|||
for(int x = 1; x <= Math.pow(width, 2); x++){ |
|||
randomJavaUtil += random.nextInt(2); |
|||
} |
|||
} |
|||
public static void findBitParityEven(){ |
|||
for(int x = 1; x <= Math.pow(width, 2); x++) { |
|||
seed = seed.pow(2).mod(m); |
|||
bitsStri = convertBinary(seed); |
|||
char[] bits = bitsStri.toCharArray(); |
|||
int counter = 0; |
|||
for (char bit : bits) { |
|||
if (bit == '1') { |
|||
counter++; |
|||
} |
|||
} |
|||
if (counter % 2 != 0) { |
|||
parityEven += "1"; |
|||
} else { |
|||
parityEven += "0"; |
|||
} |
|||
} |
|||
} |
|||
public static void findLeastSignificant(){ |
|||
seed = seedFinal; |
|||
for(int x = 1; x <= Math.pow(width, 2); x++){ |
|||
seed = seed.pow(2).mod(m); |
|||
leastSig += bitsStri.substring(bitsStri.length() - 1); |
|||
} |
|||
} |
|||
public static String convertBinary(BigInteger value){ |
|||
StringBuilder total = new StringBuilder(); |
|||
BigInteger two = BigInteger.TWO; |
|||
while(value.compareTo(BigInteger.ZERO) > 0){ |
|||
total.append(value.mod(two)); |
|||
value = value.divide(two); |
|||
} |
|||
return total.reverse().toString(); |
|||
} |
|||
public static void createImage(String useThis, String fileName) throws IOException { |
|||
int length = csprngBBS.width; |
|||
// Constructs a BufferedImage of one of the predefined image types. |
|||
BufferedImage bufferedImage = new BufferedImage(length, length, 1/*BufferedImage.TYPE_INT_RGB*/); |
|||
// Create a graphics which can be used to draw into the buffered image |
|||
Graphics2D g2d = bufferedImage.createGraphics(); |
|||
for (int y = 1; y <= length; y++) { |
|||
for (int x = 1; x <= length; x++) { |
|||
if (useThis.startsWith("1")) { |
|||
useThis = useThis.substring(1); |
|||
g2d.setColor(Color.BLACK); |
|||
g2d.fillRect(x, y, 1, 1); |
|||
} else if (useThis.startsWith("0")) { |
|||
useThis = useThis.substring(1); |
|||
g2d.setColor(Color.WHITE); |
|||
g2d.fillRect(x, y, 1, 1); |
|||
} |
|||
} |
|||
System.out.print(y + "\t"); |
|||
} |
|||
// Disposes of this graphics context and releases any system resources that it is using. |
|||
g2d.dispose(); |
|||
// Save as file |
|||
File file = new File("REPLACEFILEPATHHERE" + fileName + "." + fileformat); |
|||
ImageIO.write(bufferedImage, fileformat, file); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|jq}}== |
|||
'''Works with jq and gojq, the C and Go implementations of jq''' |
|||
It has been claimed that the elementary cellular automaton with "Rule 30" can |
|||
be used as a PRNG, |
|||
(see e.g. [[Elementary_cellular_automaton/Random_number_generator]]), |
|||
so this entry generates a set of (x,y,color) co-ordinates so that this |
|||
hypothesis might be visually evaluated e.g. using the gnuplot program. |
|||
To keep things brief, the jq filter definitions at |
|||
[[Elementary_cellular_automaton#jq]] are used but not repeated here. |
|||
<syntaxhighlight lang=jq> |
|||
include "elementary-cellular-automaton" {search : "."}; # the defs at [[Elementary_cellular_automaton#jq]] |
|||
def binary2number: |
|||
reduce (.[]|tonumber) as $x ({p:1}; .n += .p * $x | .p *= 2) | .n; |
|||
# Emit a stream of $n PRNGs in range(0;255) |
|||
def prng($n): |
|||
# 30 is 11110 |
|||
("1" + 100 * "0" ) |
|||
| [automaton(30; 8 * $n) | .[0:1]] |
|||
| _nwise(8) | binary2number ; |
|||
foreach prng(99*99) as $color ({x:0, y:1}; |
|||
.color = $color |
|||
| .x += 1 |
|||
| if .x == 100 then .x = 1 | .y += 1 else . end ) |
|||
| "\(.x) \(.y) \(.color)" |
|||
</syntaxhighlight> |
|||
Invocation: |
|||
<pre> |
|||
jq -nrf program.jq > prng.txt |
|||
gnuplot |
|||
plot("prng.txt") with image pixels |
|||
</pre> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Line 24: | Line 452: | ||
over 600 32-bit ints to represent its internal state, rather than just a product of |
over 600 32-bit ints to represent its internal state, rather than just a product of |
||
two or three primes. |
two or three primes. |
||
< |
<syntaxhighlight lang="julia">using FileIO, ImageIO |
||
save("randombw.png", rand(Float16, 1000, 1000)) |
save("randombw.png", rand(Float16, 1000, 1000)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Lua}}== |
|||
Lua uses the <code>xoroshiro256**</code> algorithm. |
|||
<syntaxhighlight lang="lua">size = 500 |
|||
math.randomseed(os.time()) |
|||
-- Writes a 256-bit grayscale PGM image file: |
|||
function writePgm(data, fn, comment) |
|||
local rows = #data |
|||
local cols = #data[1] |
|||
local file = io.open(fn, "wb") |
|||
-- Write header in ASCII |
|||
file:write("P5", "\n") |
|||
if comment ~= nil then |
|||
file:write("# ", comment, "\n") |
|||
end |
|||
file:write(cols, " ", rows, "\n") |
|||
file:write("255", "\n") |
|||
-- Write data in raw bytes |
|||
for _, r in ipairs(data) do |
|||
file:write(string.char(unpack(r))) |
|||
end |
|||
file:close() |
|||
end |
|||
img = {} |
|||
for r = 1, size do |
|||
img[r] = {} |
|||
for c = 1, size do |
|||
img[r][c] = math.random(0,255) |
|||
end |
|||
end |
|||
writePgm(img, "prng_img.pgm", string.format("PRNG Image (%d x %d)", size, size))</syntaxhighlight> |
|||
=={{header|Maxima}}== |
|||
<syntaxhighlight lang="maxima"> |
|||
genmatrix(lambda([i,j],random(1000)),1000,1000)$ |
|||
wxdraw2d(image(%,0,0,30,30)); |
|||
</syntaxhighlight> |
|||
[[File:PseudoRandomImageMaxima.png|thumb|center]] |
|||
=={{header|Nim}}== |
|||
Nim standard PRNG is an implementation of the <code>xoroshiro128+</code> (xor/rotate/shift/rotate) algorithm which is extremely fast. The standard library provides a Mersenne Twister implementation too. For this task, we used the first one. |
|||
<syntaxhighlight lang="nim">import random |
|||
import imageman |
|||
const Size = 500 |
|||
randomize() |
|||
var image = initImage[ColorRGBU](Size, Size) |
|||
for x in 0..<Size: |
|||
for y in 0..<Size: |
|||
let color = ColorRGBU([rand(255).byte, rand(255).byte, rand(255).byte]) |
|||
image[x, y] = color |
|||
image.savePNG("prng_image.png", compression = 9)</syntaxhighlight> |
|||
=={{header|Perl}}== |
|||
Perl unified the PRNG with [https://github.com/Perl/perl5/blob/11ab6d3b461cdc8944e706656209dd2a34f2f01d/util.c#L5793 its own internal drand48() implementation ] on all platforms since [https://perldoc.perl.org/5.20.0/perldelta.html#rand-now-uses-a-consistent-random-number-generator v5.20.0]. Without a manual srand, Perl by default source the seed from [https://github.com/Perl/perl5/blob/11ab6d3b461cdc8944e706656209dd2a34f2f01d/util.c#L4709 "/dev/urandom" ] if it is available so there shouldn't be any prime prerequisite. |
|||
<syntaxhighlight lang="perl">use strict; |
|||
use warnings; |
|||
use GD; |
|||
my $img = GD::Image->new(500, 500, 1); |
|||
for my $y (0..500) { |
|||
for my $x (0..500) { |
|||
my $color = $img->colorAllocate(rand 256, rand 256, rand 256); |
|||
$img->setPixel($x, $y, $color); |
|||
} |
|||
} |
|||
open F, "image500.png"; |
|||
print F $img->png;</syntaxhighlight> |
|||
[https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/PNG-image500.png image500.png] (sample image, offsite) |
|||
=={{header|Phix}}== |
|||
{{libheader|Phix/pGUI}} |
|||
<!--<syntaxhighlight lang="phix">(notonline)--> |
|||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Pseudorandom_number_generator_image.exw</span> |
|||
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- IupSaveImage(), not possible from within a browser (though a "save" button might be?)</span> |
|||
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
|||
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">=</span><span style="color: #000000;">250</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h</span><span style="color: #0000FF;">=</span><span style="color: #000000;">w</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">bw</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">w</span><span style="color: #0000FF;">*</span><span style="color: #000000;">h</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">h</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> <span style="color: #000000;">bw</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">*</span><span style="color: #000000;">h</span><span style="color: #0000FF;">+</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">255</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">image</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupImage</span><span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bw</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">object</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">IupSaveImage</span><span style="color: #0000FF;">(</span><span style="color: #000000;">image</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"bw.png"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"PNG"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span> |
|||
<!--</syntaxhighlight>--> |
|||
=={{header|PicoLisp}}== |
|||
<syntaxhighlight lang="picolisp">(seed (in "/dev/urandom" (rd 8))) |
|||
(out "image.pbm" |
|||
(prinl "P1") |
|||
(prinl 500 " " 500) |
|||
(do 500 |
|||
(do 500 |
|||
(prin (if (rand T) 1 0)) ) |
|||
(prinl) ) )</syntaxhighlight> |
|||
=={{header|Python}}== |
|||
'''Libraries:''' [https://pypi.org/project/Pillow/ Pillow], [https://docs.python.org/3/library/random.html random]<syntaxhighlight lang="python3"> |
|||
# pseudorandom number image generator by Xing216 |
|||
from random import randbytes |
|||
from PIL import Image |
|||
size = 1500 |
|||
x = bytes.fromhex(" ".join([randbytes(3).hex() for x in range(size*size)])) |
|||
img = Image.frombuffer('RGB', (size, size), x, 'raw', 'RGB', 0, 1) |
|||
img.show() |
|||
</syntaxhighlight>'''Output:''' [https://transfer.sh/tyN5SS95M0/rcXing216.png rcXing216.png] (transfer.sh) |
|||
=={{header|Raku}}== |
|||
MoarVM [https://github.com/MoarVM/MoarVM/blob/master/3rdparty/tinymt/tinymt64.c uses Mersenne Twister] as its PRNG but a prime seeder is not mandatory. |
|||
<syntaxhighlight lang="raku" line># 20200818 Raku programming solution |
|||
use Image::PNG::Portable; |
|||
srand 2⁶³ - 25; # greatest prime smaller than 2⁶³ and the max my system can take |
|||
my @data = < 250 500 1000 1500 >; |
|||
@data.map: { |
|||
my $o = Image::PNG::Portable.new: :width($_), :height($_); |
|||
for ^$_ X ^$_ -> @pixel { # about 40% slower if split to ($x,$y) or (\x,\y) |
|||
$o.set: @pixel[0], @pixel[1], 256.rand.Int, 256.rand.Int, 256.rand.Int |
|||
} |
|||
$o.write: "image$_.png" or die; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>file image*.png |
|||
image1000.png: PNG image data, 1000 x 1000, 8-bit/color RGBA, non-interlaced |
|||
image1500.png: PNG image data, 1500 x 1500, 8-bit/color RGBA, non-interlaced |
|||
image250.png: PNG image data, 250 x 250, 8-bit/color RGBA, non-interlaced |
|||
image500.png: PNG image data, 500 x 500, 8-bit/color RGBA, non-interlaced |
|||
</pre> |
|||
[https://github.com/SqrtNegInf/Rosettacode-Perl6-Smoke/blob/master/ref/PNG-image500.png image500.png] (sample image, offsite) |
|||
=={{header|Sidef}}== |
|||
{{trans|Perl}} |
|||
<syntaxhighlight lang="ruby">require('GD') |
|||
var img = %O<GD::Image>.new(500, 500, 1) |
|||
for y in (0..500), x in (0..500) { |
|||
var color = img.colorAllocate(255.irand, 255.irand, 255.irand) |
|||
img.setPixel(x, y, color) |
|||
} |
|||
File("image500.png").write(img.png, :raw)</syntaxhighlight> |
|||
=={{header|Wren}}== |
|||
{{libheader|DOME}} |
|||
DOME's 'random' module uses a pseudorandom number generator based on the '''Squirrel3''' (optionally '''Squirrel5''') noise function which doesn't need to be seeded with a prime number. Typically (as here) the seed is generated from the current system time. |
|||
<syntaxhighlight lang="wren">import "dome" for Window |
|||
import "graphics" for Canvas, Color |
|||
import "random" for Random |
|||
class Game { |
|||
static init() { |
|||
Window.title = "Pseudorandom Number Generator Image" |
|||
Window.resize(1000, 1000) |
|||
Canvas.resize(1000, 1000) |
|||
var r = Random.new() // generates seed from current time |
|||
for (x in 0...1000) { |
|||
for (y in 0...1000) { |
|||
var c = Color.rgb(r.int(256), r.int(256), r.int(256)) |
|||
Canvas.pset(x, y, c) |
|||
} |
|||
} |
|||
} |
|||
static update() {} |
|||
static draw(dt) {} |
|||
}</syntaxhighlight> |
|||
=={{header|XPL0}}== |
|||
The PRNG is linear congruential and is built-in. It's seeded with the time-of-day. |
|||
<syntaxhighlight lang="xpl0">int X, Y; |
|||
[SetVid($11B); \VESA 1280x1024x24 |
|||
for Y:= 0 to 1000-1 do |
|||
for X:= 0 to 1000-1 do |
|||
Point(X, Y, Ran($100_0000)); |
|||
]</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Essentially the same as Delphi's image. |
|||
</pre> |
Latest revision as of 11:51, 29 January 2024
- Task
Write a program that creates an image from a Pseudorandom Number Generator (PRNG) algorithm's output. The image can have the following dimensions:
- 250px by 250px : If the algorithm requires the use of prime numbers, use 8-15 bit primes.
- 500px by 500px : If the algorithm requires the use of prime numbers, use 8-15 bit primes.
- 1000px by 1000px : If the algorithm requires the use of prime numbers, use 8-32 bit primes.
- 1500px by 1500px : If the algorithm requires the use of prime numbers, use 16-64 bit primes.
- Possible Output
https://www.random.org/analysis/randbitmap-rdo.png
- See also
6502 Assembly
6502js/easy6502
The "hardware" gives us a memory-mapped port at address $00FE which contains a different random number every clock cycle. We can use this to write to video memory (there are only 16 colors so the top 4 bits of the random value are ignored.)
define vramPtr $00
define vramPtrHi $01
main:
;we're guaranteed to start off with all registers zeroed.
STA vramPtr
LDA #$02
STA vramPtrHi
LDX #4
loop:
LDA $FE ;read a random byte from the port
STA (vramPtr),y
INY
BNE loop
INC vramPtrHi
DEX
bne loop
brk ;end program
Output can be seen by copying/pasting the above code here.
Ada
-- Generate a (pseudo)random image
-- J. Carter 2023 Apr
-- Uses Ada_GUI (https://github.com/jrcarter/Ada_GUI)
with Ada.Numerics.Discrete_Random;
with Ada_GUI;
procedure Random_Image is
package Color_Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Ada_GUI.RGB_Value);
Gen : Color_Random.Generator;
Image : Ada_GUI.Widget_ID;
Event : Ada_GUI.Next_Result_Info;
use type Ada_GUI.Event_Kind_ID;
begin -- Random_Image
Color_Random.Reset (Gen => Gen);
Ada_GUI.Set_Up (Title => "Random Image");
Image := Ada_GUI.New_Graphic_Area (Width => 250, Height => 250);
All_X : for X in 0 .. 249 loop
All_Y : for Y in 0 .. 249 loop
Image.Set_Pixel (X => X, Y => Y, Color => (Red => Color_Random.Random (Gen),
Green => Color_Random.Random (Gen),
Blue => Color_Random.Random (Gen),
Alpha => 1.0) );
end loop All_Y;
end loop All_X;
Wait : loop
Event := Ada_GUI.Next_Event;
exit Wait when not Event.Timed_Out and then Event.Event.Kind = Ada_GUI.Window_Closed;
end loop Wait;
Ada_GUI.End_GUI;
end Random_Image;
end.
- Output:
Delphi
program Pseudorandom_number_generator_image;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
vcl.Graphics,
Vcl.Imaging.PngImage;
type
TRGBTriple = packed record
b: Byte;
g: Byte;
r: Byte;
end;
PRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..999] of TRGBTriple;
function Noise(cWidth, cHeight: Integer; Color: boolean = True): TBitmap;
const
Seed = 2147483647;
var
Pixels: PRGBTripleArray;
begin
RandSeed := Seed;
Result := TBitmap.Create;
with Result do
begin
SetSize(cWidth, cHeight);
PixelFormat := pf24bit;
for var row := 0 to cHeight - 1 do
begin
Pixels := ScanLine[row];
for var col := 0 to cWidth - 1 do
begin
if Color then
begin
Pixels[col].r := random(255);
Pixels[col].g := random(255);
Pixels[col].b := random(255);
end
else
begin
var Gray := Round((0.299 * random(255)) + (0.587 * random(255)) + (0.114
* random(255)));
Pixels[col].r := Gray;
Pixels[col].g := Gray;
Pixels[col].b := Gray;
end;
end;
end;
end;
end;
const
cWidth = 1000;
cHeight = 1000;
begin
// Color noise
var bmp := Noise(cWidth, cHeight);
bmp.SaveToFile('randbitmap-rdo.bmp');
// to Png
with TPngImage.create do
begin
Assign(bmp);
SaveToFile('randbitmap-rdo.png');
free;
end;
bmp.Free;
// Gray noise
bmp := Noise(cWidth, cHeight, False);
bmp.SaveToFile('randbitmap-rdo_g.bmp');
// to Png
with TPngImage.create do
begin
Assign(bmp);
SaveToFile('randbitmap-rdo_g.png');
free;
end;
bmp.Free;
end.
- Output:
Factor
Factor's default PRNG is Mersenne Twister, but it can be easily swapped out for others like Drand, Xoroshiro, Blum Blum Shub, lagged Fibonnaci, system RNGs, and more.
USING: accessors images.testing images.viewer literals math
random sequences ;
CONSTANT: size 500
<rgb-image>
${ size size } >>dim
size sq 3 * [ 256 random ] B{ } replicate-as >>bitmap
image-window
Forth
Uses gforth random generator to create PBM portable pixmap image file.
require random.fs
: prngimage
outfile-id >r
s" prngimage.pbm" w/o create-file throw to outfile-id
s\" P1\n500 500\n" type
500 0 do
500 0 do
2 random 48 + emit
loop #lf emit
loop
outfile-id close-file throw
r> to outfile-id ;
prngimage
FreeBASIC
Windowtitle "Pseudorandom number generator image"
Dim As Integer w = 500, h = w, x, y
Screenres w, h, 16
For x = 0 To w-1
For y = 0 To h-1
Pset(x, y), Rgb(Rnd * 255, Rnd * 255, Rnd * 255)
Next y
Next x
Bsave "Pseudo-Random-Algorithm.bmp",0
image500.png (sample image, offsite)
Go
The math/rand package uses a custom algorithm attributed to D.P.Mitchell and J.A.Reeds. It doesn't need to be seeded by a prime number. Typically (as here) the seed is generated from the current time.
The image is saved to a .png file which can then be viewed with a utility such as EOG.
package main
import (
"image"
"image/color"
"image/png"
"log"
"math/rand"
"os"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
img := image.NewNRGBA(image.Rect(0, 0, 1000, 1000))
for x := 0; x < 1000; x++ {
for y := 0; y < 1000; y++ {
col := color.RGBA{uint8(rand.Intn(256)), uint8(rand.Intn(256)), uint8(rand.Intn(256)), 255}
img.Set(x, y, col)
}
}
fileName := "pseudorandom_number_generator.png"
imgFile, err := os.Create(fileName)
if err != nil {
log.Fatal(err)
}
defer imgFile.Close()
if err := png.Encode(imgFile, img); err != nil {
imgFile.Close()
log.Fatal(err)
}
}
Java
Following implementation generates images from java.util.Random(uses linear congruential generator [4].) and Blum Blum Shub Algorithm with least significant bit method and even bit parity method[5].
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Random;
import java.util.Scanner;
/*
* Numbers to try:
* p = 11 or BigInteger.probablePrime(BIT1_LENGTH, rand)
* q = 23 or BigInteger.probablePrime(BIT_LENGTH, rand)
* seed = 3 or BigInteger.probablePrime(BIT_LENGTH,rand)
* */
public class csprngBBS {
public static Scanner input = new Scanner(System.in);
private static final String fileformat = "png";
private static String bitsStri = "";
private static String parityEven = "";
private static String leastSig = "";
private static String randomJavaUtil = "";
private static int width = 0;
private static int BIT_LENGTH = 0;
private static final Random rand = new SecureRandom();
private static BigInteger p = null; // 11
private static BigInteger q = null; // 23
private static BigInteger m = null;
private static BigInteger seed = null; // 3
private static BigInteger seedFinal = null;
private static final Random randMathUtil = new SecureRandom();
public static void main(String[] args) throws IOException {
System.out.print("Width: ");
width = input.nextInt();
System.out.print("Bit-Length: ");
BIT_LENGTH = input.nextInt();
System.out.print("Generator format: ");
String useGenerator = input.next();
p = BigInteger.probablePrime(BIT_LENGTH, rand);
q = BigInteger.probablePrime(BIT_LENGTH, rand);
m = p.multiply(q);
seed = BigInteger.probablePrime(BIT_LENGTH,rand);
seedFinal = seed.add(BigInteger.ZERO);
if(useGenerator.contains("parity") && useGenerator.contains("significant")) {
findLeastSignificant();
findBitParityEven();
createImage(parityEven, "parityEven");
createImage(leastSig, "significant");
}
if(useGenerator.contains("parity") && !useGenerator.contains("significant")){
findBitParityEven();
}
if(useGenerator.contains("significant") && !useGenerator.contains("parity")){
findLeastSignificant();
createImage(leastSig, "significant");
}
if(useGenerator.contains("util")){
findRandomJava(randMathUtil);
createImage(randomJavaUtil, "randomUtilJava");
}
}
public static void findRandomJava(Random random){
for(int x = 1; x <= Math.pow(width, 2); x++){
randomJavaUtil += random.nextInt(2);
}
}
public static void findBitParityEven(){
for(int x = 1; x <= Math.pow(width, 2); x++) {
seed = seed.pow(2).mod(m);
bitsStri = convertBinary(seed);
char[] bits = bitsStri.toCharArray();
int counter = 0;
for (char bit : bits) {
if (bit == '1') {
counter++;
}
}
if (counter % 2 != 0) {
parityEven += "1";
} else {
parityEven += "0";
}
}
}
public static void findLeastSignificant(){
seed = seedFinal;
for(int x = 1; x <= Math.pow(width, 2); x++){
seed = seed.pow(2).mod(m);
leastSig += bitsStri.substring(bitsStri.length() - 1);
}
}
public static String convertBinary(BigInteger value){
StringBuilder total = new StringBuilder();
BigInteger two = BigInteger.TWO;
while(value.compareTo(BigInteger.ZERO) > 0){
total.append(value.mod(two));
value = value.divide(two);
}
return total.reverse().toString();
}
public static void createImage(String useThis, String fileName) throws IOException {
int length = csprngBBS.width;
// Constructs a BufferedImage of one of the predefined image types.
BufferedImage bufferedImage = new BufferedImage(length, length, 1/*BufferedImage.TYPE_INT_RGB*/);
// Create a graphics which can be used to draw into the buffered image
Graphics2D g2d = bufferedImage.createGraphics();
for (int y = 1; y <= length; y++) {
for (int x = 1; x <= length; x++) {
if (useThis.startsWith("1")) {
useThis = useThis.substring(1);
g2d.setColor(Color.BLACK);
g2d.fillRect(x, y, 1, 1);
} else if (useThis.startsWith("0")) {
useThis = useThis.substring(1);
g2d.setColor(Color.WHITE);
g2d.fillRect(x, y, 1, 1);
}
}
System.out.print(y + "\t");
}
// Disposes of this graphics context and releases any system resources that it is using.
g2d.dispose();
// Save as file
File file = new File("REPLACEFILEPATHHERE" + fileName + "." + fileformat);
ImageIO.write(bufferedImage, fileformat, file);
}
}
jq
Works with jq and gojq, the C and Go implementations of jq
It has been claimed that the elementary cellular automaton with "Rule 30" can be used as a PRNG, (see e.g. Elementary_cellular_automaton/Random_number_generator), so this entry generates a set of (x,y,color) co-ordinates so that this hypothesis might be visually evaluated e.g. using the gnuplot program.
To keep things brief, the jq filter definitions at Elementary_cellular_automaton#jq are used but not repeated here.
include "elementary-cellular-automaton" {search : "."}; # the defs at [[Elementary_cellular_automaton#jq]]
def binary2number:
reduce (.[]|tonumber) as $x ({p:1}; .n += .p * $x | .p *= 2) | .n;
# Emit a stream of $n PRNGs in range(0;255)
def prng($n):
# 30 is 11110
("1" + 100 * "0" )
| [automaton(30; 8 * $n) | .[0:1]]
| _nwise(8) | binary2number ;
foreach prng(99*99) as $color ({x:0, y:1};
.color = $color
| .x += 1
| if .x == 100 then .x = 1 | .y += 1 else . end )
| "\(.x) \(.y) \(.color)"
Invocation:
jq -nrf program.jq > prng.txt gnuplot plot("prng.txt") with image pixels
Julia
Julia uses the Mersenne Twister algorithm for its default rand() function. That algorithm uses over 600 32-bit ints to represent its internal state, rather than just a product of two or three primes.
using FileIO, ImageIO
save("randombw.png", rand(Float16, 1000, 1000))
Lua
Lua uses the xoroshiro256**
algorithm.
size = 500
math.randomseed(os.time())
-- Writes a 256-bit grayscale PGM image file:
function writePgm(data, fn, comment)
local rows = #data
local cols = #data[1]
local file = io.open(fn, "wb")
-- Write header in ASCII
file:write("P5", "\n")
if comment ~= nil then
file:write("# ", comment, "\n")
end
file:write(cols, " ", rows, "\n")
file:write("255", "\n")
-- Write data in raw bytes
for _, r in ipairs(data) do
file:write(string.char(unpack(r)))
end
file:close()
end
img = {}
for r = 1, size do
img[r] = {}
for c = 1, size do
img[r][c] = math.random(0,255)
end
end
writePgm(img, "prng_img.pgm", string.format("PRNG Image (%d x %d)", size, size))
Maxima
genmatrix(lambda([i,j],random(1000)),1000,1000)$
wxdraw2d(image(%,0,0,30,30));
Nim
Nim standard PRNG is an implementation of the xoroshiro128+
(xor/rotate/shift/rotate) algorithm which is extremely fast. The standard library provides a Mersenne Twister implementation too. For this task, we used the first one.
import random
import imageman
const Size = 500
randomize()
var image = initImage[ColorRGBU](Size, Size)
for x in 0..<Size:
for y in 0..<Size:
let color = ColorRGBU([rand(255).byte, rand(255).byte, rand(255).byte])
image[x, y] = color
image.savePNG("prng_image.png", compression = 9)
Perl
Perl unified the PRNG with its own internal drand48() implementation on all platforms since v5.20.0. Without a manual srand, Perl by default source the seed from "/dev/urandom" if it is available so there shouldn't be any prime prerequisite.
use strict;
use warnings;
use GD;
my $img = GD::Image->new(500, 500, 1);
for my $y (0..500) {
for my $x (0..500) {
my $color = $img->colorAllocate(rand 256, rand 256, rand 256);
$img->setPixel($x, $y, $color);
}
}
open F, "image500.png";
print F $img->png;
image500.png (sample image, offsite)
Phix
-- demo\rosetta\Pseudorandom_number_generator_image.exw without js -- IupSaveImage(), not possible from within a browser (though a "save" button might be?) include pGUI.e IupOpen() integer w=250, h=w sequence bw = repeat(0,w*h) for x=0 to w-1 do for y=0 to h-1 do if rand(2)=2 then bw[x*h+y+1] = 255 end if end for end for Ihandle image = IupImage(w,h,bw) object res = IupSaveImage(image,"bw.png","PNG") IupClose()
PicoLisp
(seed (in "/dev/urandom" (rd 8)))
(out "image.pbm"
(prinl "P1")
(prinl 500 " " 500)
(do 500
(do 500
(prin (if (rand T) 1 0)) )
(prinl) ) )
Python
# pseudorandom number image generator by Xing216
from random import randbytes
from PIL import Image
size = 1500
x = bytes.fromhex(" ".join([randbytes(3).hex() for x in range(size*size)]))
img = Image.frombuffer('RGB', (size, size), x, 'raw', 'RGB', 0, 1)
img.show()
Output: rcXing216.png (transfer.sh)
Raku
MoarVM uses Mersenne Twister as its PRNG but a prime seeder is not mandatory.
# 20200818 Raku programming solution
use Image::PNG::Portable;
srand 2⁶³ - 25; # greatest prime smaller than 2⁶³ and the max my system can take
my @data = < 250 500 1000 1500 >;
@data.map: {
my $o = Image::PNG::Portable.new: :width($_), :height($_);
for ^$_ X ^$_ -> @pixel { # about 40% slower if split to ($x,$y) or (\x,\y)
$o.set: @pixel[0], @pixel[1], 256.rand.Int, 256.rand.Int, 256.rand.Int
}
$o.write: "image$_.png" or die;
}
- Output:
file image*.png image1000.png: PNG image data, 1000 x 1000, 8-bit/color RGBA, non-interlaced image1500.png: PNG image data, 1500 x 1500, 8-bit/color RGBA, non-interlaced image250.png: PNG image data, 250 x 250, 8-bit/color RGBA, non-interlaced image500.png: PNG image data, 500 x 500, 8-bit/color RGBA, non-interlaced
image500.png (sample image, offsite)
Sidef
require('GD')
var img = %O<GD::Image>.new(500, 500, 1)
for y in (0..500), x in (0..500) {
var color = img.colorAllocate(255.irand, 255.irand, 255.irand)
img.setPixel(x, y, color)
}
File("image500.png").write(img.png, :raw)
Wren
DOME's 'random' module uses a pseudorandom number generator based on the Squirrel3 (optionally Squirrel5) noise function which doesn't need to be seeded with a prime number. Typically (as here) the seed is generated from the current system time.
import "dome" for Window
import "graphics" for Canvas, Color
import "random" for Random
class Game {
static init() {
Window.title = "Pseudorandom Number Generator Image"
Window.resize(1000, 1000)
Canvas.resize(1000, 1000)
var r = Random.new() // generates seed from current time
for (x in 0...1000) {
for (y in 0...1000) {
var c = Color.rgb(r.int(256), r.int(256), r.int(256))
Canvas.pset(x, y, c)
}
}
}
static update() {}
static draw(dt) {}
}
XPL0
The PRNG is linear congruential and is built-in. It's seeded with the time-of-day.
int X, Y;
[SetVid($11B); \VESA 1280x1024x24
for Y:= 0 to 1000-1 do
for X:= 0 to 1000-1 do
Point(X, Y, Ran($100_0000));
]
- Output:
Essentially the same as Delphi's image.