- vừa được xem lúc

[Procedural Programming + Ada] Bài 17 - Console Tic-Tac-Toe App (tiếp theo)

0 0 19

Người đăng: Semi Dev

Theo Viblo Asia

Chúng ta sẽ khởi đầu code thật tự nhiên với procedure Main và các comment về những bước cần thực hiện trong code.

  1. Ngay khi khởi chạy app thì chúng ta sẽ cần phải in ra màn hình tùy chọn để người dùng User chọn ký hiệu X hoặc O để ghi vào bảng Tic-Tac-Toe và thể hiện các bước đi của User và máy tính Computer.
  2. Scan lựa chọn nhập liệu của User và lưu lại trạng thái User_Symbol.
  3. Sau khi người dùng đã chọn ký hiệu đại diện thì app cần thực hiện khởi tạo State lưu trữ trạng thái của gameboard bao gồm các bước đi của User, và các bước của Computer, và cả các ô trống còn lại. State này có thể có chứa thêm các trạng thái khác như nhận định Match_Status để thể hiện là ván cờ đã kết thúc sau một bước đi nào đó của User hoặc Computer.

Để khởi đầu đơn giản thì chúng ta sẽ mặc định là User sẽ luôn luôn được thực hiện bước đi trước. Và trình tự các thủ tục procedure tiếp theo cần thực hiện là:

  1. In ra bảng Tic-Tac-Toe để người dùng User có thể theo dõi trạng thái hiện tại của gameboard và tính toán bước đi.
  2. Nhận kết quả nhập liệu để mô tả bước đi mà User muốn thực hiện.
  3. Cập nhật trạng thái State của ứng dụng tương ứng với bước đi vừa rồi của User.
  4. Kiểm tra trạng thái của gameboard xem ván cờ đã kết thúc chưa. Nếu kết thúc rồi thì User thắng hay là kết quả hòa.

Tương tự, với lượt đi của máy tính Computer thì chúng ta cũng có các thủ tục như trên:

  1. In ra bảng Tic-Tac-Toe để người dùng User có thể theo dõi trạng thái hiện tại của gameboard và tính toán bước đi.
  2. Gọi trình tự tạo bước đi cho Computer dựa trên trạng thái của gameboard hiện tại.
  3. Cập nhật trạng thái State của ứng dụng tương ứng với bước đi vừa rồi của Computer.
  4. Kiểm tra trạng thái của gameboard xem ván cờ đã kết thúc chưa. Nếu kết thúc rồi thì Computer thắng hay là kết quả hòa.

Sau một lượt di chuyển của UserComputer như thế này thì chúng ta chỉ cần lặp lại các thủ tục từ 3 .. 10 cho đến khi ván cờ kết thúc.

with Ada.Text_IO; use Ada.Text_IO;
with App_Model; use App_Model;
with Console_IO; use Console_IO; procedure Main is -- local
begin -- 0. Put_Symbol_Menu; -- 1. Get_User_Symbol; -- -- 2. Init_App_State; -- loop -- 3. Put_Number_Board; -- 4. Get_User_Move; -- 5. Update_Move_Sets; -- 6. Update_Match_Status; -- -- 7. Put_Number_Board; -- 8. Get_Computer_Move; -- 9. Update_Move_Sets; -- 10. Update_Match_Status; -- -- exit when App_State.Match_Status /= PLAYING; -- end loop;
end Main;

Put_Symbol_Menu;

Đây là kết quả in ra dự kiến của Put_Symbol_Menu;Get_User_Symbol;:

Choose your Symbol ... 1. Letter 'X' 2. Letter 'O'
Your choice:

Chúng ta có thể thiết kế cú pháp sử dụng của các procedure khởi đầu này ở dạng tương tự với Put (Symbol_Menu);Get (User_Symbol); của thư viện Ada.Text_IO mà chúng ta đã biết. Tuy nhiên riêng đối với thao tác Put như vậy thì việc định nghĩa một hằng constant chứa toàn bộ nội dung của Symbol_Menu được định dạng thành các dòng và khoảng trống thụt vào như trên sẽ khá rườm rà trong Ada.

Vì vậy nên ở đây chúng ta sẽ thực hiện thao tác Put_Symbol_Menu với nội dung của menu được đặt trực tiếp bên trong procedure này, và định dạng bằng cách in ra từng dòng. Còn thao tác Get_User_Symbol sẽ được thiết kế dạng Get (User_Symbol); Về việc lưu lại kiểu ký hiệu mà User đã chọn thì tạm thời chúng ta sẽ định nghĩa một kiểu enum Symbol và lưu vào một biến cục bộ của procedure Main.

Và trong trường hợp lựa chọn mà người dùng nhập vào không hợp lệ thì chúng ta cần thêm một kiểu exception Error tự định nghĩa để raise và xử lý lại thao tác yêu cầu nhập lựa chọn.

package Console_IO is type Symbol is (X, O); SYMBOL_CHOICE_ERROR : exception; procedure Put_Symbol_Menu; procedure Get (User_Symbol : out Symbol);
end Console_IO;
package body Console_IO is procedure Put_Symbol_Menu is ... ; procedure Get (User_Symbol : out Symbol) is ... ; end Console_IO;

Code triển khai của Put_Symbol_Menu; thì không có gì đáng lưu ý bởi vì chúng ta chỉ đơn giản là Put_Line từng dòng nội dung trong kết quả mong muốn.

with Ada.Text_IO; use Ada.Text_IO; package body Console_IO is procedure Put_Symbol_Menu is -- local begin Put_Line ("Choose your Symbol ..."); Put_Line (" 1. Letter 'X'"); Put_Line (" 2. Letter 'O'"); end Put_Symbol_Menu; procedure Get (User_Symbol : out Symbol) is ... ; end Console_IO;

