14 เมษายน 2560

[สอนสร้างเกม] เรียนสร้างเกมกับมิกิจัง : บทที่ 3 อัลกอรึทึม (Algorithm)

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

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


อัลกอริทึมคืออะไร?

อัลกอริทึม (Algorithm) หมายถึงวิธีการแก้ปัญหาแบบเป็นลำดับขั้นตอน โดยลำดับขั้นตอนนั้นจะต้องมีความละเอียด ชัดเจน และสามารถตีความได้อย่างเดียวเท่านั้น ถ้าลองเปิดหนังสือสอนทำอาหาร ส่วนที่เป็นอัลกอรึทึมคือวิธีการทำอาหาร ในการพัฒนาเกมส่วนที่เป็นอัลกอริทึมคือวิธีการทำงานของเกม จากที่ได้เรียนไปในบทที่ 1 ว่า "อุปกรณ์จะทำงานโดยการอ่านคำสั่ง" ดังนั้นอัลกอริทึมของเกมก็คือวิธีการป้อนคำสั่งให้กับอุปกรณ์นั่นเอง


ทำไมต้องเขียนอัลกอริทึม?

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

อัลกอริทึมเป็นหนี่งในสองสิ่งสำคัญในการเขียนโปรแกรมและการพัฒนาเกม สิ่งสำคัญอีกอย่างคือความรู้เกี่ยวกับภาษาอุปกรณ์หรือเกมเอนจินที่ใช้ ในการเขียนโปรแกรมและการพัฒนาเกมไม่จำเป็นต้องมีความรู้ลึกมากก็ได้ แค่มีความรู้พื้นฐานที่สำคัญ และสามารถเปลี่ยนความคิดในหัวเป็นอัลกอริทึมได้ก็เพียงพอแล้ว เกมบางตัวใช้แค่คำสั่งพื้นฐานแต่ก็สามารถเป็นเกมฟอร์มยักษ์ได้ เพราะผู้ที่พัฒนาเกมนั้นรู้จักนำความรู้พื้นฐานมาประยุกต์ใช้ โดยการเขียนอัลกอริทึมที่มีความซับซ้อนจากคำสั่งพื้นฐานที่แม้แต่นักพัฒนาเกมมือใหม่ก็ยังทราบ

ผู้อ่านที่ไม่เคยเขียนอัลกอริทึมมาก่อนอาจรู้สึกว่าการเขียนอัลกอริทึมเป็นสิ่งที่ยาก เนื่องจากการเขียนอัลกอริทึมต้องเขียนเป็นลำดับทีละข้อ แต่ละข้อต้องละเอียด ไม่กำกวม ไม่คลุมเครือ ตีความได้อย่างเดียวเท่านั้น ยกตัวอย่างเช่น เราสั่งให้เพื่อนที่เป็นมนุษย์ต้มบะหมี่กึ่งสำเร็จรูป เราแค่บอกว่า "ต้มบะหมี่กึ่งสำเร็จรูปให้หน่อย" แค่นี้เพื่อนก็สามารถทำตามความต้องการของเราได้อย่างถูกต้องแล้ว แต่ถ้าใช้คำสั่ง "ต้มบะหมี่กึ่งสำเร็จรูปให้หน่อย" กับหุ่นยนต์ หุ่นยนต์บางตัวอาจงงทำอะไรไม่ถูกกับคำสั่งของเรา หุ่นยนต์บางตัวอาจต้มบะหมี่กึ่งสำเร็จรูปไปทั้งที่ยังไม่ได้ฉีกซองเลย หุ่นยนต์บางตัวอาจใช้นมในการต้มแทนน้ำ หุ่นยนต์บางตัวอาจใช้กระทะในการต้มแทนหม้อ ปัญหาเหล่านี้เกิดจากการใช้คำสั่งที่ไม่ละเอียดและสามารถตีความได้หลายอย่าง ในการเขียนอัลกอริทึมต้องเขียนคำสั่งให้ละเอียด ตีความได้เพียงอย่างเดียว เขียนทุกขั้นตอน ทุกคำสั่ง และต้องเขียนให้คนโง่ที่สุดในโลกก็สามารถทำตามความต้องการของเราได้อย่างถูกต้อง 100%


เขียนอัลกอริทึมได้อย่างไร?

การเขียนอัลกอริทึมสามารถทำได้ 3 แบบ ได้แก่

1. การเขียนอัลกอริทึมแบบความเรียง วิธีนี้คือการเขียนเป็นข้อความปกติ วิธีนี้เหมาะกับอัลกอริทึมที่มีขนาดเล็กและมีความซับซ้อนน้อย

