Browse Source

removed rng crates with own version based on xorshift

Inderjit Gill 2 months ago
parent
commit
9b7b2d78d1
8 changed files with 244 additions and 254 deletions
  1. 0
    3
      core/Cargo.toml
  2. 1
    1
      core/src/bitmap.rs
  3. 84
    95
      core/src/gene.rs
  4. 18
    18
      core/src/geometry/stroked_bezier_rect.rs
  5. 16
    16
      core/src/native.rs
  6. 100
    99
      core/src/prng.rs
  7. 16
    21
      core/src/unparser.rs
  8. 9
    1
      server/static/gallery.json

+ 0
- 3
core/Cargo.toml View File

@@ -5,10 +5,7 @@ authors = ["Inderjit Gill <email@indy.io>"]
5 5
 license = "GPL-3.0+"
6 6
 edition = "2018"
7 7
 
8
-
9 8
 [dependencies]
10
-rand_core = "0.4.0"
11
-rand_xorshift = "0.1.1"
12 9
 strum = "0.13.0"
13 10
 strum_macros = "0.13.0"
14 11
 log = "0.4"

+ 1
- 1
core/src/bitmap.rs View File

@@ -138,7 +138,7 @@ pub fn each(
138 138
             // invariant: elements with index >= i have been locked in place.
139 139
             i -= 1;
140 140
             // lock element i in place.
141
-            coords.swap(i, prng.gen_range(0, i as u32 + 1) as usize);
141
+            coords.swap(i, prng.next_u32_range(0, i as u32 + 1) as usize);
142 142
         }
143 143
 
