15 มิถุนายน 2562

[Source Code] สร้างเกม XO หรือ Tic-Tac-Toe | ไม่มี AI (★ ระดับง่าย)

ติดตามและพูดคุยกับเราได้ที่เพจ https://www.facebook.com/PlanilaGameDeveloper

นักสร้างเกมมือใหม่หลายคนศึกษาวิธีสร้างเกมมากมาย อ่านมาหลายตำราหลายทฤษฎี แต่กลับพบว่าหลายคนยังสร้างเกมด้วยตนเองไม่ได้สักที ถ้าคิดว่าแค่อ่านตำราให้มากเพียงอย่างเดียวแล้วจะสร้างเกมเป็น ผลลัพธ์ก็ออกมาให้เห็นแล้วว่าไม่จริง การสร้างเกมรวมทั้งการเขียนโปรแกรมมีฐานเป็นสองเสาหลักได้แก่การใช้งาน (ความรู้ด้านภาษาคอมพิวเตอร์, ความรู้ด้านการใช้โปรแกรม, ทฤษฎีต่าง ๆ ฯลฯ) และอัลกอริทึม ถ้าไม่สามารถแปลงความคิดในหัวให้เป็นอัลกอริทึมได้ก็ไม่สามารถสร้างเกมได้อย่างที่ต้องการ ผู้เขียนแนะนำให้นักสร้างเกมมือใหม่ฝึกเรื่องการออกแบบอัลกอริทึมให้คล่อง สำหรับบทความในชุดนี้ไม่ได้เขียนมาเพื่อสอนพื้นฐานหรือฝึกอัลกอริทึมของผู้อ่าน จุดประสงค์ของบทความชุดนี้คือการอธิบายอัลกอริทึมจาก source code จริงของเกมต่าง ๆ ผู้อ่าน

บทความแนะนำ
[สอนสร้างเกม] เรียนสร้างเกมกับมิกิจัง : บทที่ 3 อัลกอรึทึม (Algorithm)
[อัลกอริทึม] แบบฝึกหัดอัลกอริทึม + เฉลย ชุดที่ 1


ไฟล์ TicTacToe.zip (ลิงค์ดาวน์โหลดอยู่ท้ายบทความ) ประกอบด้วย source code 3 ชุดได้แก่
  • Java
  • Visual Basic (VB)
  • RPG Maker VX Ace (RMVXA)
Source code ทั้งสามชุดมีอัลกอริทึมเหมือนกัน ต่างกันเพียงความสามารถของแต่ละภาษาหรือโปรแกรม ผู้อ่านสามารถเลือก source code ใดก็ได้


ภาพรวมอัลกอริทึม

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

สำหรับอัลกอริทึมคร่าว ๆ นี้จะใส่เพียงแค่สิ่งที่จำเป็นจริง ๆ ในการทำงานของเกม ไม่ลงลึกถึงการเขียนโปรแกรม จะเห็นว่ามีบอกแค่ให้ตรวจสอบ "ชนะแล้ว" และ "เสมอแล้ว" ไม่ได้บอกว่าการชนะหรือการเสมอนั้นเป็นอย่างไร ส่วนตัวแปร player ที่ใส่มาในอัลกอริทึมคร่าว ๆ นี้เป็นสิ่งที่ขาดไม่ได้เพราะเป็นตัวแปรที่เก็บค่าว่าตอนนี้เป็นตาของฝ่าย X หรือเป็นตาของฝ่าย O

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


อธิบายอัลกอริทึมพร้อมตัวอย่าง

1. ออกแบบส่วนแสดงผลที่เป็นกราฟฟิก (Graphic User Interface: GUI) ในตัวอย่างนี้ RMVXA ออกแบบให้แสดงภาพตั้งต้นซึ่งเป็นภาพว่างสีส้มจำนวน 3 x 3 ภาพในแนวตั้งและแนวนอน และแสดงภาพสีน้ำเงินที่โปร่งแสงบางส่วนเพื่อใช้เป็นเคอร์เซอร์ (cursor) ส่วน Java และ VB ออกแบบเป็นปุ่มกด (button) จำนวน 3 x 3 ปุ่มในแนวตั้งและแนวนอน สำหรับภาษา Java ต้องใช้คลาสเพิ่มเติมในการแสดงหน้าต่างแบบ GUI ในตัวอย่างนี้เลือกใช้ JavaFX ในการสร้าง GUI
การเขียนโปรแกรมบางภาษา เช่น Java, C ต้องใช้คลาสพิเศษในการสร้าง GUI ซึ่งอาจยากสำหรับนักสร้างเกมมือใหม่ ถ้าไม่ต้องการออกแบบเกมแบบ GUI สามารถออกแบบเป็น command line ดังรูปข้างล่างแทนได้ แม้ว่าจะไม่สวยงามแต่ก็เขียนโปรแกรมได้ง่ายกว่า และเหมาะสมสำหรับการฝึกอัลกอริทึมสำหรับนักสร้างเกมมือใหม่ เพราะไม่ต้องเสียเวลาศึกษาและออกแบบ GUI

