2022-03-08 03:21:25 +00:00
|
|
|
# Purpose:
|
|
|
|
# The purpose of this file is to add logic and rules to the DNA that are sent to the NFTRecord.json file in DNA_Generator.py
|
|
|
|
|
|
|
|
import bpy
|
|
|
|
import json
|
|
|
|
import random
|
2022-03-11 01:03:20 +00:00
|
|
|
import collections
|
2022-03-08 03:21:25 +00:00
|
|
|
|
2022-03-12 17:02:01 +00:00
|
|
|
|
2022-03-11 01:03:20 +00:00
|
|
|
# Helper Functions
|
2022-03-08 03:21:25 +00:00
|
|
|
def isAttorVar(hierarchy, items_List):
|
2022-03-11 01:03:20 +00:00
|
|
|
items_returned = collections.defaultdict(list)
|
2022-03-08 03:21:25 +00:00
|
|
|
for i in items_List:
|
|
|
|
for j in hierarchy:
|
|
|
|
if i == j: # If i is an Attribute, add all i Variants to dictionary.
|
|
|
|
items_returned[i] = list(hierarchy[j].keys())
|
|
|
|
items_returned[i].append("Empty")
|
|
|
|
|
2022-03-11 01:03:20 +00:00
|
|
|
if i in list(hierarchy[j].keys()):
|
|
|
|
items_returned[j].append(i)
|
2022-03-08 03:21:25 +00:00
|
|
|
|
|
|
|
# Check if all variants in an attribute were included, if so, add "Empty" variant.
|
|
|
|
for i in items_returned:
|
|
|
|
if list(items_returned[i]) == list(hierarchy[i].keys()):
|
|
|
|
items_returned[i].append("Empty")
|
|
|
|
|
2022-03-11 01:03:20 +00:00
|
|
|
return dict(items_returned)
|
2022-03-08 03:21:25 +00:00
|
|
|
|
|
|
|
def getAttIndex(hierarchy, attribute):
|
|
|
|
attList = list(hierarchy.keys())
|
|
|
|
index = attList.index(attribute)
|
|
|
|
return index
|
|
|
|
|
|
|
|
def getVarNum(variant):
|
|
|
|
if variant == "Empty":
|
|
|
|
num = '0'
|
|
|
|
else:
|
|
|
|
num = variant.split("_")[1]
|
|
|
|
return num
|
|
|
|
|
2022-03-25 01:38:53 +00:00
|
|
|
def items_to_num(items_List):
|
2022-03-08 03:21:25 +00:00
|
|
|
num_List = {}
|
|
|
|
for i in items_List:
|
|
|
|
variant_num_list = []
|
|
|
|
|
|
|
|
for j in items_List[i]:
|
|
|
|
variant_num_list.append(getVarNum(j))
|
|
|
|
|
2022-03-11 01:03:20 +00:00
|
|
|
num_List[i] = variant_num_list
|
|
|
|
return num_List
|
2022-03-08 03:21:25 +00:00
|
|
|
|
2022-03-11 01:03:20 +00:00
|
|
|
def rar_selectVar(hierarchy, items_List, deconstructed_DNA):
|
|
|
|
for attribute in items_List:
|
|
|
|
|
|
|
|
a_attribute_index = getAttIndex(hierarchy, attribute)
|
|
|
|
|
|
|
|
selected_variants = items_List[attribute]
|
|
|
|
hierarchy_selected_variants = list(hierarchy[attribute])
|
|
|
|
|
|
|
|
left_over_variants = [x for x in hierarchy_selected_variants if x not in selected_variants]
|
|
|
|
|
|
|
|
if not left_over_variants:
|
|
|
|
deconstructed_DNA[int(a_attribute_index)] = "0"
|
|
|
|
else:
|
|
|
|
number_List_Of_i = []
|
|
|
|
rarity_List_Of_i = []
|
|
|
|
ifZeroBool = None
|
|
|
|
variantNum = None
|
|
|
|
|
|
|
|
for a in left_over_variants:
|
|
|
|
number = a.split("_")[1]
|
|
|
|
rarity = a.split("_")[2]
|
|
|
|
|
|
|
|
number_List_Of_i.append(int(number))
|
|
|
|
rarity_List_Of_i.append(float(rarity))
|
|
|
|
|
|
|
|
for x in rarity_List_Of_i:
|
|
|
|
if x == 0:
|
|
|
|
ifZeroBool = True
|
|
|
|
elif x != 0:
|
|
|
|
ifZeroBool = False
|
2022-03-08 03:21:25 +00:00
|
|
|
|
2022-03-11 01:03:20 +00:00
|
|
|
if ifZeroBool:
|
|
|
|
variantNum = random.choices(number_List_Of_i, k=1)
|
|
|
|
|
|
|
|
if not ifZeroBool:
|
|
|
|
variantNum = random.choices(number_List_Of_i, weights=rarity_List_Of_i, k=1)
|
|
|
|
|
|
|
|
deconstructed_DNA[int(a_attribute_index)] = str(variantNum[0])
|
|
|
|
|
|
|
|
return deconstructed_DNA
|
|
|
|
|
2022-03-25 01:38:53 +00:00
|
|
|
def reconstructDNA(deconstructedDNA):
|
|
|
|
reconstructed_DNA = ""
|
|
|
|
for a in deconstructedDNA:
|
|
|
|
num = "-" + str(a)
|
|
|
|
reconstructed_DNA += num
|
|
|
|
return (''.join(reconstructed_DNA.split('-', 1)))
|
2022-03-12 17:02:01 +00:00
|
|
|
|
2022-04-09 17:34:43 +00:00
|
|
|
def strip_empty_variant(num_list):
|
2022-04-12 02:49:40 +00:00
|
|
|
"""Strips empty variants if full attribute collection. Used for processing below."""
|
2022-04-09 17:34:43 +00:00
|
|
|
for i in num_list:
|
|
|
|
var_list = num_list[i]
|
2022-04-12 02:49:40 +00:00
|
|
|
if "0" in var_list:
|
|
|
|
var_list.remove("0")
|
2022-04-09 17:34:43 +00:00
|
|
|
num_list[i] = var_list
|
|
|
|
return num_list
|
|
|
|
|
2022-03-25 01:38:53 +00:00
|
|
|
# Rule Checks:
|
2022-03-12 17:02:01 +00:00
|
|
|
def never_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
|
|
|
|
"""Returns True if singleDNA violates Never with Rule stated in Logic.json."""
|
|
|
|
violates_rule = None
|
2022-04-09 17:34:43 +00:00
|
|
|
|
|
|
|
num_List1 = strip_empty_variant(num_List1)
|
|
|
|
num_List2 = strip_empty_variant(num_List2)
|
|
|
|
|
2022-03-12 17:02:01 +00:00
|
|
|
for a in num_List1:
|
|
|
|
for b in num_List2:
|
|
|
|
if str(deconstructed_DNA[getAttIndex(hierarchy, a)]) in num_List1[a] and \
|
|
|
|
str(deconstructed_DNA[getAttIndex(hierarchy, b)]) in num_List2[b]:
|
|
|
|
violates_rule = True
|
|
|
|
return violates_rule
|
|
|
|
else:
|
|
|
|
violates_rule = False
|
|
|
|
return violates_rule
|
|
|
|
|
|
|
|
def only_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
|
2022-03-25 01:38:53 +00:00
|
|
|
"""Returns True if singleDNA violates Only with Rule stated in Logic.json."""
|
2022-03-12 17:02:01 +00:00
|
|
|
violates_rule = None
|
2022-04-09 17:34:43 +00:00
|
|
|
|
2022-03-12 17:02:01 +00:00
|
|
|
for a in num_List1:
|
|
|
|
for b in num_List2:
|
|
|
|
if str(deconstructed_DNA[getAttIndex(hierarchy, a)]) in num_List1[a] and \
|
|
|
|
str(deconstructed_DNA[getAttIndex(hierarchy, b)]) not in num_List2[b]:
|
|
|
|
violates_rule = True
|
|
|
|
return violates_rule
|
|
|
|
|
|
|
|
else:
|
|
|
|
violates_rule = False
|
|
|
|
return violates_rule
|
|
|
|
|
2022-03-25 01:38:53 +00:00
|
|
|
def always_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
|
|
|
|
"""Returns True if singleDNA violates Always with Rule stated in Logic.json."""
|
|
|
|
violates_rule = None
|
2022-04-09 17:34:43 +00:00
|
|
|
|
2022-03-25 01:38:53 +00:00
|
|
|
for a in num_List2:
|
|
|
|
if str(deconstructed_DNA[getAttIndex(hierarchy, a)]) not in num_List2[a]:
|
|
|
|
violates_rule = True
|
|
|
|
return violates_rule
|
|
|
|
else:
|
|
|
|
violates_rule = False
|
|
|
|
return violates_rule
|
|
|
|
|
2022-03-12 17:02:01 +00:00
|
|
|
|
2022-03-11 01:03:20 +00:00
|
|
|
# Main Function
|
2022-03-12 17:02:01 +00:00
|
|
|
def logicafyDNAsingle(hierarchy, singleDNA, logicFile):
|
2022-03-25 01:38:53 +00:00
|
|
|
|
2022-03-12 17:02:01 +00:00
|
|
|
deconstructed_DNA = singleDNA.split("-")
|
|
|
|
|
2022-03-25 01:38:53 +00:00
|
|
|
didReconstruct = True
|
|
|
|
originalDNA = str(singleDNA)
|
2022-03-12 17:02:01 +00:00
|
|
|
|
2022-03-25 01:38:53 +00:00
|
|
|
while didReconstruct:
|
|
|
|
didReconstruct = False
|
|
|
|
for rule in logicFile:
|
|
|
|
items_List1 = isAttorVar(hierarchy, logicFile[rule]["Items-1"])
|
|
|
|
items_List2 = isAttorVar(hierarchy, logicFile[rule]["Items-2"])
|
|
|
|
num_List1 = items_to_num(items_List1)
|
|
|
|
num_List2 = items_to_num(items_List2)
|
2022-03-12 17:02:01 +00:00
|
|
|
|
2022-04-20 01:04:17 +00:00
|
|
|
if logicFile[rule]["Rule-Type"] == "Never With":
|
2022-03-25 01:38:53 +00:00
|
|
|
if never_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
|
2022-03-11 01:03:20 +00:00
|
|
|
|
2022-03-25 01:38:53 +00:00
|
|
|
rand_bool = bool(random.getrandbits(1))
|
2022-03-08 03:21:25 +00:00
|
|
|
|
2022-03-25 01:38:53 +00:00
|
|
|
if rand_bool:
|
|
|
|
deconstructed_DNA = rar_selectVar(hierarchy, items_List2, deconstructed_DNA)
|
2022-03-08 03:21:25 +00:00
|
|
|
|
2022-03-25 01:38:53 +00:00
|
|
|
if not rand_bool:
|
2022-03-12 17:02:01 +00:00
|
|
|
deconstructed_DNA = rar_selectVar(hierarchy, items_List1, deconstructed_DNA)
|
2022-03-11 01:03:20 +00:00
|
|
|
|
2022-04-09 17:34:43 +00:00
|
|
|
newDNA = reconstructDNA(deconstructed_DNA)
|
|
|
|
if newDNA != originalDNA:
|
|
|
|
originalDNA = str(newDNA)
|
|
|
|
didReconstruct = True
|
|
|
|
break
|
|
|
|
|
2022-04-20 01:04:17 +00:00
|
|
|
if logicFile[rule]["Rule-Type"] == "Only With":
|
2022-03-25 01:38:53 +00:00
|
|
|
if only_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
|
|
|
|
for b in num_List1:
|
|
|
|
if "0" in num_List1[b]: # If complete attribute
|
|
|
|
deconstructed_DNA[getAttIndex(hierarchy, b)] = "0"
|
|
|
|
|
|
|
|
if "0" not in num_List1[b]: # Not complete attribute, select from other variants with rarity:
|
|
|
|
deconstructed_DNA = rar_selectVar(hierarchy, items_List1, deconstructed_DNA)
|
|
|
|
|
2022-04-09 17:34:43 +00:00
|
|
|
newDNA = reconstructDNA(deconstructed_DNA)
|
|
|
|
if newDNA != originalDNA:
|
|
|
|
originalDNA = str(newDNA)
|
|
|
|
didReconstruct = True
|
|
|
|
break
|
|
|
|
|
2022-04-20 01:04:17 +00:00
|
|
|
if logicFile[rule]["Rule-Type"] == "Always With":
|
2022-03-25 01:38:53 +00:00
|
|
|
if always_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
|
|
|
|
deconstructed_DNA = rar_selectVar(hierarchy, items_List1, deconstructed_DNA)
|
|
|
|
|
2022-04-09 17:34:43 +00:00
|
|
|
newDNA = reconstructDNA(deconstructed_DNA)
|
|
|
|
if newDNA != originalDNA:
|
|
|
|
originalDNA = str(newDNA)
|
|
|
|
didReconstruct = True
|
|
|
|
break
|
2022-03-12 17:02:01 +00:00
|
|
|
|
2022-04-20 01:04:17 +00:00
|
|
|
return str(reconstructDNA(deconstructed_DNA))
|