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

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

0 0 19

Người đăng: Semi Dev

Theo Viblo Asia

Bộ đôi thủ tục tiếp theo là Put_Chess_Board;Get_User_move; lại rất tương đồng với đoạn xử lý Put_Symbol_Menu;Get (User_Symbol); trước đó.

Put_Chess_Board;

Khởi đầu mỗi ván cờ, chúng ta sẽ có một bảng Tic-Tac-Toe với các ô được đánh số 1 .. 9 để người dùng có thể định vị và nhập lựa chọn ô muốn đánh dấu.

 + - - + - - + - - + | 2 | 9 | 4 | + - - + - - + - - + | 7 | 5 | 3 | + - - + - - + - - + | 6 | 1 | 8 | + - - + - - + - - + 

Và nếu như sử dụng cách đánh số các ô trên bảng như thế này thì khi kiểm tra để cập nhật Match_Status sau mỗi bước đi của User hoặc Computer, thì chúng ta sẽ kiểm tra xem có bất kỳ bộ 3 số nào trong tập User_Set hoặc Computer_Set có tổng bằng 15 hay không. Nếu có, thì có nghĩa là User hoặc Computer đã hoàn thành được một đường thẳng nào đó trên bảng và thắng ván cờ đó.

Giả sử User_SymbolX thì ký hiệu còn lại O sẽ là của Computer, và chúng ta sẽ tùy vào dữ liệu của User_SetComputer_Set để ghi các ký hiệu tương ứng thay thế vào vị trí của các chữ số trong bảng Tic-Tac-Toe. Như vậy trình in Put_Chess_Board này có phức tạp hơn Put_Symbol_Menu một chút và ở vị trí của mỗi chữ số, chúng ta sẽ cần một function Area_Image để xác định ký ký tự được in ra là ký hiệu X hay O, hay chính chữ số đó.

package Console_IO is type Symbol is (X, O); SYMBOL_CHOICE_ERROR : exception; procedure Put_Symbol_Menu; procedure Get (User_Symbol : out Symbol); procedure Put_Chess_Board ( App_State : in State ; User_Symbol : in Symbol ) ; -- return Nothing function Area_Image ( Area : in Digit ; App_State : in State ; User_Symbol : in Symbol ) return String;
end Console_IO;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Exceptions; use Ada.Exceptions; package body Console_IO is procedure Put_Symbol_Menu is ... procedure Get (User_Symbol : out Symbol) is ... procedure Put_Chess_Board ( App_State : in State ; User_Symbol : in Symbol ) is ... function Area_Image ( Area : in Digit ; App_State : in State ; User_Symbol : in Symbol ) return String is ... end Console_IO;

Trong Put_Chess_Board thì chúng ta vẫn thực hiện in ra từng dòng copy/paste từ kết quả dự kiến. Và ở vị trí của các chữ số thì chúng ta cần sử dụng coupling function như đã nói ở trên để xác định ký tự sẽ được in ra.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Exceptions; use Ada.Exceptions; package body Console_IO is -- ... procedure Put_Chess_Board ( App_State : in State ; User_Symbol : in Symbol ) is begin Put_Line ("+ - - + - - + - - + "); Put_Line ("| " & Area_Image (2, App_State, User_Symbol) & " | " & Area_Image (9, App_State, User_Symbol) & " | " & Area_Image (4, App_State, User_Symbol) & " | "); Put_Line ("+ - - + - - + - - + "); Put_Line ("| " & Area_Image (7, App_State, User_Symbol) & " | " & Area_Image (5, App_State, User_Symbol) & " | " & Area_Image (3, App_State, User_Symbol) & " | "); Put_Line ("+ - - + - - + - - + "); Put_Line ("| " & Area_Image (6, App_State, User_Symbol) & " | " & Area_Image (1, App_State, User_Symbol) & " | " & Area_Image (8, App_State, User_Symbol) & " | "); Put_Line ("+ - - + - - + - - + "); end Put_Chess_Board; -- function Area_Image ... end Console_IO;

Và ở Area_image, thao tác kiểm tra chữ số được truyền vào đang thuộc *_Set nào sẽ được ủy thác cho một function khác để duy trì logic xử lý ký tự in ra với các nhánh lệnh dễ theo dõi.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Exceptions; use Ada.Exceptions; package body Console_IO is -- ... function Area_Image ( Area : in Digit ; App_State : in State ; User_Symbol : in Symbol ) return String is Computer_Symbol : Symbol; Result : String := "0"; begin Computer_Symbol := (if User_Symbol = X then O else X); -- if Found (Area, App_State.User_Set) then Result := Symbol'Image (User_Symbol); elsif Found (Area, App_State.Computer_Set) then Result := Symbol'Image (Computer_Symbol); else -- Found in App_State.Common_Set case Area is when 1 => Result := "1"; when 2 => Result := "2"; when 3 => Result := "3"; when 4 => Result := "4"; when 5 => Result := "5"; when 6 => Result := "6"; when 7 => Result := "7"; when 8 => Result := "8"; when 9 => Result := "9"; when others => Result := "0"; end case; end if; -- return Result; end Area_Image; end Console_IO;

