連連看(三)

Python3 實現QQ遊戲連連看遊戲輔助

目錄

Python3 實現QQ遊戲連連看遊戲輔助

0、本片前言 

1、水平方向

2、垂直方向

3、一個拐角

4、兩個拐角

5、判斷是否可以連接


 0、本片前言

從這裏開始,我們可以按照上一篇文章中介紹的方法,手動賦值一個矩陣和 total ,不用每次調試運行都打開遊戲、截圖、保存、構建矩陣了。

本文使用的是這個矩陣,total = 32

       [ [1,  2,  3,  4,  5,  1,  1,  6,  7,  8,   9, 10, 11, 12, 13, 14, 15,  9,  7],
         [16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  3],
         [17, -1, 18, 19, 20, 21, 22,  2,  9, 12,  4,  7, 16, 12, 23, 17,  6, -1,  5],
         [18, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  8, -1,  5],
         [25, -1,  2, -1, 22, 20, 16, 19, 26, 23,  4,  1, 27,  8, -1, -1, 14, -1,  6],
         [16, -1, 28, -1, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, 17],
         [ 3, -1, 19, -1, 15,  3, 21, 24, 11,  5, 18, 28, 27, 30, 25, 22, 10, -1, 27],
         [17, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19],
         [11, -1, 31, 29, 20, 13,  4, 13, 14, 11, 10, 24,  7, 18, 14, 12, 30,  8, 28],
         [31, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
         [ 9,  6, 10, 24, 27, 26,  2, 25, 28, 20, 23, 29, 22, 29, 31, 31, 13, 21, 25]])

 每寫完一個函數都可以進行測試,方法就是 print 看結果

# 使用保存的矩陣和 total 初始化
linkup = game()

# 隨心所欲的想要測試的兩點座標帶入即可
print(linkup.vertical(3, 1, 4, 1))
print(linkup.two_corner(r1, c1, r2, c2))

1、水平方向

首先判斷是否在同一行,然後根據進行掃描兩點之間是否存在非空(非 -1)的點。

第一次寫的時候發現測試 (0, 5) 和 (0, 6) 這兩點的時候,發現明明是可以連接的,但是返回的卻是 False。

因爲有兩種特殊情況:

1、如果兩點相連接,導致在 for 循環一次都不運行。(使用 Pycharm 的 Debug 模式發現)

      解決方案就是判斷同一行的兩點是否縱座標相鄰。如果兩個座標點所對應的矩陣中的值相同,可以連線。但這就引起了第二個特殊情況:其中一個點是 -1,另一個點爲大於零的數字。

2、其中一個點是 -1,另一個點爲大於零的數字。(主要是爲了後面的拐點連線判斷做鋪墊)

    解決方案是用或操作對兩個點進行判斷,若其中一個爲 -1,可以連線。

# 判斷水平方向
    def horizon(self, row1: int, col1: int, row2: int, col2: int) -> bool:
        if row1 == row2:
            for i in range(min(col1, col2) + 1, max(col1, col2)):
                # print(self.game_map[row1, i])
                if self.game_map[row1, i] != -1:
                    return False
            # 解決 conjunction
            if min(col1, col2) + 1 == max(col1, col2):
                if (self.game_map[row1, col1] == -1) or (self.game_map[row2, col2] == -1):
                    return True
                if self.game_map[row1, col1] == self.game_map[row2, col2]:
                    return True
            return True
        return False

 

2、垂直方向

與水平方向相同,舉一反三,不再贅述。

    # 判斷垂直方向
    def vertical(self, row1: int, col1: int, row2: int, col2: int) -> bool:
        if col1 == col2:
            for i in range(min(row1, row2) + 1, max(row1, row2)):
                # print(self.game_map[i, col1])
                if self.game_map[i, col1] != -1:
                    return False
            # 解決 conjunction
            if min(row1, row2) + 1 == max(row1, row2):
                if (self.game_map[row1, col1] == -1) or (self.game_map[row2, col2] == -1):
                    return True
                if self.game_map[row1, col1] == self.game_map[row2, col2]:
                    return True
            return True
        return False

 

