项目:Al五子棋
项目负责人:郑雨轩
项目制作时间:6天
项目完成时间:18.7.12
项目采用语言:Python
项目采用主要算法:博弈算法, 最大值最小值算法, 剪枝(Alpha - Beta)算法, 随机算法, 限制搜索边框算法等
测试机器计算层数运算时间:
一层:秒回
二层:秒回
三层:2秒
(随着棋子的个数和位置而受影响)
由于代码重复性与神经网络知识点牵扯运算速度,并未进行第四次,第五次测试
三层代码:
import sys
import random
from PyQt5.QtWidgets import QWidget, QDesktopWidget, QApplication
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtCore import Qt
random.seed() # 省略参数,意味着取当前系统时间
class MyQWidget(QWidget):
def __init__(self):
# 设置棋盘与棋子的间隔
self.D = 56
self.d = 54
# 设置棋盘为二维数组
self.Board = [[255]*15 for i in range(15)]
# 设置出棋方
self._Bool = False
# 设置赢方
self._over = 255
super().__init__()
self.initUI()
def initUI(self):
# 窗口绘制
self.resize(16 * self.D, 16 * self.D)
self.center()
self.setWindowTitle('Go_Bang')
def center(self):
# 窗口归中
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def paintEvent(self, QPaintEvent):
if self._over == 255:
# 绘制板块
qpLine = QPainter()
qpElip = QPainter()
qpLine.begin(self)
self.drawLines(qpLine)
qpLine.end()
qpElip.begin(self)
self.drawEllipse(qpElip)
qpElip.end()
else:
if self._over == 1:
print('Black Win!')
else:
print('White Win!')
self.update()
def drawLines(self, qpLine):
# 绘制棋盘
for i in range(1, 16):
if i == 1 or i == 15:
pen = QPen(Qt.black, 2, Qt.SolidLine)
qpLine.setPen(pen)
else:
pen = QPen(Qt.black, 1, Qt.SolidLine)
qpLine.setPen(pen)
qpLine.drawLine(self.D, i * self.D, 15 * self.D, i * self.D)
qpLine.drawLine(i * self.D, self.D, i * self.D, 15 * self.D)
def drawEllipse(self, qpElip):
# 绘制棋子
MinX, MaxX, MinY, MaxY = self.AlUpDnLfRt(15, 0, 15, 0)
for i in range(MinX, MaxX):
for j in range(MinY, MaxY):
if self.Board[i][j] == 1:
qpElip.setPen(Qt.darkGray)
qpElip.setBrush(Qt.black)
qpElip.drawEllipse((j + 0.5) * self.D, (i + 0.5) * self.D, self.d, self.d)
elif self.Board[i][j] == 0:
qpElip.setPen(Qt.darkGray)
qpElip.setBrush(Qt.white)
qpElip.drawEllipse((j + 0.5) * self.D, (i + 0.5) * self.D, self.d, self.d)
self.update()
def mousePressEvent(self, e):
apos_x = e.pos().x()
apos_y = e.pos().y()
if apos_x >= 0.5 * self.D and apos_x <= 15.5 * self.D and apos_y >= 0.5 * self.D and apos_y <= 15.5 * self.D:
apos_x, apos_y = self.aimPoint(apos_x, apos_y)
apos_x, apos_y = self._Scope(apos_x, apos_y)
if apos_x != -1:
if self.Board[apos_y][apos_x] == 255:
if self._Bool == 0:
self.Board[apos_y][apos_x] = 0
else:
self.Board[apos_y][apos_x] = 0
self._Bool = not self._Bool
self.Traverse()
self.AlRobotGo()
self.Traverse()
print('Player to:')
@staticmethod
def _Scope(apos_x, apos_y):
if apos_x >= 0 and apos_x <= 14 and apos_y >= 0 and apos_y <= 14:
return apos_x, apos_y
else:
return -1
def aimPoint(self, apos_x, apos_y):
# 计算棋坐标
sur_x = int(apos_x / self.D)
sur_y = int(apos_y / self.D)
apos_x %= self.D
apos_y %= self.D
if apos_x >= (self.D / 2):
sur_x += 1
if apos_y >= (self.D / 2):
sur_y += 1
sur_x, sur_y = self._Scope(sur_x - 1, sur_y - 1)
return sur_x, sur_y
def Traverse(self):
MinX, MaxX, MinY, MaxY = self.AlUpDnLfRt(15, 0, 15, 0)
for i in range(MinX, MaxX):
for j in range(MinY, MaxY):
if self.Board[i][j] != 255:
b_Up = _Right = b_Down = _Scp = 1
_Color = self.Board[i][j]
# 判断该点前点
_Uold = self.oldCompare(i + 1, j - 1, _Color)
_Rold = self.oldCompare(i, j - 1, _Color)
b_Dold = self.oldCompare(i - 1, j - 1, _Color)
_Sold = self.oldCompare(i - 1, j, _Color)
# 判断该点范围
if i - 4 < MinX and i + 4 > MaxX and j - 4 < MinY and j + 4 > MaxY:
break
# 进行遍历该点附近点
if _Uold != 0:
b_Up = self.Up_RangeDirct(i, j, _Color, b_Up)
if _Rold != 0:
_Right = self.Rt_RangeDirct(i, j, _Color, _Right)
if b_Dold != 0:
b_Down = self.Dn_RangeDirct(i, j, _Color, b_Down)
if _Sold != 0:
_Scp = self.Sp_RangeDirct(i, j, _Color, _Scp)
# 进行胜负判断
self.Game_over(b_Up, b_Down, _Right, _Scp, _Color)
def oldCompare(self, x, y, n_color):
if -1 != self._Scope(x, y):
if self.Board[x][y] == n_color:
return 0
elif self.Board[x][y] == 255:
return 255
else:
return 1
else:
return 2
def Up_RangeDirct(self, x, y, n_color, now):
for k in range(1, 5):
if -1 != self._Scope(x - k, y + k):
if self.Board[x - k][y + k] == n_color:
now += 1
else:
return 0
else:
return 0
return now
def Rt_RangeDirct(self, x, y, n_color, now):
for k in range(1, 5):
if -1 != self._Scope(x, y + k):
if self.Board[x][y + k] == n_color:
now += 1
else:
return 0
else:
return 0
return now
def Dn_RangeDirct(self, x, y, n_color, now):
for k in range(1, 5):
if -1 != self._Scope(x + k, y + k):
if self.Board[x + k][y + k] == n_color:
now += 1
else:
return 0
else:
return 0
return now
def Sp_RangeDirct(self, x, y, n_color, now):
for k in range(1, 5):
if -1 != self._Scope(x + k, y):
if self.Board[x + k][y] == n_color:
now += 1
else:
return 0
else:
return 0
return now
def AlRobotGo(self):
# 人机下棋
if self._Bool:
TrueScore = -10000
MaxMinMaxScore = 10000
TrueX = MaxMinMaxX = x = 0
TrueY = MaxMinMaxY = y = 0
MinX, MaxX, MinY, MaxY = self.AlUpDnLfRt(15, 0, 15, 0)
for i in range(MinX, MaxX):
for j in range(MinY, MaxY):
if self.Board[i][j] == 255:
self.Board[i][j] = 1
MinMaxScore_Flag = 1
MinMaxScore_Ok_Flag = 2
MMinX, MMaxX, MMinY, MMaxY = self.AlUpDnLfRt(MaxX, MinX, MaxY, MinY)
for ii in range(MMinX, MMaxX):
for jj in range(MMinY, MMaxY):
if ii != i or jj != j:
if self.Board[ii][jj] == 255:
self.Board[i][j] = 1
self.Board[ii][jj] = 0
NewScore = -100000
NewScore_Flag = 1
MinMaxScore_Ok_Flag -= 1
if MinMaxScore_Ok_Flag == 0:
MinMaxScore_Flag = 0
MMMinX, MMMaxX, MMMinY, MMMaxY = self.AlUpDnLfRt(MMaxX, MMinX, MMaxY, MMinY)
for iii in range(MMMinX, MMMaxX):
for jjj in range(MMMinY, MMMaxY):
if iii != i or jjj != j:
if iii != ii or jjj != jj:
if self.Board[iii][jjj] == 255:
self.Board[i][j] = 1
self.Board[ii][jj] = 0
self.Board[iii][jjj] = 1
_Score = self.AlTraverse()
self.Board[i][j] = 255
self.Board[ii][jj] = 255
self.Board[iii][jjj] = 255
if _Score > NewScore:
NewScore = _Score
x = i
y = j
if MinMaxScore_Flag == 1:
MaxMinMaxScore = NewScore
MaxMinMaxX = x
MaxMinMaxY = y
if _Score >= MaxMinMaxScore and MinMaxScore_Flag == 0:
NewScore_Flag = 0
break
if NewScore_Flag == 0:
break
if NewScore < MaxMinMaxScore and MinMaxScore_Flag == 0:
MaxMinMaxScore = NewScore
MaxMinMaxX = x
MaxMinMaxY = y
if MaxMinMaxScore > TrueScore:
TrueScore = MaxMinMaxScore
TrueX = MaxMinMaxX
TrueY = MaxMinMaxY
if MaxMinMaxScore == TrueScore:
if random.randint(0,1):
TrueScore = MaxMinMaxScore
TrueX = MaxMinMaxX
TrueY = MaxMinMaxY
self.Board[TrueX][TrueY] = 1
print('Alrbot to........')
self._Bool = 0
def AlTraverse(self):
# 人机遍历
W_Score = B_Score = 10000
MinX, MaxX, MinY, MaxY = self.AlUpDnLfRt(15, 0, 15, 0)
for i in range(MinX, MaxX):
for j in range(MinY, MaxY):
if self.Board[i][j] != 255:
b_Up = _Right = b_Down = _Scp = 1
_UpF = _RiF = _DnF = _ScF = 0
N_Color = self.Board[i][j]
# 判断该点前点
_Uold = self.oldCompare(i + 1, i - 1, N_Color)
_Rold = self.oldCompare(i, j - 1, N_Color)
_Dold = self.oldCompare(i - 1, j - 1, N_Color)
_Sold = self.oldCompare(i - 1, j, N_Color)
# 进行遍历该点附近点
if _Uold != 0:
_UpF, b_Up = self.Al_Up_RangeDirct(i, j, N_Color, b_Up)
if _Rold != 0:
_RiF, _Right = self.Al_Rt_RangeDirct(i, j, N_Color, _Right)
if _Dold != 0:
_DnF, b_Down = self.Al_Dn_RangeDirct(i, j, N_Color, b_Down)
if _Sold != 0:
_ScF, _Scp = self.Al_Sp_RangeDirct(i, j, N_Color, _Scp)
New_Score = self.Now_Score(_Uold, b_Up, _UpF) + self.Now_Score(_Rold, _Right, _RiF) + self.Now_Score(_Dold, b_Down, _DnF) + self.Now_Score(_Sold, _Scp, _ScF)
if N_Color == 1:
B_Score += New_Score
else:
W_Score += New_Score
return (B_Score - W_Score)
def Al_Up_RangeDirct(self, x, y, n_color, now):
for k in range(1, 5):
if -1 != self._Scope(x - k, y + k):
if self.Board[x - k][y + k] == n_color:
now += 1
elif self.Board[x - k][y + k] == 255:
return 255, now
else:
return 1, now
else:
return 2, now
return 0, now
def Al_Rt_RangeDirct(self, x, y, n_color, now):
for k in range(1, 5):
if -1 != self._Scope(x, y + k):
if self.Board[x][y + k] == n_color:
now += 1
elif self.Board[x][y + k] == 255:
return 255, now
else:
return 1, now
else:
return 2, now
return 0, now
def Al_Dn_RangeDirct(self, x, y, n_color, now):
for k in range(1, 5):
if -1 != self._Scope(x + k, y + k):
if self.Board[x + k][y + k] == n_color:
now += 1
elif self.Board[x + k][y + k] == 255:
return 255, now
else:
return 1, now
else:
return 2, now
return 0, now
def Al_Sp_RangeDirct(self, x, y, n_color, now):
for k in range(1, 5):
if -1 != self._Scope(x + k, y):
if self.Board[x + k][y] == n_color:
now += 1
elif self.Board[x + k][y] == 255:
return 255, now
else:
return 1, now
else:
return 2, now
return 0, now
@staticmethod
def Now_Score(O_lD, N_oW, N_wF):
if N_oW < 5:
if O_lD == 255:
if N_wF == 255:
if N_oW == 1:
return 0
elif N_oW == 2:
return 100
elif N_oW == 3:
return 1000
else:
return 5000
elif N_wF == 1 or N_wF == 2:
if N_oW == 1:
return 0
elif N_oW == 2:
return 20
elif N_oW == 3:
return 500
else:
return 1500
elif O_lD == 1 or O_lD == 2:
if N_wF == 255:
if N_oW == 1:
return 0
elif N_oW == 2:
return 20
elif N_oW == 3:
return 500
else:
return 1500
else:
return 0
else:
return 0
else:
return 12345
def AlUpDnLfRt(self, x1, x2, y1, y2):
MinX = x1
MaxX = x2
MinY = y1
MaxY = y2
for i in range(x2, x1):
for j in range(y2, y1):
if self.Board[i][j] != 255:
if i > MaxX:
&n