Praneat Blog

Yosapol Jitrak
Game Developer & Game Infrastructure
20 Apr 2020

Bitwise C# [3/3] Apply Bitwise

หลังจากที่ปูพื้นจาก Bitwise C# [1/3] Why to Bitwise
และ Bitwise C# [2/3] Bitwise Operator กันไปแล้ว
บทความนี้จะพาคุณผู้อ่านไปดูการประยุกต์ใช้กันจริง ๆ แล้ว


ไม่รู้ยังจำปัญหาของเราตั้งแต่บทความแรกได้อยู่หรือเปล่า
ขอเกริ่นให้นึกออกกันสักนิดหน่อยนะครับ
ผมได้โจทย์ทำเกมผสมสี มีสีตามนี้ เหมือนเดิมเลยครับ

  • สีขาว
  • สีแดง
  • สีน้ำเงิน
  • สีเหลือง
  • สีม่วง
  • สีส้ม
  • สีเขียว

คิดว่าคงจะนึกออกกันบ้างแล้ว คราวนี้มาต่อกัน
การที่จะทำเรื่อง Bitwise ในภาษา C# ตามโจทย์ของเรานั้น
เรายังต้องใช้ Flags attribute
เพื่อให้ Enum type ของเราสามารถแสดงชุดของ Flags ได้

สุดท้ายแล้วหน้าตาของ ColorType ก็ออกมาเป็นดังนี้

[System.Flags]
public enum ColorType
{
    White = 0,
    Red = 1 << 0,
    Blue = 1 << 1,
    Yellow = 1 << 2,
    Purple = Red | Blue,
    Orange = Red | Yellow,
    Green = Blue | Yellow,  
}


เวลาเอาไปใช้งานก็จะประมาณนี้

ColorType colorType = color1 | color2;
bool isPurple = colorType == ColorType.Purple;



ขอยกอีกตัวอย่างนึงเป็นเรื่องเช็คสถานะ Quest ว่าตรงตามเงื่อนไขของเราหรือเปล่า
โดยมี Quest state ดังนี้

[System.Flags]
public enum QuestState 
{

    /// <summary>
    /// Quest is unassigned
    /// </summary>
    Unassigned = 0x1,

    /// <summary>
    /// Quest is active (assigned but not completed yet)
    /// </summary>
    Active = 0x2,

    /// <summary>
    /// Quest was completed successfully; corresponds to "success" or "done"
    /// </summary>
    Success = 0x4,

    /// <summary>
    /// Quest was completed in failure
    /// </summary>
    Failure = 0x8,

    /// <summary>
    /// Quest was abandoned
    /// </summary>
    Abandoned = 0x10
}

อันนี้เอามาจาก Plugin ชื่อว่า Dialogue System
(ที่น่าตามันเป็นแบบนี้ เพราะเขาเขียนในรูปแบบของเลขฐาน 16 นะครับ)


ทีนี้ปัญหามันเกิดก็ตอนที่ต้องการจะเช็คอะไรสักอย่าง
ให้ทำงานก็ต่อเมื่อ Quest เป็นสถานะนึง หรืออีกสถานะนึงก็ได้
เช่น เป็นทั้ง Active หรือ Success ก็ได้ ถึงจะทำงานที่ต้องการ

QuestState questState = QuestState.Active | QuestState.Success;


การที่เราจะเช็คว่าสถานะ Quest ของเรานั้นเป็นค่าใดค่าหนึ่งในเงื่อนไขหรือเปล่า
เราจะต้องใช้ตัวดำเนินการ &(AND) มาช่วย จะเขียนได้แบบนี้

bool isQuestStateMatch = (quest.QuestState & matchQuestState) == quest.QuestState;
if (isQuestStateMatch) ...


จะเห็นได้ว่าหากเราเสียเวลาคิด และหาข้อมูล ก่อนที่จะลงมือทำไป
อาจจะช่วยเราลดความยุ่งยากซับซ้อนในการทำงานของเราไปได้มาก


Link: Bitwise C# [1/3] Why to Bitwise
Link: Bitwise C# [2/3] Bitwise Operator