3、一個拐角

 增加兩個拐點 (cor_one_row, cor_one_col) = (row1, col2) 和 (cor_two_row, cor_two_col) = (row2, col1) 作爲輔助,不用擔心兩個點的位置關係,因爲在水平和垂直的判斷中,我們都使用了 max 和 min 函數進行修正。

那麼思路就是判斷:

1、point1 與 cor_one 之間是否可以水平連接,point2 與 cor_one 之間是否可以垂直連接。

2、point2 與 cor_two 之間是否可以水平連接,point1 與 cor_two 之間是否可以垂直連接。

其中一個可行,那麼 point1 與 point2 之間可以連線。

# 判斷一個拐點
def one_corner(self, row1: int, col1: int, row2: int, col2: int) -> bool:
    cor_one_row, cor_one_col = row1, col2
    cor_two_row, cor_two_col = row2, col1
    if self.game_map[cor_one_row, cor_one_col] == -1:
        if self.horizon(cor_one_row, cor_one_col, row1, col1) & self.vertical(cor_one_row, cor_one_col, row2, col2):
            return True
        if self.game_map[cor_two_row, cor_two_col] == -1:
            if self.horizon(cor_two_row, cor_two_col, row2, col2) & self.vertical(cor_two_row, cor_two_col, row1, col1):
                return True
    return False

 

4、兩個拐角

詳細分析:

1、在 point1 的水平或垂直連線上任意一點可以與 point2 經過一個拐點的連線連接,即兩點間可以經過兩個拐點鏈接

2、在 point2 的水平或垂直連線上任意一點可以與 point1 經過一個拐點的連線連接,即兩點間可以經過兩個拐點鏈接

輔助函數:用於獲取兩目標點所在水平和垂直方向上的空白點(-1)

ps:此函數可以優化,大家可以自行修改優化,歡迎評論私信。

# 收集水平、垂直方向可行點
def collect_points(self, row: int, col: int) -> list:
    points = []
    # 向右方搜索
    for i in range(col + 1, 19):
        try:
            if self.game_map[row, i] == -1:
                points.append((row, i))
            else:
                break
        except IndexError as err:
            # print("Ignore col error.")
            continue
    # 向左方搜索
    for i in range(col - 1, -1, -1):
        try:
            if self.game_map[row, i] == -1:
                points.append((row, i))
            else:
                break
        except IndexError as err:
            # print("Ignore col error.")
            continue
    # 向上方搜索
    for i in range(row - 1, -1, -1):
        try:
            if self.game_map[i, col] == -1:
                points.append((i, col))
            else:
                break
        except IndexError as err:
            # print("Ignore row error.")
            continue
    # 向下方搜索
    for i in range(row + 1, 19):
        try:
            if self.game_map[i, col] == -1:
                points.append((i, col))
            else:
                break
        except IndexError as err:
            # print("Ignore row error.")
            continue
    return points

然後拿着這些點進行遍歷,看看是否存在可以經過一個拐點和另一個目標點連接的。存在,則可以兩拐點鏈接。

最終判斷兩個拐點的完整代碼: 

# 判斷兩個拐點
def two_corner(self, row1: int, col1: int, row2: int, col2: int) -> bool:
    for item in self.collect_points(row1, col1):
        if self.one_corner(item[0], item[1], row2, col2):
            return True
    for item in self.collect_points(row2, col2):
        if self.one_corner(item[0], item[1], row1, col1):
            return True
        return False

 

5、判斷是否可以連接

符合任意一種連接方式即可認定爲可以連接。

# 判斷是否可以連接
def erasable(self, row1: int, col1: int, row2: int, col2: int) -> bool:
    flag_no_corner = (self.horizon(row1, col1, row2, col2)) or (self.vertical(row1, col1, row2, col2))
    flag_corner = (self.one_corner(row1, col1, row2, col2)) or (self.two_corner(row1, col1, row2, col2))
    return flag_no_corner or flag_corner

【本片完】

【下一篇:連連看(四)—— 你看我這鼠標比用戶還真(Pymouse 的替身)

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章