
“ถ้าหากว่าเราวางแผนการรบมาแบบนึง เราจะรู้ได้อย่างไรว่าแผนเราจะเป็นไปตามที่วางไว้?”
เราอาจจะแบ่งวิธีการตอบคำถามนี้ได้ออกมาเป็นสองมุมมองคือ “นักปฏิบัติ” และ “นักวิเคราะห์”
นักปฏิบัติจะบอกว่า “งั้นเราลองทดสอบดูไหม” เช่นอาจจะแบ่งแผนออกเป็นแผนย่อย ๆ แล้วลองฝึก หรืออาจจะลองสร้างพื้นที่จำลองขึ้นมาแล้วทดสอบดูว่าผลลัพธ์จะเป็นยังไง
ส่วนนักวิเคราะห์ก็อาจจะบอกว่า “นี่คือเคสที่น่าจะเกิดขึ้นได้ 1,2,3,4 และนี่คือเหตุผลว่าทำไมถ้าเคส 1 เกิดขึ้นเราจะชนะ เคส 2 เกิดขึ้นเราจะชนะ เคส 3…”
(NOTE: อย่างไรก็ตามในโลกความเป็นจริงเราไม่สามารถจะ proof อะไรได้แน่นอน 100% ในขณะที่ในโลกของคณิตศาสตร์ และหลักเหตุผลผลเราสามารถ gurantee 100% ว่าสิ่ง ๆ นึงจะเป็นจริงเสมอ)
เรามองว่าการเขียนโค้ดก็เหมือนกัน วิธีการแรกเรียกว่า “empirical analysis” หรือทดสอบผ่านการทดลองแล้วคอย observe ดูผลลัพธ์ว่าเป็นไปตามที่เราต้องการไหม
ยกตัวอย่างเช่น เราอาจจะลองเขียนโค้ดขึ้นมาแล้วลอง manual test หรือทำ unit test ผลลัพธ์ถูกตามที่คาดไว้ไหม
หรือเราอาจจะเขียน script ง่าย ๆ ขึ้นมาเพื่อ generate random test cases หรือ simulate scenarios ต่าง ๆ ขึ้นมาเพื่อดูว่ามีอะไรที่ unexpected เกิดขึ้นไหม จะได้แก้ได้ทันก่อนใช้จริง
(อย่างไรก็ตามวิธีนี้ != การรันตีได้ว่าไม่มีบัค; บางทีเราอาจจะพลาดลืมเทสในเคสใดไป)
ส่วนอีกวิธีการนึงเราเรียกมันว่า “logical proof” หรือการใช้หลักเหตุและผลที่แน่นอนว่าทำไม algorithm ของเราถึงจะถูกต้องเสมอ ๆ
ยกตัวอย่างเช่นสมมุติว่าเราอยากจะ “ระเบิด TNT ใน Minecraft 1,000 ลูก” เราก็ต้องพิสูจน์ว่า
- เราสามารถจุดระเบิดลูกแรกได้ไหม?
- ระเบิดลูกนึงเมื่อระเบิดแล้วจะไปจุดระเบิดลูกต่อไปในรัศมี X ได้ไหม?
- ระเบิดแต่ละลูกสามารถระเบิดได้แค่ครั้งเดียว? (ไม่งั้นมันจะระเบิดไม่สิ้นสุด)
(ไว้จะมาเขียนเรื่องนี้ละเอียด ๆ อีกทีทีหลังนะครับ แต่อย่างไรก็ตามเชื่อว่าน่าจะเห็นภาพกันคร่าว ๆ)
อย่างไรก็ตามเรามองว่ามันไม่ใช่ตัวเลือกขาวดำว่าเราจะทำ 1 หรือ 2 แต่เป็นเรื่องของ spectrum หรือ shade มากกว่าว่าเราควรจะทำ 1 หรือ 2 มากหรือน้อยแค่ไหน
ในบางระบบที่ไม่สำคัญมากแค่ manual test ก็คงพอแล้ว ในบางระบบที่เราต้อง modify มันบ่อย ๆ แล้วเราอยากได้ confidence เวลาแก้ก็อาจจะต้อง setup unit test เอาไว้
ในบางระบบที่ซับซ้อนขึ้นมาหน่อยเราก็อาจจะต้องเขียน script เพื่อ generate random scenarios ต่าง ๆ เพื่อเช็คว่าจะมีอะไรแปลก ๆ เกิดขึ้นไหม
หรือในระบบที่เราอาจจะต้องมี informal proof (ใช้ภาษาพูด) ไว้ให้ตัวเองมั่นใจสักหน่อยว่า โค้ดของเราจะทำงานถูกต้อง หรือในบางระบบอาจจะต้องมี math formal proof ที่ไม่อยากให้มีความกำกวมทางภาษาเข้ามาทำให้อะไรผิดพลาดได้ (เช่น lib หรือ module ที่หลาย ๆ ระบบสำคัญ ๆ จะเอาไปใช้งาน)