基于VB中WINSOCK控件的网上象棋系统的实现

         本文发表在《微型机与应用》杂志2001年第3期。





     基于VBWINSOCK控件的网上象棋系统的实现

     马根峰1   ,  孙艳2  王平1

(1.重庆邮电学院自己主动化学院,重庆,4000652. 铁道部第十九project局四处。内蒙 通辽,028000 )

 

    摘要     本文首先介绍了Visual Basic中的WINSOCK控件的用法。然后深入探讨了网上象棋系统的设计思想及事实上现过程。

    关键词    WINSOCK控件。TCPUDP

    中图分类号:    文献标识码

 

 

1      引言

    MicrosoftVisual Basic 是可视化的、面向对象的、採用事件驱动方式的结构化的高级程序设计语言。它提供了开发Microsoft Windows(R)应用程序的迅速、最简捷的方法。在网上象棋系统的工作中。笔者利用VB编写了网上象棋系统,实现了网上下棋的基本功能。

 

 

2 VBWINSOCK控件简单介绍 

利用 WinSock 控件能够与远程计算机建立连接。并通过用户数据文报协议 (UDP)或者传输控制协议 (TCP)进行数据交换。

这两种协议都能够用来创建客户与server应用

    程序。

Winsock它提供了訪问 TCP  UDP 网络服务的方便途径。

Visual BasicVisual C++的开发者都可使用它。

为编写客户或server应用程序,不必了解 TCP 的细节或调用低级的Winsock APIs

通过设置控件的属性并调用其方法就可轻易连接到一台远程机器上去,而且还可双向交换数据。

2.1  TCP 基础

传输数据协议同意创建和维护与远程计算机的连接。连接两台计算机就可彼此进行传输数据。

假设创建客户应用程序,就必须知道server计算机名或者 IP 地址(RemoteHost 属性)。还要知道server进行侦听的port(RemotePort 属性)。然后调用 Connect 方法。

假设创建server应用程序。就应设置一个收听port(LocalPort 属性)并调用 Listen 方法。

当客户计算机须要连接时就会发生 ConnectionRequest 事件。

为了完毕连接。可调用 ConnectionRequest 事件内的 Accept 方法。

建立连接后,不论什么一方计算机都能够收发数据。为了发送数据。可调用 SendData 方法。当接收数据时会发生 DataArrival 事件。调用 DataArrival 事件内的 GetData 方法就可获取数据。

2.2   UDP 基础

用户数据报协议 (UDP) 是一个无连接协议。

跟 TCP 的操作不同,计算机并不建立连接。

另外 UDP 应用程序能够是客户机。也能够是server。

 

为了传输数据,首先要设置计算机ARemoteHost为计算机B的名称或IP地址,然后将计算机ARemotePort属性设置为计算机BLocalPort 属性,最后调用Bind方法然后,指定用于 UDP 连接的 LocalPort  LocalIP

经过上面的在个步骤之后,计算机AB就能够调用 SendData 方法来着手发送信息。还能够在 DataArrival 事件内的利用 GetData 方法来获取已发送的信息了。

 

 

3  网上象棋中的几个关键问题  

   3.1   怎样将象棋中的棋子和棋盘的信息用计算机来描写叙述出来 

l  象棋中棋盘

           象棋中棋盘共同拥有九列,十行,共同拥有´ 10 个点。我将显示器的最左下角看成是坐标原点,屏幕上方为Y轴的正方向。单位是1;屏幕的右方向看成是X轴的正方向,单位是1。然后用90个坐标(IJ)从(11)到(910)来表示这90个点的位置。

l  确定每一个坐标点的物理地址。

    首先给出坐标原点的物理坐标(X0Y0),然后利用公式

      X = X0+ (i1 - 1) * intColToCol

Y = Y0-(j1 - 1) * intRowToRow

         当中intColToColintRowToRow分别表示棋盘列间距、行间距。

l  棋子

双方棋子共´ 16个,我自己定义了记录类型qiZis ,它用域 index caption blnDeleted xy分别表示棋子的序号、棋子的名称、是否被吃掉、在棋盘中的逻辑坐标的X值、Y值。

