อัลกอริธึม (algorithm)

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

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

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

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

แก้ไขโปรเจกที่แชร์ในเว็บไซต์ Scratch

สำหรับคนที่ได้สร้างโปรเจก Scratch แล้วแชร์โปรเจกนั้นในเว็บไซต์ scratch.mit.edu เมื่อต้องการแก้ไข ปรับปรุงโปรเจกที่ได้แชร์ไปแล้ว สามารถทำได้ง่ายๆ เพียงปรับปรุงโปรเจกด้วยโปรแกรม Scratch ในเครื่องของตัวเองตามที่ต้องการ แล้วทำการแชร์อีกครั้งด้วย ชื่อเดิม เท่านั้นเอง แต่ถ้าต้องการแชร์โปรเจกเดิม ในเวอร์ชั่นใหม่ ให้แก้ไขชื่อใหม่ อาจใช้ตัวเลขต่อท้าย เพื่อสื่อถึงโปรเจกเดิมแต่เป็นเวอร์ชั่นใหม่

Ant Sim

หลังจากโปรเจก Delicious Fish คราวนี้ขอแนะนำโปรเจก Ant Sim เป็นโปรเจกใหม่ของผม ลองเข้าไปเล่นในเว็บไซต์ Scratch หรือ ดาวน์โหลดไปเล่นที่เครื่องก็ได้ แนะนำติชมด้วย ยิ่งดีครับ

Scratch Project

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

BYOB

เราเรียนรู้ Scratch มาระดับหนึ่งแล้ว บางคนเห็นศักยภาพของมันในการส่งเสริมให้เด็กๆ เรียนรู้การเขียนโปรแกรม บางคนสงสัยว่าเด็กระดับไหนเหมาะกับโปรแกรม Scratch อันที่จริงเหมาะกับเด็กทุกระดับ แม้กระทั่งผู้ใหญ่ ที่ไม่มีประสบการณ์การเขียนโปรแกรมมาก่อน ก็สามารถใช้โปรแกรมนี้ได้ไม่ยาก โปรเจกใน Scratch เน้นการใช้สื่อชนิดต่างๆ ไม่ว่าจะเป็น ภาพ เสียง หรือ แอนิเมชั่น ฯลฯ ทำให้ผู้เรียนไม่เบื่อ อย่างไรก็ตาม กลุ่มเป้าหมายของ Scratch น่าจะเป็นเด็กประถมปลาย (ป.4-ป.6) ไปถึงมัธยมต้น (ม.1-ม.3)

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

ด้วยเหตุนี้ จึงมีกลุ่มนักวิจัยในมหาวิทยาลัย California Berkeley สร้างโปรเจก BYOB (build your own blocks) หรือ Snap ซึ่งเป็นโปรเจกต่อยอดจาก Scratch ให้มีความสามารถด้านการเขียนโปรแกรมสูงขึ้น โปรเจกที่ว่านี้มีตัวการ์ตูนชื่อ Alonzo เป็นสัญลักษณ์ ถ้าอยากทดลองดูแล้ว สามารถดาวน์โหลด BYOB ได้ที่ http://byob.berkeley.edu

หลักการเขียนโปรแกรมใน Scratch ตอนที่ 8

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

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

รูปแบบฟังก์ชันใน Scratch มีหลากหลาย และซับซ้อนกว่าที่คิด มาลองดูตัวอย่างใน Delicious Fish

เมธเธิด (method) คือฟังก์ชันที่ใช้เฉพาะกับตัวละครตัวใดตัวหนึ่ง (object function) คล้ายกับการเขียนโปรแกรมเชิงวัตถุ ปกติเมธเธิดของวัตถุใดจะทำงาน เมื่อมีการส่งสาร (massage) มายังวัตถุนั้นโดยตรง ใน Scratch สามารถสร้างสคริปต์ให้เป็นเมธเธิดได้ โดยสร้างรหัสให้กับวัตถุนั้นโดยเฉพาะ เช่น ปลาทองเมื่อถูกกิน จะส่งรหัส “got-me” ออกไป แต่มีเฉพาะปลาตัวใหญ่เท่านั้นที่รับรหัสนี้ อาจพูดได้ว่า สคริปต์ที่รับรหัส “got-me” ของปลาตัวใหญ่ เป็นเมธเธิดหรือฟังก์ชันของวัตถุ นอกจาก “got-me” แล้ว ยังมีรหัสที่ทำหน้าที่เหมือนกันอีก คือ “got 1” กับ “oh-no”