2. ประกาศตัวแปร global ตั้งชื่อว่า player ตัวแปรนี้ใช้เพื่อบอกโปรแกรมว่าตอนนี้เป็นตาของฝ่ายใด ถ้า player เท่ากับ 0 หมายถึงเป็นตาของฝ่าย X และ 1 หมายถึงเป็นตาของฝ่าย O (ยกเว้นในตัวอย่าง RMVXA จะใช้ 1 เป็นตาของฝ่าย X และ 2 ใช้เป็นตาของฝ่าย O แทน เนื่องจากข้อจำกัดของโปรแกรม) จากนั้นกำหนดให้ player เป็นฝ่าย X เริ่มเล่นก่อนไว้ในตอนโปรแกรมเริ่มต้นทำงานครั้งแรก (player = 0 ในตัวอย่าง Java, VB)

ในภาษาคอมพิวเตอร์หลายภาษา เช่น VB, C++ สามารถประกาศตัวแปรแบบ global ได้โดยการประกาศตัวแปรให้อยู่ภายในคลาสแต่อยู่นอกโปรแกรมย่อย (โปรแกรมย่อยเรียกได้หลายชื่อ เช่น subprogram, function, procedure) แต่บางภาษา เช่น Java, C# ไม่สามารถประกาศตัวแปร global ได้โดยตรง ให้ใช้วิธีประกาศตัวแปรในคลาสอีกคลาสแทน (เป็นการใช้ OOP เพื่อมองตัวแปรเป็นออบเจ็กต์) แต่จะไม่อธิบายรายละเอียดในบทความนี้เนื่องจากเป็นเรื่องเฉพาะภาษานั้น ๆ ส่วนใน RMVXA ตัวแปรทั่วไปมีลักษณะเป็นตัวแปร global อยู่แล้ว ไม่ต้องทำอะไรเป็นพิเศษ

3. จากนั้นเขียนโค้ดสำหรับตอบสนองต่อการคลิกปุ่มกด (ในตัวอย่าง RMVXA คือการกดคีย์บอร์ดเพื่อเลือกภาพ รวมถึงการเลื่อนเคอร์เซอร์) ใน Java และ VB ไม่มีอะไรมาก เพียงแค่ใส่โค้ดให้เรียกใช้โปรแกรมย่อย symbol เมื่อคลิกปุ่มกดใดปุ่มกดหนึ่งซึ่งต้องใส่โค้ดนี้ในทั้งเก้าปุ่มกด เราจะเขียน symbol กันในขั้นตอนต่อไป แต่สำหรับ RMVXA ไม่รองรับคำสั่งจากเมาส์จึงต้องใส่คำสั่งตรวจสอบการกดคีย์บอร์ดแทนโดยใช้อีเวนต์แบบ parallel process ภายในอีเวนต์ใส่คำสั่งตรวจสอบเงื่อนไขการกดคีย์บอร์ด ถ้ากดลูกศรให้ทำการเลื่อนเคอร์เซอร์ ถ้ากด spacebar หรือ enter (ในโปรแกรมจะเรียกว่าคีย์ C) ให้ตรวจสอบต่อซึ่งจะอธิบายในขั้นตอนต่อไป

4. เขียนโปรแกรมย่อย symbol ส่วนนี้จะตรวจสอบว่าปุ่มกดที่ถูกคลิกมีเครื่องหมาย X หรือ O แล้วหรือไม่ ถ้ามีอยู่แล้วจะแสดงกล่องข้อความบอกว่าผิดกติกา แต่ถ้าไม่มีเครื่องหมายอยู่จะใส่เครื่องหมาย X หรือ O ในปุ่มกดที่ถูกคลิก (ถ้า player = 0 ให้ใส่เครื่องหมาย X ถ้า player = 1 ให้ใส่เครื่องหมาย O; ยกเว้นในตัวอย่าง RMVXA จะเป็นค่า 1 และ 2 แทน) เมื่อใส่เครื่องหมายเสร็จแล้วให้เปลี่ยนตัวแปร player เป็นค่าของผู้เล่นอีกฝ่าย (จาก 0 เปลี่ยนเป็น 1 และจาก 1 เปลี่ยนเป็น 0) สุดท้ายให้เรียกใช้โปรแกรมย่อย checkEnd ซึ่งจะอธิบายในขั้นตอนต่อไป