外观上用命令button数组(其序号index132)来代表棋子。
 

3.2  怎样将象棋的规则怎样转换成计算机算法

    象棋中走子的规则例如以下:

“马走日、象走田、车走直路炮翻山 ”等等

      上面的这些规则怎样用计算机来描写叙述出来,怎样在计算机中来控制棋子的行走和吃子,这成了网上象棋的关键。我在实现这个系统的时候是採用下面的方案。

l  对于走子

首先取得用户点击鼠标的位置(通过窗口的MouseDown事件),然后找出90个坐标点中物理坐标最为相近的一个坐标点。记下它的逻辑坐标,然后通过函数blnCanMove(ByValIndexMoved As Integer, ByVal oldX As Integer, ByVal oldY As Integer, ByVal newXAs Integer, ByVal newY As Integer)  As Boolean 来推断序号为IndexMoved的棋子能否从逻辑坐标(oldXoldY)移动到(newXnewY)。

在这个函数中则集中了每种棋子的走子规则。它主要是通过对两个坐标值进行处理来推断棋子IndexMoved能否这样走子。

以行车为例。该函数在运行时要经过下面的推断:

每一,目标位置和起始位置是否在一条直线上,即目标位置的逻辑X

Y坐标值与起始位置的XY坐标值是否有一个相等。

第二。目标位置与起始位置之间是否无其他的棋子。仅仅有满足这两个条件,才干行车。

再举一个复杂的样例。能不能走马要经过下面的推断:

第一。目标位置与起始位置是否构成日字,目标位置与起始位置边线的斜率是否为21/2(首先还必须是否会发生除0中断),以及横纵坐标之差中是否一个为1另人个为2

          第二,推断在有可能发生别马腿的位置上是否有别的棋子。

l  对于吃子

每一。要推断两个棋子是否属于同一方;

第二,取出目标棋子的逻辑坐标,再用函数blnCanEated(ByVal

IndexMoved As Integer, ByVal oldX As Integer, ByVal oldY As Integer,ByVal intdexStable As Integer, ByVal newX As Integer, ByVal newY As Integer) AsBoolean 来推断源棋子IndexMoved 能否从逻辑坐标(oldXoldY)移动到(newXnewY)并吃掉这个位置的对方的棋子intdexStable

         这个函数同函数blnCanMove大致相似,不同之处在于炮的规则在二个函数中有区别。在走炮的时候。目标位置与起始位置之间不能有别的棋子,而在用炮吃子的时候,目标位置与起始位置中间必须有且仅仅有一个棋子。

 

3.3  怎样通知对方自己棋子的变化 

l  对于Winsock控件的协议选择。

能够用Winsock控件来实现计算机间通信的功能。其关键之处在于对于协议的选取。事实上对于网上象棋这个应用来说。事实上这两种协议都能够实现数据据传输的功能。

在这我选取了传输控制协议TCP。原因例如以下:

第一、   数据发送是间歇的,用户间在下棋的过程中不断传输和接收数据。

第二、   TCP提供的是可靠的传输服务。

第三、   UDP提供的是面向无连接的服务,我希望客户计算机提出下棋  

请求之后,得到server的确认信息。

 

l  须要传输的信息。

        在这里。通信的一方仅仅须要将它所移动的棋子的索引號、目标位置的逻辑坐标、是否删除棋子以及假设要删除棋子的话被删除的棋子的索引號这四类信息传送给通信的还有一方。

        在系统中我通过字符串strSend = CStr(intIndex) & "|" & CStr(i) &"|" & CStr(j) & "d" & "0"strSend = CStr(intIndex) &"|" & CStr(i) & "|" & CStr(j) &"d" & CStr(index) 来分别传送不删除棋子、删除棋子Index的信息,而intIndex则是源棋子。ij则是目标位置的逻辑坐标。

                            假设是删除棋子,则必须对被吃掉的棋子採取处理,可採用的方案是将棋子的blnDeleted设为TRUE、属性Visible设为FALSE

 

 3.4 怎样保证棋手依次走棋

        一名棋手在走棋之后,马上将自己的应用程序中的全部棋子锁定(使各个命令button的Enable属性为FALSE),直到对方传送到信息才解除对全部棋子的锁定。

        

 

