The tile result doesn't look right
This commit is contained in:
247
Set.gd
Normal file
247
Set.gd
Normal file
@@ -0,0 +1,247 @@
|
||||
class_name Set extends RefCounted
|
||||
## A custom implementation of a set data structure in GDScript.
|
||||
##
|
||||
## Usage Example:
|
||||
## [codeblock]
|
||||
## var mySet = Set.new([1, 2, 3])
|
||||
## var otherSet = Set.new([2, 3, 4])
|
||||
##
|
||||
## var differenceSet = mySet.difference(otherSet)
|
||||
## print(differenceSet.elements()) # Output: [1]
|
||||
##
|
||||
## mySet.intersection_update(otherSet)
|
||||
## print(mySet.elements()) # Output: [2, 3]
|
||||
## [/codeblock]
|
||||
|
||||
|
||||
var _set := {}
|
||||
|
||||
## The constructor initializes the set with elements from the specified object,
|
||||
## supporting various data types. Unsupported types trigger an assertion error.
|
||||
func _init(obj: Variant = null) -> void:
|
||||
match typeof(obj):
|
||||
TYPE_ARRAY, TYPE_PACKED_BYTE_ARRAY, TYPE_PACKED_COLOR_ARRAY, \
|
||||
TYPE_PACKED_FLOAT32_ARRAY, TYPE_PACKED_FLOAT64_ARRAY, \
|
||||
TYPE_PACKED_INT32_ARRAY, TYPE_PACKED_INT64_ARRAY, \
|
||||
TYPE_PACKED_VECTOR2_ARRAY, TYPE_PACKED_VECTOR3_ARRAY, \
|
||||
TYPE_PACKED_STRING_ARRAY:
|
||||
for element in obj:
|
||||
add(element)
|
||||
TYPE_NIL: pass
|
||||
_:
|
||||
assert(false, "Type %s unsupported for Set objects" % [typeof(obj)])
|
||||
|
||||
## Adds an [param element] to the set.
|
||||
func add(element: Variant) -> void:
|
||||
_set[element] = 0
|
||||
|
||||
## Clears all elements from the set.
|
||||
func clear() -> void:
|
||||
_set.clear()
|
||||
|
||||
## Creates and returns a new [Set] containing the same elements as the current set.
|
||||
func duplicate() -> Set:
|
||||
var new_set := Set.new()
|
||||
new_set._set = _set.duplicate()
|
||||
return new_set
|
||||
|
||||
# O(min(|self|, |set|))
|
||||
## Returns a new [Set] containing elements that are present in the current set
|
||||
## but not in the provided [param set].
|
||||
func difference(set: Set) -> Set:
|
||||
if set.hash() == self.hash():
|
||||
return Set.new()
|
||||
var out := self.duplicate()
|
||||
if set.size() > self.size():
|
||||
for element in self.elements():
|
||||
if set.has(element):
|
||||
out.erase(element)
|
||||
else:
|
||||
for element in set.elements():
|
||||
out.erase(element)
|
||||
return out
|
||||
|
||||
# O(min(|self|, |set|))
|
||||
## Modifies the current [Set] to contain elements present in the current set\
|
||||
## but not in the provided [param set].
|
||||
func difference_update(set: Set) -> void:
|
||||
if set.hash() == self.hash():
|
||||
self.clear()
|
||||
return
|
||||
if set.size() > self.size():
|
||||
for element in self.elements():
|
||||
if set.has(element):
|
||||
self.erase(element)
|
||||
else:
|
||||
for element in set.elements():
|
||||
self.erase(element)
|
||||
|
||||
# O(min(|self|, |set|))
|
||||
## Returns a new [Set] containing elements common to both the current set and
|
||||
## the provided [param set].
|
||||
func intersection(set: Set) -> Set:
|
||||
if set.hash() == self.hash():
|
||||
return duplicate()
|
||||
var out := Set.new()
|
||||
if set.size() > self.size():
|
||||
for element in self.elements():
|
||||
if set.has(element):
|
||||
out.add(element)
|
||||
else:
|
||||
for element in set.elements():
|
||||
if self.has(element):
|
||||
out.add(element)
|
||||
return out
|
||||
|
||||
# O(min(|self|, |set|))
|
||||
## Modifies the current set to contain only elements common to both the
|
||||
## current set and the provided [param set].
|
||||
func intersection_update(set: Set) -> void:
|
||||
if set.hash() == self.hash():
|
||||
return
|
||||
var out := Set.new()
|
||||
if set.size() > self.size():
|
||||
for element in self.elements():
|
||||
if set.has(element):
|
||||
out.add(element)
|
||||
else:
|
||||
for element in set.elements():
|
||||
if self.has(element):
|
||||
out.add(element)
|
||||
self.clear()
|
||||
self._set = out._set
|
||||
|
||||
# O([1, min(|self|, |set|)])
|
||||
## Returns [code]true[/code] if the sets have no elements in common;
|
||||
## otherwise, returns [code]false[/code].
|
||||
func isdisjoint(set: Set) -> bool:
|
||||
if set.size() > self.size():
|
||||
for element in self.elements():
|
||||
if set.has(element):
|
||||
return false
|
||||
else:
|
||||
for element in set.elements():
|
||||
if self.has(element):
|
||||
return false
|
||||
return true
|
||||
|
||||
# O([1, |self|])
|
||||
## Returns [code]true[/code] if every element of the current set is present
|
||||
## in the provided [param set]; otherwise, returns [code]false[/code].
|
||||
func issubset(set: Set) -> bool:
|
||||
if set.size() < self.size():
|
||||
return false
|
||||
else:
|
||||
for element in self.elements():
|
||||
if !set.has(element):
|
||||
return false
|
||||
return true
|
||||
|
||||
# O([1, |set|])
|
||||
## Returns [code]true[/code] if every element of the provided [param set]
|
||||
## is present in the current set; otherwise, returns [code]false[/code].
|
||||
func issuperset(set: Set) -> bool:
|
||||
if self.size() < set.size():
|
||||
return false
|
||||
else:
|
||||
for element in set.elements():
|
||||
if !self.has(element):
|
||||
return false
|
||||
return true
|
||||
|
||||
# O(|self|) ?
|
||||
## Removes and returns an arbitrary element from the set.
|
||||
func pop() -> Variant:
|
||||
assert(self.size() > 0)
|
||||
var element = self.elements()[randi() % self.size()]
|
||||
self.erase(element)
|
||||
return element
|
||||
|
||||
## Removes the specified [param element] from the set.
|
||||
func erase(element: Variant) -> void:
|
||||
_set.erase(element)
|
||||
|
||||
# O(min(|self|, |set|))
|
||||
## Returns a new [Set] containing elements that are present in either
|
||||
## the current set or the provided [param set], but not in both.
|
||||
func symmetric_difference(set: Set) -> Set:
|
||||
if set.hash() == self.hash():
|
||||
return Set.new()
|
||||
if set.size() > self.size():
|
||||
var out := set.duplicate()
|
||||
for element in self.elements():
|
||||
if set.has(element):
|
||||
out.remove(element)
|
||||
return out
|
||||
else:
|
||||
var out := self.duplicate()
|
||||
for element in set.elements():
|
||||
if self.has(element):
|
||||
out.remove(element)
|
||||
return out
|
||||
|
||||
# O(min(|self|, |set|))
|
||||
## Modifies the current set to contain elements that are present in either
|
||||
## the current set or the provided [param set], but not in both.
|
||||
func symmetric_difference_update(set: Set) -> void:
|
||||
if set.size() > self.size():
|
||||
var temp := set.duplicate()
|
||||
for element in self.elements():
|
||||
if temp.has(element):
|
||||
temp.erase(element)
|
||||
else:
|
||||
temp.add(element)
|
||||
self._set = temp._set
|
||||
else:
|
||||
for element in set.elements():
|
||||
if self.has(element):
|
||||
self.erase(element)
|
||||
else:
|
||||
self.add(element)
|
||||
|
||||
# O(min(|self|, |set|))
|
||||
## Returns a new [Set] containing all elements from both the current
|
||||
## set and the provided [param set].
|
||||
func union(set: Set) -> Set:
|
||||
if set.size() > self.size():
|
||||
var out := set.duplicate()
|
||||
for element in self.elements():
|
||||
out.add(element)
|
||||
return out
|
||||
else:
|
||||
var out := self.duplicate()
|
||||
for element in set.elements():
|
||||
out.add(element)
|
||||
return out
|
||||
|
||||
# O(min(|self|, |set|))
|
||||
## Modifies the current set to contain all elements from both the current set
|
||||
## and the provided [param set].
|
||||
func update(set: Set) -> void:
|
||||
if set.size() > self.size():
|
||||
var temp := set.duplicate()
|
||||
for element in self.elements():
|
||||
temp.add(element)
|
||||
self._dict = temp._dict
|
||||
else:
|
||||
var temp := self.duplicate()
|
||||
for element in set.elements():
|
||||
temp.add(element)
|
||||
self._dict = temp.dict
|
||||
|
||||
## Returns an [Array] containing all elements of the set.
|
||||
func elements() -> Array:
|
||||
return _set.keys()
|
||||
|
||||
## Returns [code]true[/code] if the set contains the specified [param element];
|
||||
## otherwise, returns [code]false[/code].
|
||||
func has(element: Variant) -> bool:
|
||||
return _set.has(element)
|
||||
|
||||
## Returns the number of elements in the set.
|
||||
func size() -> int:
|
||||
return _set.size()
|
||||
|
||||
## Returns a hash value for the set.
|
||||
func hash() -> int:
|
||||
return _set.hash()
|
||||
Reference in New Issue
Block a user