การพัฒนาเครื่องเล่นเกมเป่ายิ้งฉุบ (Rock-Paper-Scissors) ด้วยระบบสมองกลฝังตัวและจอแสดงผล OLED
บทความนี้เกิดจากโปรเจกต์ขนาดเล็ก (Mini-project) ในสมัยที่ผมยังเรียนวิศวกรรม โดยในตอนแรกผมตั้งใจจะพัฒนาเกมที่มีอินเทอร์เฟซผ่านหน้าจอสัมผัส (Touch Screen) แต่เนื่องจากข้อจำกัดด้านงบประมาณที่อาจบานปลาย ผมจึงตัดสินใจปรับเปลี่ยนมาใช้ปุ่มกดแบบ Tactile Buttons แทน ซึ่งนอกจากจะช่วยประหยัดต้นทุนแล้ว ยังช่วยให้เราได้เรียนรู้พื้นฐานการจัดการ Input/Output (I/O) และการออกแบบ State Machine ของเกมได้อย่างลึกซึ้งยิ่งขึ้น
กลไกของเกมและการออกแบบตรรกะ (Game Logic Design)
เกมเป่ายิ้งฉุบเป็นตัวอย่างที่คลาสสิกของ Zero-sum game ซึ่งผลลัพธ์ของผู้เล่นฝ่ายหนึ่งจะตรงข้ามกับอีกฝ่ายเสมอ ในโหมดการเล่นแบบ 1 ต่อ 1 เมื่อผู้เล่นแต่ละฝ่ายเลือกตัวเลือกจาก ค้อน (Rock), กระดาษ (Paper) และกรรไกร (Scissors) จะเกิดความเป็นไปได้ทั้งหมด 9 รูปแบบ (3^2) ซึ่งประกอบด้วยการชนะ การแพ้ และการเสมอ
เพื่อให้เห็นภาพรวมของการทำงาน เราสามารถสรุปผลลัพธ์ผ่านตารางความสัมพันธ์ได้ดังนี้:

เมื่อเรามีตรรกะที่ชัดเจนตามตารางข้างต้น การเขียนโปรแกรมด้วยเงื่อนไข if-else หรือ switch-case เพื่อประมวลผลและแสดงผลผ่านจอ OLED ก็จะทำได้ง่ายและเป็นระบบ
รายละเอียดอุปกรณ์และส่วนประกอบทางเทคนิค
ในการสร้างโปรเจกต์นี้ ผมเลือกใช้อุปกรณ์ที่หาได้ง่ายแต่มีประสิทธิภาพเพียงพอสำหรับการรัน Logic เกมแบบ Real-time:
- จอแสดงผล OLED (SSD1306): ใช้จอขนาด 0.96 นิ้ว ความละเอียด 128x64 พิกเซล เชื่อมต่อผ่านโปรโตคอล I2C (Inter-Integrated Circuit) ซึ่งใช้สายสัญญาณเพียง 2 เส้น (SDA และ SCL) ทำให้ประหยัดขา I/O ของไมโครคอนโทรลเลอร์
- ปุ่มกด Tactile Buttons (3 ชุด): ทำหน้าที่เป็น Input สำหรับ ค้อน, กระดาษ และกรรไกร ในทางวิศวกรรมเราต้องคำนึงถึงปรากฏการณ์ Switch Bouncing (การสั่นสะเทือนของหน้าสัมผัส) ดังนั้นในโค้ดจึงต้องมีการทำ Software Debouncing หรือใช้ฟังก์ชัน Delay สั้นๆ เพื่อให้อ่านค่าได้อย่างแม่นยำ
- ไมโครคอนโทรลเลอร์ (Arduino): ทำหน้าที่เป็นสมองกลางในการประมวลผล Logic และสุ่มค่าสำหรับโหมดสู้กับคอมพิวเตอร์
การออกแบบโหมดการเล่นและอัลกอริทึม
ผมได้พัฒนาฟีเจอร์ของเกมให้รองรับ 2 โหมดหลัก เพื่อความหลากหลายในการใช้งาน:
- Player vs Player (PvP): รับค่าจากปุ่มกดสองฝั่งเพื่อตัดสินผล
- Player vs Computer (PvC): ในโหมดนี้ คอมพิวเตอร์จะสร้าง Input ผ่านฟังก์ชัน
random()ของ Arduino โดยผมใช้ค่าจากขา Analog ที่ลอยไว้ (Floating Pin) มาเป็น Seed เพื่อให้การสุ่มมีความเป็นธรรมชาติที่สุด (Pseudo-random)
หากผลลัพธ์ออกมาเป็น "เสมอ" (Draw) ระบบถูกออกแบบให้ทำการ Restart เกมในโหมดเดิมโดยอัตโนมัติ จนกว่าจะมีการตัดสินผู้ชนะ เพื่อให้ Flow ของเกมมีความต่อเนื่อง
การจัดการหน่วยความจำและกราฟิก Bitmap
การใช้จอ OLED เป็นครั้งแรก สิ่งที่น่าตื่นเต้นที่สุดคือการแสดงผลกราฟิก Bitmap ผมได้ออกแบบภาพ Theme ของเกมและแปลงให้เป็น Hexadecimal Array เพื่อเก็บไว้ใน PROGMEM (Flash Memory) ของ Arduino วิธีนี้ช่วยประหยัดแรม (SRAM) ที่มีอยู่อย่างจำกัด ทำให้เราสามารถแสดงโลโก้เกมสวยๆ ในตอนเริ่มต้นระบบได้โดยไม่ทำให้เครื่องค้าง
สำหรับการทดสอบ ผมได้จำลองการทำงานทั้งหมดผ่าน Wokwi Online Simulator ซึ่งเป็นเครื่องมือที่ดีมากสำหรับการตรวจสอบความถูกต้องของวงจรและ Logic ก่อนการลงมือบัดกรีอุปกรณ์จริง
การวิเคราะห์โค้ด (Code Logic Analysis)
แม้จำนวนบรรทัดของโค้ดอาจจะดูยาว แต่โครงสร้างหลักนั้นเรียบง่ายมาก:
- Setup Section: กำหนดค่า Baud rate สำหรับ Serial monitor และ Initialize หน้าจอ OLED พร้อมแสดงภาพ Bitmap เริ่มต้น
- Loop Section: คอยตรวจสอบสถานะการกดปุ่ม (Digital Read) เมื่อตรวจพบการกด จะเข้าสู่ฟังก์ชันการตัดสินใจ
- Decision Logic: ใช้การเปรียบเทียบค่า Index ของตัวเลือก เช่น ให้ 0=ค้อน, 1=กระดาษ, 2=กรรไกร แล้วใช้เงื่อนไขคณิตศาสตร์หรือ
ifมาหาผู้ชนะตามตารางที่ออกแบบไว้
หากใครกำลังมองหาโปรเจกต์เริ่มต้นด้าน Embedded Systems ที่รวมทั้งเรื่อง Digital Input, I2C Communication และ Game Logic โปรเจกต์นี้ถือเป็นจุดเริ่มต้นที่ยอดเยี่ยมครับ! Happy Coding!