Phép kiểm tra xem có tìm thấy Found ô trống Area trong một *_Set nào đó hay không - rất có thể sẽ được sử dụng lại và không hẳn thuộc về mảng làm việc Input/Output với cửa sổ Console; Vì vậy nên chúng ta sẽ định nghĩa tại package App_Model.

package App_Model is -- ... function Found (Area : Digit; Move_Set : Digit_Array) return Boolean; end App_Model;
package body App_Model is -- procedure Init ... function Found ( Area : Digit ; Move_Set : Digit_Array ) return Boolean is Result : Boolean := FALSE; begin for Index in Move_Set'Range loop if Area = Move_Set (Index) then Result := TRUE; end if; end loop; -- return Result; end Found; end App_Model;

Và cuối cùng là code sử dụng ở Main, chúng ta sẽ tạm thời thêm vào một vài câu lệnh để thể hiện một bước đi của User và một bước đi của Computer ở phía trước câu lệnh in bảng để kiểm tra logic hoạt động của Area_Image và `Found (Area, Move_Set).

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; App_State : State;
begin Put_Symbol_Menu; Get (User_Symbol); Init (App_State); -- loop Put_Chess_Board (App_State, User_Symbol); -- Put_Line ("User Moved: 1"); App_State.Common_Set (1) := 0; App_State.User_Set (1) := 1; -- Put_Line ("Computer Moved: 9"); App_State.Common_Set (9) := 0; App_State.Computer_Set (9) := 9; -- Put_Chess_Board (App_State, User_Symbol); -- 4. Get_User_Move -- 5. Update_User_Set -- 6. Update_Match_Status -- -- 7. Put_Chess_Board -- 8. Get_Computer_Move -- 9. Update_Computer_Set -- 10. Update_Match_Status -- -- exit when App_State.Match_Status /= PLAYING; -- end loop
end Main;
alr run Choose your Symbol ... 1. Letter 'X' 2. Letter 'O'
Your choice: 1
You've chosen: X
+ - - + - - + - - +
| 2 | 9 | 4 |
+ - - + - - + - - +
| 7 | 5 | 3 |
+ - - + - - + - - +
| 6 | 1 | 8 |
+ - - + - - + - - +
User Moved: 1
Computer Moved: 9
+ - - + - - + - - +
| 2 | O | 4 |
+ - - + - - + - - +
| 7 | 5 | 3 |
+ - - + - - + - - +
| 6 | X | 8 |
+ - - + - - + - - +

Get_User_Move;

Thao tác Get_User_Move; cũng có thể thiết kế với cú pháp sử dụng giống như Get (User_Symbol); trước đó. và kết quả sẽ được lưu lại vào biến cục bộ User_move của procedure Main. Trong trường hợp giá trị người dùng nhập vào ngoài khoảng 1 .. 9 thì chúng ta sẽ cần phải phát động ngoại lệ để đưa ra thông báo và yêu cầu thực hiện lại việc nhập liệu.

with App_Model; use App_Model; package Console_IO is type Symbol is (X, O); SYMBOL_CHOICE_ERROR : exception; MOVE_CHOICE_ERROR : exception; procedure Put_Symbol_Menu; procedure Get (User_Symbol : out Symbol); procedure Put_Chess_Board ... procedure Get (User_Move : out Digit); function Area_Image ... return String;
end Console_IO;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Exceptions; use Ada.Exceptions; package body Console_IO is -- ... procedure Get (User_Move : out Digit) is User_Input : String := "0"; Chosen_Number : Integer; begin Put ("Your move: "); Get (User_Input); Chosen_Number := Integer'Value (User_Input); case Chosen_Number is when 0 => raise MOVE_CHOICE_ERROR; when others => User_Move := Chosen_Number; end case; exception when others => Put_Line ("Choice number should be in 1 .. 9"); Get (User_Move); -- end when end Get; -- function Area_Image ... end Console_IO;

Và ở code sử dụng tại Main chúng ta sẽ tạm thời thêm lệnh Put_Line để kiểm tra kết quả nhập liệu.

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; App_State : State; User_Move : Digit;
begin Put_Symbol_Menu; Get (User_Symbol); Init (App_State); -- loop Put_Chess_Board (App_State, User_Symbol); Get (User_Move); Put_Line ("User Moved: " & Digit'Image (User_Move)); -- 5. Update_User_Set -- 6. Update_Match_Status -- -- 7. Put_Chess_Board -- 8. Get_Computer_Move -- 9. Update_Computer_Set -- 10. Update_Match_Status -- -- exit when App_State.Match_Status /= PLAYING; -- end loop
end Main;
Choose your Symbol ... 1. Letter 'X' 2. Letter 'O'
Your choice: 1
You've chosen: X
+ - - + - - + - - +
| 2 | 9 | 4 |
+ - - + - - + - - +
| 7 | 5 | 3 |
+ - - + - - + - - +
| 6 | 1 | 8 |
+ - - + - - + - - +
Your move: 0
Choice number should be in 1 .. 9
Your move: A
Choice number should be in 1 .. 9
Your move: 1
User Moved: 1

(chưa đăng tải) [Procedural Programming + Ada] Bài 20 - 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