4  系统实现简单介绍 

4.1  client的TcpForclient_DataArrival事件的处理 

TcpForClient.GetData st

'获得要移动的棋子的INDEX值和目标点的坐标(IJ

   ………

qiZi(index).x =i

qiZi(index).y =j

Dim TempPhysicalZBAs ZuoBiao

TempPhysicalZB =transZB_Logic_physical(i, j)

CmdIcon(index).MoveTempPhysicalZB.x - halfCmdWidth,

TempPhysicalZB.y - halfCmdHeight

‘推断老将是否被吃掉以及相应的操作

   ………

 

对于server端的TcpForserver_DataArrival事件的处理相似于client。

 

4.2  函数blnCanMove来推断棋子的走动是否合法 

Private FunctionblnCanMove (ByVal IndexMoved As Integer, ByVal oldX As Integer, ByVal

oldY As Integer, ByVal newX As Integer, ByVal newY As Integer) AsBoolean

………

Select CaseIndexMoved

    Case 1, 2, 3, 4, 5  '红兵

        If (oldY < 6) And (oldX = newX AndnewY = oldY + 1) Then

 '没有过河时仅仅能向前走

            blnCanMove = True

               ElseIf (oldY >= 6) And (Abs(oldX - newX)= 1 And oldY = newY) Or

(oldX = newX AndnewY - oldY = 1) Then '过河后能够左右和向前移动

            blnCanMove = True

       Else

           blnCanMove = False

       End If

    ………

 

4.3  推断是否别象眼的函数blnElphonentStoped 

Private FunctionblnElphonentStoped(ByVal x1 As Integer, ByVal y1 As Integer,

 ByVal x2 As Integer, ByVal y2As Integer) As Boolean

Dim i, xMid, yMid, iCount As Integer

xMid = (x1 + x2) / 2

yMid = (y1 + y2) / 2

iCount = 0

For i = 1 To 32

        If qiZi(i).blnDeleted = False Then

            If (qiZi(i).x = xMid) And(qiZi(i).y = yMid) Then

                       iCount = iCount + 1

                  End If

        End If

Next i

If iCount = 0 Then

    blnElphonentStoped = False

Else

    blnElphonentStoped = True

End If

End Function

 

4.4  用来移动棋子的事件处理过程Form_MouseDown 

 Form_MouseDown(Button As Integer, Shift AsInteger, x As Single, y As Single)

   For i = 1 To 9

      For j = 1 To 10

          TempPhysicalZB = transZB_Logic_physical(i, j)

          If Abs(x - TempPhysicalZB.x) <= intColToCol / 2 And

Abs(y -TempPhysicalZB.y) <= intRowToRow / 2 Then

IfblnCanMove(intIndex, qiZi(intIndex).x, qiZi(intIndex).y, i, j) = False Then

                  MsgBox "你不能这么走!", vbCritical +vbOKOnly, "         错误"

                  Exit Sub

              End If                  

               strSend = CStr(intIndex) &"|" & CStr(i) & "|" & CStr(j) &"d" & "0"

                    'Call BeforeMove(intIndex,i, j)

               qiZi(intIndex).x = i

qiZi(intIndex).y= j

CmdIcon(intIndex).Move TempPhysicalZB.x - halfCmdWidth,

TempPhysicalZB.y- halfCmdHeight

                TcpForClient.SendData strSend

                Exit Sub

            End If

       Next j

   Next i

End Sub

 


  參考文献:

  1  希望图书创作室 · 中文Visual Basic 6.0教程 · 北京 :宇航出版社。1999.5

 2   Microsoft 公司·  Microsoft  Development Network

 

 

Realizationof the system of Chinese chess in network by winsock control of VB

                   MAGen-feng   SUN Yan   Wang  Ping

           

  Abstract    Firstly this paper describes how to uses thewinsock control in Visual Basic.   

Then it deeply analyses the design priciple and completion processof this system

Key words   Winsock controlTCPUDP

 

  

原文地址:https://www.cnblogs.com/yjbjingcha/p/7017044.html