การส่งและรับรหัสเป็นรูปแบบหนึ่งของฟังก์ชันที่ขึ้นกับเหตุการณ์ การส่งรหัสเป็นเหตุการณ์แบบหนึ่ง (event) และเมื่อมีฟังก์ชันใดที่สนใจรหัสนี้ (event listening) ได้รับรหัสนี้ ก็จะเริ่มทำงานเพื่อตอบสนองกับเหตุการณ์ที่เกิดขึ้น (response function) ตัวอย่างเช่น เมื่อเริ่มต้นเกม ตัวควบคุมเกมจะส่งรหัส “setup” ให้ปลาทุกตัวเตรียมพร้อมสำหรับการเล่น ปลาทุกตัวก็ตอบสนองรหัสนี้ด้วยการซ่อนตัว (hide) เท่านั้นเอง แต่เมื่อเข้าสู่แต่ละระดับเกม ปลาจะได้รับรหัส “level1” ตามมาด้วย “level2” จนกระทั่งจบเกม เมื่อได้รับรหัส “game-over” ปลาแต่ละตัวจะตอบสนองต่างกันไป

การใช้การรับส่งรหัส เป็นการประสานงานให้สอดคล้องกันระหว่างตัวละคร แต่ฟังก์ชันที่ขึ้นกับเหตุการณ์ ยังมีอีกหลายแบบ ที่ไม่ขึ้นกับรหัส เช่น ขึ้นกับเวลา (time event) ในเกมที่มีการควบคุมเวลา เวลาหมดถือเป็นเหตุการณ์หนึ่ง ที่ทำให้เกิดการเปลี่ยนระดับเกม หรือการจบเกม นอกจากนั้น ผู้เล่นยังเป็นคนทำให้เกิดเหตุการณ์ต่างๆ อีก เช่น การใช้เมาส์ลากไปมา (mouse event) ทำให้ปลาตัวใหญ่เคลื่อนที่ตามเมาส์

เมื่อปลาตัวใหญ่กินปลาแต่ละชนิดได้ มันจะรับรหัสจากปลาทั้งสามชนิด และต้องแสดงแอนิเมชั่นการเคี้ยวพร้อมเสียงประกอบ แต่ถ้าต้องเขียนสคริปต์แสดงแอนิเมชั่นที่เหมือนกันหมด สำหรับปลาทั้งสามชนิด จะทำให้สคริปต์ยาวขึ้น และในอนาคตถ้าต้องการเพิ่มปลาชนิดอื่นอีก ก็ต้องเขียนสคริปต์เหมือนกันอีก ซึ่งไม่ใช่วิธีการเขียนโปรแกรมที่ดี ดังนั้นในสคริปต์ปลาตัวใหญ่ จึงนำส่วนที่เป็นแอนิเมชั่น (chomp) ออกมาเป็นฟังก์ชันต่างหาก ซึ่งเป็นฟังก์ชันที่ถูกเรียกใช้ภายในสคริปต์ปลาตัวใหญ่เท่านั้น เป็นฟังก์ชันส่วนตัว (private function) ด้วยวิธีนี้ ฟังก์ชัน oh-on, got 1, got-me จะเรียกใช้ฟังก์ชัน chomp เพื่อแสดงแอนิเมชั่นแทน ซึ่งเป็นการเรียกใช้ฟังก์ชันภายในฟังก์ชันอีกทีหนึ่ง

เมื่อปลาแต่ละชนิดถูกกิน คะแนนจะเปลี่ยนแปลง อาจขึ้นหรือลงก็ได้ และจำนวนปลาแต่ละชนิดที่ถูกกินก็เพิ่มขึ้นด้วย การที่จะตามการเปลี่ยนแปลงนี้ได้ ต้องสร้างตัวแปรโกลบอล (Score, goldfish, goldfish1, greenfish) มาเก็บค่าเหล่านึ้ไว้