สำหรับตัวอย่าง RMVXA จะใส่คำสั่งเหล่านี้ในเงื่อนไขตรวจสอบคีย์ C (จากขั้นตอนก่อนหน้า) ไม่ได้แยกเป็นอีเวนต์อื่น เพราะผู้เขียนคิดว่าถ้าแยก symbol โปรแกรมอาจทำงานช้าจนเกิดบักแสดงเครื่องหมายซ้ำ จึงใส่คำสั่งในเงื่อนไขตรวจสอบคีย์ C เพื่อให้โปรแกรมทำงานต่อเนื่องทันที แต่ถ้าต้องการให้คำสั่งดูง่ายสบายตา ผู้อ่านสามารถแยกเป็นอีเวนต์ symbol เหมือนตัวอย่าง Java และ VB ได้
5. เขียนโปรแกรมย่อย checkEnd ส่วนนี้จะตรวจสอบว่าตอนนี้จบเกมแล้วหรือไม่ ถ้ายังไม่จบเกมก็ไม่มีอะไรเกิดขึ้น เกมจะทำงานต่อไปตามปกติ ถ้าจบเกมแล้วให้เรียกโปรแกรมย่อย messageEnd เพื่อแสดงข้อความว่าจบเกมแล้วปิดเกม

การจบเกมแบ่งออกเป็น 2 กรณีได้แก่ การจบเกมแบบมีการชนะ-แพ้และการจบเกมแบบเสมอกัน สิ่งแรกที่ต้องตรวจสอบคือการจบเกมแบบชนะ-แพ้ วิธีตรวจสอบคือตรวจว่ามีเครื่องหมายเหมือนกันเรียงกันในแนวตั้ง แนวนอน หรือแนวทแยงหรือไม่ ถ้ามีแล้วฝ่ายไหนเป็นผู้ชนะ เมื่อตรวจสอบแล้วพบว่าไม่มีการชนะ-แพ้ให้ตรวจสอบการเสมอเป็นลำดับต่อมา การเสมอของเกมนี้มีอยู่เพียงวิธีเดียวคือปุ่มกดทั้งเก้าปุ่มมีเครื่องหมายครบหมดแล้ว แต่ยังไม่มีฝ่ายใดเป็นฝ่ายชนะ จึงให้ถือว่าทั้งสองฝ่ายเสมอกัน

ในตัวอย่าง RMVXA จะแยกโปรแกรมย่อย checkEnd และ messageEnd ออกมาจากอีเวนต์หลักเหมือนกับตัวอย่าง Java และ VB โปรแกรมย่อยทั้งสองจะใส่ไว้ในเหตุการณ์ทั่วไป (common event) ในฐานข้อมูล (กดปุ่ม F9 เพื่อเข้าฐานข้อมูล แล้วคลิกแท็บเหตุการณ์ทั่วไป) การแยกออกมาจากอีเวนต์หลักทำให้เรียกใช้งานได้ง่ายและเรียกซ้ำได้หลายครั้งโดยไม่ต้องเขียนคำสั่งซ้ำ


ทดสอบเกม

