由于女朋友每天玩这个小游戏,每天挑战我……囧,只好写了一个辅助工具帮我自动满分,最后的结果是大家一起满分……本人不是程序员,请大家指正。
主要使用了PIL模块和pymouse模块,一个做图像识别,另一个做自动点击,这个小工具只在我的电脑,Python2.5+XP下测试通过。
- # -*- coding: utf-8 -*-
- #这是一个QQ空间3366小游戏中的彩色砖块游戏的辅助工具
- #他可以帮你自动计算一种正确的算法,保证你得200分!
- #使用时不能有任何窗口遮挡游戏界面,同时也不能做其他操作
- #程序基本原理:
- #彩色砖块可以看作是一个23*15的矩阵,其中有10中颜色的砖块。没有砖块的空白块填充有灰白相间的背景
- #点击其中一个空白块,则四周相同的砖块将消除,直至所有砖块消除为止
- #游戏首先截取屏幕,然后寻找边长为25的灰色块和白色块,并加上一个偏移量,从而确定矩阵的起始坐标。
- #通过获取矩阵中心点位置的颜色,确定所在位置的砖块,然后记录在一个二维列表中。
- #将所有空白块按顺序生成一个列表,随即选出一个空白块,直到找到四周有相同砖块可以点击的空白块。
- #在二维列表中进行消除,重复以上操作,将点击的空白块顺序记录在一个列表中,直到矩阵全部为空白块为止。
- #如果当还有砖块但已经找不到周围可以消除的空白块,则表示这种点击顺序不成功。然后从新计算一种点击顺序,直至成功未知。
- #最后按计算出的顺序模拟鼠标点击砖块。
- import copy
- import time
- import random
- import pymouse
- from PIL import ImageGrab
- from PIL import Image
- raw_input(u"输入任意键开始……".encode("gb2312"))
- #定义灰色正方形块,白色正方形块的RGB值
- gray = (237, 237, 237)
- white = (247, 247, 247)
- #定义砖块颜色
- color = {
- 1:(0, 102, 255), #蓝色
- 2:(255, 102, 102), #红色
- 3:(204, 102, 204),#紫色
- 4:(204, 102, 0), #棕色
- 5:(0, 204, 0), #绿色
- 6:(102, 204, 204),#青色
- 7:(255, 153, 0),#橙色
- 8:(187, 187, 187),#中灰
- 9:(204, 204, 102),#咖啡色
- 10:(255, 136, 255)#淡紫
- }
- #定义方块大小
- blockSize = 25
- #定义游戏方块矩阵的大小
- gameSize = [23, 15]
- #屏幕截图
- #screen = Image.open("screen.bmp") #用来测试的截图
- screen = ImageGrab.grab()
- #获得屏幕像素矩阵
- xy = screen.load()
- #遍历每一个像素,发现RGB值等于gray的像素时,检查他的右24和下24像素是否为gray
- #灰色块
- print u"正在获取游戏起始坐标……"
- isGray = False
- #白色块
- isWhite = False
- for y in xrange(screen.size[1]):
- for x in xrange(screen.size[0]):
- if xy[x, y] == gray:
- #查右24个像素RGB值为gray的像素,不是则继续找
- for i in xrange(blockSize):
- try:
- if xy[x+i, y] == gray:
- isGray = True
- else:
- isGray = False
- break
- except IndexError:
- isGray = False
- break
- if isGray == True:
- #检查前一个像素和后第25个像素的RGB是否为white
- if xy[x-1, y] == white and xy[x+blockSize, y] == white:
- isWhite = True
- if isWhite == True: break
- if isWhite == True: break
- #定义游戏操作区的开始坐标
- gamePos = [x+10, y+31+10]
- #记录砖块状况的二维数组
- array = []
- for y in xrange(gameSize[1]):
- xArray = []
- for x in xrange(gameSize[0]):
- #获得砖块RGB值
- blackRGB = xy[gamePos[0]+blockSize*x, gamePos[1]+blockSize*y]
- #如果砖块RGB值为gray, white,则此二维坐标为空
- if blackRGB in [gray, white]:
- xArray.append(0)
- else:
- for key in color:
- if color[key] == blackRGB:
- xArray.append(key)
- break
- array.append(xArray)
- #复制array,用于以后重复寻找正确的点击顺序
- ar = copy.deepcopy(array)
- #检查一个空白点周围4边的色块,返回一个包含边界色块坐标的列表
- def check(x, y):
- border = []
- #前
- i = 0
- while True:
- i = i+1
- z = y-i
- if z in [-1, 23]:
- break
- if array[x][z] != 0:
- border.append([x, z])
- break
- #后
- i = 0
- while True:
- i = i+1
- z = y+i
- if z in [-1, 23]:
- break
- if array[x][z] != 0:
- border.append([x, z])
- break
- #上
- i = 0
- while True:
- i = i+1
- z = x-i
- if z in [-1, 15]:
- break
- if array[z][y] != 0:
- border.append([z, y])
- break
- #下
- i = 0
- while True:
- i = i+1
- z = x+i
- if z in [-1, 15]:
- break
- if array[z][y] != 0:
- border.append([z, y])
- break
- return border
- #比较一个空白色块周围4边的色块,如颜色相同则消除
- def compare(border, doCompare=False):
- a = border.pop()
- aValue = array[a[0]][a[1]]
- list = copy.deepcopy(border)
- for b in list:
- bValue = array[b[0]][b[1]]
- if aValue == bValue:
- array[a[0]][a[1]] = 0
- array[b[0]][b[1]] = 0
- border.remove(b)
- doCompare = True
- if border != []: doCompare = compare(border, doCompare)
- return doCompare
- #在游戏矩阵中寻找空白块模拟点击消除
- def simClick():
- emptyBlack = []
- for x, xArray in enumerate(array):
- for y, value in enumerate(xArray):
- #如果方块是空白的,则查看四个方向有无相同色块
- if value == 0:
- emptyBlack.append([x, y])
- lenEmptyBlack = len(emptyBlack)
- #如果空白色块的数量达到23*15,那么说明此时已经完成了游戏
- if lenEmptyBlack == gameSize[0]*gameSize[1]: return "complete"
- for i in xrange(lenEmptyBlack):
- randomBlack = random.choice(emptyBlack)
- x, y = randomBlack
- border = check(x, y)
- if border != []:
- if compare(border) == True:
- return randomBlack
- #如果已经没有可以合并的色块,则表示此种点击顺序失败
- return "fail"
- #寻找正确点击顺序的算法,返回一个依次点击的列表
- def algorithm():
- print u"正在计算正确的点击顺序……"
- while True:
- clickOrder = []
- global array
- array = copy.deepcopy(ar)
- while True:
- randomBlack = simClick()
- if randomBlack not in ["complete", "fail"]:
- clickOrder.append(randomBlack)
- continue
- if randomBlack == "fail": break
- else: return clickOrder
- #开始真正玩游戏。
- def playGame(clickOrder):
- #模拟鼠标点击
- print u"开始自动玩游戏……"
- mouse = pymouse.PyMouse()
- for x, y in clickOrder:
- mouse.press(gamePos[0]+blockSize*y, gamePos[1]+blockSize*x)
- time.sleep(0.6)
- print u"完成!3秒后自动退出!"
- time.sleep(3)
- playGame(algorithm())