4.2.5 获取图片连接方式
通过自定义函数getLinkType()获取图片的连接方式,代码如下所示。
def getLinkType(pre_row, pre_col, cur_row, cur_col):
if pics_map[pre_row][pre_col] != pics_map[cur_row][cur_col]:
return NONE_LINK
if isNoCornerLink(pre_row, pre_col, cur_row, cur_col):
return NO_CORNER_LINK
if isOneCornerLink(pre_row, pre_col, cur_row, cur_col):
return ONE_CORNER_LINK
if isTwoCornerLink(pre_row, pre_col, cur_row, cur_col):
return TWO_CORNER_LINK
return NONE_LINK
其中,getLinkType()函数的前两个参数表示第一次选中图片的行号和列号,后两个参数表示第二次选中图片的行号和列号。第2-3行表示当选中的两张图片不同时,返回自定义常量NONE_LINK;之后分别调用自定义函数isNoCornerLink()、isOneCornerLink()和isTwoCornerLink()判断两张图片是否是直接连通、单拐点连通和双拐点连通;如果不是以上三种连通方式,则返回NONE_LINK。
4.2.6 根据连通状态处理图片
回到“4.2.2 取消图片的标识”中提到的clickCanvas()函数中。如果两次选中的不是同一张图片,则调用“4.2.5 获取图片连接方式”中提到的getLinkType()判断两张图片的连通状态,代码如下所示。
linktype = getLinkType(PRE_CLICK_ROW, PRE_CLICK_COL, click_row, click_col)
之后,根据linktype的值进行后续处理,代码如下所示。
if linktype != NONE_LINK:
delLinkedPic(PRE_CLICK_ROW, PRE_CLICK_COL, click_row, click_col)
canvas.delete("rectRedOne")
FIRSTCLICK = True
else:
FIRSTCLICK = True
canvas.delete('rectRedOne')
第1行代码表示返回值不是NONE_LINK,也就是两张图片是连通状态,之后第2行代码调用自定义函数delLinkedPic()删除两张图片,该函数将在后面详细描述;第3行代码输出标识图片的红框;第4行代码将第一次点击的标志设置为True;如果返回值是NONE_LINK,则说明选中的两张图片没有处于连通状态,此时将第一次点击的标志设置为True,然后删除第一张图片的红框标识,让玩家重新选择。
4.2.7 消除连通的图片
通过自定义函数delLinkedPic()消除连通的图片,代码如下所示。
def delLinkedPic(pre_row, pre_col, cur_row, cur_col):
pics_map[pre_row][pre_col] = MAP_EMPTY
pics_map[cur_row][cur_col] = MAP_EMPTY
canvas.delete('im%d%d'%(pre_row, pre_col))
canvas.delete('im%d%d'%(cur_row, cur_col))
其中,第1行代码显示了delLinkedPic()函数的四个参数,前两个参数表示第一张图片所在行号和列号,后两个参数表示第二张图片所在的行号和列号;第2-3行代码在图片地图上将这两个图片所在的位置设置为MAP_EMPTY;第4-5行代码消除这两张图片,这两张图片的标签格式是“im行号列号”,在导入图片时进行的设置。
4.2.8 完整代码
GAMESTART = False
FIRSTCLICK = True
PRE_CLICK_ROW = 0
PRE_CLICKY_COL = 0
NONE_LINK = 0
NO_CORNER_LINK = 1
ONE_CORNER_LINK = 2
TWO_CORNER_LINK = 3
def getLinkType(pre_row, pre_col, cur_row, cur_col):
if pics_map[pre_row][pre_col] != pics_map[cur_row][cur_col]:
return NONE_LINK
if isNoCornerLink(pre_row, pre_col, cur_row, cur_col):
return NO_CORNER_LINK
if isOneCornerLink(pre_row, pre_col, cur_row, cur_col):
return ONE_CORNER_LINK
if isTwoCornerLink(pre_row, pre_col, cur_row, cur_col):
return TWO_CORNER_LINK
return NONE_LINK
def isNoCornerLink(pre_row, pre_col, cur_row, cur_col):
start = -1
end = -1
if pre_row == cur_row:
if pre_col<cur_col:
start = pre_col
end = cur_col
else:
start = cur_col
end = pre_col
for i in range(start+1, end):
if pics_map[pre_row][i] != MAP_EMPTY:
return False
return True
elif pre_col == cur_col:
if pre_row<cur_row:
start = pre_row
end = cur_row
else:
start = cur_row
end = pre_row
for i in range(start+1, end):
if pics_map[i][pre_col] != MAP_EMPTY:
return False
return True
return False
def isOneCornerLink(pre_row, pre_col, cur_row, cur_col):
if isNoCornerLink(pre_row, pre_col, pre_row, cur_col)\
and isNoCornerLink(pre_row, cur_col, cur_row, cur_col):
return True
if isNoCornerLink(pre_row, pre_col, cur_row, pre_col)\
and isNoCornerLink(cur_row, pre_col, cur_row, cur_col):
return True
return False
def isTwoCornerLink(pre_row, pre_col, cur_row, cur_col):
for col in range(-1, COL_PIC+1):
if col==pre_col or col==cur_col:
continue
if col==-1 or col==COL_PIC:
if isNoCornerLink(pre_row, pre_col, pre_row, col)\
and isNoCornerLink(cur_row, cur_col, cur_row, col):
return True
else:
if isNoCornerLink(pre_row, pre_col, pre_row, col) \
and isNoCornerLink(cur_row, cur_col, cur_row, col) \
and isNoCornerLink(pre_row, col,cur_row, col) \
and pics_map[pre_row][col]==MAP_EMPTY \
and pics_map[cur_row][col]==MAP_EMPTY:
return True
for row in range(-1, ROW_PIC+1):
if row==pre_row or col==cur_row:
continue
if row==-1 or row==COL_PIC:
if isNoCornerLink(pre_row, pre_col, row, pre_col)\
and isNoCornerLink(cur_row, cur_col, row, cur_col):
return True
else:
if isNoCornerLink(pre_row, pre_col, row, pre_col) \
and isNoCornerLink(cur_row, cur_col, row, cur_col) \
and isNoCornerLink(row, pre_col,row, cur_col) \
and pics_map[row][pre_col]==MAP_EMPTY \
and pics_map[row][cur_col]==MAP_EMPTY:
return True
return False
def delLinkedPic(pre_row, pre_col, cur_row, cur_col):
pics_map[pre_row][pre_col] = MAP_EMPTY
pics_map[cur_row][cur_col] = MAP_EMPTY
canvas.delete('im%d%d'%(pre_row, pre_col))
canvas.delete('im%d%d'%(cur_row, cur_col))
def clickCanvas(event):
if GAMESTART:
click_col, click_row = getClickedMap(event.x, event.y)
if(click_col>=0 and click_row>=0) and (not pics_map[click_row][click_col] == MAP_EMPTY):
global FIRSTCLICK
if FIRSTCLICK:
drawRect(click_row, click_col)
FIRSTCLICK = False
global PRE_CLICK_ROW, PRE_CLICK_COL
PRE_CLICK_ROW = click_row
PRE_CLICK_COL = click_col
else:
if PRE_CLICK_ROW==click_row and PRE_CLICK_COL==click_col:
FIRSTCLICK = True
canvas.delete('rectRedOne')
else:
linktype = getLinkType(PRE_CLICK_ROW, PRE_CLICK_COL, click_row, click_col)
if linktype != NONE_LINK:
delLinkedPic(PRE_CLICK_ROW, PRE_CLICK_COL, click_row, click_col)
canvas.delete("rectRedOne")
FIRSTCLICK = True
else:
FIRSTCLICK = True
canvas.delete('rectRedOne')
此时,我们编写的这个连连看游戏就基本上成型了。您可以试着玩一下了!