2 điểm bởi GN⁺ 2024-06-15 | 1 bình luận | Chia sẻ qua WhatsApp
  • Trong lúc kiểm chứng lịch đốt nhiên liệu tối ưu để hạ cánh ở trò chơi Lunar Landing đầu tiên do học sinh trung học Jim Storer tạo ra năm 1969, một lỗi đã lộ ra: vào đúng khoảnh khắc lẽ ra tàu phải chạm đất, trò chơi lại phán nhầm là nó vẫn đang bay
  • Chiến lược gây ra vấn đề là suicide burn: tắt động cơ trong 70 giây, đốt 164.31426784 lbs/sec trong 10 giây, rồi đốt ở mức tối đa 200 lbs/sec; trò chơi bỏ lỡ cú hạ cánh mềm vốn phải nằm giữa một cú hạ cánh mạnh và một lần bay ngược lên mà không hạ cánh
  • Mã gốc không dùng tích phân Euler đơn giản mà dùng phương trình tên lửa Tsiolkovsky và chuỗi Taylor để tính chuyển động trong mỗi lượt 10 giây, cho thấy mức độ tinh vi đáng kể đối với sản phẩm của một học sinh trung học trong môi trường PDP-8 năm 1969
  • Nguyên nhân lỗi là công thức xấp xỉ điểm thấp nhất của quỹ đạo trước khi chạm đất đã thiếu phép chia cho 2 ở mẫu số bên trong căn bậc hai, khiến thời gian tới điểm thấp nhất luôn bị ước lượng thiếu
  • Sau khi thêm factor of two bị thiếu và bỏ phần bù 0.05 giây, kết quả suicide burn được cải thiện xuống còn 1.66 MPH, nhưng để đạt cú hạ cánh hoàn hảo dưới 1 MPH vẫn còn bị giới hạn bởi xấp xỉ 2 hạng của chuỗi Taylor và việc tính lại thời điểm hạ cánh

Lunar Landing năm 1969 và quá trình tìm chiến lược hạ cánh tối ưu

  • Jim Storer viết trò chơi Lunar Landing đầu tiên vài tháng sau khi Neil Armstrong đáp xuống Mặt Trăng, khi còn là học sinh tại Lexington High School ở Massachusetts
  • Đến năm 1973, trò chơi đã lan truyền rộng đến mức được gọi là “by far and away the single most popular computer game”
  • Đây là trò chơi dạng văn bản, và toàn bộ chuyển động của tàu đổ bộ Mặt Trăng chỉ diễn ra theo phương thẳng đứng
  • Người chơi quyết định lượng nhiên liệu sẽ đốt ở mỗi bước 10 giây trong mô phỏng, rồi cố gắng hạ cánh lên bề mặt Mặt Trăng càng êm càng tốt
  • Trong quá trình tìm lịch đốt nhiên liệu tối ưu, một chiến lược về lý thuyết là tốt nhất lại không hoạt động đúng trong trò chơi
    • Trên thực tế, tàu đổ bộ đã ở tình huống chạm bề mặt
    • Nhưng trò chơi lại phán nhầm là chưa chạm bề mặt
    • Nguyên nhân cuối cùng là một phép chia cho hai bị thiếu đã không bị ai chú ý suốt gần 55 năm

Hạ cánh với ít nhiên liệu nhất và suicide burn

  • Muốn hạ cánh với lượng nhiên liệu tối thiểu thì phải đi xuống trong thời gian ngắn nhất có thể
  • Chiến lược tối ưu là ban đầu tắt động cơ để tăng tốc rơi, rồi đúng vào thời điểm muộn nhất có thể mới giảm tốc bằng lực đẩy tối đa để vận tốc khi chạm đất gần bằng 0
  • Cộng đồng Kerbal Space Program gọi kiểu chiến lược này là suicide burn
    • Vì thời điểm phải canh cực kỳ sát và gần như không có chỗ cho sai số
  • Lịch đốt được tìm ra bằng thử sai và tìm kiếm nhị phân thủ công như sau
    • Không đốt nhiên liệu trong 70 giây
    • Đốt nhiên liệu ở mức 164.31426784 lbs/sec trong 10 giây tiếp theo
    • Sau đó đốt ở mức tối đa 200 lbs/sec
  • Trò chơi coi dưới 1 MPH là một cú hạ cánh hoàn hảo
  • Với lịch này, tàu hạ cánh ở tốc độ hơn 3.5 MPH và nhận đánh giá “could be better”
  • Nhưng nếu chỉ tăng thêm 0.00000001 lbs/sec nhiên liệu thì tàu lại không chạm bề mặt mà bay ngược lên ở 114 MPH
  • Nghĩa là kết quả hạ cánh mềm vốn phải tồn tại giữa hạ cánh mạnhbay ngược lên không hạ cánh đã biến mất

