窗體代碼:
Dim ChessBoard(-2 To 10, -2 To 10) As Byte ''棋盤(8豎*8棋)
Dim x(10) As Integer, y(10) As Integer ''搜索的每種走法
Dim x1(10) As Integer, y1(10) As Integer ''搜索的每種走法的可吃子坐標
Dim BestLocate As CHESSER
Dim CurrentPlayer As Byte ''當前玩家
Dim CurrentStep As Integer ''當前步
Dim 人機模式 As Boolean
Dim cSel As Byte ''玩家選擇了哪個棋子
Dim tTemp As Boolean
Const MAXDOWNPOINT = 7
Rem 如果Cer為1(黑方),則返回2(紅方),否則返加1(黑方)
Public Function NextCer(ByVal Cer As Byte) As Byte
NextCer = 1
If Cer = 1 Then NextCer = 2
End Function
Rem 棋盤
Private Sub Initial()
Dim i As Integer, j As Integer
For i = 1 To 8: For j = 1 To 8: ChessBoard(i, j) = 0: Next j: Next i
ChessBoard(1, 2) = 201
ChessBoard(1, 4) = 201
ChessBoard(1, 6) = 201
ChessBoard(1, 8) = 201
ChessBoard(2, 1) = 201
ChessBoard(2, 3) = 201
ChessBoard(2, 5) = 201
ChessBoard(2, 7) = 201
ChessBoard(3, 2) = 201
ChessBoard(3, 4) = 201
ChessBoard(3, 6) = 201
ChessBoard(3, 8) = 201
ChessBoard(6, 1) = 101
ChessBoard(6, 3) = 101
ChessBoard(6, 5) = 101
ChessBoard(6, 7) = 101
ChessBoard(7, 2) = 101
ChessBoard(7, 4) = 101
ChessBoard(7, 6) = 101
ChessBoard(7, 8) = 101
ChessBoard(8, 1) = 101
ChessBoard(8, 3) = 101
ChessBoard(8, 5) = 101
ChessBoard(8, 7) = 101
End Sub
Rem 反顯示(將屏幕顯示的內容存入ChessBoard數組)
Private Sub ReDisplay()
Dim i As Integer, j As Integer, k As Integer
k = 0
For i = 1 To 8
For j = 1 To 8
If cbText(k).Text = "" Then ChessBoard(i, j) = 0
If cbText(k).Text = "101" Then ChessBoard(i, j) = 101
If cbText(k).Text = "201" Then ChessBoard(i, j) = 201
If cbText(k).Text = "102" Then ChessBoard(i, j) = 102
If cbText(k).Text = "202" Then ChessBoard(i, j) = 202
k = k + 1
Next j
Next i
End Sub
Rem 顯示(將ChessBoard數組的內容顯示到屏幕後)
Private Sub Display()
Dim i As Integer, j As Integer, k As Integer
k = 0
For i = 1 To 8
For j = 1 To 8
If ChessBoard(i, j) = 0 Then
cbText(k).Text = ""
Else
cbText(k).Text = ChessBoard(i, j)
End If
k = k + 1
Next j
Next i
Call 勝負判斷
End Sub
Rem 勝負判斷
Private Sub 勝負判斷()
Dim i As Integer, j As Integer
Dim a As Integer, b As Integer
a = 0: b = 0
For i = 1 To 8
For j = 1 To 8
If Int(ChessBoard(i, j) / 100) = 1 Then a = a + 1 ''計算玩家的棋子數
If Int(ChessBoard(i, j) / 100) = 2 Then b = b + 1 ''計算電腦的棋子數
Next j
Next i
If a = 0 Then Call MsgBox("我贏了!", vbOKOnly + 32, "提示:"): Exit Sub
If b = 0 Then Call MsgBox("我認輸了!", vbOKOnly + 32, "提示:"): Exit Sub
End Sub
Rem 返回估值
Private Function CurrentValue(Cer As Byte) As Integer
Dim i As Integer, j As Integer
CurrentValue = 0
For i = 1 To 8
For j = 1 To 8
If Int(ChessBoard(i, j) / 100) = Cer Then _
CurrentValue = CurrentValue + ChessBoard(i, j) Mod 100 * 100 + 100 ''是我方的棋子,棋子為1加100分,棋子為2加200分
If Int(ChessBoard(i, j) / 100) = NextCer(Cer) Then _
CurrentValue = CurrentValue - (ChessBoard(i, j) Mod 100 * 100 + 100) ''對方的棋子,棋子為1減100分,棋子為2減200分
Next j
Next i
End Function
Rem 如果Cer方i,j的棋子還可以吃子則返回True
Private Function IsLine(Cer As Byte, i As Byte, j As Byte) As Boolean
Dim x As Byte, y As Byte, x1 As Byte, y1 As Byte
IsLine = False
''開始搜索棋盤
''如果是Cer方的棋子
If Int(ChessBoard(i, j) / 100) = Cer Then
''吃子式走法1:即如果基本走法的位置有對方的棋子則可以跳吃(走法限制:Cer為1或棋子為加強棋才可走)
If Int(ChessBoard(i - 1, j - 1) / 100) = NextCer(Cer) And (Cer = 1 Or ChessBoard(i, j) Mod 100 = 2) Then
x = (i - 1) - 1 ''目標坐標
y = (j - 1) - 1
x1 = i - 1 ''吃子坐標
y1 = j - 1
If x > 0 And y > 0 And x < 9 And y < 9 And ChessBoard(x, y) = 0 Then IsLine = True '有可吃子,返回True
End If
''吃子式走法2
If Int(ChessBoard(i - 1, j + 1) / 100) = NextCer(Cer) And (Cer = 1 Or ChessBoard(i, j) Mod 100 = 2) Then
x = (i - 1) - 1
y = (j + 1) + 1
x1 = i - 1
y1 = j + 1
If x > 0 And y > 0 And x < 9 And y < 9 And ChessBoard(x, y) = 0 Then IsLine = True '有可吃子,返回True
End If
''吃子式走法3
If Int(ChessBoard(i + 1, j - 1) / 100) = NextCer(Cer) And (Cer = 2 Or ChessBoard(i, j) Mod 100 = 2) Then
x = (i + 1) + 1
y = (j - 1) - 1
x1 = i + 1
y1 = j - 1
If x > 0 And y > 0 And x < 9 And y < 9 And ChessBoard(x, y) = 0 Then IsLine = True '有可吃子,返回True
End If
''吃子式走法4
If Int(ChessBoard(i + 1, j + 1) / 100) = NextCer(Cer) And (Cer = 2 Or ChessBoard(i, j) Mod 100 = 2) Then
x = (i + 1) + 1
y = (j + 1) + 1
x1 = i + 1
y1 = j + 1
If x > 0 And y > 0 And x < 9 And y < 9 And ChessBoard(x, y) = 0 Then IsLine = True '有可吃子,返回True
End If
End If
End Function
Rem 如果Cer方的棋子還可以吃子則返回True
Private Function IsLine2(Cer As Byte) As Boolean
Dim x As Byte, y As Byte, x1 As Byte, y1 As Byte
Dim i As Integer, j As Integer
IsLine2 = False
''開始搜索棋盤
For i = 1 To 8
For j = 1 To 8
''如果是Cer方的棋子
If Int(ChessBoard(i, j) / 100) = Cer Then
''吃子式走法1:即如果基本走法的位置有對方的棋子則可以跳吃(走法限制:Cer為1或棋子為加強棋才可走)
If Int(ChessBoard(i - 1, j - 1) / 100) = NextCer(Cer) And (Cer = 1 Or ChessBoard(i, j) Mod 100 = 2) Then
x = (i - 1) - 1 ''目標坐標
y = (j - 1) - 1
x1 = i - 1 ''吃子坐標
y1 = j - 1
If x > 0 And y > 0 And x < 9 And y < 9 And ChessBoard(x, y) = 0 Then IsLine2 = True '有可吃子,返回True
End If
''吃子式走法2
If Int(ChessBoard(i - 1, j + 1) / 100) = NextCer(Cer) And (Cer = 1 Or ChessBoard(i, j) Mod 100 = 2) Then
x = (i - 1) - 1
y = (j + 1) + 1
x1 = i - 1
y1 = j + 1
If x > 0 And y > 0 And x < 9 And y < 9 And ChessBoard(x, y) = 0 Then IsLine2 = True '有可吃子,返回True
End If
''吃子式走法3
If Int(ChessBoard(i + 1, j - 1) / 100) = NextCer(Cer) And (Cer = 2 Or ChessBoard(i, j) Mod 100 = 2) Then
x = (i + 1) + 1
y = (j - 1) - 1
x1 = i + 1
y1 = j - 1
If x > 0 And y > 0 And x < 9 And y < 9 And ChessBoard(x, y) = 0 Then IsLine2 = True '有可吃子,返回True
End If
''吃子式走法4
If Int(ChessBoard(i + 1, j + 1) / 100) = NextCer(Cer) And (Cer = 2 Or ChessBoard(i, j) Mod 100 = 2) Then
x = (i + 1) + 1
y = (j + 1) + 1
x1 = i + 1
y1 = j + 1
If x > 0 And y > 0 And x < 9 And y < 9 And ChessBoard(x, y) = 0 Then IsLine2 = True '有可吃子,返回True
End If
End If
Next j
Next i
End Function
Rem 搜索程序
Private Function Search(Cer As Byte, Steps As Integer, IsTop As Boolean, UpMax As Integer)
Dim a As Integer, b As Integer, b1 As Integer, b2 As Integer, i As Integer, j As Integer, k As Integer, l As Integer, v As Integer
Dim MaxValue As Integer
Dim Sc(40) As CHESSER
Dim IsEat(7) As Boolean ''搜索到的7種走法有沒有吃子
Dim EAT As Boolean ''有沒有吃子
If IsTop Then
List1.Clear
For i = 0 To 40: Sc(i).Allow = False: Next i ';默認情況下所有走法皆不允許,如果所有值均為False則皆允許
End If
EAT = False
For i = 0 To 7: IsEat(7) = False: Next i ''默認情況所有搜索到的走法都沒有吃子
Steps = Steps - 1
If Steps < 1 And IsLine2(Cer) = False Then
''如果我方無子可吃時才返回估值
Search = -CurrentValue(Cer) ''返回估值
Exit Function
End If
k = 0
''開始搜索棋盤
For i = 1 To 8
For j = 1 To 8
''如果是Cer方的棋子
If Int(ChessBoard(i, j) / 100) = Cer Then
For i1 = 1 To MAXDOWNPOINT: x(i1) = 0: x1(i1) = 0: Next ''x記載所有走法,清空x
''列出所有走法
''基本走法:上左、上右、下左、下右
x(0) = i - 1: y(0) = j - 1
x(1) = i - 1: y(1) = j + 1
x(2) = i + 1: y(2) = j - 1
x(3) = i + 1: y(3) = j + 1
''棋子表示方法:白棋 101(普通)、102 (過底的威力棋)
'' 紅棋 201(普通)、202 (過底的威力棋)
''下壹句解釋:如果是白棋(101、102),不允許後退(刪除x(2)、x(3))
If Cer = 1 And ChessBoard(i, j) Mod 100 <> 2 Then x(2) = -2: x(3) = -2
''下壹句解釋:如果是紅棋(201、202),不允許後退(刪除x(0)、x(1))
If Cer = 2 And ChessBoard(i, j) Mod 100 <> 2 Then x(0) = -2: x(1) = -2
''吃子式走法1:即如果基本走法的位置有對方的棋子則可以跳吃(走法限制:Cer為1或棋子為加強棋才可走)
If Int(ChessBoard(i - 1, j - 1) / 100) = NextCer(Cer) And (Cer = 1 Or ChessBoard(i, j) Mod 100 = 2) Then
x(4) = (i - 1) - 1 ''目標坐標
y(4) = (j - 1) - 1
x1(4) = i - 1 ''吃子坐標
y1(4) = j - 1
If x(4) > 0 And y(4) > 0 And x(4) < 9 And y(4) < 9 And ChessBoard(x(4), y(4)) = 0 Then _
EAT = True: IsEat(4) = True ''有可吃子,必需走此步,其余走法無效
End If
''吃子式走法2
If Int(ChessBoard(i - 1, j + 1) / 100) = NextCer(Cer) And (Cer = 1 Or ChessBoard(i, j) Mod 100 = 2) Then
x(5) = (i - 1) - 1
y(5) = (j + 1) + 1
x1(5) = i - 1
y1(5) = j + 1
If x(5) > 0 And y(5) > 0 And x(5) < 9 And y(5) < 9 And ChessBoard(x(5), y(5)) = 0 Then _
EAT = True: IsEat(5) = True ''有可吃子,必需走此步,其余走法無效
End If
''吃子式走法3
If Int(ChessBoard(i + 1, j - 1) / 100) = NextCer(Cer) And (Cer = 2 Or ChessBoard(i, j) Mod 100 = 2) Then
x(6) = (i + 1) + 1
y(6) = (j - 1) - 1
x1(6) = i + 1
y1(6) = j - 1
If x(6) > 0 And y(6) > 0 And x(6) < 9 And y(6) < 9 And ChessBoard(x(6), y(6)) = 0 Then _
EAT = True: IsEat(6) = True ''有可吃子,必需走此步,其余走法無效
End If
''吃子式走法4
If Int(ChessBoard(i + 1, j + 1) / 100) = NextCer(Cer) And (Cer = 2 Or ChessBoard(i, j) Mod 100 = 2) Then
x(7) = (i + 1) + 1
y(7) = (j + 1) + 1
x1(7) = i + 1
y1(7) = j + 1
If x(7) > 0 And y(7) > 0 And x(7) < 9 And y(7) < 9 And ChessBoard(x(7), y(7)) = 0 Then _
EAT = True: IsEat(7) = True ''有可吃子,必需走此步,其余走法無效
End If
''如果有吃子走法,刪除沒有吃子的其它走法
If EAT = True Then
For a = 0 To 7
If IsEat(a) = False Then x(a) = -1
Next a
End If
''存入Sc(走法表)中
For a = 0 To 7
'If x(a) = 5 And y(a) = 2 Then Stop
''如果超過棋盤將不能走
If x(a) > 0 And y(a) > 0 And x(a) < 9 And y(a) < 9 Then
''如果目標有棋子則不能走,為0才存入
If ChessBoard(x(a), y(a)) = 0 Then
''將走法存入“走法表”
Sc(k).Initx = i
Sc(k).Inity = j
Sc(k).ObjX = x(a)
Sc(k).ObjY = y(a)
Sc(k).x1 = x1(a) ''被吃子位置
Sc(k).y1 = y1(a)
If IsEat(a) = True Then Sc(k).Allow = True ''如果有吃子,則允許此著走法
k = k + 1
End If
End If
Next a
'If EAT = True Then i = 100: j = 100 ''如果有吃子則不必再搜索
End If
Next j
Next i
MaxValue = -30000 ''當前分數
tTemp = False
''搜索是否有允許走法,如果沒有則所有走法皆允許
For i = 0 To k - 1
If Sc(i).Allow = True Then tTemp = True
Next i
''如果有允許走法,則除允許走法外,其余走法皆不允許走
If tTemp = False Then
For i = 0 To k - 1: Sc(i).Allow = True: Next i
End If
''試走每種走法
For i = 0 To k - 1
If Sc(i).Allow = True Then
b1 = ChessBoard(Sc(i).Initx, Sc(i).Inity) ''記錄起點棋子和終點棋子
b2 = ChessBoard(Sc(i).ObjX, Sc(i).ObjY)
b = ChessBoard(Sc(i).x1, Sc(i).y1) ''記錄被吃子位置的棋子
ChessBoard(Sc(i).Initx, Sc(i).Inity) = 0 ''清除起點的棋子
ChessBoard(Sc(i).ObjX, Sc(i).ObjY) = b1 ''試下棋
ChessBoard(Sc(i).x1, Sc(i).y1) = 0 ''清除被吃子位置的棋子
''如果到邊界則威力加強
''下句:如果是黑方(101、102)
If Cer = 1 Then
''下句:如果走到第壹行則棋子變成102,威力加強
If Sc(i).ObjX = 1 Then ChessBoard(Sc(i).ObjX, Sc(i).ObjY) = 102
End If
''下句:如果是紅方(201、202)
If Cer = 2 Then
''下句:如果走到第八行則棋子變成202,威力加強
If Sc(i).ObjX = 8 Then ChessBoard(Sc(i).ObjX, Sc(i).ObjY) = 202
End If
If b > 0 And IsLine(Cer, Sc(i).ObjX, Sc(i).ObjY) = True And EAT = True Then
''如果可連續吃子
v = CurrentValue(Cer) + 300 ''V為當前局面價值加300分
Else
v = Search(NextCer(Cer), Steps - 1, False, -UpMax) ''沒有連續可吃子,繼續搜索
End If
''恢復棋盤
ChessBoard(Sc(i).x1, Sc(i).y1) = b ''恢復被吃子
ChessBoard(Sc(i).Initx, Sc(i).Inity) = b1 ''記錄起點棋子和終點棋子
ChessBoard(Sc(i).ObjX, Sc(i).ObjY) = b2
'' 顯示每種走法的得分
If IsTop Then
List1.AddItem "從" & Str(Sc(i).Initx) & "," & Str(Sc(i).Inity) & _
"到" & Str(Sc(i).ObjX) & "," & Str(Sc(i).ObjY) & "得分:" & Str(v)
End If
'如果這種走法分數高,記錄
If IsTop And (v > MaxValue Or MaxValue = -30000) Then
BestLocate.Initx = Sc(i).Initx
BestLocate.Inity = Sc(i).Inity
BestLocate.ObjX = Sc(i).ObjX
BestLocate.ObjY = Sc(i).ObjY
BestLocate.x1 = Sc(i).x1
BestLocate.y1 = Sc(i).y1
MaxValue = v
End If
If v > MaxValue Then MaxValue = v
'下句: 如果 MaxValue >= -UpMax //α-β剪枝, 符合剪枝條件的就Cut掉。UpMax為上層的MaxValue
If IsTop = False And MaxValue >= -UpMax Then i = 100 ''剪枝程序
End If
Next i
If IsTop = False Then Search = -MaxValue Else Search = MaxValue
End Function
Private Sub cbText_Click(Index As Integer)
Dim i As Integer, j As Integer, C As Integer ''C記載吃子
Dim Temp As String, Temp2 As String, Temp3 As String
Dim x As Byte, y As Byte, x2 As Byte, y2 As Byte
If cbText(Index).BackColor <> &HC0E0FF Then Call MsgBox("落棋無效!", vbOKOnly + 32, "提示:"): Exit Sub
If cSel = 0 And Trim(cbText(Index).Text) > "" Then cSel = Index: cbText(cSel).ForeColor = QBColor(12): Exit Sub ''如果玩家壹個也沒先且當前棋盤位置有棋子,則標示玩家選擇此棋子
If cSel <> 0 And Val(cbText(Index).Text) = Val(cbText(cSel).Text) Then cbText(cSel).ForeColor = H80000008&: cSel = 0: Exit Sub ''如果玩家兩次選擇相同的棋子則取消選擇
If cSel <> 0 Then
''下棋
cbText(Index).Text = cbText(cSel).Text
''判斷是否可變成加強棋
k = Val(cbText(Index).Text)
If Int(k / 100) = 1 And Index < 8 Then cbText(Index).Text = "102" ''如果1方走到頂端就變成加強棋
If Int(k / 100) = 2 And Index > 55 Then cbText(Index).Text = "202" ''如果2方走到頂端就變成加強棋
cbText(cSel).Text = ""
cbText(cSel).ForeColor = H80000008&
''判斷有沒有吃子
''向上左斜
If Index - cSel = -18 Then
cbText(Index + 9).Text = "": ''被吃子
C = Index + 9
End If
''向上右斜
If Index - cSel = -14 Then
cbText(Index + 7).Text = "": ''被吃子
C = Index + 7
End If
''向下左斜
If Index - cSel = 14 Then
cbText(Index - 7).Text = "": ''被吃子
C = Index - 7
End If
''向下右斜
If Index - cSel = 18 Then
cbText(Index - 9).Text = "": ''被吃子
C = Index - 9
End If
''存儲走法
k = 0: Temp = "": Temp2 = "": Temp = ""
For i = 1 To 8
For j = 1 To 8
If k = cSel Then Temp = "從" & Str(i) + "," + Str(j)
If k = Index Then Temp2 = " 到" + Str(i) + "," + Str(j): x = i: y = j
If k = C Then Temp3 = "吃子 " & Str(i) & "," & Str(j): x2 = i: y2 = j
k = k + 1
Next j
Next i
List2.AddItem "第" & Str(CurrentStep) & "手 " & Str(CurrentPlayer) + "方" + Temp + Temp2 + Temp3
CurrentStep = CurrentStep + 1
Text3.Text = Temp + Temp2
cSel = 0
Call ReDisplay
''下句:如果是人機模式並且玩家還沒有可吃子
If 人機模式 = True And (IsLine(CurrentPlayer, x, y) = True And x2 > 1 And y2 > 2) = False Then
'If 人機模式 = True Then
''看玩家走了哪方的棋子,就運算另壹方的棋子
CurrentPlayer = NextCer(Int(Val(cbText(Index).Text) / 100))
Call Command2_Click ''如果是人機模式則讓電腦運長
End If
End If
End Sub
Private Sub Command1_Click()
List2.Clear ''清除棋譜
CurrentStep = 1
Call Initial
Call Display
End Sub
Private Sub Command2_Click()
Dim t As Boolean
Command2.Enabled = False
t:
Text1.Text = Str(Search(CurrentPlayer, Val(Text2.Text), True, 0))
Command2.Enabled = True
With BestLocate
t = DownChess(.Initx, .Inity, .ObjX, .ObjY, .x1, .y1)
Call Display
If t = True And IsLine(CurrentPlayer, .ObjX, .ObjY) Then Call MsgBox("我還想再吃壹個"): GoTo t ''如果所下之棋還能吃子(連續吃)則再運算
End With
CurrentPlayer = NextCer(CurrentPlayer)
End Sub
Rem 移棋
Rem Sx,Sy:起點棋子 Ex,Ey:終點棋子 Ax,Ay:被吃子
Rem 如果有吃子則返回True
Private Function DownChess(Sx As Byte, Sy As Byte, ex As Byte, ey As Byte, Ax As Byte, Ay As Byte) As Boolean
ChessBoard(ex, ey) = ChessBoard(Sx, Sy)
ChessBoard(Sx, Sy) = 0
ChessBoard(Ax, Ay) = 0 ''清除被吃子
If Ax <> 0 And Ay <> 0 Then DownChess = True Else DownChess = False
Text3.Text = "第" & Str(CurrentStep) & "手 " & Str(CurrentPlayer) + "方從" & Str(Sx) + "," + Str(Sy) + "到" + Str(ex) + "," + Str(ey) & _
"吃子 " & Str(Ax) & "," & Str(Ay)
CurrentStep = CurrentStep + 1
List2.AddItem Text3.Text
''下句:如果是黑方(101、102)
If Int(ChessBoard(ex, ey) / 100) = 1 Then
''下句:如果走到第壹行則棋子變成102,威力加強
If ex = 1 Then ChessBoard(ex, ey) = 102
End If
''下句:如果是紅方(201、202)
If Int(ChessBoard(ex, ey) / 100) = 2 Then
''下句:如果走到第八行則棋子變成202,威力加強
If ex = 8 Then ChessBoard(ex, ey) = 202
End If
End Function
Rem 運算壹
Private Sub Command3_Click()
CurrentPlayer = 1
Call Command2_Click
End Sub
Rem 運算二
Private Sub Command4_Click()
CurrentPlayer = 2
Call Command2_Click
End Sub
Private Sub Command5_Click()
Call ReDisplay
End Sub
Private Sub Command6_Click()
If 人機模式 = False Then 人機模式 = True Else 人機模式 = False
If 人機模式 = False Then Command6.Caption = " 人機模式": Command6.ToolTipText = "當前模式:人人對戰" Else Command6.Caption = " 休息模式": Command6.ToolTipText = "當前模式:人機對戰"
End Sub
Private Sub Command7_Click()
End
End Sub
Rem 存譜
Private Sub Command8_Click()
On Error GoTo e
Dim i As Integer
Open InputBox("請輸入文件名:") For Output As #1
For i = 0 To List2.ListCount - 1
Print #1, List2.List(i)
Next i
Close #1
Exit Sub
e:
Call MsgBox("存儲錯誤!", vbOKOnly + 32, "提示:")
Err.Clear
Exit Sub
End Sub
Private Sub Form_Load()
人機模式 = False
cSel = 0
CurrentPlayer = 1
Call Command1_Click
End Sub
模塊代碼:
Type CHESSER
Chess As Byte ''為何棋,在BestLocate則標明為何數組
Initx As Byte ''起初棋的位置
Inity As Byte
ObjX As Byte ''經運算後的落棋點
ObjY As Byte
x1 As Byte
y1 As Byte
Allow As Boolean ''是否允許
End Type