Get (User_Symbol);

Thao tác Get (User_Symbol) cũng khá đơn giản và trình tự cần thực hiện là chúng ta sẽ Put thông báo Your choice: để con trỏ không nhảy duống dòng mới và nội dung nhập liệu của User sẽ xuất hiện trên cùng dòng. Sau đó thực hiện thao tác Get (User_Input) để hiện con trỏ nhập liệu và nhận vào chuỗi thông tin.

Việc còn lại là chuyển chuỗi nhập liệu thành giá trị số nguyên Chosen_Number bởi vì nội dung của menu đang gợi ý người dùng nhập vào 1 hoặc 2 để chọn ký hiệu X hoặc O. Sau đó tạo cấu trúc điều kiện để thực hiện gán kết quả phù hợp cho tham số User_Symbol, hoặc raise SYMBOL_CHOICE_ERROR nếu người dùng nhập lựa chọn không hợp lệ.

with Ada.Text_IO; use Ada.Text_IO; package body Console_IO is procedure Put_Symbol_Menu is ... procedure Get (User_Symbol : out Symbol) is User_Input : String := "9"; Chosen_Number : Integer; begin Put ("Your choice: "); Get (User_Input); Chosen_Number := Integer'Value (User_Input); case Chosen_Number is when 1 => User_Symbol := X; when 2 => User_Symbol := O; when others => raise SYMBOL_CHOICE_ERROR; end case; Put_Line ("You've chosen: " & Symbol'Image (User_Symbol)); exception when others => Put_Line ("Choice number should be 1 or 2 ..."); Get (User_Symbol); -- end when end Get;

Phần thân của procedure là khối begin .. exception .. end ở đây vẫn khá dễ theo dõi do code cần thực hiện cũng không dài lắm. Riêng phần exception thì ở đây chúng ta có thể sử dụng others để bao gồm cả những ngoại lệ khác ví dụ như thao tác chuyển kiểu dữ liệu sang từ User_Input sang Chosen_Number.

Một lưu ý khác là procedure Get mà chúng ta tự định nghĩa sẽ được xem là một phiên bản overload song song với Ada.Text_IO.Get. Với chữ ký biểu trưng Get (out Symbol) có thể được trình biên dịch dễ dàng phân biệt với Get (out String) của Ada.Text_IO. Vì vậy nên khi chúng ta sử dụng Get (User_Input) ở đầu procedure và sau đó lại gọi Get (User_Symbol) ở phần exception sẽ không cần tham chiếu từ tên của các package để phân biệt.

with Ada.Text_IO; use Ada.Text_IO;
with App_Model; use App_Model;
with Console_IO; use Console_IO; procedure Main is User_Symbol : Symbol;
begin Put_Symbol_Menu; Get (User_Symbol); -- -- 2. Init_App_State; -- loop -- 3. Put_Number_Board -- 4. Get_User_Move -- 5. Update_Move_Sets -- 6. Update_Match_Status -- -- 7. Put_Number_Board -- 8. Get_Computer_Move -- 9. Update_Move_Sets -- 10. Update_Match_Status -- -- exit when App_State.Match_Status /= PLAYING; -- end loop;
end Main;

Cuối cùng là code sử dụng tại Main, chúng ta cần bổ sung biến cục bộ User_Symbol để lưu ký hiệu mà người dùng đã chọn trong suốt ván cờ.

alr run Choose your Symbol ... 1. Letter 'X' 2. Letter 'O'
Your choice: A
Choice number should be 1 or 2 ...
Your choice: 9
Choice number should be 1 or 2 ...
Your choice: 1
You've chosen: X

[Procedural Programming + Ada] Bài 18 - Console Tic-Tac-Toe App (tiếp theo)

Bình luận

Bài viết tương tự

- vừa được xem lúc

Closure trong Javascript - Phần 2: Định nghĩa và cách dùng

Các bạn có thể đọc qua phần 1 ở đây. Để mọi người không quên, mình xin tóm tắt gọn lại khái niệm lexical environment:.

0 0 67

- vừa được xem lúc

Var vs let vs const? Các cách khai báo biến và hằng trong Javascript

Dạo này mình tập tành học Javascript, thấy có 2 cách khai báo biến khác nhau nên đã tìm tòi sự khác biệt. Nay xin đăng lên đây để mọi người đọc xong hy vọng phân biệt được giữa let và var, và sau đó là khai báo hằng bằng const.

0 0 47

- vừa được xem lúc

VueJS: Tính năng Mixins

Chào mọi người, hôm nay mình sẽ viết về Mixins và 1 số vấn đề trong sử dụng Mixins hay ho mà mình gặp trong dự án thực. Trích dẫn từ trang chủ của VueJS:.

0 0 41

- vừa được xem lúc

Asset Pipeline là cái chi chi?

Asset Pipeline. Asset pipeline là cái chi chi. . Giải thích:.

0 0 75

- vừa được xem lúc

Tạo data table web app lấy dữ liệu từ Google Sheets sử dụng Apps Script

Google Sheets là công cụ tuyệt vời để lưu trữ bảng tính trực tuyến, bạn có thể truy cập bảng tính bất kỳ lúc nào ở bất kỳ đâu và luôn sẵn sàng để chia sẻ với người khác. Bài này gồm 2 phần.

0 0 280

- vừa được xem lúc

Học Deep Learning trên Coursera miễn phí

Bạn muốn bắt đầu với Deep Learning nhưng không biết bắt đầu từ đâu? Bạn muốn có một công việc ở mức fresher về Deep Learning? Bạn muốn khoe bạn bè về kiến thức Deep Learning của mình. Bắt đầu từ đâu.

0 0 50