Mô phỏng vật lý tinh vi hơn dự đoán

  • Ban đầu người ta tưởng trò chơi dùng tích phân Euler, vốn vẫn rất phổ biến cả ở game hiện đại
    • Tính lực tại thời điểm đầu khoảng thời gian
    • Dùng F=ma để suy ra gia tốc
    • Rồi giả sử gia tốc không đổi trong suốt khoảng đó
  • Nhưng mã Lunar Landing thực tế còn tinh vi hơn
  • Jim Storer dùng nghiệm chính xác của phương trình tên lửa Tsiolkovsky
  • Việc tính log được triển khai bằng khai triển chuỗi Taylor
    • Giá trị lớn nhất của đối số là 0.1212
    • Chỉ với 5 hạng đã đạt độ chính xác hơn 6 chữ số
  • Việc rút gọn đại số cũng giúp giảm sai số làm tròn
  • Jim Storer nhớ rằng khi đó mình đã quen với các khái niệm như vi tích phân và chuỗi Taylor, và người cha là nhà vật lý đã giúp suy ra các phương trình
  • Việc suicide burn trở thành chiến lược tối ưu cũng xuất phát từ chính phương trình tên lửa này, và đây không phải nguyên nhân của lỗi

Vì sao việc xác định chạm đất lại khó

  • Phương trình tên lửa hoạt động tốt cho đến trước khi tàu đổ bộ chạm mặt đất
  • Va chạm giữa các vật rắn là một phần khó trong các engine động lực học, và Lunar Landing cũng gặp thách thức lớn nhất ở việc xác định thời điểm chạm đất
  • Chỉ kiểm tra thời điểm đầu và cuối của một lượt 10 giây là không đủ
    • Ở đầu lượt, tàu có thể đang đi xuống
    • Đến cuối lượt, tàu có thể đang đi lên
    • Nó có thể đã đi xuống dưới bề mặt rồi lại bay lên trong khoảng giữa
  • Trong trường hợp đó, chương trình phải tua ngược thời gian để tìm thời điểm chạm đất sớm hơn
  • Điểm kiểm tra tự nhiên là điểm thấp nhất của quỹ đạo, nơi vận tốc bằng 0
  • Với phương trình tên lửa, không thể biểu diễn điểm thấp nhất này dưới dạng đóng chỉ bằng các hàm toán học cơ bản
    • Chú thích cho biết cần đến Lambert W
  • Tuy nhiên có thể xấp xỉ nó bằng vài hạng đầu của chuỗi Taylor của log
    • Nếu chỉ dùng hai hạng đầu thì bài toán rút gọn thành phương trình bậc hai
    • Có thể dùng công thức nghiệm bậc hai ở mức toán trung học
    • Trong phạm vi một lượt 10 giây, độ chính xác kỳ vọng nằm trong khoảng 0.1%

Công thức bậc hai thay thế và độ ổn định số

  • Trong mã của Jim Storer, căn bậc hai xuất hiện ở mẫu số chứ không phải tử số
  • Điều này không khớp với công thức nghiệm bậc hai quen thuộc, mà trùng với dạng thay thế của công thức nghiệm bậc hai, nơi căn bậc hai nằm ở bên dưới
  • Dạng thay thế này có một ưu điểm số học quan trọng
    • Sau khi phát hiện có chạm đất, chương trình cũng dùng xấp xỉ phương trình bậc hai từ chuỗi Taylor để tìm thời điểm chạm đất thực sự
    • Dạng thông thường có thể gặp lỗi chia cho 0 khi hệ số bậc hai bằng 0
    • Điều này xảy ra khi lực đẩy của tên lửa cân bằng chính xác với trọng lực
    • Đây là tình huống khá phổ biến với người chơi đang lơ lửng gần mặt đất hoặc hạ xuống rất chậm
  • Khi lực đẩy gần bằng trọng lực, dạng thông thường còn gặp catastrophic cancellation ở tử số, và mẫu số nhỏ sẽ khuếch đại sai số
  • Dạng thay thế vẫn hoạt động tốt cả trong trường hợp phương trình thực chất trở thành tuyến tính vì hệ số bậc hai bằng 0
  • Với bối cảnh năm 1969, việc một học sinh trung học tự suy ra lại hoặc đã học được dạng này là điều rất ấn tượng