144 144
         for coord in coords {

+ 84
- 95
core/src/gene.rs View File

@@ -176,7 +176,7 @@ impl Genotype {
176 176
 
177 177
         genotypes.push(Genotype::build_from_initial_values(trait_list)?);
178 178
         for _ in 1..population_size {
179
-            let genotype_seed = prng.prng_f32_defined_range() as i32;
179
+            let genotype_seed = prng.next_f32_defined_range() as i32;
180 180
             genotypes.push(Genotype::build_from_seed(trait_list, genotype_seed)?);
181 181
         }
182 182
 
@@ -220,7 +220,7 @@ impl Genotype {
220 220
         let mut child: Genotype = Default::default();
221 221
 
222 222
         let num_genes = self.genes.len();
223
-        let crossover_index: usize = prng.prng_usize_range(0, num_genes);
223
+        let crossover_index: usize = prng.next_usize_range(0, num_genes);
224 224
 
225 225
         for i in 0..crossover_index {
226 226
             child.push_gene(self.genes[i].clone())
@@ -242,7 +242,7 @@ impl Genotype {
242 242
         let num_genes = self.genes.len();
243 243
 
244 244
         for i in 0..num_genes {
245
-            let r = prng.prng_f32();
245
+            let r = prng.next_f32();
246 246
             if r < mutation_rate {
247 247
                 self.gene_generate_new_var(i, prng, trait_list)?;
248 248
             }
@@ -321,11 +321,11 @@ pub fn next_generation(
321 321
 
322 322
     for _ in 0..(population_size - num_parents) {
323 323
         // select 2 different parents
324
-        let a_index = rng.prng_usize_range(0, num_parents - 1);
324
+        let a_index = rng.next_usize_range(0, num_parents - 1);
325 325
 
326 326
         let mut b_index = a_index;
327 327
         for _ in 0..retry_count {
328
-            b_index = rng.prng_usize_range(0, num_parents - 1);
328
+            b_index = rng.next_usize_range(0, num_parents - 1);
329 329
             if b_index != a_index {
330 330
                 break;
331 331
             }
@@ -471,8 +471,8 @@ mod tests {
471 471
         let genotype = Genotype::build_from_seed(&trait_list, 432).unwrap();
472 472
 
473 473
         assert_eq!(genotype.genes.len(), 2);
474
-        gene_float(&genotype.genes[0], 8.82988);
475
-        gene_float(&genotype.genes[1], 6.2474613);
474
+        gene_float(&genotype.genes[0], 6.74415);
475
+        gene_float(&genotype.genes[1], 7.869932);
476 476
     }
477 477
 
478 478
     #[test]
@@ -483,8 +483,8 @@ mod tests {
483 483
         let genotype = Genotype::build_from_seed(&trait_list, 432).unwrap();
484 484
 
485 485
         assert_eq!(genotype.genes.len(), 2);
486
-        gene_2d(&genotype.genes[0], 59.75697, 56.067802);
487
-        gene_2d(&genotype.genes[1], 55.85068, 57.474014);
486
+        gene_2d(&genotype.genes[0], 56.77736, 58.385616);
487
+        gene_2d(&genotype.genes[1], 51.329006, 58.351044);
488 488
     }
489 489
 
490 490
     fn is_float(var: &Var, expected: f32) {
@@ -532,19 +532,19 @@ mod tests {
532 532
         is_keyword(&res, Keyword::Transformers);
533 533
 
534 534
         {
535
-            let (res, genotype) = run_with_seeded_genotype(s, 56534).unwrap();
535
+            let (res, genotype) = run_with_seeded_genotype(s, 6534).unwrap();
536 536
             assert_eq!(genotype.genes.len(), 1);
537
-            is_keyword(&res, Keyword::KnightRider);
537
+            is_keyword(&res, Keyword::Chrome);
538 538
         }
539 539
         {
540
-            let (res, genotype) = run_with_seeded_genotype(s, 6534).unwrap();
540
+            let (res, genotype) = run_with_seeded_genotype(s, 1534).unwrap();
541 541
             assert_eq!(genotype.genes.len(), 1);
542
-            is_keyword(&res, Keyword::HotlineMiami);
542
+            is_keyword(&res, Keyword::KnightRider);
543 543
         }
544 544
         {
545 545
             let (res, genotype) = run_with_seeded_genotype(s, 2009).unwrap();
546 546
             assert_eq!(genotype.genes.len(), 1);
547
-            is_keyword(&res, Keyword::Rainbow);
547
+            is_keyword(&res, Keyword::Mars);
548 548
         }
549 549
     }
550 550
 
@@ -555,24 +555,21 @@ mod tests {
555 555
         let res = compile_and_execute(s).unwrap();
556 556
         is_float(&res, 12.3);
557 557
 
558
-        // a = 222 b = 223 c = 224 d = 225
559
-        {
560
-            let (res, genotype) = run_with_seeded_genotype(s, 211).unwrap(); // 222
561
-            assert_eq!(genotype.genes.len(), 1);
562
-            is_float(&res, 12.3);
558
+        let (res, genotype) = run_with_seeded_genotype(s, 211).unwrap(); // 222
559
+        assert_eq!(genotype.genes.len(), 1);
560
+        is_float(&res, 12.3);
563 561
 
564
-            let (res, genotype) = run_with_seeded_genotype(s, 25).unwrap(); // 224
565
-            assert_eq!(genotype.genes.len(), 1);
566
-            is_float(&res, 14.5);
562
+        let (res, genotype) = run_with_seeded_genotype(s, 25).unwrap(); // 224
563
+        assert_eq!(genotype.genes.len(), 1);
564
+        is_float(&res, 12.3);
567 565
 
568
-            let (res, genotype) = run_with_seeded_genotype(s, 37).unwrap(); // 223
569
-            assert_eq!(genotype.genes.len(), 1);
570
-            is_float(&res, 13.4);
566
+        let (res, genotype) = run_with_seeded_genotype(s, 37).unwrap(); // 223
567
+        assert_eq!(genotype.genes.len(), 1);
568
+        is_float(&res, 14.5);
571 569
 
572
-            let (res, genotype) = run_with_seeded_genotype(s, 45).unwrap(); // 225
573
-            assert_eq!(genotype.genes.len(), 1);
574
-            is_float(&res, 15.6);
575
-        }
570
+        let (res, genotype) = run_with_seeded_genotype(s, 45).unwrap(); // 225
571
+        assert_eq!(genotype.genes.len(), 1);
572
+        is_float(&res, 15.6);
576 573
     }
577 574
 
578 575
     fn assert_native_opcode_in_program(program: &Program, native: Native) {
@@ -590,25 +587,19 @@ mod tests {
590 587
     }
591 588
 
592 589
     #[test]
593
-    fn gen_select_natives() {
590
+    fn gen_select_natives_xx() {
594 591
         let s = "({rect (gen/select from: '(rect circle circle-slice))} position: [100 100])";
595 592
         {
596
-            // dbg!(Native::Rect as i32);
597
-            // seed 6 == genotype[0].name: 305  Rect
598
-            let (program, _genotype) = program_with_seeded_genotype(s, 6).unwrap();
593
+            let (program, _genotype) = program_with_seeded_genotype(s, 7).unwrap();
599 594
             assert_native_opcode_in_program(&program, Native::Rect);
600 595
         }
601 596
         {
602
-            // dbg!(Native::Circle as i32);
603
-            // seed 5 == genotype[0].name: 306  Circle
604
-            let (program, _genotype) = program_with_seeded_genotype(s, 5).unwrap();
605
-            assert_native_opcode_in_program(&program, Native::Circle);
597
+            let (program, _genotype) = program_with_seeded_genotype(s, 5800).unwrap();
598
+            assert_native_opcode_in_program(&program, Native::CircleSlice);
606 599
         }
607 600
         {
608
-            // dbg!(Native::CircleSlice as i32);
609
-            // seed 14 == genotype[0].name: 307  CircleSlice
610
-            let (program, _genotype) = program_with_seeded_genotype(s, 14).unwrap();
611
-            assert_native_opcode_in_program(&program, Native::CircleSlice);
601
+            let (program, _genotype) = program_with_seeded_genotype(s, 19).unwrap();
602
+            assert_native_opcode_in_program(&program, Native::Circle);
612 603
         }
613 604
     }
614 605
 
@@ -619,23 +610,21 @@ mod tests {
619 610
         let res = compile_and_execute(s).unwrap();
620 611
         is_float(&res, 12.3);
621 612
 
622
-        {
623
-            let (res, genotype) = run_with_seeded_genotype(s, 211).unwrap();
624
-            assert_eq!(genotype.genes.len(), 1);
625
-            is_float(&res, 12.3);
613
+        let (res, genotype) = run_with_seeded_genotype(s, 211).unwrap();
614
+        assert_eq!(genotype.genes.len(), 1);
615
+        is_float(&res, 12.3);
626 616
 
627
-            let (res, genotype) = run_with_seeded_genotype(s, 25).unwrap();
628
-            assert_eq!(genotype.genes.len(), 1);
629
-            is_float(&res, 14.5);
617
+        let (res, genotype) = run_with_seeded_genotype(s, 27).unwrap();
618
+        assert_eq!(genotype.genes.len(), 1);
619
+        is_float(&res, 13.4);
630 620
 
631
-            let (res, genotype) = run_with_seeded_genotype(s, 37).unwrap();
632
-            assert_eq!(genotype.genes.len(), 1);
633
-            is_float(&res, 13.4);
621
+        let (res, genotype) = run_with_seeded_genotype(s, 37).unwrap();
622
+        assert_eq!(genotype.genes.len(), 1);
623
+        is_float(&res, 14.5);
634 624
 
635
-            let (res, genotype) = run_with_seeded_genotype(s, 45).unwrap();
636
-            assert_eq!(genotype.genes.len(), 1);
637
-            is_float(&res, 15.6);
638
-        }
625
+        let (res, genotype) = run_with_seeded_genotype(s, 45).unwrap();
626
+        assert_eq!(genotype.genes.len(), 1);
627
+        is_float(&res, 15.6);
639 628
     }
640 629
 
641 630
     // bug_gen_select_custom_locals
@@ -653,7 +642,7 @@ mod tests {
653 642
         let (res, genotype) = run_with_seeded_genotype(s, seed).unwrap();
654 643
         assert_eq!(genotype.genes.len(), genotype_length);
655 644
 
656
-        is_float(&res, 4.4);
645
+        is_float(&res, 1.1);
657 646
     }
658 647
 
659 648
     #[test]
@@ -666,41 +655,41 @@ mod tests {
666 655
         let (res, genotype) = run_with_seeded_genotype(s, 432).unwrap();
667 656
         is_col(
668 657
             &res,
669
-            &Colour::new(ColourFormat::Rgb, 0.97569704, 0.6067802, 0.585068, 0.3),
658
+            &Colour::new(ColourFormat::Rgb, 0.67773575, 0.8385617, 0.13290067, 0.3),
670 659
         );
671 660
         assert_eq!(genotype.genes.len(), 1);
672 661
     }
673 662
 
674 663
     #[test]
675
-    fn genotype_compile() {
664
+    fn genotype_compile_xxx() {
676 665
         geno_test(
677 666
             "(+ {3 (gen/scalar min: 10 max: 20)} {4 (gen/scalar min: 100 max: 105)})",
678 667
             432,
679 668
             2,
680 669
             7.0,
681
-            122.79086,
670
+            120.97017,
682 671
         );
683
-        geno_test("(+ 6 {3 (gen/int min: 1 max: 100)})", 432, 1, 9.0, 104.0);
672
+        geno_test("(+ 6 {3 (gen/int min: 1 max: 100)})", 432, 1, 9.0, 74.0);
684 673
         geno_test(
685 674
             "(+ 6 {3 (gen/scalar min: 1 max: 100)})",
686 675
             432,
687 676
             1,
688 677
             9.0,
689
-            103.59401,
678
+            74.09584,
690 679
         );
691
-        geno_test("(+ 6 {3 (gen/int min: 1 max: 100)})", 874, 1, 9.0, 60.0);
680
+        geno_test("(+ 6 {3 (gen/int min: 1 max: 100)})", 874, 1, 9.0, 81.0);
692 681
         geno_test(
693 682
             "(+ 6 {3 (gen/scalar min: 1 max: 100)})",
694 683
             874,
695 684
             1,
696 685
             9.0,
697
-            59.47561,
686
+            81.0833,
698 687
         );
699 688
     }
700 689
 
701 690
     #[test]
702 691
     fn genotype_compile_stray() {
703
-        geno_test("{3 (gen/stray from: 3 by: 0.5)}", 432, 1, 3.0, 3.475697);
692
+        geno_test("{3 (gen/stray from: 3 by: 0.5)}", 432, 1, 3.0, 3.1777358);
704 693
         geno_test("{3 (gen/stray-int from: 3 by: 0.5)}", 432, 1, 3.0, 3.0);
705 694
     }
706 695
 
@@ -712,7 +701,7 @@ mod tests {
712 701
             7524,
713 702
             2,
714 703
             (100.0, 200.0),
715
-            (93.04805, 197.49728),
704
+            (94.410095, 202.5176),
716 705
         );
717 706
     }
718 707
 
@@ -737,9 +726,9 @@ mod tests {
737 726
             let (res, genotype) = run_with_seeded_genotype(expr, seed).unwrap();
738 727
             if let Var::Vector(vs) = res {
739 728
                 assert_eq!(vs.len(), 3);
740
-                is_2d(&vs[0], (0.9825403, 0.85869956));
741
-                is_2d(&vs[1], (0.59191173, 0.999328));
742
-                is_2d(&vs[2], (0.22858822, 0.4880673));
729
+                is_2d(&vs[0], (0.9590588, 0.9022932));
730
+                is_2d(&vs[1], (0.8897112, 0.013709899));
731
+                is_2d(&vs[2], (0.85696673, 0.5854448));
743 732
             } else {
744 733
                 assert!(false);
745 734
             }
@@ -765,9 +754,9 @@ mod tests {
765 754
             let (res, genotype) = run_with_seeded_genotype(expr, seed).unwrap();
766 755
             if let Var::Vector(vs) = res {
767 756
                 assert_eq!(vs.len(), 3);
768
-                is_2d(&vs[0], (59.8254, 58.586998));
769
-                is_2d(&vs[1], (55.919117, 59.99328));
770
-                is_2d(&vs[2], (52.28588, 54.880672));
757
+                is_2d(&vs[0], (59.590588, 59.022934));
758
+                is_2d(&vs[1], (58.89711, 50.1371));
759
+                is_2d(&vs[2], (58.569668, 55.854446));
771 760
             } else {
772 761
                 assert!(false);
773 762
             }
@@ -794,9 +783,9 @@ mod tests {
794 783
         let (res, genotype) = run_with_seeded_genotype(expr, seed).unwrap();
795 784
         if let Var::Vector(vs) = res {
796 785
             assert_eq!(vs.len(), 3);
797
-            is_float(&vs[0], 0.6279464);
798
-            is_float(&vs[1], 0.46001887);
799
-            is_float(&vs[2], 0.51953447);
786
+            is_float(&vs[0], 0.12203506);
787
+            is_float(&vs[1], 0.8389967);
788
+            is_float(&vs[2], 0.6913055);
800 789
         } else {
801 790
             assert!(false);
802 791
         }
@@ -818,44 +807,44 @@ mod tests {
818 807
         let (_, genotype_b) = run_with_seeded_genotype(expr, seed_b).unwrap();
819 808
 
820 809
         assert_eq!(genotype_a.genes.len(), 3);
821
-        gene_float(&genotype_a.genes[0], 0.000778846);
822
-        gene_float(&genotype_a.genes[1], 0.5599265);
823
-        gene_float(&genotype_a.genes[2], 0.8937246);
810
+        gene_float(&genotype_a.genes[0], 0.12962966);
811
+        gene_float(&genotype_a.genes[1], 0.66991657);
812
+        gene_float(&genotype_a.genes[2], 0.056645457);
824 813
 
825 814
         assert_eq!(genotype_b.genes.len(), 3);
826
-        gene_float(&genotype_b.genes[0], 0.1344259);
827
-        gene_float(&genotype_b.genes[1], 0.052326918);
828
-        gene_float(&genotype_b.genes[2], 0.024050714);
815
+        gene_float(&genotype_b.genes[0], 0.49113372);
816
+        gene_float(&genotype_b.genes[1], 0.8261006);
817
+        gene_float(&genotype_b.genes[2], 0.9936072);
829 818
 
830 819
         let parents = vec![genotype_a, genotype_b];
831 820
         let children = next_generation(&parents, 5, 0.2, 234, &trait_list).unwrap();
832 821
 
833 822
         // first 2 children should be clones of the parents
834 823
         assert_eq!(children[0].genes.len(), 3);
835
-        gene_float(&children[0].genes[0], 0.000778846);
836
-        gene_float(&children[0].genes[1], 0.5599265);
837
-        gene_float(&children[0].genes[2], 0.8937246);
824
+        gene_float(&children[0].genes[0], 0.12962966);
825
+        gene_float(&children[0].genes[1], 0.66991657);
826
+        gene_float(&children[0].genes[2], 0.056645457);
838 827
 
839 828
         assert_eq!(children[1].genes.len(), 3);
840
-        gene_float(&children[1].genes[0], 0.1344259);
841
-        gene_float(&children[1].genes[1], 0.052326918);
842
-        gene_float(&children[1].genes[2], 0.024050714);
829
+        gene_float(&children[1].genes[0], 0.49113372);
830
+        gene_float(&children[1].genes[1], 0.8261006);
831
+        gene_float(&children[1].genes[2], 0.9936072);
843 832
 
844 833
         // 3 children
845 834
         assert_eq!(children[2].genes.len(), 3);
846
-        gene_float(&children[2].genes[0], 0.6867611); // mutation
847
-        gene_float(&children[2].genes[1], 0.052326918); // b
848
-        gene_float(&children[2].genes[2], 0.024050714); // b
835
+        gene_float(&children[2].genes[0], 0.49113372); // mutation
836
+        gene_float(&children[2].genes[1], 0.8261006); // b
837
+        gene_float(&children[2].genes[2], 0.9936072); // b
849 838
 
850 839
         assert_eq!(children[3].genes.len(), 3);
851
-        gene_float(&children[3].genes[0], 0.000778846); // a
852
-        gene_float(&children[3].genes[1], 0.5599265); // a
853
-        gene_float(&children[3].genes[2], 0.024050714); // b
840
+        gene_float(&children[3].genes[0], 0.12962966); // a
841
+        gene_float(&children[3].genes[1], 0.8261006); // a
842
+        gene_float(&children[3].genes[2], 0.463081); // b
854 843
 
855 844
         assert_eq!(children[4].genes.len(), 3);
856
-        gene_float(&children[4].genes[0], 0.000778846); // a
857
-        gene_float(&children[4].genes[1], 0.052326918); // b
858
-        gene_float(&children[4].genes[2], 0.024050714); // b
845
+        gene_float(&children[4].genes[0], 0.21231069); // a
846
+        gene_float(&children[4].genes[1], 0.29541624); // b
847
+        gene_float(&children[4].genes[2], 0.9936072); // b
859 848
 
860 849
         assert_eq!(children.len(), 5);
861 850
     }

+ 18
- 18
core/src/geometry/stroked_bezier_rect.rs View File

@@ -74,14 +74,14 @@ pub fn render(
74 74
         let h = y_start + stroke_half_thickness + (i as f32 * stroke_offset_factor);
75 75
 
76 76
         let coords: [f32; 8] = [
77
-            (prng.prng_f32_range(-1.0, 1.0) * vol) + x_start + (0.0 * th_width),
78
-            h + (prng.prng_f32_range(-1.0, 1.0) * vol),
79
-            (prng.prng_f32_range(-1.0, 1.0) * vol) + x_start + (1.0 * th_width),
80
-            h + (prng.prng_f32_range(-1.0, 1.0) * vol),
81
-            (prng.prng_f32_range(-1.0, 1.0) * vol) + x_start + (2.0 * th_width),
82
-            h + (prng.prng_f32_range(-1.0, 1.0) * vol),
83
-            (prng.prng_f32_range(-1.0, 1.0) * vol) + x_start + (3.0 * th_width),
84
-            h + (prng.prng_f32_range(-1.0, 1.0) * vol),
77
+            (prng.next_f32_range(-1.0, 1.0) * vol) + x_start + (0.0 * th_width),
78
+            h + (prng.next_f32_range(-1.0, 1.0) * vol),
79
+            (prng.next_f32_range(-1.0, 1.0) * vol) + x_start + (1.0 * th_width),
80
+            h + (prng.next_f32_range(-1.0, 1.0) * vol),
81
+            (prng.next_f32_range(-1.0, 1.0) * vol) + x_start + (2.0 * th_width),
82
+            h + (prng.next_f32_range(-1.0, 1.0) * vol),
83
+            (prng.next_f32_range(-1.0, 1.0) * vol) + x_start + (3.0 * th_width),
84
+            h + (prng.next_f32_range(-1.0, 1.0) * vol),
85 85
         ];
86 86
 
87 87
         stroked_bezier::render(
@@ -95,7 +95,7 @@ pub fn render(
95 95
             stroke_thickness,
96 96
             &rgb_from_lab,
97 97
             colour_volatility,
98
-            prng.prng_f32(),
98
+            prng.next_f32(),
99 99
             Easing::Linear,
100 100
             uvm,
101 101
         )?;
@@ -110,14 +110,14 @@ pub fn render(
110 110
         let v = x_start + stroke_half_thickness + (i as f32 * stroke_offset_factor);
111 111
 
112 112
         let coords: [f32; 8] = [
113
-            v + (prng.prng_f32_range(-1.0, 1.0) * vol),
114
-            (prng.prng_f32_range(-1.0, 1.0) * vol) + y_start + (0.0 * th_height),
115
-            v + (prng.prng_f32_range(-1.0, 1.0) * vol),
116
-            (prng.prng_f32_range(-1.0, 1.0) * vol) + y_start + (1.0 * th_height),
117
-            v + (prng.prng_f32_range(-1.0, 1.0) * vol),
118
-            (prng.prng_f32_range(-1.0, 1.0) * vol) + y_start + (2.0 * th_height),
119
-            v + (prng.prng_f32_range(-1.0, 1.0) * vol),
120
-            (prng.prng_f32_range(-1.0, 1.0) * vol) + y_start + (3.0 * th_height),
113
+            v + (prng.next_f32_range(-1.0, 1.0) * vol),
114
+            (prng.next_f32_range(-1.0, 1.0) * vol) + y_start + (0.0 * th_height),
115
+            v + (prng.next_f32_range(-1.0, 1.0) * vol),
116
+            (prng.next_f32_range(-1.0, 1.0) * vol) + y_start + (1.0 * th_height),
117
+            v + (prng.next_f32_range(-1.0, 1.0) * vol),
118
+            (prng.next_f32_range(-1.0, 1.0) * vol) + y_start + (2.0 * th_height),
119
+            v + (prng.next_f32_range(-1.0, 1.0) * vol),
120
+            (prng.next_f32_range(-1.0, 1.0) * vol) + y_start + (3.0 * th_height),
121 121
         ];
122 122
 
123 123
         stroked_bezier::render(
@@ -131,7 +131,7 @@ pub fn render(
131 131
             stroke_thickness,
132 132
             &rgb_from_lab,
133 133
             colour_volatility,
134
-            prng.prng_f32(),
134
+            prng.next_f32(),
135 135
             Easing::Linear,
136 136
             uvm,
137 137
         )?;

+ 16
- 16
core/src/native.rs View File

@@ -2062,7 +2062,7 @@ fn prng_values_execute(vm: &mut Vm) -> Result<Option<Var>> {
2062 2062
 
2063 2063
     let mut vs: Vec<Var> = Vec::new();
2064 2064
     for _ in 0..num {
2065
-        let f = ref_mut_prng_state.prng_f32_defined_range();
2065
+        let f = ref_mut_prng_state.next_f32_defined_range();
2066 2066
         vs.push(Var::Float(f))
2067 2067
     }
2068 2068
 
@@ -2087,7 +2087,7 @@ fn prng_value_execute(vm: &mut Vm) -> Result<Option<Var>> {
2087 2087
     }
2088 2088
 
2089 2089
     let mut ref_mut_prng_state = ref_mut_prng_state_struct(&vm.stack, vm.sp, 1)?;
2090
-    let res = ref_mut_prng_state.prng_f32_defined_range();
2090
+    let res = ref_mut_prng_state.next_f32_defined_range();
2091 2091
 
2092 2092
     Ok(Some(Var::Float(res)))
2093 2093
 }
@@ -3021,7 +3021,7 @@ fn gen_stray_int_execute(vm: &mut Vm) -> Result<Option<Var>> {
3021 3021
     let by: f32 = vm.stack_peek(2)?;
3022 3022
 
3023 3023
     let by = mathutil::absf(by);
3024
-    let value = vm.prng_state.prng_f32_range(from - by, from + by);
3024
+    let value = vm.prng_state.next_f32_range(from - by, from + by);
3025 3025
     let value = value.floor();
3026 3026
 
3027 3027
     Ok(Some(Var::Float(value)))
@@ -3044,7 +3044,7 @@ fn gen_stray_execute(vm: &mut Vm) -> Result<Option<Var>> {
3044 3044
     let by: f32 = vm.stack_peek(2)?;
3045 3045
 
3046 3046
     let by = mathutil::absf(by);
3047
-    let value = vm.prng_state.prng_f32_range(from - by, from + by);
3047
+    let value = vm.prng_state.next_f32_range(from - by, from + by);
3048 3048
 
3049 3049
     Ok(Some(Var::Float(value)))
3050 3050
 }
@@ -3087,7 +3087,7 @@ fn gen_stray_2d_execute(vm: &mut Vm) -> Result<Option<Var>> {
3087 3087
     // pick a scalar between min and max
3088 3088
     let value = vm
3089 3089
         .prng_state
3090
-        .prng_f32_range(from_index - by_index, from_index + by_index);
3090
+        .next_f32_range(from_index - by_index, from_index + by_index);
3091 3091
 
3092 3092
     Ok(Some(Var::Float(value)))
3093 3093
 }
@@ -3141,7 +3141,7 @@ fn gen_stray_3d_execute(vm: &mut Vm) -> Result<Option<Var>> {
3141 3141
     };
3142 3142
 
3143 3143
     // pick a scalar between min and max
3144
-    let value = vm.prng_state.prng_f32_range(from - by, from + by);
3144
+    let value = vm.prng_state.next_f32_range(from - by, from + by);
3145 3145
 
3146 3146
     Ok(Some(Var::Float(value)))
3147 3147
 }
@@ -3195,7 +3195,7 @@ fn gen_stray_4d_execute(vm: &mut Vm) -> Result<Option<Var>> {
3195 3195
     };
3196 3196
 
3197 3197
     // pick a scalar between min and max
3198
-    let value = vm.prng_state.prng_f32_range(from - by, from + by);
3198
+    let value = vm.prng_state.next_f32_range(from - by, from + by);
3199 3199
 
3200 3200
     Ok(Some(Var::Float(value)))
3201 3201
 }
@@ -3217,7 +3217,7 @@ fn gen_int_execute(vm: &mut Vm) -> Result<Option<Var>> {
3217 3217
     let max: f32 = vm.stack_peek(2)?;
3218 3218
 
3219 3219
     // pick a scalar between min and max
3220
-    let value = vm.prng_state.prng_f32_range(min, max + 1.0);
3220
+    let value = vm.prng_state.next_f32_range(min, max + 1.0);
3221 3221
 
3222 3222
     Ok(Some(Var::Float(value.floor())))
3223 3223
 }
@@ -3239,7 +3239,7 @@ fn gen_scalar_execute(vm: &mut Vm) -> Result<Option<Var>> {
3239 3239
     let max: f32 = vm.stack_peek(2)?;
3240 3240
 
3241 3241
     // pick a scalar between min and max
3242
-    let value = vm.prng_state.prng_f32_range(min, max);
3242
+    let value = vm.prng_state.next_f32_range(min, max);
3243 3243
 
3244 3244
     Ok(Some(Var::Float(value)))
3245 3245
 }
@@ -3260,8 +3260,8 @@ fn gen_2d_execute(vm: &mut Vm) -> Result<Option<Var>> {
3260 3260
     let min: f32 = vm.stack_peek(1)?;
3261 3261
     let max: f32 = vm.stack_peek(2)?;
3262 3262
 
3263
-    let x = vm.prng_state.prng_f32_range(min, max);
3264
-    let y = vm.prng_state.prng_f32_range(min, max);
3263
+    let x = vm.prng_state.next_f32_range(min, max);
3264
+    let y = vm.prng_state.next_f32_range(min, max);
3265 3265
 
3266 3266
     Ok(Some(Var::V2D(x, y)))
3267 3267
 }
@@ -3284,7 +3284,7 @@ fn gen_select_execute(vm: &mut Vm) -> Result<Option<Var>> {
3284 3284
     }
3285 3285
 
3286 3286
     let from = stack_peek_vars(&vm.stack, vm.sp, 1)?;
3287
-    let index = vm.prng_state.prng_usize_range(0, from.len());
3287
+    let index = vm.prng_state.next_usize_range(0, from.len());
3288 3288
 
3289 3289
     Ok(Some(from[index].clone()))
3290 3290
 }
@@ -3305,14 +3305,14 @@ fn gen_col_execute(vm: &mut Vm) -> Result<Option<Var>> {
3305 3305
         vm.stack_peek(1)?
3306 3306
     } else {
3307 3307
         // no alpha was given so generate a random value
3308
-        vm.prng_state.prng_f32_range(0.0, 1.0)
3308
+        vm.prng_state.next_f32_range(0.0, 1.0)
3309 3309
     };
3310 3310
 
3311 3311
     Ok(Some(Var::Colour(Colour::new(
3312 3312
         ColourFormat::Rgb,
3313
-        vm.prng_state.prng_f32_range(0.0, 1.0),
3314
-        vm.prng_state.prng_f32_range(0.0, 1.0),
3315
-        vm.prng_state.prng_f32_range(0.0, 1.0),
3313
+        vm.prng_state.next_f32_range(0.0, 1.0),
3314
+        vm.prng_state.next_f32_range(0.0, 1.0),
3315
+        vm.prng_state.next_f32_range(0.0, 1.0),
3316 3316
         alpha,
3317 3317
     ))))
3318 3318
 }

+ 100
- 99
core/src/prng.rs View File

@@ -13,9 +13,99 @@
13 13
 // You should have received a copy of the GNU General Public License
14 14
 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
15 15
 
16
+use std::num::Wrapping as wrap;
17
+
16 18
 use crate::mathutil::{clamp, lerp};
17
-use rand_core::{RngCore, SeedableRng};
18
-use rand_xorshift::XorShiftRng;
19
+
20
+#[derive(Clone, Debug)]
21
+pub struct PrngStateStruct {
22
+    seed0: u64,
23
+    seed1: u64,
24
+    min: f32,
25
+    max: f32,
26
+}
27
+
28
+impl PrngStateStruct {
29
+    pub fn new(seed: i32, min: f32, max: f32) -> Self {
30
+        let mut prng = PrngStateStruct {
31
+            seed0: 0,
32
+            seed1: 0,
33
+            min,
34
+            max,
35
+        };
36
+        prng.set_state(seed);
37
+        prng
38
+    }
39
+
40
+    pub fn set_state(&mut self, seed: i32) {
41
+        self.seed0 = seed as u64 * seed as u64;
42
+        self.seed1 = (seed + 3145) as u64;
43
+
44
+        // warm up
45
+        self.next_f32();
46
+        self.next_f32();
47
+        self.next_f32();
48
+        self.next_f32();
49
+        self.next_f32();
50
+    }
51
+
52
+    pub fn clone_rng(&mut self, other: PrngStateStruct) {
53
+        self.seed0 = other.seed0;
54
+        self.seed1 = other.seed1;
55
+        self.min = other.min;
56
+        self.max = other.max;
57
+    }
58
+
59
+    // 0..1
60
+    pub fn next_f32(&mut self) -> f32 {
61
+        let a = self.next_u32();
62
+        a as f32 / std::u32::MAX as f32
63
+    }
64
+
65
+    pub fn next_u32(&mut self) -> u32 {
66
+        self.next_u64() as u32
67
+    }
68
+
69
+    #[inline]
70
+    pub fn next_u64(&mut self) -> u64 {
71
+        let mut s1 = wrap(self.seed0);
72
+        let s0 = wrap(self.seed1);
73
+        let result = s0 + s1;
74
+        self.seed0 = s0.0;
75
+        s1 ^= s1 << 23;
76
+        self.seed1 = (s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5)).0;
77
+        result.0
78
+    }
79
+
80
+    pub fn next_u32_range(&mut self, low: u32, high: u32) -> u32 {
81
+        let a = self.next_u32();
82
+        (a % (high - low)) + low
83
+    }
84
+
85
+    pub fn next_f32_range(&mut self, min: f32, max: f32) -> f32 {
86
+        let value = self.next_f32();
87
+        (value * (max - min)) + min
88
+    }
89
+
90
+    pub fn next_usize_range(&mut self, min: usize, max: usize) -> usize {
91
+        self.next_f32_range(min as f32, max as f32) as usize
92
+    }
93
+
94
+    pub fn next_f32_defined_range(&mut self) -> f32 {
95
+        let value = self.next_f32();
96
+        (value * (self.max - self.min)) + self.min
97
+    }
98
+
99
+    pub fn next_f32_around(&mut self, val: f32, percent: f32, min: f32, max: f32) -> f32 {
100
+        let value = self.next_f32();
101
+        let range = ((max - min) / 100.0) * percent;
102
+        let lowest = val - range;
103
+        let highest = val + range;
104
+        let res = (value * (highest - lowest)) + lowest;
105
+
106
+        clamp(res, min, max)
107
+    }
108
+}
19 109
 
20 110
 const PERMUTATIONS: [usize; 512] = [
21 111
     151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69,
@@ -69,94 +159,6 @@ const INDICES: [usize; 64] = [
69 159
     8, 9, 10, 11,
70 160
 ];
71 161
 
72
-#[derive(Clone, Debug)]
73
-pub struct PrngStateStruct {
74
-    pub rng: XorShiftRng,
75
-    min: f32,
76
-    max: f32,
77
-}
78
-
79
-fn as_u8(i: i32) -> u8 {
80
-    (i % (1 << 8)) as u8
81
-}
82
-
83
-impl PrngStateStruct {
84
-    pub fn new(seed: i32, min: f32, max: f32) -> Self {
85
-        PrngStateStruct {
86
-            rng: PrngStateStruct::make_xor_shift_rng(seed),
87
-            min,
88
-            max,
89
-        }
90
-    }
91
-
92
-    pub fn set_state(&mut self, seed: i32) {
93
-        self.rng = PrngStateStruct::make_xor_shift_rng(seed);
94
-    }
95
-
96
-    pub fn clone_rng(&mut self, other: PrngStateStruct) {
97
-        self.rng = other.rng.clone();
98
-    }
99
-
100
-    pub fn gen_range(&mut self, low: u32, high: u32) -> u32 {
101
-        let a = self.rng.next_u32();
102
-        (a % (high - low)) + low
103
-    }
104
-
105
-    // 0..1
106
-    pub fn prng_f32(&mut self) -> f32 {
107
-        let a = self.rng.next_u32();
108
-
109
-        a as f32 / std::u32::MAX as f32
110
-    }
111
-
112
-    pub fn prng_f32_range(&mut self, min: f32, max: f32) -> f32 {
113
-        let value = self.prng_f32();
114
-        (value * (max - min)) + min
115
-    }
116
-
117
-    pub fn prng_usize_range(&mut self, min: usize, max: usize) -> usize {
118
-        self.prng_f32_range(min as f32, max as f32) as usize
119
-    }
120
-
121
-    pub fn prng_f32_defined_range(&mut self) -> f32 {
122
-        let value = self.prng_f32();
123
-        (value * (self.max - self.min)) + self.min
124
-    }
125
-
126
-    pub fn prng_f32_around(&mut self, val: f32, percent: f32, min: f32, max: f32) -> f32 {
127
-        let value = self.prng_f32();
128
-        let range = ((max - min) / 100.0) * percent;
129
-        let lowest = val - range;
130
-        let highest = val + range;
131
-        let res = (value * (highest - lowest)) + lowest;
132
-
133
-        clamp(res, min, max)
134
-    }
135
-
136
-    fn make_xor_shift_rng(seed: i32) -> XorShiftRng {
137
-        let seedy: [u8; 16] = [
138
-            as_u8(seed),
139
-            as_u8(seed + 1),
140
-            as_u8(seed + seed - 2),
141
-            as_u8(seed + 3),
142
-            as_u8(seed + seed - 4),
143
-            as_u8(seed + 5),
144
-            as_u8(seed + seed - 6),
145
-            as_u8(seed + 7),
146
-            as_u8(seed + seed - 8),
147
-            as_u8(seed + 9),
148
-            as_u8(seed + seed - 10),
149
-            as_u8(seed + 11),
150
-            as_u8(seed + seed - 12),
151
-            as_u8(seed + 13),
152
-            as_u8(seed + seed - 14),
153
-            as_u8(seed + 15),
154
-        ];
155
-
156
-        XorShiftRng::from_seed(seedy)
157
-    }
158
-}
159
-
160 162
 fn fade(t: f32) -> f32 {
161 163
     t * t * t * (t * (t * 6.0 - 15.0) + 10.0)
162 164
 }
@@ -243,7 +245,7 @@ pub mod tests {
243 245
              (probe scalar: (prng/value from: p))
244 246
              (probe scalar: (prng/value from: p))
245 247
              (probe scalar: (prng/value from: p))",
246
-            "0.36151162 0.4412291 0.37725854 0.5783009 0.65834785 0.48318255 0.7342905 0.44944018 0.56456256",
248
+            "0.16439326 0.58795106 0.12325332 0.039127756 0.9678266 0.8247009 0.787962 0.13722154 0.94319534",
247 249
         );
248 250
     }
249 251
 
@@ -260,7 +262,7 @@ pub mod tests {
260 262
              (probe scalar: (prng/value from: p))
261 263
              (probe scalar: (prng/value from: p))
262 264
              (probe scalar: (prng/value from: p))",
263
-            "5.3797703 7.0697656 4.541839 7.1620464 6.7335386 3.5603561 3.4189374 3.1284251 8.890152",
265
+            "7.696081 6.462363 6.579473 4.650559 5.4763083 4.6319327 8.11852 6.7570615 5.3803825",
264 266
         );
265 267
     }
266 268
 
@@ -272,7 +274,7 @@ pub mod tests {
272 274
              (probe scalar: (nth from: vs n: 0))
273 275
              (probe scalar: (nth from: vs n: 1))
274 276
              (probe scalar: (nth from: vs n: 2))",
275
-            "0.36151162 0.4412291 0.37725854",
277
+            "0.16439326 0.58795106 0.12325332",
276 278
         );
277 279
     }
278 280
 
@@ -282,19 +284,19 @@ pub mod tests {
282 284
             "(define p (prng/build seed: 5 min: 0 max: 1))
283 285
              (define vs (prng/values from: p num: 3))
284 286
              (nth from: vs n: 0)",
285
-            0.36151162,
287
+            0.16439326,
286 288
         );
287 289
         is_float(
288 290
             "(define p (prng/build seed: 5 min: 0 max: 1))
289 291
              (define vs (prng/values from: p num: 3))
290 292
              (nth from: vs n: 1)",
291
-            0.4412291,
293
+            0.58795106,
292 294
         );
293 295
         is_float(
294 296
             "(define p (prng/build seed: 5 min: 0 max: 1))
295 297
              (define vs (prng/values from: p num: 3))
296 298
              (nth from: vs n: 2)",
297
-            0.37725854,
299
+            0.12325332,
298 300
         );
299 301
     }
300 302
 
@@ -303,11 +305,10 @@ pub mod tests {
303 305
         let mut prng = PrngStateStruct::new(542, 0.0, 1.0);
304 306
 
305 307
         for _ in 0..100 {
306
-            let f = prng.prng_f32();
308
+            let f = prng.next_f32();
307 309
             println!("{}", f);
308 310
         }
309 311
 
310
-        assert_eq!(prng.prng_f32(), 0.7896869);
312
+        assert_eq!(prng.next_f32(), 0.49469042);
311 313
     }
312
-
313 314
 }

+ 16
- 21
core/src/unparser.rs View File

@@ -402,35 +402,35 @@ mod tests {
402 402
         seeded_unparse_check(
403 403
             975,
404 404
             "(+ 6 {3 (gen/int min: 1 max: 50)})",
405
-            "(+ 6 {46 (gen/int min: 1 max: 50)})",
405
+            "(+ 6 {42 (gen/int min: 1 max: 50)})",
406 406
         );
407 407
         seeded_unparse_check(
408 408
             975,
409 409
             "{rainbow (gen/select from: col/procedural-fn-presets)}",
410
-            "{transformers (gen/select from: col/procedural-fn-presets)}",
410
+            "{robocop (gen/select from: col/procedural-fn-presets)}",
411 411
         );
412 412
         seeded_unparse_check(
413 413
             342,
414 414
             "[8 {3 (gen/int min: 0 max: 9)}]",
415
-            "[8 {4 (gen/int min: 0 max: 9)}]",
415
+            "[8 {5 (gen/int min: 0 max: 9)}]",
416 416
         );
417 417
 
418 418
         seeded_unparse_check(
419 419
             764,
420 420
             "{3.45 (gen/scalar min: 0 max: 9)}",
421
-            "{2.38 (gen/scalar min: 0 max: 9)}",
421
+            "{4.08 (gen/scalar min: 0 max: 9)}",
422 422
         );
423 423
 
424 424
         seeded_unparse_check(
425 425
             764,
426 426
             "{3.4 (gen/scalar min: 0 max: 9)}",
427
-            "{2.4 (gen/scalar min: 0 max: 9)}",
427
+            "{4.1 (gen/scalar min: 0 max: 9)}",
428 428
         );
429 429
 
430 430
         seeded_unparse_check(
431 431
             764,
432 432
             "(col/rgb r: {0.4 (gen/scalar)} g: 0.1)",
433
-            "(col/rgb r: {0.3 (gen/scalar)} g: 0.1)",
433
+            "(col/rgb r: {0.5 (gen/scalar)} g: 0.1)",
434 434
         );
435 435
 
436 436
         seeded_unparse_check(
@@ -447,30 +447,25 @@ mod tests {
447 447
 (gen/int min: 80 max: 670)}) (rect position: [500 500] colour: red
448 448
 width: {120 (gen/int min: 80 max: 400)} height: {140 (gen/int min: 80
449 449
 max: 670)})",
450
-            "(rect position: [500 500] colour: red width: {164 (gen/int min: 80 max:
451
-400)} height: {562 (gen/int min: 80 max: 670)}) (rect position: [500
452
-500] colour: red width: {289 (gen/int min: 80 max: 400)} height: {663
453
-(gen/int min: 80 max: 670)}) (rect position: [500 500] colour: red
454
-width: {210 (gen/int min: 80 max: 400)} height: {148 (gen/int min: 80
455
-max: 670)})",
450
+            "(rect position: [500 500] colour: red width: {225 (gen/int min: 80 max:\n400)} height: {466 (gen/int min: 80 max: 670)}) (rect position: [500\n500] colour: red width: {135 (gen/int min: 80 max: 400)} height: {603\n(gen/int min: 80 max: 670)}) (rect position: [500 500] colour: red\nwidth: {192 (gen/int min: 80 max: 400)} height: {624 (gen/int min: 80\nmax: 670)})",
456 451
         );
457 452
 
458 453
         seeded_unparse_check(
459 454
             764,
460 455
             "{b (gen/select from: '(a b c))}",
461
-            "{a (gen/select from: '(a b c))}",
456
+            "{b (gen/select from: '(a b c))}",
462 457
         );
463 458
 
464 459
         seeded_unparse_check(
465 460
             764,
466 461
             "{(col/rgb r: 1 g: 0 b: 0.4 alpha: 1) (gen/col)}",
467
-            "{(col/rgb r: 0.82 g: 0.65 b: 0.99 alpha: 0.26) (gen/col)}",
462
+            "{(col/rgb r: 0.65 g: 0.17 b: 0.89 alpha: 0.45) (gen/col)}",
468 463
         );
469 464
 
470 465
         seeded_unparse_check(
471 466
             653,
472 467
             "{(col/rgb r: 1 g: 0 b: 0.4 alpha: 1) (gen/col alpha: 1)}",
473
-            "{(col/rgb r: 0.78 g: 0.97 b: 0.89 alpha: 1.00) (gen/col alpha: 1)}",
468
+            "{(col/rgb r: 0.75 g: 0.59 b: 0.33 alpha: 1.00) (gen/col alpha: 1)}",
474 469
         );
475 470
     }
476 471
 
@@ -479,25 +474,25 @@ max: 670)})",
479 474
         seeded_unparse_check(
480 475
             653,
481 476
             "{[[1.00 2.00] [3.00 4.00]] (gen/2d)}",
482
-            "{[[0.78 0.97] [0.89 0.11]] (gen/2d)}",
477
+            "{[[0.75 0.59] [0.33 0.85]] (gen/2d)}",
483 478
         );
484 479
 
485 480
         seeded_unparse_check(
486 481
             653,
487 482
             "{[[  1.00   2.00  ] [  3.00   4.00  ]] (gen/2d)}",
488
-            "{[[  0.78   0.97  ] [  0.89   0.11  ]] (gen/2d)}",
483
+            "{[[  0.75   0.59  ] [  0.33   0.85  ]] (gen/2d)}",
489 484
         );
490 485
 
491 486
         seeded_unparse_check(
492 487
             653,
493 488
             "{[[10 20] [30 40]] (gen/2d min: 60 max: 70)}",
494
-            "{[[68 70] [69 61]] (gen/2d min: 60 max: 70)}",
489
+            "{[[67 66] [63 69]] (gen/2d min: 60 max: 70)}",
495 490
         );
496 491
 
497 492
         seeded_unparse_check(
498 493
             653,
499 494
             "{ [ [ 50.1 60.23 ] [ 70.456 80.7890 ]] (gen/2d min: 40 max: 90) }",
500
-            "{ [ [ 79.1 88.54 ] [ 84.577 45.4872 ]] (gen/2d min: 40 max: 90) }",
495
+            "{ [ [ 77.3 69.69 ] [ 56.680 82.6415 ]] (gen/2d min: 40 max: 90) }",
501 496
         );
502 497
     }
503 498
 
@@ -506,7 +501,7 @@ max: 670)})",
506 501
         seeded_unparse_check(
507 502
             764,
508 503
             "{[10 20] (gen/stray-2d from: [10 20] by: [5 5])}",
509
-            "{[8 23] (gen/stray-2d from: [10 20] by: [5 5])}",
504
+            "{[10 22] (gen/stray-2d from: [10 20] by: [5 5])}",
510 505
         );
