发信人: hunter__fox(雁回西楼)
整理人: hunter__fox(2002-03-16 23:07:15), 站内信件
|
这是一个五子其和小程序,代码中留下了写算法的接口,此代码目已经可完成基本功能,但存盘等功能尚未写代码,可按自己喜好写。
* 五子棋程序
* Hunter 2001-11-08
* Hunter 2001-06-11
* Hunter 2001-06-08
*
* 请自己定博弈算法,并在
* _Form的Init 中相应处调用----Line 49
* _QiPan的Go 中相应处调用----Line 157
#Define Size_QiZi_Loc 30 && 棋子大小
#Define Total_Line_Loc 15 && 棋盘线数
#Define Renju_Loc "五子棋" && 表单标题
#Define MsgTest_Loc "此处已经有棋子了。"
#Define MsgTitle_Loc "不能落子"
#Define Black_Loc "黑棋"
#Define White_Loc "白棋"
#Define Victory_Loc "胜利"
#Define ReSatrt_Loc "重新开始吗?"
Public poRenju
poRenju = CreateObject("_Form")
poRenju.Show(1)
Read Events
Close All
Release All
Clear All
* Quit
*类别列表:
* _Form-------------表单>>>>DoComputer
* _QiPan------------棋盘>>>>Go(),ReBew(),SaveLog(),LoadLog(),GoLog,QiZiCount[225]
* _Container--------容器基类>>>>无边框,透明,高宽为棋子大小
* _B------------黑棋子
* _W------------白棋子
* _Hover--------光标标志>>>>随鼠标移动,>>>>Top_Assign(),Left_Assign(),X,Y
* _Line-------------线条基类>>>>鼠标事件由容器处理
* _LineX--------盘中竖线>>>>宽度为零
* _LineY--------盘中横线>>>>高度为零
* _LineHover----光标线>>>>蓝色
*==========表单定义
Define Class _Form As Form
AutoCenter = .T.
BorderStyle = 2
Caption = Renju_Loc
Desktop = .T.
MaxButton = .F.
ShowWindow = 2
WindowType = 1
DoComputer = "" && 电脑是否下棋----为空不下棋,"W"表示下白棋,"B"表示下黑棋
Add Object oQiPan As _QiPan With Top = 2,Left = 2 && 棋盘
Procedure Init
DoDefault()
* 表单比棋盘略大一些
This.Height = This.oQiPan.Height + 4
This.Width = This.oQiPan.Width + 4
If This.DoComputer = "B"
&& 请在此调用自己的博弈算法
EndIf
EndProc
Procedure Destroy
&& 在此退出
Clear Events
EndProc
Procedure KeyPress
LParameters nKeyCode,nShift
If IsNull(ThisForm.DoComputer)
Do Case && 用键盘控制鼠标的移动,只要调用热点的相应方法即可.
Case nKeyCode = 5 && 向上
This.oQiPan.Hover.MoveUp
Case nKeyCode = 24 && 向下
This.oQiPan.Hover.MoveDown
Case nKeyCode = 19 && 向左
This.oQiPan.Hover.MoveLeft
Case nKeyCode = 4 && 向右
This.oQiPan.Hover.MoveRight
Case nKeyCode = 13 Or nKeyCode = 32 && 空格及回车是落子.
This.oQiPan.Hover.Click
Case nKeyCode = 27 && ESC 退出
ThisForm.Destroy
OtherWise
DoDefault()
EndCase
EndIf
EndProc
EndDefine
*==========棋盘定义
Define Class _QiPan As Container
Start = .T.
BackColor = RGB(255,128,0)
BorderWidth = 2
BorderColor = RGB(0,0,255)
Height = Size_QiZi_Loc * Total_Line_Loc + 4
Width = Size_QiZi_Loc * Total_Line_Loc + 4
GoLog = "" && 落子记录,每一步用一字节记录,前四位记X值,
&& 后四后记Y值,最长有225字节.通过它的长度可知该谁走棋
&& 以下是棋盘中的线条
Add Object Protected Line01 As _LineX With Left = Size_QiZi_Loc * 0.5 + 2
Add Object Protected Line02 As _LineX With Left = Size_QiZi_Loc * 1.5 + 2
Add Object Protected Line03 As _LineX With Left = Size_QiZi_Loc * 2.5 + 2
Add Object Protected Line04 As _LineX With Left = Size_QiZi_Loc * 3.5 + 2
Add Object Protected Line05 As _LineX With Left = Size_QiZi_Loc * 4.5 + 2
Add Object Protected Line06 As _LineX With Left = Size_QiZi_Loc * 5.5 + 2
Add Object Protected Line07 As _LineX With Left = Size_QiZi_Loc * 6.5 + 2
Add Object Protected Line08 As _LineX With Left = Size_QiZi_Loc * 7.5 + 2
Add Object Protected Line09 As _LineX With Left = Size_QiZi_Loc * 8.5 + 2
Add Object Protected Line10 As _LineX With Left = Size_QiZi_Loc * 9.5 + 2
Add Object Protected Line11 As _LineX With Left = Size_QiZi_Loc * 10.5 + 2
Add Object Protected Line12 As _LineX With Left = Size_QiZi_Loc * 11.5 + 2
Add Object Protected Line13 As _LineX With Left = Size_QiZi_Loc * 12.5 + 2
Add Object Protected Line14 As _LineX With Left = Size_QiZi_Loc * 13.5 + 2
Add Object Protected Line15 As _LineX With Left = Size_QiZi_Loc * 14.5 + 2
Add Object Protected Line16 As _LineY With Top = Size_QiZi_Loc * 0.5 + 2
Add Object Protected Line17 As _LineY With Top = Size_QiZi_Loc * 1.5 + 2
Add Object Protected Line18 As _LineY With Top = Size_QiZi_Loc * 2.5 + 2
Add Object Protected Line19 As _LineY With Top = Size_QiZi_Loc * 3.5 + 2
Add Object Protected Line20 As _LineY With Top = Size_QiZi_Loc * 4.5 + 2
Add Object Protected Line21 As _LineY With Top = Size_QiZi_Loc * 5.5 + 2
Add Object Protected Line22 As _LineY With Top = Size_QiZi_Loc * 6.5 + 2
Add Object Protected Line23 As _LineY With Top = Size_QiZi_Loc * 7.5 + 2
Add Object Protected Line24 As _LineY With Top = Size_QiZi_Loc * 8.5 + 2
Add Object Protected Line25 As _LineY With Top = Size_QiZi_Loc * 9.5 + 2
Add Object Protected Line26 As _LineY With Top = Size_QiZi_Loc * 10.5 + 2
Add Object Protected Line27 As _LineY With Top = Size_QiZi_Loc * 11.5 + 2
Add Object Protected Line28 As _LineY With Top = Size_QiZi_Loc * 12.5 + 2
Add Object Protected Line29 As _LineY With Top = Size_QiZi_Loc * 13.5 + 2
Add Object Protected Line30 As _LineY With Top = Size_QiZi_Loc * 14.5 + 2
&& 以下是棋盘中的五个点
Add Object Protected Line31 As _Line With BorderWidth = 8,Height = 0,Width = 0,;
Top = Size_QiZi_Loc * 3.5 + 2,left = Size_QiZi_Loc * 3.5 + 2
Add Object Protected Line32 As _Line With BorderWidth = 8,Height = 0,Width = 0,;
Top = Size_QiZi_Loc * 3.5 + 2,left = Size_QiZi_Loc * 11.5 + 2
Add Object Protected Line33 As _Line With BorderWidth = 8,Height = 0,Width = 0,;
Top = Size_QiZi_Loc * 7.5 + 2,left = Size_QiZi_Loc * 7.5 + 2
Add Object Protected Line34 As _Line With BorderWidth = 8,Height = 0,Width = 0,;
Top = Size_QiZi_Loc * 11.5 + 2,left = Size_QiZi_Loc * 3.5 + 2
Add Object Protected Line35 As _Line With BorderWidth = 8,Height = 0,Width = 0,;
Top = Size_QiZi_Loc * 11.5 + 2,left = Size_QiZi_Loc * 11.5 + 2
&& 以下是棋盘中用于标识光标的热点对象
Add Object Hover As _Hover
Procedure Init
This.AddProperty("QiZiCount[255]",.Null.) && 此属性用于保存棋盘中所下的棋子,因为动态添加的棋
&& 子在清盘时要清掉,所以用此属性保存对它们的引用.
DoDefault()
EndProc
Procedure MouseMove
LParameters nButton,nShift,nXCoord,nYCoord
&& 鼠标移动时同步移动热点
This.Hover.Left = Int((nXCoord-2) / Size_QiZi_Loc) * Size_QiZi_Loc + 2
This.Hover.Top = Int((nYCoord-2) / Size_QiZi_Loc) * Size_QiZi_Loc + 2
EndProc
Procedure MouseUp
LParameters nButton,nShift,nXCoord,nYCoord
EndProc
Procedure Go &&落子
&& 落子方法的参数说明:
&& nTop 落子与棋盘上方的距离
&& nLeft 落子与棋盘左边的距离
&& nX 从左向右第几列(1---15)
&& nY 从上向下第几行(1---15)
LParameters nTop,nLeft,nX,nY
If This.Start = .F. && 这一局已经结束
If MessageBox(ReSatrt_Loc,4,Renju_Loc) = 6
This.ReNew()
EndIf
Return
EndIf
If At(Chr(nX * 16 + nY),This.GoLog) > 0 && 有棋子的地方不能落子
MessageBox(MsgTest_Loc,0,Renju_Loc)
Return
EndIf
Local lnQiZiID
lnQiZiID = Len(This.GoLog)+1 && GoLog 中保存的是行棋的记录
&& 先画一个棋子
This.AddObject("o_"+Alltrim(Str(lnQiZiID)),;
Iif(Mod(Len(This.GoLog),2) = 0,"_B","_W"))
This.QiZiCount[lnQiZiID] = ;
Evaluate("This.o_" + Alltrim(Str(lnQiZiID)))
This.QiZiCount[lnQiZiID].Top = nTop
This.QiZiCount[lnQiZiID].Left = nLeft
This.QiZiCount[lnQiZiID].Visible = .T.
&& 更新行棋记录
This.GoLog = This.GoLog + Chr(nX * 16 + nY)
If IsVictory(This.GoLog)
MessageBox(Iif(Mod(Len(This.GoLog),2) = 1,Black_Loc,White_Loc) + Victory_Loc,0,Renju_Loc)
This.Start = .F.
Else
&& /////////////////////////////////////////////////////////////
&& 若该电脑走,则调用博弈算法
&& 请在此调用自已的博弈算法,并再调用此程序段下棋.
&& /////////////////////////////////////////////////////////////
EndIf
EndProc
Procedure ReNew && 清盘
Local lnQiZiID
lnQiZiID = 1
Do While Not(IsNull(This.QiZiCount[lnQiZiID]))
This.RemoveObject(This.QiZiCount[lnQiZiID].Name)
This.QiZiCount[lnQiZiID] = .Null.
lnQiZiID = lnQiZiID + 1
EndDo
This.GoLog = ""
This.Start = .T.
EndProc
Procedure SaveLog && 棋局存盘
EndProc
Procedure LoadLog && 读存盘文件
EndProc
EndDefine
*==========竖线定义
Define Class _LineX As _Line
Height = Size_QiZi_Loc * (Total_Line_Loc - 1)+1
Width = 0
Top = Size_QiZi_Loc * 0.5+2
EndDefine
*==========横线定义
Define Class _LineY As _Line
Width = Size_QiZi_Loc * (Total_Line_Loc - 1)+1
Height = 0
Left = Size_QiZi_Loc * 0.5+2
EndDefine
*==========黑棋子定义
Define Class _B As _ConTainer
Add Object Protected Shape1 As Shape With ;
Curvature=99,FillStyle=0,Top = 1,Left = 1,;
Height = Size_QiZi_Loc - 2,Width = Size_QiZi_Loc - 2
EndDefine
*==========白棋子定义
Define Class _W As _ConTainer
Add Object Protected Shape1 As Shape With ;
Curvature=99,FillStyle=0,Top = 1,Left = 1,;
Height = Size_QiZi_Loc - 2,Width = Size_QiZi_Loc - 2,;
BorderColor=RGB(192,192,192),FillColor=RGB(255,255,255)
EndDefine
*==========热点定义
Define Class _Hover As _Container
X = 0
Y = 0
Add Object Protected Line1 As _LineHover With Width = 0,Height = Size_QiZi_Loc / 4,;
Left = 0,Top = 0
Add Object Protected Line2 As _LineHover With Height = 0,Width = Size_QiZi_Loc / 4,;
Top = 0,Left = 0
Add Object Protected Line3 As _LineHover With Width = 0,Height = Size_QiZi_Loc / 4,;
Left = 0,Top = Size_QiZi_Loc / 4 * 3 + 1
Add Object Protected Line4 As _LineHover With Height = 0,Width = Size_QiZi_Loc / 4,;
Top = 0,Left = Size_QiZi_Loc / 4 * 3 + 1
Add Object Protected Line5 As _LineHover With Width = 0,Height = Size_QiZi_Loc / 4,;
Left = Size_QiZi_Loc - 1,Top = 0
Add Object Protected Line6 As _LineHover With Height = 0,Width = Size_QiZi_Loc / 4,;
Top = Size_QiZi_Loc - 1,Left = 0
Add Object Protected Line7 As _LineHover With Width = 0,Height = Size_QiZi_Loc / 4,;
Left = Size_QiZi_Loc - 1,Top = Size_QiZi_Loc / 4 * 3 + 1
Add Object Protected Line8 As _LineHover With Height = 0,Width = Size_QiZi_Loc / 4,;
Top = Size_QiZi_Loc - 1,Left = Size_QiZi_Loc / 4 * 3 + 1
Procedure Click
This.Parent.Go(This.Top,This.Left,This.X,This.Y) && 落子----由棋盘完成
EndProc
Procedure Left_Assign
LParameters vNewVal
This.Left = vNewVal
This.X = Int((This.Left - 2) / Size_QiZi_Loc) + 1
EndProc
Procedure Top_Assign
LParameters vNewVal
This.Top = vNewVal
This.Y = Int((This.Top - 2) / Size_QiZi_Loc) + 1
EndProc
&& 定义下面的四个方法是为了支持键盘操作
Procedure MoveUp && 上移
If This.Y > 1
This.Top = This.Top - Size_QiZi_Loc
EndIf
EndProc
Procedure MoveDown && 下移
If This.Y < Total_Line_Loc
This.Top = This.Top + Size_QiZi_Loc
EndIf
EndProc
Procedure MoveLeft && 左移
If This.X > 1
This.Left = This.Left - Size_QiZi_Loc
EndIf
EndProc
Procedure MoveRight && 右移
If This.X < Total_Line_Loc
This.Left = This.Left + Size_QiZi_Loc
EndIf
EndProc
EndDefine
*==========热点标识线条
Define Class _LineHover As _Line
BorderColor = RGB(0,0,255)
EndDefine
*==========容器基类
Define Class _Container As Container
BackStyle = 0
BorderWidth = 0
Height = Size_QiZi_Loc
Width = Size_QiZi_Loc
EndDefine
*==========线条基类
Define Class _Line As Line
Procedure MouseMove && 不处理事件,全部传到容器中进行处理,但要重算坐标
LParameters nButton,nShift,nXCoord,nYCoord
This.Parent.MouseMove(nButton,nShift,nXCoord,nYCoord)
EndProc
Procedure MouseDown
LParameters nButton,nShift,nXCoord,nYCoord
This.Parent.MouseDown(nButton,nShift,nXCoord,nYCoord)
EndProc
Procedure MouseUp
LParameters nButton,nShift,nXCoord,nYCoord
This.Parent.MouseUp(nButton,nShift,nXCoord,nYCoord)
EndProc
Procedure Click
This.Parent.Click
EndProc
Procedure DblClick
This.Parent.DblClick
EndProc
EndDefine
*====================================================================================
Function IsVictory(GoLog) && 判断最后落子者是否构成五连
Local laGo[Total_Line_Loc,Total_Line_Loc] && 这是一张棋盘
Local n,lcEveryOne,lnX,lnY
&& 生成棋盘
For n = Len(GoLog) To 1 Step -2 && 这张棋盘只需记录一种棋子即可
lcEveryOne = Subst(GoLog,n,1)
lnX = Int(Asc(lcEveryOne) / 16)
lnY = Mod(Asc(lcEveryOne),16)
laGo[lnX,lnY] = .T.
EndFor
Release n,lcEveryOne
lnX = Int(Asc(Right(GoLog,1)) / 16) && 最后落点 ,值为 1 ~ Total_Line_Loc
lnY = Mod(Asc(Right(GoLog,1)),16)
Local X,Y,Z && 是否在四个方向之一构成五连----构成五连则胜出
For X = Max(lnX - 4,1) To Min(lnX,Total_Line_Loc - 4) && Y 轴不变
If laGo[X,lnY] And ;
laGo[X + 1,lnY] And ;
laGo[X + 2,lnY] And ;
laGo[X + 3,lnY] And ;
laGo[X + 4,lnY]
Return .T.
EndIf
EndFor
For Y = Max(lnY - 4,1) To Min(lnY,Total_Line_Loc - 4) && X 轴不变
If laGo[lnX,Y] And ;
laGo[lnX,Y + 1] And ;
laGo[lnX,Y + 2] And ;
laGo[lnX,Y + 3] And ;
laGo[lnX,Y + 4]
Return .T.
EndIf
EndFor
For Z = 4 + Max(lnX,lnY) - Total_Line_Loc To Min(lnX - 1,lnY - 1,4) && XY 轴同步改变
If laGo[lnX - Z,lnY - Z] And ;
laGo[lnX - Z + 1,lnY - Z + 1] And ;
laGo[lnX - Z + 2,lnY - Z + 2] And ;
laGo[lnX - Z + 3,lnY - Z + 3] And ;
laGo[lnX - Z + 4,lnY - Z + 4]
Return .T.
EndIf
EndFor
For Z = Max(0,lnX + 4 - Total_Line_Loc,4 - lnY) ;
To Min(4,lnX - 1,Total_Line_Loc - lnY) && X 轴增加 Y 轴减少
If laGo[lnX - Z,lnY + Z] And ;
laGo[lnX - Z + 1,lnY + Z - 1] And ;
laGo[lnX - Z + 2,lnY + Z - 2] And ;
laGo[lnX - Z + 3,lnY + Z - 3] And ;
laGo[lnX - Z + 4,lnY + Z - 4]
Return .T.
EndIf
EndFor
Return .F.
EndFunc
---- 在代码天地里
我要做一个
猎狐者 |
|