Chương trình viết bằng ngôn ngữ Visual Basic 6, cho phép 2 người chơi trên 2 máy tính khác nhau thông qua mạng.
Chương trình cho 2 người chơi carô trên 2 máy tính khác nhau trong 1 mạng là 1 ứng dụng mạng. Thường 1 ứng dụng mạng dùng mô hình client-server để hoạt động. Với mô hình client-server, 1 ứng dụng mạng gồm 2 module độc lập chạy trên 2 máy: module client và module server. Module Client và module Server sẽ kết nối với nhau bằng 1 cầu nối (phương tiện truyền tin), khi cần, module client sẽ gởi 1 thông báo “request” tới module server để nhờ server phục vụ. Sau khi nhận 1 request từ module client, module server sẽ thực hiện rồi gởi kết quả về module client bằng 1 thông báo “reply”. Khi nào client/server không muốn giao tiếp với đối tác nữa thì nó sẽ đóng cầu nối lại.
Vấn đề thiết yếu nhất khi viết 1 ứng dụng mạng là định nghĩa được tập các thông báo request/reply mà client/server sẽ dùng trong giao tiếp với nhau. Phụ thuộc vào chức năng và tính chất hoạt động của ứng dụng mà giao thức sẽ ra sao. Thí dụ, sau khi phân tích chức năng của trò chơi carô, ta có thể định nghĩa giao thức làm việc tối giản cho ứng dụng này như sau:
Client có thể dùng 1 trong 2 thông báo request sau:
- “Restart” để yêu cầu server khởi động lại trò chơi hầu chơi ván mới.
- “x,y” để thông báo tọa độ của cell mà người dùng trên máy client vừa chọn.
Còn Server có thể dùng 1 trong 3 thông báo reply sau :
- “Accepted” để thông báo cho client biết mình đã chấp nhận yêu cầu kết nối của client và sẵn sàng phục vụ yêu cầu từ client.
- “Restart” để yêu cầu client khởi động lại trò chơi hầu chơi ván mới.
- “x,y” để thông báo tọa độ của cell mà người dùng trên máy server vừa chọn.
Khi viết ứng dụng mạng bằng ngôn ngữ VB 6.0, cách dễ dàng nhất là dùng điều khiển ActiveX của Microsoft có tên là Winsock. Điều khiển Winsock có thể hoạt động ở 1 trong 2 chế độ: winsock client hay winsock server. Winsock Server có thể giao tiếp với nhiều client đồng thời, còn winsock client thì chỉ có thể giao tiếp với 1 server tại từng thời điểm.
Để demo rõ ràng cụ thể, chúng tôi xây dựng ứng dụng (ở mức đơn giản nhất) cho 2 người trên 2 máy chơi carô, người chơi trên server sẽ đi trước với ký hiệu “O”, người chơi trên client sẽ đi sau với ký hiệu “X”. Sau đây là phát họa thuật giải của module server:
1. thiết lập các thông số hoạt động cho điều khiển winsock server, chờ và lắng nghe yêu cầu kết nối từ client…
2. khi client yêu cầu kết nối thì chấp thuận rồi gởi reply “Accepted” về client để báo sẵn sàng.
3. chờ người dùng ấn chuột vào vị trí chơi, kiểm tra tính hợp lệ, nếu hợp lệ sẽ hiển thị ký hiệu “O” vào vị trí và gởi thông báo “x,y” về client biết rồi kiểm tra xem server thắng chưa, nếu chưa thì chờ client chơi. Nếu server thắng thì dừng trò chơi và chờ yêu cầu chơi ván khác từ người dùng trên server hay trên client.
4. khi người dùng client đi xong, server sẽ nhận được thông báo “x,y” từ client gởi tới, server sẽ hiển thị ký hiệu “X” vào vị trí x,y, kiểm tra xem client thắng chưa, nếu chưa thì quay về bước 3. Nều client thắng thì dừng trò chơi và chờ yêu cầu chơi ván khác từ người dùng trên server hay trên client.
Tương tự, sau đây là phát họa thuật giải của module client:
1. yêu cầu người dùng cung cấp địa chỉ máy server cần giao tiếp, thiết lập các thông số hoạt động cho điều khiển winsock client, gọi tác vụ Connect của winsock client đế yêu cầu nối kết với server.
2. chờ đợi, khi nhận được reply “Accepted” từ server gởi về, client bắt đầu hoạt động. Theo qui ước ở trên, client sẽ đi sau.
3. client chờ server đi.
4. khi nhận được thông báo “x,y” từ server gởi tới, client sẽ hiển thị ký hiệu “O” vào vị trí x,y, kiểm tra xem server thắng chưa. Nếu server thắng thì dừng trò chơi và chờ yêu cầu chơi ván khác từ người dùng trên server hay trên client.
5. chờ người dùng ấn chuột vào vị trí chơi, kiểm tra tính hợp lệ, nếu hợp lệ sẽ hiển thị ký hiệu “X” vào vị trí và gởi thông báo “x,y” về server biết rồi kiểm tra xem client thắng chưa, nếu chưa thì quay về bước 3. Nếu client thắng thì dừng trò chơi và chờ yêu cầu chơi ván khác từ người dùng trên server hay trên client.
Dựa vào thuật giải được phát họa ở trên, ta sẽ hiện thực 2 module client và server để chúng thực hiện đúng theo thuật giải đã phát họa.
Qui trình vẽ các ảnh bitmap
Bàn cờ carô gồm nhiều ô cờ, mỗi ô cờ sẽ ở 1 trong 5 trạng thái sau : trống chưa đi, quân O đi, quân X đi, quân O thắng, quân X thắng. Dùng trình soạn thảo ảnh bitmap (Paint, CorelDraw, PhotoShop,...) vẽ 5 ảnh bitmap với kích thước bằng nhau (16*16) và lưu lên thành 5 file null.jpg, O.jpg, X.jpg, Ob.jpg, Xb.jpg.
Qui trình xây dựng module CaroServer bằng VB 6.0
1. chạy VB 6.0, tạo Propject "Standard EXE".
2. chọn menu Project.Components để hiển thị cửa sổ Components, duyệt tìm và chọn 2 mục “Microsoft Winsock Control 6.0” và “Microsoft Windows Common Control x.0” để “add” chúng vào cửa sổ ToolBox của Project.
3. Thiết kế Form cho ứng dụng CaroServer như sau:
Form Server có 3 label, 1 đối tượng ImageList, 1 đối tượng Winsock và 1 menu bar. Đặt tên cho 3 label lần lượt là lblState, lblPrompt1, lblPrompt2, tên cho ImageList là imgList, tên cho winsock là ServerSock. Để thiết kế menu bar, chọn menu Tools.Menu Editor rồi đặc tả 1 menu pop-up có tiêu đề “Thi hành lệnh…”, menu pop-up này chứa 2 option “Chơi lại ván khác” và “Dừng chương trình”. Đặt tên cho 2 option lần lượt là mnuExecPlay, menuExecQuit.
4. Thiết lập dữ liệu cho đối tượng ImageList : ấn phải chuột trên đối tượng ImageList rồi chọn mục Properties để hiển thị cửa sổ thuộc tính của đối tượng này. Chọn tag General, chọn option Custom, nhập độ rộng, độ cao của các ảnh miêu tả ô cờ. Chọn tag Images rồi chọn button "Insert Picture" để thêm từng file ảnh ô cờ vào. Lưu ý các file ảnh phải được thêm vào theo thứ tự sau: 1. null.jpg, 2. O.jpg, 3. X.jpg, 4. Ob.jpg, 5. Xb.jpg để tương thích với chỉ số được dùng trong code của chương trình dưới đây.
5. chọn menu View.Code để hiển thị cửa sổ soạn code cho form rồi viết đoạn code VB 6.0 sau đây:
Option Explicit
'Định nghĩa các hằng gợi nhớ được dùng
Private Const SID = 1 'mã nhận dạng người chơi ở server
Private Const CID = 2 'mã nhận dạng người chơi ở client
Private Const BLANC_IMG = 0 'mã ảnh miêu tả cell trống
Private Const O_IMG = 1 'mã ảnh miêu tả cell O
Private Const X_IMG = 2 'mã ảnh miêu tả cell X
Private Const WO_IMG = 3 'mã ảnh miêu tả cell O thắng
Private Const WX_IMG = 4 'mã ảnh miêu tả cell X thắng
'Định nghĩa các biến được dùng
Private Board() As Integer 'Ma trận tráng thái các ô
Private intRowsBoard As Integer 'số lượng hàng
Private intColsBoard As Integer 'số lượng cột
'Các biến miêu tả vị trí 5 ô thắng
Private WinRow As Integer, WinRStep As Integer
Private WinCol As Integer, WinCStep As Integer
'Các biến miêu tả tọa độ góc trên trái bàn cờ
Private intBaseX As Integer, intBaseY As Integer
'Các biến miêu tả kích thước từng ô cờ
Private intCellWidth As Integer, intCellHeight As Integer
'biến miêu tả trạng thái hoạt động
Dim curState As Integer
'biến miêu tả mã người thắng cuộc
Dim WinID As Integer
'1. thủ tục thiết lập các thông số ban đầu
Private Sub Form_Load()
Dim row As Integer, col As Integer
intRowsBoard = 20
intColsBoard = 20
intCellWidth = 15
intCellHeight = 15
intBaseX = 4
intBaseY = 70
'thiết lập lại kích thước form cho phù hợp
Me.ScaleMode = vbPixels
Me.Width = Me.ScaleX(intColsBoard * intCellWidth + intBaseX + 16, vbPixels, vbTwips)
Me.Height = Me.ScaleY(intRowsBoard * intCellHeight + intBaseY + 65, vbPixels, vbTwips)
ReDim Board(intRowsBoard - 1, intColsBoard - 1)
InitBoard
'hiển thị các thông báo cần thiết
lblState = "Đang chờ Client kết nối..."
lblPrompt1 = "Quân của bạn là O, quân của đối thủ là X"
lblPrompt2 = "Bạn hãy chờ đợi...."
'thiết lập port giao tiếp cho Server socket
ServerSock.LocalPort = 1001 'giá trị từ 0-65535
'chờ client kết nối tới
ServerSock.Listen
End Sub
'thủ tục khởi tạo trạng thái bàn cờ
Private Sub InitBoard()
Dim row As Integer, col As Integer
'thiết lập trạng thái chưa chơi
curState = 0
For row = 0 To intRowsBoard - 1
For col = 0 To intColsBoard - 1
Board(row, col) = 0
Next col
Next row
'hiển thị bàn cờ trống ban đầu
Form_Paint
End Sub
'thủ tục hiển thị bàn cờ
Private Sub Form_Paint()
Dim row As Integer, col As Integer
For row = 0 To intRowsBoard - 1
For col = 0 To intColsBoard - 1
DisplayElem row, col, Board(row, col)
Next col
Next row
End Sub
'3. Thủ tục xử lý ấn chuột trên Form
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
Dim row As Integer, col As Integer
'nếu chưa đến lượt thì chưa cho phép đi
If curState <> SID Then Exit Sub
'kiểm tra vị trí ấn chuột nằm trong bàn cờ ?
If intBaseX > x Or x > intBaseX + intColsBoard * intCellWidth Or _
intBaseY > y Or y > intBaseY + intRowsBoard * intCellHeight Then Exit Sub
'Xác định vị trí hàng, cột của ô cờ được ấn
col = (x - intBaseX) \ intCellWidth
row = (y - intBaseY) \ intCellHeight
'nếu ô cờ đã chơi rồi thì không xử lý nữa
If Board(row, col) <> 0 Then Exit Sub
'ghi nhận mã người chơi vào ô cờ
Board(row, col) = curState
'hiển thị chữ O vào ô cờ
DisplayElem row, col, curState
'gởi tọa độ x,y của ô cờ về cho Client biết
ServerSock.SendData row & "," & col
'kiểm tra người chơi trên máy server thắng chưa?
If KiemtraThang(row, col, curState) Then
WinID = curState
curState = 0
FlashDisplay (WinID)
MsgBox ("Hoan hô! Bạn đã thắng rồi.")
lblPrompt2 = "Bạn hãy chọn option Chơi lại ván khác"
Exit Sub
End If
'chuyển quyền chơi về cho Client
curState = CID
lblPrompt2 = "Bạn hãy đợi đối thủ đi..."
End Sub
'Hàm kiểm tra người chơi có mã id đã thắng chưa?
Public Function KiemtraThang(h As Integer, c As Integer, ByVal id As Integer) As Boolean
Dim count As Integer
Dim col As Integer, row As Integer
'kiểm tra các ô nằm ngang ở hàng h
count = 1
col = c + 1
While col < intColsBoard And Board(h, col) = id
count = count + 1
col = col + 1
Wend
col = c - 1
While col >= 0 And Board(h, col) = id
count = count + 1
col = col - 1
Wend
If count >= 5 Then
WinRow = h: WinCol = col + 1
WinRStep = 0: WinCStep = 1
KiemtraThang = True
Exit Function
End If
'kiểm tra các ô dọc ở cột c
count = 1
row = h + 1
While row < intRowsBoard And Board(row, c) = id
count = count + 1
row = row + 1
Wend
row = h - 1
While row >= 0 And Board(row, c) = id
count = count + 1
row = row - 1
Wend
If count >= 5 Then
WinRow = row + 1: WinCol = c
WinRStep = 1: WinCStep = 0
KiemtraThang = True
Exit Function
End If
'kiểm tra các ô xéo từ trên trái xuống dưới phải
count = 1
row = h + 1: col = c + 1
While row < intRowsBoard And col < intColsBoard And Board(row, col) = id
count = count + 1
row = row + 1: col = col + 1
Wend
row = h - 1: col = c - 1
While row >= 0 And col >= 0 And Board(row, col) = id
count = count + 1
row = row - 1: col = col - 1
Wend
If count >= 5 Then
WinRow = row + 1: WinCol = col + 1
WinRStep = 1: WinCStep = 1
KiemtraThang = True
Exit Function
End If
'kiểm tra các ô xéo từ trên phải xuống dưới trái
count = 1
row = h + 1: col = c - 1
While row < intRowsBoard And col >= 0 And Board(row, col) = id
count = count + 1
row = row + 1: col = col - 1
Wend
row = h - 1: col = c + 1
While row >= 0 And col < intColsBoard And Board(row, col) = id
count = count + 1
row = row - 1: col = col + 1
Wend
If count >= 5 Then
WinRow = row + 1: WinCol = col - 1
WinRStep = 1: WinCStep = -1
KiemtraThang = True
Exit Function
End If
'nếu chạy tới đây thì người chơi id chưa thắng
KiemtraThang = False
End Function
'Thủ tục hiển thị 5 ô cờ thắng
Public Sub FlashDisplay(ByVal id As Integer)
Dim i As Integer
For i = 0 To 4
If id = CID Then
DisplayElem WinRow + WinRStep * i, WinCol + WinCStep * i, WX_IMG
Else
DisplayElem WinRow + WinRStep * i, WinCol + WinCStep * i, WO_IMG
End If
Next i
End Sub
'Thủ tục hiển thị ô cờ có mã imgCode ở vị trí(row,col)
Private Sub DisplayElem(row As Integer, col As Integer, imgCode As Integer)
Dim x As Integer, y As Integer
Dim curPic As Object
'xác định tọa độ x,y theo đơn vị pixcel từ tọa độ row,col luận lý
x = intBaseX + col * intCellWidth
y = intBaseY + row * intCellHeight
'hiển thị ảnh bitmap ở vị trí xác định
PaintPicture ImgList.ListImages.Item(imgCode + 1).Picture, x, y, intCellWidth, intCellHeight, 0, 0, , , vbSrcCopy
End Sub
'Thủ tục xử lý option "Chơi lại ván khác"
Private Sub mnuExecPlay_Click()
'khởi động lại bàn cờ
InitBoard
'gởi reply "Restart" về cho client biết
ServerSock.SendData "Restart"
'chuyển quyền ban đầu về người chơi ở Server
curState = SID
'hiển thị thông báo cho người dùng biết
lblPrompt2 = "Chơi lại từ đầu. Bạn hãy ấn chuột vào cell cần đi"
End Sub
'Thủ tục xử lý option "Dừng chương trình"
Private Sub mnuExecQuit_Click()
'chưa hiện thực, người chơi chỉ cần click chuột vào icon X
End Sub
'2. Thủ tục xử lý sự kiện yêu cầu kết nối từ client
Private Sub ServerSock_ConnectionRequest(ByVal requestID As Long)
If ServerSock.State <> sckClosed Then ServerSock.Close
'Chấp nhận yêu cầu nối kết.
ServerSock.Accept requestID
ServerSock.SendData "Accepted"
'Hiển thị thông báo cho người dùng biết.
lblState = "Da ket noi voi Client. "
lblPrompt2 = "Bạn hãy tìm và ấn chuột vào ô cờ cần đi..."
'chuyển quyền ban đầu về người chơi ở Server
curState = SID
End Sub
'4.Thủ tục nhận thông tin về nước đi của đối thủ
Private Sub ServerSock_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
Dim buf As String
Dim pos As Integer
Dim row As Integer, col As Integer
'nhận dữ liệu từ client gởi tới
ServerSock.GetData strData
'kiểm tra xem có phải là request "Restart" ?
If strData = "Restart" Then
'khởi động lại bàn cờ
InitBoard
'chuyển quyền ban đầu về người chơi ở Server
curState = SID
'hiển thị thông báo cho người dùng biết
lblPrompt2 = "Chơi lại từ đầu. Bạn hãy ấn chuột vào cell cần đi"
Exit Sub
End If
'nếu chưa đến lượt người chơi ở client thì không xử lý
If curState <> CID Then Exit Sub
'xác định tọa độ cell do client ở về
pos = InStr(1, strData, ",", 0)
buf = Left(strData, pos - 1)
row = CInt(buf)
buf = Mid(strData, pos + 1)
col = CInt(buf)
'ghi nhận mã người chơi vào ô cờ
Board(row, col) = curState
'hiển thị chữ X vào ô cờ
DisplayElem row, col, curState
'kiểm tra người chơi trên máy client thắng chưa ?
If KiemtraThang(row, col, curState) Then
WinID = curState
curState = 0
FlashDisplay (WinID)
MsgBox ("Rất tiếc. Bạn đã thua rồi.")
lblPrompt2 = "Bạn hãy chọn option Chơi lại ván khác"
Exit Sub
End If
'chuyển quyền chơi về cho server
curState = SID
lblPrompt2 = "Bạn hãy tìm và ấn chuột vào ô cờ cần đi..."
End Sub
6. Chọn menu File.Make Project1.exe và nhập tên file khả thi cần tạo ra (CaroServer) để VB dịch mã nguồn ra file khả thi của module Server.
Qui trình xây dựng module CaroClient
1. chạy VB 6.0, tạo Propject "Standard EXE".
2. chọn menu Project.Components để hiển thị cửa sổ Components, duyệt tìm và chọn 2 mục “Microsoft Winsock Control 6.0” và “Microsoft Windows Common Control x.0” để “add” chúng vào cửa sổ ToolBox của Project.
3. Thiết kế Form cho ứng dụng CaroClient như sau:
Form Client có 3 label, 1 đối tượng ImageList, 1 đối tượng Winsock và 1 menu bar. Đặt tên cho 3 label lần lượt là lblState, lblPrompt1, lblPrompt2, tên cho ImageList là imgList, tên cho winsock là ClientSock. Để thiết kế menu bar, chọn menu Tools.Menu Editor rồi đặc tả 1 menu pop-up có tiêu đề “Thi hành lệnh…”, menu pop-up này chứa 3 option : "Kết nối với server", “Chơi lại ván khác” và “Dừng chương trình”. Đặt tên cho 3 option lần lượt là mnuExecConnect, mnuExecPlay, menuExecQuit.
4. Thiết lập dữ liệu cho đối tượng ImageList : ấn phải chuột trên đối tượng ImageList rồi chọn mục Properties để hiển thị cửa sổ thuộc tính của đối tượng này. Chọn tag General, chọn option Custom, nhập độ rộng, độ cao của các ảnh miêu tả ô cờ. Chọn tag Images rồi chọn button "Insert Picture" để thêm từng file ảnh ô cờ vào. Lưu ý các file ảnh phải được thêm vào theo thứ tự sau: (1) null.jpg, (2) O.jpg, (3) X.jpg, (4) Ob.jpg, (5) Xb.jpg để tương thích với chỉ số được dùng trong code của chương trình dưới đây.
5. chọn menu View.Code để hiển thị cửa sổ soạn code cho form rồi viết đọan code VB 6.0 sau đây:
Option Explicit
'Định nghĩa các hằng gợi nhớ được dùng
Private Const SID = 1 'mã nhận dạng người chơi ở server
Private Const CID = 2 'mã nhận dạng người chơi ở client
Private Const BLANC_IMG = 0 'mã ảnh miêu tả cell trống
Private Const O_IMG = 1 'mã ảnh miêu tả cell O
Private Const X_IMG = 2 'mã ảnh miêu tả cell X
Private Const WO_IMG = 3 'mã ảnh miêu tả cell O thắng
Private Const WX_IMG = 4 'mã ảnh miêu tả cell X thắng
'Định nghĩa các biến được dùng
Private Board() As Integer 'Ma trận tráng thái các ô
Private intRowsBoard As Integer 'số lượng hàng
Private intColsBoard As Integer 'số lượng cột
'Các biến miêu tả vị trí 5 ô thắng
Private WinRow As Integer, WinRStep As Integer
Private WinCol As Integer, WinCStep As Integer
'Các biến miêu tả tọa độ góc trên trái bàn cờ
Private intBaseX As Integer, intBaseY As Integer
'Các biến miêu tả kích thước từng ô cờ
Private intCellWidth As Integer, intCellHeight As Integer
'biến miêu tả trạng thái hoạt động
Dim curState As Integer
'biến miêu tả mã người thắng cuộc
Dim WinID As Integer
'1. thủ tục thiết lập các thông số ban đầu
Private Sub Form_Load()
Dim row As Integer, col As Integer
intRowsBoard = 20
intColsBoard = 20
intCellWidth = 15
intCellHeight = 15
intBaseX = 4
intBaseY = 70
'thiết lập lại kích thước form cho phù hợp
Me.ScaleMode = vbPixels
Me.Width = Me.ScaleX(intColsBoard * intCellWidth + intBaseX + 16, vbPixels, vbTwips)
Me.Height = Me.ScaleY(intRowsBoard * intCellHeight + intBaseY + 65, vbPixels, vbTwips)
ReDim Board(intRowsBoard - 1, intColsBoard - 1)
InitBoard
'hiển thị các thông báo cần thiết
lblState = ""
lblPrompt1 = "Quân của bạn là X, quân của đối thủ là O"
lblPrompt2 = "Bạn hãy yêu cầu kết nối tới server đi..."
End Sub
'thủ tục khởi tạo trạng thái bàn cờ
Private Sub InitBoard()
Dim row As Integer, col As Integer
'thiết lập trạng thái chưa chơi
curState = 0
For row = 0 To intRowsBoard - 1
For col = 0 To intColsBoard - 1
Board(row, col) = 0
Next col
Next row
'hiển thị bàn cờ trống ban đầu
Form_Paint
End Sub
'thủ tục hiển thị bàn cờ
Private Sub Form_Paint()
Dim row As Integer, col As Integer
For row = 0 To intRowsBoard - 1
For col = 0 To intColsBoard - 1
DisplayElem row, col, Board(row, col)
Next col
Next row
End Sub
'3. Thủ tục xử lý ấn chuột trên Form
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
Dim row As Integer, col As Integer
'nếu chưa đến lượt thì chưa cho phép đi
If curState <> CID Then Exit Sub
'kiểm tra vị trí ấn chuột nằm trong bàn cờ ?
If intBaseX > x Or x > intBaseX + intColsBoard * intCellWidth Or _
intBaseY > y Or y > intBaseY + intRowsBoard * intCellHeight Then Exit Sub
'Xác định vị trí hàng, cột của ô cờ được ấn
col = (x - intBaseX) \ intCellWidth
row = (y - intBaseY) \ intCellHeight
'nếu ô cờ đã chơi rồi thì không xử lý nữa
If Board(row, col) <> 0 Then Exit Sub
'ghi nhận mã người chơi vào ô cờ
Board(row, col) = curState
'hiển thị chữ O vào ô cờ
DisplayElem row, col, curState
'gởi tọa độ x,y của ô cờ về cho server biết
ClientSock.SendData row & "," & col
'kiểm tra người chơi trên máy client thắng chưa ?
If KiemtraThang(row, col, curState) Then
WinID = curState
curState = 0
FlashDisplay (WinID)
MsgBox ("Hoan hô! Bạn đã thắng rồi.")
lblPrompt2 = "Bạn hãy chọn option Chơi lại ván khác"
Exit Sub
End If
'chuyển quyền chơi về cho Server
curState = SID
lblPrompt2 = "Bạn hãy đợi đối thủ đi..."
End Sub
'Hàm kiểm tra người chơi có mã id đã thắng chưa?
Public Function KiemtraThang(h As Integer, c As Integer, ByVal id As Integer) As Boolean
Dim count As Integer
Dim col As Integer, row As Integer
'kiểm tra các ô nằm ngang ở hàng h
count = 1
col = c + 1
While col < intColsBoard And Board(h, col) = id
count = count + 1
col = col + 1
Wend
col = c - 1
While col >= 0 And Board(h, col) = id
count = count + 1
col = col - 1
Wend
If count >= 5 Then
WinRow = h: WinCol = col + 1
WinRStep = 0: WinCStep = 1
KiemtraThang = True
Exit Function
End If
'kiểm tra các ô dọc ở cột c
count = 1
row = h + 1
While row < intRowsBoard And Board(row, c) = id
count = count + 1
row = row + 1
Wend
row = h - 1
While row >= 0 And Board(row, c) = id
count = count + 1
row = row - 1
Wend
If count >= 5 Then
WinRow = row + 1: WinCol = c
WinRStep = 1: WinCStep = 0
KiemtraThang = True
Exit Function
End If
'kiểm tra các ô xéo từ trên trái xuống dưới phải
count = 1
row = h + 1: col = c + 1
While row < intRowsBoard And col < intColsBoard And Board(row, col) = id
count = count + 1
row = row + 1: col = col + 1
Wend
row = h - 1: col = c - 1
While row >= 0 And col >= 0 And Board(row, col) = id
count = count + 1
row = row - 1: col = col - 1
Wend
If count >= 5 Then
WinRow = row + 1: WinCol = col + 1
WinRStep = 1: WinCStep = 1
KiemtraThang = True
Exit Function
End If
'kiểm tra các ô xéo từ trên phải xuống dưới trái
count = 1
row = h + 1: col = c - 1
While row < intRowsBoard And col >= 0 And Board(row, col) = id
count = count + 1
row = row + 1: col = col - 1
Wend
row = h - 1: col = c + 1
While row >= 0 And col < intColsBoard And Board(row, col) = id
count = count + 1
row = row - 1: col = col + 1
Wend
If count >= 5 Then
WinRow = row + 1: WinCol = col - 1
WinRStep = 1: WinCStep = -1
KiemtraThang = True
Exit Function
End If
'nếu chạy tới đây thì người chơi id chưa thắng
KiemtraThang = False
End Function
'Thủ tục hiển thị 5 ô cờ thắng
Public Sub FlashDisplay(ByVal id As Integer)
Dim i As Integer
For i = 0 To 4
If id = CID Then
DisplayElem WinRow + WinRStep * i, WinCol + WinCStep * i, WX_IMG
Else
DisplayElem WinRow + WinRStep * i, WinCol + WinCStep * i, WO_IMG
End If
Next i
End Sub
'Thủ tục hiển thị ô cờ có mã imgCode ở vị trí(row,col)
Private Sub DisplayElem(row As Integer, col As Integer, imgCode As Integer)
Dim x As Integer, y As Integer
Dim curPic As Object
'xác định tọa độ x,y theo đơn vị pixcel từ tọa độ row,col luận lý
x = intBaseX + col * intCellWidth
y = intBaseY + row * intCellHeight
'hiển thị ảnh bitmap ở vị trí xác định
PaintPicture ImgList.ListImages.Item(imgCode + 1).Picture, x, y, intCellWidth, intCellHeight, 0, 0, , , vbSrcCopy
End Sub
'Thủ tục xử lý option "Chơi lại ván khác"
Private Sub mnuExecPlay_Click()
'khởi động lại bàn cờ
InitBoard
'gởi reply "Restart" về cho client biết
ClientSock.SendData "Restart"
'chuyển quyền ban đầu về người chơi ở Server
curState = SID
'hiển thị thông báo cho người dùng biết
lblState = "Đang yêu cầu server chơi lại..."
lblPrompt2 = "Hãy chờ đợi..."
End Sub
'Thủ tục xử lý option "Dừng chương trình"
Private Sub mnuExecQuit_Click()
'chưa hiện thực, người chơi chỉ cần click chuột vào icon X
End Sub
'Thủ tục xử lý option "Kết nối với server"
Private Sub mnuExecConnect_Click()
'hiển thị form Connect
frmConnect.Show vbModal
'nếu người dùng chấp nhận
If frmConnect.fOk Then
'thiết lập thông tin về server
ClientSock.RemoteHost = frmConnect.txtTCP
ClientSock.RemotePort = 1001
'yêu cầu kết nối với server
ClientSock.Connect
'Hiển thị thông báo cho người dùng biết.
lblState = "Đang yêu cầu kết nối với server..."
lblPrompt2 = "Hãy chờ đợi..."
End If
End Sub
'4.Thủ tục nhận thông tin về nước đi của đối thủ
Private Sub ClientSock_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
Dim buf As String
Dim pos As Integer
Dim row As Integer, col As Integer
'nhận dữ liệu từ client gởi tới
ClientSock.GetData strData
'kiểm tra xem có phải là request "Accepted" ?
If strData = "Accepted" Then
'chuyển quyền ban đầu về người chơi ở Server
curState = SID
'hiển thị thông báo cho người dùng biết
lblState = "Đã kết nối tới server."
lblPrompt2 = "Hãy chờ đối thủ đi trước..."
Exit Sub
End If
'kiểm tra xem có phải là request "Restart" ?
If strData = "Restart" Then
'khởi động lại bàn cờ
InitBoard
'chuyển quyền ban đầu về người chơi ở Server
curState = SID
'hiển thị thông báo cho người dùng biết
lblPrompt2 = "Chơi lại từ đầu. Hãy chờ đối thủ đi trước..."
Exit Sub
End If
'nếu chưa đến lượt người chơi ở Server thì không xử lý
If curState <> SID Then Exit Sub
'xác định tọa độ cell do Server ở về
pos = InStr(1, strData, ",", 0)
buf = Left(strData, pos - 1)
row = CInt(buf)
buf = Mid(strData, pos + 1)
col = CInt(buf)
'ghi nhận mã người chơi vào ô cờ
Board(row, col) = curState
'hiển thị chữ O vào ô cờ
DisplayElem row, col, curState
'kiểm tra người chơi trên máy server thắng chưa?
If KiemtraThang(row, col, curState) Then
WinID = curState
curState = 0
FlashDisplay (WinID)
MsgBox ("Rất tiếc. Bạn đã thua rồi.")
lblPrompt2 = "Bạn hãy chọn option Chơi lại ván khác"
Exit Sub
End If
'chuyển quyền chơi về cho server
curState = CID
lblPrompt2 = "Bạn hãy tìm và ấn chuột vào ô cờ cần đi..."
End Sub
6. Chọn menu Project.Add Form để hiển thị cửa sổ "Add Form". Chọn icon "Form" rồi ấn button OK để tạo 1 form trống mới. Thiết kế form mới như sau:
Form Kết nối có 1 label, 1 textbox, 2 button. Đặt tên cho textbox là txtTCP, tên cho button Connect là btnConnect, tên cho button Cancel là btnCancel. Đặt tên cho form mới là frmConnect. Ấn kép chuột vào button OK để tạo thủ tục xử lý sự kiện Click chuột trên button này. Khi cửa sổ soạn code của form hiển thị, viết đoạn code VB 6.0 sau đây:
Option Explicit
Public fOk As Boolean
'thủ tục xử lý button Cancel
Private Sub btnCancel_Click()
fOk = False
Me.Visible = False
Me.Hide
End Sub
'thủ tục xử lý button Connect
Private Sub btnConnect_Click()
fOk = True
Me.Visible = False
Me.Hide
End Sub
7. Chọn menu File.Make Project1.exe và nhập tên file khả thi cần tạo ra (CaroClient) để VB dịch mã nguồn ra file khả thi của module Client.
8. Sau khi đã xây dựng được 2 module client & server của ứng dụng mạng, bạn có thể cài đặt từng module vào từng máy người chơi. Ở đây, với mục đích dễ kiểm tra, bạn sẽ chạy 2 module trên cùng 1 máy, module CaroServer sẽ chạy trước, module CaroClient sẽ chạy sau. Người chơi trên CaroClient sẽ chọn option "Kết nối tới server..." để cung cấp địa chỉ máy sẽ server (localhost hay 127.0.0.1). Module CaroServer sẽ chấp nhận và yêu cầu người trên Server chơi trước rồi tới người trên Client chơi sau, cứ thế tiếp tục cho đến khi 1 trong 2 người chơi thắng hoặc khi có yêu cầu "Chơi lại ván khác" bởi 1 trong 2 người chơi.
Theo pcworld