511 506
     }
512 507
 
@@ -515,7 +510,7 @@ max: 670)})",
515 510
         seeded_unparse_check(
516 511
             764,
517 512
             "{[0.977 0.416 0.171] (gen/scalar)}",
518
-            "{[0.265 0.816 0.654] (gen/scalar)}",
513
+            "{[0.454 0.653 0.172] (gen/scalar)}",
519 514
         );
520 515
     }
521 516
 

+ 9
- 1
server/static/gallery.json View File

@@ -1,5 +1,13 @@
1 1
 [
2
-  {"id":65,"name":"1918-dev-bitmap","image":"img/seni/blank.png"},
2
+  {"id":73,"name":"1918-dev-bitmap","image":"img/seni/blank.png"},
3
+  {"id":72,"name":"sketch/1922-skull-face","image":"img/seni/blank.png"},
4
+  {"id":71,"name":"sketch/1922-skull","image":"img/seni/blank.png"},
5
+  {"id":70,"name":"sketch/1921-yellow-skull-helmet","image":"img/seni/blank.png"},
6
+  {"id":69,"name":"sketch/1922-hand","image":"img/seni/blank.png"},
7
+  {"id":68,"name":"sketch/1922-pencil-skull","image":"img/seni/blank.png"},
8
+  {"id":67,"name":"sketch/1919-skull","image":"img/seni/blank.png"},
9
+  {"id":66,"name":"1918-skull","image":"img/seni/blank.png"},
10
+  {"id":65,"name":"1918-einstein","image":"img/seni/blank.png"},
3 11
   {"id":64,"name":"1841-schotteresque","image":"img/seni/160c-schotter.png"},
4 12
   {"id":63,"name":"1841-nib","image":"img/seni/1841-nib.png"},
5 13
   {"id":62,"name":"1840-boxes","image":"img/seni/1840-boxes.png"},

Loading…
Cancel
Save