ตัวอย่างความเรียงที่อธิบายวิธีการทำไข่ดาว
นำกระทะไปวางบนเตาแก๊ส เปิดเตาแก๊ส เทน้ำมันพืชลงไปในกระทะ 30 มิลลิลิตร แล้วรอจนกว่าน้ำมันเดือด เมื่อน้ำมันเดือดแล้ว ตอกไข่ไก่ 1 ฟอง แล้วใส่ไข่ขาวกับไข่แดงลงในกระทะ ส่วนเปลือกไข่นั้นให้ทิ้งลงในถังขยะ เสร็จแล้วรอจนกว่าไข่ขาวและไข่แดงเริ่มแข็งตัว เมื่อไข่ขาวและไข่แดงเริ่มแข็งตัวแล้ว ใช้ตะหลิวพลิกไข่ขาวและไข่แดงแล้ววางไว้บนกระทะเหมือนเดิม เมื่อไข่ขาวและไข่แดงสุกแล้ว นำตะหลิวตักไข่ขาวและไข่แดงมาวางไว้บนจาน ปิดเตาแก๊ส เพียงเท่านี้ก็ทำไข่ดาวเสร็จแล้ว

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

รูปภาพพื้นฐานที่ควรทราบ ได้แก่
รูปภาพ
ความหมาย
วิธีใช้
ดำเนินการทั่วไป
(Process)
ใช้กับการดำเนินการทั่วไป เช่น การประกาศตัวแปร การคำนวณ เป็นต้น
ตรวจสอบเงื่อนไข
(Decision)
ใช้ตรวจสอบด้วยเงื่อนไข "ถ้า...แล้ว... (If...Then...)" ลูกศรที่ออกจากรูปภาพนี้ต้องมีสองเส้น เส้นหนึ่งเขียนกำกับว่า "จริง (True)" อีกเส้นหนึ่งเขียนกำกับว่า "เท็จ (False)"
แสดงลำดับขั้นตอน
(Arrow)
ใช้บอกลำดับการทำงาน เชื่อมรูปภาพหนึ่งกับอีกรูปภาพหนึ่ง โดยให้ฝั่งหัวลูกศรคือลำดับการทำงานต่อไป รูปภาพหนึ่งจะมีลูกศรออกมาได้แค่ 1 เส้นเท่านั้น ยกเว้นรูปภาพตรวจสอบเงื่อนไขที่มีลูกศรออกมา 2 เส้น
จุดเริ่มต้นหรือจุดสิ้นสุด
(Start/End)
ใช้เพื่อกำหนดจุดเริ่มต้นและจุดสิ้นสุด Flowchart ทั้งหมดต้องมีรูปภาพนี้ 2 รูปเสมอ รูปหนึ่งคือจุดเริ่มต้น อีกรูปหนึ่งคือจุดสิ้นสุด
รับข้อมูลหรือแสดงผลแบบไม่เจาะจง
(Input/Output)
ใช้เพื่อรับข้อมูลหรือแสดงผลแบบไม่เจาะจงอุปกรณ์ในการรับข้อมูลหรือแสดงผล
จุดเชื่อมต่อภายในหน้าเดียวกัน
(On-Page Reference)
ใช้เชื่อมบริเวณที่มีลูกศรหลายเส้นชี้มารวมกัน เช่น บริเวณหลังจากการตรวจสอบเงื่อนไขอาจจะมีลูกศรชี้มาที่ตำแหน่งเดียวกันหลายเส้น เราจะใช้รูปภาพนี้เพื่อรวมลูกศรเหล่านั้นให้เหลือเพียงเส้นเดียว
จุดเชื่อมต่อระหว่างหน้า
(Off-Page Reference)
ใช้เชื่อมการทำงานที่เขียนอยู่คนละหน้ากัน (ในกรณีที่เขียน Flowchart หลายหน้า)

ตัวอย่าง Flowchart ที่อธิบายวิธีการหุงข้าว

***คลิกที่รูปเพื่อดูรูปขนาดใหญ่***

3. การเขียนอัลกอริทึมแบบ Pseudo Code วิธีนี้คือการเขียนคำสั่งทีละบรรทัดคล้ายกับการเขียนโปรแกรม แต่คำสั่งที่ใช้จะเปลี่ยนจากภาษาอุปกรณ์เป็นภาษามนุษย์ที่สามารถเข้าใจได้ง่ายแทน คำสั่งจะเขียนด้วยคำว่าอะไรก็ได้ที่เราเข้าใจได้ง่าย วิธีนี้เหมาะกับอัลกอริทึมที่มีขนาดใหญ่

ตัวอย่าง Pseudo Code ที่อธิบายวิธีการต้มน้ำ



ในการพัฒนาเกมจริงตัวเกมจะมีขนาดใหญ่มาก การเขียนอัลกอริทึมแบบความเรียงอาจไม่เหมาะสมนักเท่าไร ผู้อ่านควรเลือกเขียนอัลกอริทึมแบบ Flowchart หรือ Pseudo Code จะดีกว่า ส่วนจะเลือกเขียนแบบไหนก็ขึ้นอยู่กับความถนัดของแต่ละคน Flowchart อ่านเข้าใจง่ายกว่า Pseudo Code แต่ก็ใช้พื้นที่มากกว่าด้วยเช่นกัน ส่วน Pseudo Code สามารถแปลเป็นภาษาอุปกรณ์ได้ง่ายกว่า Flowchart แต่ก็อ่านเข้าใจได้ยากกว่า Flowchart


โครงสร้างของอัลกอริทึมมีอะไรบ้าง?