Lỗi thực sự: factor of two bị thiếu

  • Khi tự tay suy ra công thức và đối chiếu, người ta thấy nó gần như giống hệt mã của Jim Storer, chỉ khác ở chỗ thiếu số 2 ở mẫu số bên trong căn bậc hai
  • Nhiều khả năng đây chỉ là một sai sót đơn giản phát sinh trong lúc suy ra công thức hoặc nhập vào máy tính
  • Khi đó MACSYMA mới chỉ xuất hiện được khoảng một năm và cũng không phải công cụ mà học sinh trung học có thể dùng, nên mọi phép suy ra đều phải làm bằng giấy bút
  • Vì lỗi này, thời gian tới điểm thấp nhất luôn bị ước lượng thiếu
  • Mã nguồn cố bù lại bằng hai cách
    • Cộng thêm 0.05 giây
    • Ước lượng lại từ một vị trí mới và gần hơn
  • Nhưng trong trường hợp suicide burn cụ thể, chính phần bù này lại khiến thời điểm hạ cánh bị bỏ lỡ
    • Lần ước lượng đầu tiên là một thời điểm tàu vẫn đang đi xuống phía trên bề mặt
    • Lần thứ hai là một thời điểm sau điểm thấp nhất khi tàu đã bắt đầu đi lên
    • Khoảng cách giữa hai thời điểm này có thể ngắn hơn 0.05 giây

Kết quả sau khi sửa và những giới hạn còn lại

  • Khi thêm factor of two bị thiếu và bỏ phần bù 0.05 giây, kết quả suicide burn được cải thiện
  • Sau khi sửa, cú suicide burn tốt nhất đạt tốc độ hạ cánh 1.66 MPH
    • Tức là đã tiến được khoảng 3/4 chặng đường tới cú hạ cánh hoàn hảo dưới 1 MPH
  • Lý do vẫn chưa hoàn hảo là vì chương trình vẫn chỉ dùng hai hạng đầu của chuỗi Taylor
  • Sau khi xác định điểm thấp nhất nằm dưới bề mặt, chương trình vẫn phải tìm lại thời điểm tàu chạm bề mặt lần đầu
    • Quá trình này cũng dùng một phép xấp xỉ tương tự
    • Có thể thêm lặp để cải thiện kết quả
  • Khi lỗi đã được sửa, thời gian lại bị ước lượng thừa, nên có thể cần tua ngược thời gian
    • Trong trường hợp đó có thể phải chọn nghiệm còn lại của phương trình bậc hai
  • Một cách đơn giản hơn là chỉ dùng một hạng Taylor và xử lý theo cách gần giống phương pháp Newton
  • Cũng có thể dừng khi độ lớn vận tốc giảm xuống dưới một ngưỡng nhất định, rồi lấy độ cao tại thời điểm đó để quyết định có hạ cánh hay chưa
  • Tuy nhiên những thay đổi như vậy sẽ khiến mã phức tạp hơn, trong khi trò chơi nguyên bản vốn đã đủ thú vị để chơi

Vì sao lỗi tồn tại lâu đến vậy

  • Việc hạ cánh mềm vốn vẫn làm được
    • Kết thúc lượt 14 ở độ cao thấp và vận tốc thấp
    • Dùng lực đẩy thấp trong lượt 15
    • Và hạ cánh ở một thời điểm nào đó sau mốc 150 giây
  • Điều gây ra vấn đề là kiểu suicide burn lực đẩy tối đa về mặt lý thuyết, kết thúc vào khoảng 148 giây
  • Xét tổng thể, đây vẫn là một đoạn mã cực kỳ ấn tượng đối với sản phẩm do một học sinh trung học 18 tuổi viết trên PDP-8 năm 1969
  • Khi đó các trường trung học còn chưa dạy khoa học máy tính, và những khái niệm tính toán số như lặp cải tiến ước lượng bằng phương pháp Newton hay lo ngại catastrophic cancellation cũng chưa phổ biến rộng rãi
  • Lý do lỗi gần 55 năm không bị phát hiện là vì ngay cả khi có lỗi, trò chơi vẫn khó, vẫn vui, và vẫn có thể hạ cánh mềm
  • Việc không chỉ muốn thắng mà còn muốn tìm ra chiến lược tối ưu đã dẫn đến quá trình giải thích một sai khác nhỏ nhưng thú vị

