using System; using System.Collections.Generic; using UnityEngine; [Serializable] public struct BitSet8 { [SerializeField] byte m_set; public int bitCount => 8; public void SetBit(int index, bool value) { if (index < 0 || index >= 8) return; byte mask = (byte)(1 << index); if (!value) m_set &= (byte)~mask; else m_set |= mask; } public bool GetBit(int index) { if (index < 0 || index >= 8) return false; return (m_set & (byte)(1 << index)) != 0; } public bool GetBitsAll(int count) { count = Math.Min(count, bitCount); byte mask = (byte)(byte.MaxValue >> (bitCount - count)); return (m_set & mask) == mask; } public bool GetBitsAny(int count) { count = Math.Min(count, bitCount); byte mask = (byte)(byte.MaxValue >> (bitCount - count)); return (m_set & mask) != 0; } public void Reset() => m_set = 0; static public implicit operator BitSet8(byte value) => new BitSet8 { m_set = value }; } [Serializable] public class BitSet16 { [SerializeField] ushort m_set; public int bitCount => 16; public void setBit(int index, bool value) { if (index < 0 || index >= 16) return; ushort mask = (ushort)(1 << index); if (!value) m_set &= (ushort)~mask; else m_set |= mask; } public bool getBit(int index) { if (index < 0 || index >= 16) return false; return (m_set & (ushort)(1 << index)) != 0; } public void reset() => m_set = 0; static public implicit operator BitSet16(ushort value) => new BitSet16 { m_set = value }; } [Serializable] public class Bitset32 { public struct Mask { public readonly uint v; public Mask(uint value) => v = value; } [SerializeField] uint bitSet; public int bitCount => 32; public void SetBit(int index, bool value) { if (index < 0 || index >= 32) return; uint mask = (uint)1 << index; if (!value) bitSet &= ~mask; else bitSet |= mask; } public bool GetBit(int index) { if (index < 0 || index >= bitCount) return false; return (bitSet & ((uint)1 << index)) != 0; } public bool MatchAll(Bitset32 other) => (bitSet & other.bitSet) == other.bitSet; public bool MatchAll(Mask mask) => (bitSet & mask.v) == mask.v; public bool MatchAny(Bitset32 other) => (bitSet & other.bitSet) != 0; public bool MatchAny(Mask mask) => (bitSet & mask.v) != 0; public void Reset() => bitSet = 0; public static Mask GetMask(params int[] indices) { uint mask = 0; foreach (var index in indices) { if (index < 0 || index >= 32) continue; mask |= (uint)1 << index; } return new Mask(mask); } public static Mask GetMask(params Enum[] indices) { uint mask = 0; foreach (var index in indices) { int i = Convert.ToInt32(index); if (i < 0 || i >= 32) continue; mask |= (uint)1 << i; } return new Mask(mask); } public static Mask GetMask(IReadOnlyList indices) { uint mask = 0; foreach (var index in indices) { int i = Convert.ToInt32(index); if (i < 0 || i >= 32) continue; mask |= (uint)1 << i; } return new Mask(mask); } public static implicit operator Bitset32(uint value) => new Bitset32 { bitSet = value }; } [Serializable] public class BitSetArray { [SerializeField] byte[] m_set = new byte[] { 0 }; public int bitCount => m_set.Length * 8; public void setBit(int index, bool value) { int arrayIndex = index / 8; int bitIndex = index % 8; if (arrayIndex >= m_set.Length) Array.Resize(ref m_set, arrayIndex + 1); byte mask = (byte)(1 << bitIndex); if (!value) m_set[arrayIndex] &= (byte)~mask; else m_set[arrayIndex] |= mask; } public bool getBit(int index) { if (index >= bitCount) return false; int arrayIndex = index / 8; int bitIndex = index % 8; return (m_set[arrayIndex] & (byte)(1 << bitIndex)) != 0; } public bool getBitsAny(int count) { count = Math.Min(count, bitCount); int targetByteIndex = 0; while (count > 0) { if ((m_set[targetByteIndex] & byte.MaxValue >> (8 - Math.Min(count, 8))) != 0) return true; count -= 8; ++targetByteIndex; } return false; } public void reset() => m_set = new byte[] { new byte() }; public void shrinkToFit() { int i; for (i = m_set.Length - 1; i >= 0; i--) { if (m_set[i] != 0) break; } Array.Resize(ref m_set, i + 1); } }