การเขียนนิพจน์คณิตศาสตร์ในทางอุปกรณ์แล้ว เราจะกำหนดตัวแปรขึ้นมาเพื่อใช้เก็บค่าที่สามารถเปลี่ยนแปลงได้ ซึ่งเราจะนำตัวแปรไว้ใช้ในการรับข้อมูล คำนวณเลข วนลูป ฯลฯ โดยเราจะใช้ตัวอักษรแทนตัวแปรแต่ละตัว การเขียนนิพจน์ที่มีเครื่องหมาย = หมายความว่านำค่าฝั่งขวามาไว้ในค่าฝั่งซ้าย เช่น X = Y หมายความว่าให้ X มีค่าเท่ากับ Y โดยที่ Y ยังมีค่าเท่าเดิม, N = N + 1 หมายความว่าให้ N ค่าใหม่เท่ากับ N ค่าเดิมบวกด้วย 1 โดยที่ N ค่าเดิมจะถูกลบทิ้งไป แล้วเก็บ N ค่าใหม่ลงในหน่วยความจำของอุปกรณ์แทน ในเรื่องของการเขียนนิพจน์และตัวแปรเราจะเรียนอย่างละเอียดกันในบทต่อไป

โครงสร้างของอัลกอริทึมคือรูปแบบเส้นทางการทำงานของอัลกอริทึม โครงสร้างของอัลกอริทึมมี 3 แบบ ได้แก่
โครงสร้าง
ตัวอย่าง Flowchart
ตัวอย่าง Pseudo Code
โครงสร้างแบบลำดับ
(Sequence Structure)

เป็นโครงสร้างที่มีเส้นทางการทำงานเพียงเส้นเดียว
โครงสร้างแบบเงื่อนไข
(Decision Structure)

เป็นโครงสร้างที่มีการใช้เงื่อนไข "ถ้า...แล้ว..." ในการตรวจสอบ เส้นทางการทำงานเมื่อผ่านเงื่อนไขจะเพิ่มอีก 1 เส้นทาง
โครงสร้างแบบทำซ้ำ
(Loop Structure)

เป็นโครงสร้างที่มีการทำงานซ้ำเส้นทางเดิม (Loop) และใช้เงื่อนไขในการกำหนดว่าจะทำงานในลูปต่อไปหรือไม่

การเขียนอัลกอริทึมที่เป็นโครงสร้างแบบทำซ้ำจำเป็นต้องมีการตรวจเงื่อนไขด้วยเสมอ โดยใช้การตรวจเงื่อนไขเพื่อกำหนดว่าจะยังทำงานในลูปต่อไปหรือออกจากลูป ถ้าไม่มีการตรวจเงื่อนไขหรือตั้งเงื่อนไขไม่ดีอาจเกิดการทำซ้ำแบบไม่สิ้นสุด (Infinity Loop) ซึ่งจะทำให้การทำงานตามอัลกอริทึมของเราไม่มีวันจบสิ้น การทำงานก็จะติดอยู่แต่ในลูปเดิมเป็นจำนวนอนันต์ครั้ง

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


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

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

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

สำหรับในบทนี้ก็ขอจบลงเพียงเท่านี้ บทความนี้จะอัพบทใหม่ทุกวันศุกร์ แล้วพบกันใหม่กับบทความ "เรียนสร้างเกมกับมิกิจัง" ขอบคุณค่ะ

"Success represents the 1% of your work which results from the 99% that is called failure." - Soichiro Honda
"คนเราประสบความสำเร็จเพียง 1% เท่านั้น ส่วนอีก 99% คือความล้มเหลว"



แบบฝึกหัดประจำบทที่ 3

กำหนดให้ : เครื่องหมาย <= แทนน้อยกว่าหรือเท่ากับ และเครื่องหมาย >= แทนมากกว่าหรือเท่ากับ

แบบฝึกหัดที่ 3.1 จงบอกผลลัพธ์ของอัลกอริทึมแบบ Flowchart และแบบ Pseudo Code จากโจทย์ต่อไปนี้ ถ้าโจทย์ข้อใดมีการรับข้อมูลให้สมมติข้อมูลนั้นขึ้นมา
1.
2.
3.

4.

5.


แบบฝึกหัดที่ 3.2 จงเขียนอัลกอริทึมแบบ Flowchart และแบบ Pseudo Code จากโจทย์ต่อไปนี้
  1. วิธีการซักผ้า
  2. วิธีการทำความสะอาดห้องนอน
  3. ให้แสดงเครื่องหมาย # บรรทัดละ 20 ตัว จำนวน 7 บรรทัด โดยสามารถใช้คำสั่งแสดงข้อความได้ครั้งละหนึ่งตัวอักษรเท่านั้น
  4. ออกแบบโปรแกรมเครื่องคิดเลขที่มีตัวดำเนินการ (Operator) 2 ตัวคือบวกและลบ โดยรับข้อมูลทั้งหมดมาจากคีย์บอร์ด
  5. หาตัวคูณร่วมน้อย (ค.ร.น.) ของจำนวน 3 จำนวนที่รับข้อมูลมาจากคีย์บอร์ด

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

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