1 bình luận

 
GN⁺ 2024-06-15
Các ý kiến trên Hacker News
  • Năm 2009, Jim Storer đã được xác định là người tạo ra trò chơi Lunar Lander đầu tiên và được phỏng vấn; sau đó lịch sử của trò chơi cũng được tổng hợp lại
    Về sau, ông ấy còn cung cấp cả mã nguồn, thật sự rất tuyệt
    https://technologizer.com/2009/07/19/lunar-lander/index.html
    Đoạn tôi thích nhất là khi Storer nói: “Từ sau khi tốt nghiệp trung học, tôi chưa từng nghĩ lại về trò chơi đó. Cho đến khi vài tháng trước có người gửi email cho tôi về chuyện này, tôi thậm chí còn không hề biết rằng ngoài trò tôi làm hồi trung học còn có những trò Lunar Lander khác.”
    • Thật vinh dự khi được đưa vào bài viết này. Ban đầu tôi làm Lander (1990) cho Windows 2.x
      Năm 1989, khi ứng tuyển một công việc liên quan đến Lotus Notes, tôi đã cho người phỏng vấn Tim Halvorsen xem trò Lander, và ông ấy nói: “Hay đấy, thử chạy trên Windows 3 xem nào”
      Lúc đầu tôi nghĩ thật tốt vì được xem Windows 3 khi nó còn chưa phát hành, nhưng ngay sau đó ông ấy nói: “Windows 3 chạy mọi thứ ở protected mode, nên nếu con trỏ vượt ra ngoài phạm vi là sẽ chết ngay”, rồi đề nghị thử
      Tôi nín thở suốt lúc chương trình chạy, nhưng may là Lander không chết, Tim cũng hài lòng, và cuối cùng tôi nhận được công việc đó, khiến sự nghiệp của tôi hoàn toàn rẽ sang hướng khác
    • Cũng từng có trò chơi hạ cánh cơ khí xuất hiện trước Lunar Lander
      Tôi không tìm được ảnh, nhưng theo trí nhớ thì nó giống kiểu máy này
      https://content.invisioncic.com/r322239/monthly_10_2015/post...
      Tuy nhiên nó có địa hình và các hố, và bạn phải hạ cánh vào hố đang sáng đèn. Khi phi thuyền nhấn vào nút ở giữa hố, đèn sẽ tắt và một hố khác sẽ sáng lên; nếu ngắm không chuẩn, nó sẽ va vào mép, nghiêng đi và thất bại
      Nghĩ lại thì cách điều khiển có lẽ giống máy gắp UFO: căn chỉnh từ phía trên rồi bấm “land”. Nó từng có ở Disneyland Main Street Arcade ngày xưa
    • Một trong những trò chơi đầu tiên tôi từng cố làm theo khi học lập trình hồi trung học là Lunar Lander: https://github.com/celwell/space-landing làm bằng Java applet
  • Dòng có vấn đề có vẻ là 08.10
    Tôi thấy hơi lạ khi bài viết nhiều lần nói “ấn tượng đối với một học sinh lớp 12 năm 1969”. Với những người thiên về kỹ thuật lớn lên trong kỷ nguyên không gian, điều đó hẳn đã có tác động rất lớn, và tôi cũng nhớ đến bộ phim cũ October Sky
    Trong bài phỏng vấn gốc, người tạo trò chơi được nói là giỏi giải tích, nên nếu có hứng thú và năng khiếu về không gian hoặc tên lửa thì việc thử lập trình một trò mô phỏng hạ cánh xuống Mặt Trăng có vẻ cũng tự nhiên
    [1]: https://www.cs.brandeis.edu/~storer/LunarLander/LunarLander/...
    • Năm 1969 ở Mỹ, số học sinh trung học có thể tiếp cận máy tính có lẽ chỉ ở mức vài trăm người, và số học sinh có khả năng sử dụng máy tính còn ít hơn nữa
      Kỷ nguyên không gian có thể đã truyền cảm hứng, nhưng với công chúng nói chung vào thời đó, máy tính gần như không tồn tại, và phát triển phần mềm cũng chưa phải là một nghề được biết đến rộng rãi. Ngành khoa học máy tính ở Mỹ cũng chỉ bắt đầu xuất hiện từ năm 1962, nên việc ông ấy là học sinh lớp 12 vào năm 1969 là khá đáng chú ý
    • Năm 1969 tôi là học sinh trung học, cũng biết giải tích ở mức nào đó, và rất quan tâm đến lập trình
      Tôi học ở một trường trung học lớn trong một thành phố khá lớn có một trường kỹ thuật lớn, nhưng rào cản lớn nhất là khả năng tiếp cận máy tính
      Trường có một máy teletype nối với mainframe từ xa, và tôi cùng bạn bè tìm được vài máy tính ở đại học có thể dùng ban đêm, nhưng phần lớn chỉ có đầu đọc thẻ và máy in dòng, hoàn toàn không có terminal đồ họa
      Vào thời đó, tổ hợp gồm kỹ năng, hứng thú và khả năng tiếp cận như vậy hẳn là khá hiếm
    • Tôi tò mò trò này được viết bằng ngôn ngữ nào, và xem bài viết liên quan đến trò chơi này thì thấy đó là một ngôn ngữ tên FOCAL
      https://retro365.blog/2021/12/02/bits-from-my-personal-colle...
      Wikipedia về FOCAL:
      https://en.wikipedia.org/wiki/FOCAL_(programming_language)
    • Tôi là tác giả bài gốc. Tôi hiểu rằng cụm “ấn tượng đối với một học sinh lớp 12 năm 1969” có thể nghe hơi lạ, nhưng để làm trò chơi này cần khá nhiều thứ
      Từ vật lý trung học, bắt đầu với sơ đồ vật thể tự do rồi xử lý hai lực là trọng lực và lực đẩy thì một học sinh trung bình đạt điểm A môn vật lý cũng có thể làm được
      Nhưng trọng lực phụ thuộc vào khoảng cách tới tâm, tức là một giá trị liên tục thay đổi. Bạn phải biết rằng dù bắt đầu ở độ cao 120 dặm, sự thay đổi không lớn nên có thể xấp xỉ bằng hằng số
      Cách lực đẩy hoạt động như một hàm của tốc độ đốt nhiên liệu cũng khó hiểu. Nếu tăng gấp đôi lưu lượng nhiên liệu thì vận tốc khí thải có tăng gấp đôi không, P và T trong định luật khí lý tưởng PV=nRT thay đổi thế nào — những vấn đề như vậy sẽ xuất hiện
      Vì vậy, nếu ông ấy hỏi cha mình là một nhà vật lý, rồi tìm ra các đặc tính của động cơ tên lửa và phương trình tên lửa Tsiolkovsky, thì chỉ riêng điều đó đã là ấn tượng đối với một học sinh lớp 12
      Muốn đi từ vận tốc sang vị trí thì phải tích phân, và tôi không biết liệu một học sinh trung bình đạt điểm A môn vật lý có nghĩ ra việc thay lời gọi FLOG() bằng chuỗi Taylor rồi tích phân từng hạng hay không
      Các chi tiết như cần dùng bao nhiêu hạng của chuỗi Taylor, hay nó có hội tụ không, cũng khá hóc búa. Nếu Jim đã nghĩ đến những điểm tinh tế này thì rất đáng nể; cũng có khả năng ông ấy chỉ thấy 5 hạng có vẻ nhiều nên dùng như vậy

