五、之前我们已经实现了小图标的切割,初始化游戏界面等基本内容,下面是连连看的核心逻辑内容。首先连连看里面判断两个小图标能不能消除,一般有以下三种类型(当然前提是两个小图标是一样的):直连 --- ,单拐连 !--,双拐连!---!,而单拐连本质就是两个直连,双拐连本质是两个单拐连。
1、增加枚举常量
def main():
...
EMPTYCELL = -1
NONE_LINK = 0 #不连 #新增
DIRECT_LINK = 1 #直连 --- #新增
ONE_CORNER_LINK = 5 #单拐连 !_
TWO_CORNER_LINK = 8 #双拐连 !_! #新增
...
2、新增方法 :getTwoIconsLinkType,参数是两个小图标,返回就是上述定义的枚举常量。
def main():
...
'''
获得两个点连通类型
'''
def getTwoIconsLinkType(Cell0, Cell8):
#第一步:两个cell里面的图片是否相同,不同就不谈
if cur_game[Cell0[0]][Cell0[1]] != cur_game[Cell8[0]][Cell8[1]]:
return {'type':NONE_LINK}
if isDirectLink(Cell0,Cell8):
return {'type':DIRECT_LINK}
if isOneCornerLink(Cell0,Cell8):
return {'type':ONE_CORNER_LINK}
if isTwoCornerLink(Cell0,Cell8):
return {'type':TWO_CORNER_LINK}
return {'type':NONE_LINK}
...
代码中首先看图片是否相同,图片相同再看是哪种连通方式。
3、getTwoIconsLinkType中涉及到isDirectLink,isOneCornerLink,isTwoCornerLink三个函数,下面逐一添加:isDirectLink
def main():
...
'''
DIRECT_LINK = 1 #直连 ---
'''
def isDirectLink(C1, C2):
start = -1
end = -1
# Y方向
if C1[1] == C2[1]:
# 大小判断
if C2[0] < C1[0]:
start = C2[0]
end = C1[0]
else:
start = C1[0]
end = C2[0]
for x in range(start + 1, end):
if cur_game[x][C1[1]] != EMPTYCELL:
return False
return True
# X方向
elif C1[0] == C2[0]:
if C1[1] > C2[1]:
start = C2[1]
end = C1[1]
else:
start = C1[1]
end = C2[1]
for y in range(start + 1, end):
if cur_game[C1[0]][y] != EMPTYCELL:
return False
return True
return False
...
由于传入的是两个小图标的下标,所以用下标可以判断是同行还是同列。以同行为例(第一个下标相同),首先比较两者的第二个下标,将小的赋值给start,大的赋值给end,然后从start到end,这之间的所有小图标都为空EMPTYCELL,即没有阻挡的,可以认为是直连类型。也就是怎么把要解决的问题转化为数学模型,然后通过计算机的程序语言来实现,就是我们码农要掌握的技能,这也是常常说的逻辑思维能力的一种表现。当然,你不是码农就不要理会。
下面继续讲解单拐连的代码:isOneCornerLink
def main():
...
'''
ONE_CORNER_LINK = 5 #单拐连 !_
'''
def isOneCornerLink(C1, C2):
corner = (C1[0], C2[1])
if isDirectLink(C1, corner) and isDirectLink(corner, C2) and isEmptyCell(corner[0],corner[1]):
return True
corner = (C2[0], C1[1])
if isDirectLink(C1, corner) and isDirectLink(corner, C2) and isEmptyCell(corner[0],corner[1]):
return True
return False
逻辑设计如下:
紧接着,再完成双拐连的函数:isTwoCornerLink
def main():
...
'''
TWO_CORNER_LINK = 8 #双拐连 !_!
'''
def isTwoCornerLink(C1, C2):
# Y方向
for y in range(-1, game_rows + 1):
corner1 = (C1[0], y)
corner2 = (C2[0], y)
if y == C1[1] or y == C2[1]:
continue
if y == -1 or y == game_rows:
if isDirectLink(C1, corner1) and isDirectLink(corner2, C2):
return True
else:
if isDirectLink(C1, corner1) and isDirectLink(corner1, corner2) and isDirectLink(corner2, C2) and isEmptyCell(corner1[0],corner2[1]) and isEmptyCell(corner2[0],corner2[1]):
return True
# X方向
for x in range(-1, game_cols + 1):
corner1 = (x, C1[1])
corner2 = (x, C2[1])
if x == C1[0] or x == C2[0]:
continue
if x == -1 or x == game_cols:
if isDirectLink(C1, corner1) and isDirectLink(corner2, C2):
return True
else:
if isDirectLink(C1, corner1) and isDirectLink(corner1, corner2) and isDirectLink(corner2, C2) and isEmptyCell(corner1[0],corner2[1]) and isEmptyCell(corner2[0],corner2[1]):
return True
return False
...
至此,我们的核心逻辑已经实现。
六、修改mouseClick事件
def main():
...
'''
鼠标点击响应
'''
def mouseClick(posX,posY):
nonlocal isFirst
nonlocal compareCell
nonlocal isStart
if isStart:
curCell = getPoint(posX,posY)
# print (curCell)
if isUseful(curCell[0],curCell[1]) and not isEmptyCell(curCell[0],curCell[1]):
if isFirst :
drawRedRect(curCell[0],curCell[1])
isFirst = False
compareCell = curCell
else:
if compareCell[0] == curCell[0] and compareCell[1] == curCell[1]:
isFirst = True
delRedRectangle(curCell[0],curCell[1])
else:
linkType = getTwoIconsLinkType(compareCell, curCell) #新增
if linkType['type'] != NONE_LINK: #新增
pass
#消掉匹配的小图标
#删除红色的首次选中框
#设置isFirst为True
#if 游戏结束:
'''
通关后重置isStart,isFirst参数
'''
else: #新增 无法消掉的时候,去掉首个选中的红框,将第二个赋值为首个选中,给它画红框
delRedRectangle(compareCell[0],compareCell[1]) #新增
compareCell = curCell #新增
drawRedRect(curCell[0],curCell[1]) #新增
待更新...