ผู้อ่านสามารถเล่นเกมได้โดยไม่ต้องใช้โปรแกรม IDE หรือเกมเอนจินใด ๆ สำหรับเกมที่สร้างจาก Java ต้องติดตั้ง Java Virtual Machine ภายในคอมพิวเตอร์ก่อนจึงจะเล่นได้ (ดาวน์โหลด JVM เวอร์ชันล่าสุดฟรีได้ที่ https://www.java.com/en/download/) เกมที่สร้างจาก RMVXA ต้องติดตั้ง RTP ก่อนจึงจะเล่นได้ (ดาวน์โหลด RTP ฟรีได้ที่ http://www.rpgmakerweb.com/download/additional/run-time-packages) ส่วนเกมที่สร้างจาก VB สำหรับ Windows ที่ไม่เก่ามากเกินไปสามารถเล่นได้ทันทีโดยไม่ต้องติดตั้งโปรแกรมเพิ่มเติม ตำแหน่งที่เก็บตัวเกมสำหรับเล่นมีดังนี้
  • TicTacToe\ Java\ [PLAY] TicTacToe - Java.jar
  • TicTacToe\ Visual Basic\ [PLAY] Tic Tac Toe - Visual Basic.exe
  • TicTacToe\ RPG Maker VX Ace\ Game.exe

หมายเหตุ : เกมที่สร้างจาก Java สามารถเปิดได้ในหลายระบบปฏิบัติการ ถ้าสังเกตดี ๆ จะพบว่าตัวเกมที่สร้างด้วย Java เป็นไฟล์ .jar ไม่ใช่ .exe


ดาวน์โหลด

TicTacToe.zip (1.67 MB)
Mediafire: http://www.mediafire.com/file/26fgj3678u3hxda/TicTacToe.zip/file
Mega: https://mega.nz/#!KaQ2xKoB!OhBdWvy696qjXOn-f0SnqI4hxHK484mJwdfZrNhRRR8

ข้อมูลเชิงเทคนิค
  • TicTacToe - Java พัฒนาด้วยโปรแกรม Netbeans IDE 8.2 และใช้ JDK 1.8
  • TicTacToe - Visual Basic รองรับ Visual Studio ตั้งแต่เวอร์ชัน 2010 เป็นต้นไป
  • TicTacToe - RPG Maker VX Ace ไม่ได้รวม RTP ไว้


กล่าวส่งท้าย

จุดประสงค์ของบทความชุดนี้คือเพื่อเป็นตัวอย่างการแปลงความคิดในหัวเป็นอัลกอริทึม นักสร้างเกมมือใหม่หลายคนสร้างเกมเองไม่ได้ ทั้งที่ศึกษาวิธีการสร้างเกมมาตั้งมากมาย ผู้เขียนเคยเขียนบทความเรื่องสอนออกแบบอัลกอริทึมและมีแบบฝึกหัดอัลกอริทึมมาแล้ว แต่บางคนอาจรู้สึกว่าบทความเหล่านั้นเป็นวิชาการเกินไป ไม่คิดว่าจำเป็นต้องใช้เมื่อสร้างเกมจริง ๆ บางตัวอย่างในบทความเหล่านั้นอาจดูง่ายหรือไกลตัวเกินไป ผู้เขียนจึงยกตัวอย่างอัลกอริทึมที่เป็นเกมจริง ๆ มาเลย จะได้เห็นภาพได้ชัดเจนว่าอัลกอริทึมคืออะไร หรือมีความสำคัญอย่างไรในการสร้างเกม

ขอย้ำว่าจุดประสงค์ของบทความนี้คือการฝึกแปลงความคิดในหัวให้เป็นอัลกอริทึม ไม่ได้เน้นความสวยงามของเกม และไม่ได้สอนว่าอัลกอริทึมเหล่านี้จะแปลงเป็นคำสั่งคอมพิวเตอร์ได้อย่างไร เนื่องจากเรื่องนั้นผู้อ่านสามารถศึกษาเองได้ และเข้าใจได้ไม่ยากเท่าเรื่องอัลกอริทึม ดังนั้นคำอธิบายในบทความนี้จะเน้นไปที่อัลกอริทึม ไม่ใช่ตัวภาษาคอมพิวเตอร์หรือโปรแกรมใดอย่างเจาะจง ถ้ามีส่วนที่ไม่เข้าใจและเป็นเรื่องของภาษา Java, VB หรือตัวโปรแกรม RMVXA ท่านสามารถศึกษาเพิ่มเติมได้จากตำราอื่น ๆ ในกรณีที่สงสัยเรื่องอัลกอริทึมให้ท่านลองแก้ไขโค้ดบางส่วน เพื่อดูว่าถ้าแก้ไขอัลกอริทึมส่วนหนึ่งไปแล้วจะส่งผลอย่างไร

ท่านสามารถพูดคุย ถามสิ่งที่สงสัย หรืออยากให้มีบทความแจก source code ของเกมอะไรอีก ติดต่อเราได้ที่ความคิดเห็นข้างล่างนี้ หรืออีกช่องทางติดต่อคือทางเพจ Facebook ชื่อเพจว่า Planila Game Developer


แบบฝึกหัด

  1. ออกแบบเกม Tic Tac Toe ที่แสดงผลเป็นแบบ command line
  2. ปรับปรุงเกม Tic Tac Toe จาก source code ให้การแสดงผล GUI สวยงามขึ้นกว่าเดิม
  3. ออกแบบ AI ให้สามารถเล่นเกม Tic Tac Toe โต้ตอบกับมนุษย์ได้

ไม่มีความคิดเห็น:

แสดงความคิดเห็น