Ngay cả nếu mô phỏng gần Mặt Trăng đã xong, việc phát hiện va chạm với mặt đất cũng là một vấn đề. Thay vì giải trực tiếp nghiệm khi độ cao bằng 0, cách nhìn vào điểm vận tốc bằng 0 xuất hiện đúng một lần trong quá trình quay là khá sáng tạo
Việc đảo ngược phương trình tên lửa để tính lượng nhiên liệu cần thiết khi đưa vào delta-V mong muốn cũng vượt quá toán phổ thông và giải tích cơ bản. Thực tế cần một hàm mới như Lambert W
Cuối cùng phải giải đa thức bậc 5 bằng chuỗi Taylor, nên phải quyết định bỏ các hạng bậc 3, 4, 5 để biến nó thành phương trình bậc hai. Điều ấn tượng là ông ấy hiểu rằng có thể dùng các mức xấp xỉ khác nhau cho những tình huống khác nhau, khi ở đây ông ấy đánh giá rằng có thể bỏ các hạng mà bình thường khi tính động lực học thì không bỏ
Ngoài ra, việc bằng cách nào đó dùng dạng thay thế của phương trình bậc hai cho thấy có thể đây không chỉ là mức tìm rồi chép lại

  • Dù nổi tiếng là trò Lunar Lander đầu tiên, phần thật sự ấn tượng là các kỹ thuật giải tích số được sử dụng
  • Vào giữa thập niên 1970, ông ấy đã làm một trò chơi hạ cánh Mặt Trăng với đồ họa vector 2D cho thiết bị đầu cuối đồ họa Adage
    Người chơi phải lao vào nhanh theo phương ngang rồi dùng các nút động cơ đẩy bên và động cơ chính của LEM để giảm tốc và hạ cánh thẳng đứng; nếu quá nhanh hoặc hết nhiên liệu thì sẽ tạo thành hố va chạm, còn tùy chất lượng hạ cánh mà một hoặc nhiều lá cờ Mỹ được cắm xuống
    Vài năm trước ông ấy đã vứt bản sao duy nhất vì nghĩ mã nguồn chẳng có giá trị và cũng sẽ không được tái sử dụng, nhưng sau đó hối tiếc khi nhận ra đó là một trò chơi đồ họa khá sớm về mặt lịch sử và có thể hồi sinh bằng một mô phỏng đơn giản
    • Ý muốn nói là “hạ cánh thẳng đứng”, không phải “hạ cánh ngang”
  • Trong cuốn sách lập trình đầu tiên của tôi có phiên bản BASIC của trò này, nhưng tôi không thể chạy nó cho đúng
    25 năm sau xem lại thì tôi kinh ngạc vì nó có quá nhiều lỗi vô lý, logic cũng rối như “440 IF GOTO 450”
    Cuối cùng khi trưởng thành tôi đã viết lại nó [1], nhưng hồi nhỏ thì tôi không có cơ hội thành công nào. Đến giờ tôi vẫn tò mò không biết làm sao đoạn mã gần như chạy được ở đâu đó trong nội bộ nhà xuất bản Tây Ban Nha bị lãng quên ấy lại biến thành dạng như bản cuối cùng đó
    [1] https://7c0h.com/blog/new/moon_landing_in_basic.html
    • Nói “không có cơ hội” vẫn còn là chưa đủ
      Kiểu mã BASIC này có gốc rễ từ thập niên 1960–1970, và trong các tạp chí in cùng tuyển tập mã đăng mã nguồn thời đó, biên tập viên có quyền rất lớn
      Ý thức rằng phải đăng nguyên xi mã nguồn, không đổi dù chỉ một ký tự, còn yếu, nên các biên tập viên thường “cẩn thận” sửa mã nguồn vì nghĩ đó là lỗi đánh máy “rõ ràng” hoặc là quyết định biên tập
      Từ thập niên 1980, toàn ngành bắt đầu cải thiện và bài học rằng không được đụng vào mã nguồn trong ấn phẩm in đã được học một cách chậm chạp và đau đớn
      Tôi cũng tự hỏi liệu xu hướng này có thúc đẩy sự trỗi dậy của BBS và làm suy yếu quyền lực mà báo in từng nắm trong việc phân phối mã nguồn hay không. Nếu những người nắm quyền ở truyền thông in cởi mở hơn với việc người ngoài có quyền kiểm soát tuyệt đối đối với một phần nội dung “của họ”, có lẽ lịch sử đã khác
      Hồi nhỏ tôi bắt đầu lập trình chỉ với vài cuốn sách lập trình ở trường và thư viện địa phương, không có người lớn giúp đỡ; thật kỳ lạ là dù rất nhiều chương trình tôi gõ tay cũng đầy lỗi tương tự, tôi vẫn tiếp tục bám lấy việc lập trình
    • Đọc rất thú vị. Hồi nhỏ, khi thấy C64 “như có phép thuật” nạp hình ảnh liên quan đến game chỉ bằng vài dòng mã, tôi từng nghĩ các hình đó đơn giản là đã nằm sẵn đâu đó bên trong máy
      Bổ sung một chút về kiểu logic rối như “440 IF GOTO 450”: một phần mã trong sách rõ ràng cần được dọn dẹp, nhưng BASIC phổ biến trên máy tính gia đình thời đó rất có thể chỉ xử lý số dòng và có câu lệnh rẽ nhánh cực kỳ hạn chế
      BASIC được dùng có vẻ hỗ trợ lập trình có cấu trúc, nhưng điều này rất hiếm trên máy tính gia đình thời đó. Đến mức năm 1984, một tạp chí C64 đã đăng một loạt bài dài ít nhất 3 số để giới thiệu với độc giả sự kỳ diệu của lập trình có cấu trúc
      Do các ràng buộc của câu lệnh IF rất nặng, kiểu rẽ nhánh điều kiện theo phong cách hợp ngữ dùng GOTO là rất phổ biến và trên thực tế là cần thiết
      Không thể lồng IF, và nếu muốn kết hợp nhiều IF thì phải nhảy qua phần không được chọn. Commodore/C64 BASIC, thực chất là Microsoft BASIC, thậm chí không có ELSE, nên thường phải mô phỏng nhánh ELSE bằng điều kiện phủ định và lệnh nhảy
      C64 BASIC có một hành vi đặc biệt: các câu lệnh khác trên cùng dòng cũng thuộc THEN. Ví dụ 10 IF A=1 THEN PRINT “FOO” : PRINT “BAR” sẽ in FOO BAR khi A=1, còn không thì không in gì
      Tất nhiên điều đó chỉ khả thi khi có thể nhét các câu lệnh vào một dòng bị giới hạn. Một số phương ngữ BASIC khác sẽ xem PRINT “BAR” là nằm ngoài ELSE, về mặt cú pháp thì sạch hơn, nhưng tùy các tính năng phương ngữ cung cấp mà có thể kém tiện hơn
      Khi đó không có những tiện ích và sự nghiêm ngặt mà ngày nay ta coi là hiển nhiên. C64 BASIC có nhiều đặc tính kỳ quặc giống như sản phẩm phụ của cách triển khai, nên đặc biệt tạo cảm giác “bừa bộn”. Chẳng hạn mọi hàm đều phải có đối số dù thực ra không cần; muốn in bộ nhớ còn lại thì phải viết kiểu vô nghĩa như ?FRE(123)
    • Có lẽ đó là kết quả pha trộn giữa lỗi sao chép/dán trong quá trình biên tập, hạn chót và thiếu đảm bảo chất lượng
  • Có vẻ chiến lược hạ cánh mềm tối ưu nhiên liệu không đúng với dạng chính xác của “suicide burn” nên đã bị bỏ qua, nhưng có lẽ là nhập 164.31426784 lbs/second tại t=70 giây, rồi sau đó thay một trong các lần nhập 200 lbs/second bằng 199.99999999 lbs/second
    Càng “chơi” 199.99999999 sớm thì càng tốt, nên chỉ cần tìm vét cạn lần nhập sớm nhất vẫn cho hạ cánh mềm
    • Bản chất của lỗi là khó xác định thời điểm tàu đổ bộ chạm bề mặt
      Để trò chơi nhận ra đã hạ cánh, độ cao phải nhỏ hơn 0 trong khoảng 0,05 giây. Nếu trong thời gian đó lực đẩy là 200 hoặc 199, thì để độ cao âm lâu như vậy, vận tốc tại điểm độ cao bằng 0 phải lớn hơn 1 MPH
      Ngay cả khi sửa lỗi, mã vẫn chỉ xấp xỉ điểm thấp nhất. Sau khi phát hiện hạ cánh, vẫn phải tính thời điểm hạ cánh thực sự, tức thời điểm độ cao chứ không phải vận tốc bằng 0, và việc này cũng dùng xấp xỉ
      Vì vậy thời gian có thể lệch một chút. Nếu ở bước thời gian cuối đang đốt với 200 hoặc 199, gia tốc lớn khiến một sai số thời gian rất nhỏ cũng dẫn đến sai số vận tốc lớn
      Thay vào đó, nếu đốt ở khoảng 10 lbs/sec thì dù lệch chừng 0,08 giây, thay đổi vận tốc cũng không lớn
  • Nếu viết một cách ngây thơ, có lẽ tôi sẽ không dùng công thức đặc biệt nào mà tính lại khối lượng và gia tốc theo khối lượng mới ở mỗi khung hình, rồi tính giao điểm với mặt đất tại ranh giới mỗi khung hình

