-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathstep1-nft-generator.js
More file actions
117 lines (93 loc) · 2.78 KB
/
step1-nft-generator.js
File metadata and controls
117 lines (93 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
const fs = require('fs');
var BigNumber = require('bignumber.js');
const config = require('./config.js');
const attributes = config.attributes;
function getRandomInt(max) {
return BigNumber.random(20)
.multipliedBy(max - 1)
.plus(1)
.integerValue();
}
function attributeName(i) {
return attributes[i].name;
}
function propertyName(i, j) {
const property = attributes[i].values[j - 1];
return property?.value ? property?.value : property;
}
function logAttributes(prefix, face) {
console.log(prefix, face.map((value, index) => {
return [attributeName(index), propertyName(index, value)];
}));
}
function getLenByWeights(values, required = false) {
const weight = values.reduce((acc, v) => {
return acc + (typeof v === "object" && v.weight ? v.weight : 1);
}, 0);
return weight + !+required;
}
function mapValueByWeight(values, property) {
const map = {};
values.forEach((value, index) => {
const weight = typeof value === "object" && value.weight ? value.weight : 1;
const lastIndex = Object.keys(map).length;
for (let i=0; i<weight; i++) {
map[lastIndex + i + 1] = index + 1;
}
});
return property ? map[property] : property;
}
function codeToArray(code) {
let arr = [];
for (let i=attributes.length-1; i>=0; i--) {
const len = getLenByWeights(
attributes[i].values,
attributes[i].required,
);
let property = parseInt(code.mod(len).toFixed()) + +attributes[i].required;
arr[i] = mapValueByWeight(attributes[i].values, property);
code = code.minus(arr[i]).dividedBy(len).integerValue();
}
return arr;
}
function bnIncludes(arr, bn) {
for (let i=0; i<arr.length; i++) {
if (arr[i].eq(bn)) return true;
}
return false;
}
function generateNFTs() {
// Get a bigint of possible combinations
let combinations = new BigNumber(1);
for (let i=0; i<attributes.length; i++) {
combinations = combinations.multipliedBy(
getLenByWeights(attributes[i].values, attributes[i].required)
);
}
console.log(`Possible combinations: ${combinations.toString()}`);
// generate desired count of different random numbers in the range
let faceCodes = [];
let faces = [];
while (
faces.length < config.desiredCount &&
combinations.isGreaterThan(faceCodes.length)
) {
let code = getRandomInt(combinations);
if (!bnIncludes(faceCodes, code)) {
faceCodes.push(code);
const face = codeToArray(code);
logAttributes('Randomized NFT:', face);
faces.push(face);
}
}
console.log('faces', faces.length);
// Save faces
if (!fs.existsSync(config.outputFolder)){
fs.mkdirSync(config.outputFolder);
}
fs.writeFileSync(`${config.outputFolder}/${config.outputJSON}`, JSON.stringify(faces));
}
function main() {
generateNFTs();
}
main();