Tôi thắc mắc liệu điều đó có nghĩa là tốc độ khung hình càng thấp thì cách này càng kém chính xác, hay chỉ đơn giản là vì cái thú khi dùng phương trình thực tế
Cũng tò mò không biết ở tốc độ khung hình ban đầu thì sự khác biệt giữa hai cách có thể cảm nhận được đến mức nào

  • Không hề có xuất đồ họa hay tốc độ khung hình theo nghĩa bạn đang nghĩ. Kết quả hẳn được in ra kiểu như thế này
    https://www.cs.brandeis.edu/~storer/LunarLander/LunarLander/...
    Nếu chỉ cập nhật khối lượng và gia tốc mỗi 10 giây thì sẽ cực kỳ thiếu chính xác
  • Tôi là tác giả bài gốc. Tôi cũng đã dự đoán cách ngây thơ đó, và trong bài đã giải thích nó là phương pháp Euler
    Xét về độ chính xác vật lý, đặc biệt khi ở gần bề mặt và tốc độ đốt nhiên liệu cao, khối lượng thay đổi khá đáng kể. Nhưng về độ khó hay độ vui của trò chơi, cũng như chiến lược của người chơi, tôi nghĩ sẽ không có khác biệt lớn
    Thực tế, một trong các mô phỏng hạ cánh Mặt Trăng khác trong sách BASIC computer games có vẻ dùng cách tiếp cận ngây thơ như vậy
    Nếu 10 giây là quá dài, có thể giữ một lượt trong giao diện người dùng là 10 giây, còn bên trong thì chia mỗi lượt nhỏ hơn, chẳng hạn thành 10 bước thời gian mỗi bước 1 giây
    Trò chơi hiện có ở một số phần thực ra cũng làm như vậy, nên mô phỏng vật lý được thiết kế để nhận đầu vào là một khoảng thời gian S tùy ý, chứ không phải lúc nào cũng là trọn 10 giây
  • Tôi đã hơi nhầm trong chốc lát vì nhớ mình từng chơi Spacewar trên PDP-1 vào thập niên 1960, và nhớ nhầm rằng cũng có trò hạ cánh
    Nhưng không có trò hạ cánh nào cả, và Storer là người đầu tiên. Lịch sử thú vị liên quan nằm ở đây
    https://www.acriticalhit.com/moonlander-one-giant-leap-for-g...
  • Cách nói “suicide burn trở thành tối ưu vì phương trình tên lửa” nếu xét nghiêm ngặt thì không đúng
    Ngay cả khi không tính đến hiệu ứng tàu nhẹ đi do đốt nhiên liệu, tức là bỏ phần việc mà phương trình tên lửa làm ở đây, suicide burn vẫn là tối ưu
    Lý do thật sự là suicide burn giảm thiểu tổn thất do trọng lực
    https://en.wikipedia.org/wiki/Gravity_loss
    • Tôi là tác giả bài gốc. Đúng vậy, tôi đã nói đơn giản hóa
      Ý tôi là trong động lực học có hai phần: phương trình tên lửa và trọng lực, và hai phần này được cộng tuyến tính với nhau. Vận tốc tăng thêm do trọng lực gây ra phải được loại bỏ bằng cách tăng delta-V của phương trình tên lửa
      Delta-V do trọng lực bằng gia tốc trọng trường nhân với thời gian, nên cần tối thiểu hóa thời gian
      Điều đáng ngạc nhiên là trong phương trình tên lửa, mất bao lâu, dùng trình tự đốt nào, đốt liên tục ở tốc độ không đổi hay đốt bằng các cú phun ngắn và mạnh đều không quan trọng
      Vì vậy, để hạ cánh với vận tốc 0 mà tốn ít nhiên liệu nhất, bạn chỉ cần hạ cánh trong thời gian ngắn nhất có thể
  • Tôi vẫn còn giữ một cuộn băng đục lỗ có vẻ dành cho PDP-11, trên đó ghi “Lunar Lander”, nhưng không biết nên trao cho ai
    • Internet Archive hoặc Computer History Museum có vẻ phù hợp. Nếu muốn gợi ý nơi có thể quan tâm, hãy hỏi @textfiles
  • Khá bất ngờ. Tôi nhớ mình từng chơi trò này sau khi ai đó port nó sang Wang 2200 BASIC vào giữa thập niên 1970
    Tôi không tự tìm ra cách hạ cánh, nhưng nhớ có người đã chỉ kỹ thuật để vài lượt đầu bay theo quán tính rồi bật lực đẩy tối đa. Khi đó tôi không nhớ có thuật ngữ “suicide burn”. Có lẽ đó là từ xuất hiện về sau, sau khi Kerbal Space Program trở nên nổi tiếng
    Tôi cũng nhớ vào giữa thập niên 1970 tại Lawrence Hall of Science ở Berkeley, trò hạ cánh Mặt Trăng này chạy trên vài thiết bị đầu cuối. Tôi không biết nó đang chạy trên máy tính nào
    Tôi chưa từng thấy mã nguồn của chương trình này, và hoàn toàn không biết phần toán lại tinh vi đến vậy. Hồi đó tôi còn quá nhỏ nên chắc đã không hiểu nổi, và thành thật mà nói giờ cũng không chắc mình có hiểu được không
    • Tôi nhớ khoảng đầu năm 1973 ở Lawrence có thể chơi Lunar Lander, có lẽ trên thiết bị đầu cuối ADM-3. Thường có một nhóm nam thiếu niên tụ tập quanh đó
      Một “tính năng” của chế độ kiosk dành cho trò chơi là nếu bấm Ctrl-C đúng thời điểm, có thể thoát khỏi chế độ kiosk để chơi các trò khác
      Đó là tình cờ, hay là mồi nhử dành cho các hacker thời kỳ đầu?