Python 連連看連接算法
更新時間:2008年11月22日 22:02:25 作者:
這段時間老是“不務(wù)正業(yè)”的搞一些東西玩。之前的貪吃蛇,俄羅斯方塊激發(fā)了我研究游戲算法的興趣。經(jīng)過1個星期的構(gòu)思,連連看的連接算法終于出爐了。再過一段時間就基于這個算法使用JavaScript推出網(wǎng)頁版的連連看。下面是說明及代碼。
功能:為連連看游戲提供連接算法
說明:模塊中包含一個Point類,該類是游戲的基本單元“點”,該類包含屬性:x,y,value。
其中x,y代表了該點的坐標,value代表該點的特征:0代表沒有被填充,1-8代表被填充為游戲圖案,9代表被填充為墻壁
模塊中還包含一個名為points的Point列表,其中保存著整個游戲界面中的每個點
使用模塊的時候應(yīng)首先調(diào)用createPoints方法,初始化游戲界面中每個點,然后可通過points訪問到每個點,繼而初始化界面
模塊中核心的方法是link,通過提供源點和終點,可嘗試連接兩點,如果可以連接則返回保存路徑的path列表,否則返回False
#-*-coding:utf-8-*-
"""連連看連接算法
為連連看游戲提供連接算法
模塊中包含一個Point類,該類是游戲的基本單元“點”,該類包含屬性:x,y,value。
其中x,y代表了該點的坐標,value代表該點的特征:0代表沒有被填充,1-8代表被填充為游戲圖案,9代表被填充為墻壁
模塊中還包含一個名為points的Point列表,其中保存著整個游戲界面中的每個點
使用模塊的時候應(yīng)首先調(diào)用createPoints方法,初始化游戲界面中每個點,然后可通過points訪問到每個點,繼而初始化界面
模塊中核心的方法是link,通過提供源點和終點,可嘗試連接兩點,如果可以連接則返回保存路徑的path列表,否則返回False
"""
import random
__author__ ="http://blog.csdn.net/anhulife"
__license__ ="python"
class Point:
"""Point類
Point類是游戲中基本單元:“點”
"""
def __init__(self,x,y,value):
self.x = x
self.y = y
self.value = value
self.directs = None
self.changed = 0
def __createDirect(self,pre,target):
"""構(gòu)造點的方向集
每個點在連接的過程中都持有一個方向集,這個方向集中保存著該點的前進方向選擇的優(yōu)先級
優(yōu)先級:指向目標點的方向級別最高,在同等級別并且遵循x方向優(yōu)先于y方向
"""
self.directs = list()
stx = target.x - self.x
sty = target.y - self.y
if stx >= 0 :
self.directs.append("right")
self.directs.append("left")
else:
self.directs.append("left")
self.directs.append("right")
if sty >= 0 :
self.directs.insert(1,"up")
self.directs.append("down")
else:
self.directs.insert(1,"down")
self.directs.append("up")
if pre == None :
return
spx = pre.x - self.x
spy = pre.y - self.y
if spx == 0 :
if spy == 1:
self.directs.remove("up")
else:
self.directs.remove("down")
else :
if spx == 1:
self.directs.remove("right")
else:
self.directs.remove("left")
def forward(self,pre,target):
"""點的前進動作
點的前進即是依次從方向集中取出優(yōu)先級高的方向,并判斷該方向上的下一個點是否被填充
如果沒有被填充則說明該方向可通,并返回該方向。否則試探下一個方向,如果方向集中沒有方向可用了,則返回None
"""
if self.directs == None :
self.__createDirect(pre,target)
if len(self.directs) == 0 :
return None
direct = None
while(True):
if len(self.directs) == 0 :
break
tmpDirect = self.directs.pop(0)
if tmpDirect == "up" :
x = self.x
y = self.y + 1
elif tmpDirect == "down":
x = self.x
y = self.y - 1
elif tmpDirect == "left":
x = self.x - 1
y = self.y
elif tmpDirect == "right":
x = self.x + 1
y = self.y
p = points[x][y]
if p.value > 0 and p != target:
continue
else :
direct = tmpDirect
if pre == None:
self.changed = 1
else:
if (pre.x - self.x) == 0 and (p.x - self.x) == 0:
self.changed = 0
else:
if (pre.y - self.y) == 0 and (p.y - self.y) == 0:
self.changed = 0
else :
self.changed = 1
break
return direct
def isChanged(self):
"""判斷方向變化
返回在該點前進時,是否帶來了方向的變化,即方向不同于原方向
"""
return self.changed
def __eq__(self,p):
if p == None :
return False
if self.x == p.x and self.y == p.y :
return True
else:
return False
points = list()
def createPoints(w,h):
"""構(gòu)造游戲界面的點
初始化界面中的所有的點,并且規(guī)則如下:
最外一層是“墻壁”點,接下來的一層是沒有被填充的點,被包裹的是填充的點
"""
r = random.randint
for x in range(w):
temp = list()
for y in range(h):
if x == 0 or x == (w-1) or y == 0 or y == (h-1):
temp.append(Point(x,y,9))
else:
if x == 1 or x == (w-2) or y == 1 or y == (h-2):
temp.append(Point(x,y,0))
else:
temp.append(Point(x,y,r(1,8)))
points.append(temp)
def link(source,target):
"""點的連接
連接方法的思想:針對源點的每個方向嘗試前進,如果可以前進,則將針對該方向上的下個點的每個方向嘗試前進
當一個點的可選方向都不能前進的時候,則返回到已有前進路徑中的前一個點,嘗試該點其他可選方向。當回源點
的每個方向都走不通或是路徑的方向變化等于4的時候,連接失敗返回False。否則當路徑連接到目標點而且路徑的方向變化小
于4的時候,連接成功返回路徑
"""
if source == target:
return False
path = list()
change = 0
current = source
while True:
if current==target and change < 4:
for p in path:
p.directs = None
return path
if change == 4:
current.directs = None
current = path.pop(len(path)-1)
change = change - current.isChanged()
continue
if change == 0:
direct = current.forward(None,target)
else:
direct = current.forward(path[len(path)-1],target)
if direct != None:
change = change + current.isChanged()
if direct == "up" :
x = current.x
y = current.y + 1
elif direct == "down":
x = current.x
y = current.y - 1
elif direct == "left":
x = current.x - 1
y = current.y
elif direct == "right":
x = current.x + 1
y = current.y
print x,y
path.append(current)
current = points[x][y]
else:
if change == 0:
return False
else:
current.directs = None
current = path.pop(len(path)-1)
change = change - current.isChanged()
createPoints(8,8)
p = link(points[2][2],points[5][2])
print p
說明:模塊中包含一個Point類,該類是游戲的基本單元“點”,該類包含屬性:x,y,value。
其中x,y代表了該點的坐標,value代表該點的特征:0代表沒有被填充,1-8代表被填充為游戲圖案,9代表被填充為墻壁
模塊中還包含一個名為points的Point列表,其中保存著整個游戲界面中的每個點
使用模塊的時候應(yīng)首先調(diào)用createPoints方法,初始化游戲界面中每個點,然后可通過points訪問到每個點,繼而初始化界面
模塊中核心的方法是link,通過提供源點和終點,可嘗試連接兩點,如果可以連接則返回保存路徑的path列表,否則返回False
復制代碼 代碼如下:
#-*-coding:utf-8-*-
"""連連看連接算法
為連連看游戲提供連接算法
模塊中包含一個Point類,該類是游戲的基本單元“點”,該類包含屬性:x,y,value。
其中x,y代表了該點的坐標,value代表該點的特征:0代表沒有被填充,1-8代表被填充為游戲圖案,9代表被填充為墻壁
模塊中還包含一個名為points的Point列表,其中保存著整個游戲界面中的每個點
使用模塊的時候應(yīng)首先調(diào)用createPoints方法,初始化游戲界面中每個點,然后可通過points訪問到每個點,繼而初始化界面
模塊中核心的方法是link,通過提供源點和終點,可嘗試連接兩點,如果可以連接則返回保存路徑的path列表,否則返回False
"""
import random
__author__ ="http://blog.csdn.net/anhulife"
__license__ ="python"
class Point:
"""Point類
Point類是游戲中基本單元:“點”
"""
def __init__(self,x,y,value):
self.x = x
self.y = y
self.value = value
self.directs = None
self.changed = 0
def __createDirect(self,pre,target):
"""構(gòu)造點的方向集
每個點在連接的過程中都持有一個方向集,這個方向集中保存著該點的前進方向選擇的優(yōu)先級
優(yōu)先級:指向目標點的方向級別最高,在同等級別并且遵循x方向優(yōu)先于y方向
"""
self.directs = list()
stx = target.x - self.x
sty = target.y - self.y
if stx >= 0 :
self.directs.append("right")
self.directs.append("left")
else:
self.directs.append("left")
self.directs.append("right")
if sty >= 0 :
self.directs.insert(1,"up")
self.directs.append("down")
else:
self.directs.insert(1,"down")
self.directs.append("up")
if pre == None :
return
spx = pre.x - self.x
spy = pre.y - self.y
if spx == 0 :
if spy == 1:
self.directs.remove("up")
else:
self.directs.remove("down")
else :
if spx == 1:
self.directs.remove("right")
else:
self.directs.remove("left")
def forward(self,pre,target):
"""點的前進動作
點的前進即是依次從方向集中取出優(yōu)先級高的方向,并判斷該方向上的下一個點是否被填充
如果沒有被填充則說明該方向可通,并返回該方向。否則試探下一個方向,如果方向集中沒有方向可用了,則返回None
"""
if self.directs == None :
self.__createDirect(pre,target)
if len(self.directs) == 0 :
return None
direct = None
while(True):
if len(self.directs) == 0 :
break
tmpDirect = self.directs.pop(0)
if tmpDirect == "up" :
x = self.x
y = self.y + 1
elif tmpDirect == "down":
x = self.x
y = self.y - 1
elif tmpDirect == "left":
x = self.x - 1
y = self.y
elif tmpDirect == "right":
x = self.x + 1
y = self.y
p = points[x][y]
if p.value > 0 and p != target:
continue
else :
direct = tmpDirect
if pre == None:
self.changed = 1
else:
if (pre.x - self.x) == 0 and (p.x - self.x) == 0:
self.changed = 0
else:
if (pre.y - self.y) == 0 and (p.y - self.y) == 0:
self.changed = 0
else :
self.changed = 1
break
return direct
def isChanged(self):
"""判斷方向變化
返回在該點前進時,是否帶來了方向的變化,即方向不同于原方向
"""
return self.changed
def __eq__(self,p):
if p == None :
return False
if self.x == p.x and self.y == p.y :
return True
else:
return False
points = list()
def createPoints(w,h):
"""構(gòu)造游戲界面的點
初始化界面中的所有的點,并且規(guī)則如下:
最外一層是“墻壁”點,接下來的一層是沒有被填充的點,被包裹的是填充的點
"""
r = random.randint
for x in range(w):
temp = list()
for y in range(h):
if x == 0 or x == (w-1) or y == 0 or y == (h-1):
temp.append(Point(x,y,9))
else:
if x == 1 or x == (w-2) or y == 1 or y == (h-2):
temp.append(Point(x,y,0))
else:
temp.append(Point(x,y,r(1,8)))
points.append(temp)
def link(source,target):
"""點的連接
連接方法的思想:針對源點的每個方向嘗試前進,如果可以前進,則將針對該方向上的下個點的每個方向嘗試前進
當一個點的可選方向都不能前進的時候,則返回到已有前進路徑中的前一個點,嘗試該點其他可選方向。當回源點
的每個方向都走不通或是路徑的方向變化等于4的時候,連接失敗返回False。否則當路徑連接到目標點而且路徑的方向變化小
于4的時候,連接成功返回路徑
"""
if source == target:
return False
path = list()
change = 0
current = source
while True:
if current==target and change < 4:
for p in path:
p.directs = None
return path
if change == 4:
current.directs = None
current = path.pop(len(path)-1)
change = change - current.isChanged()
continue
if change == 0:
direct = current.forward(None,target)
else:
direct = current.forward(path[len(path)-1],target)
if direct != None:
change = change + current.isChanged()
if direct == "up" :
x = current.x
y = current.y + 1
elif direct == "down":
x = current.x
y = current.y - 1
elif direct == "left":
x = current.x - 1
y = current.y
elif direct == "right":
x = current.x + 1
y = current.y
print x,y
path.append(current)
current = points[x][y]
else:
if change == 0:
return False
else:
current.directs = None
current = path.pop(len(path)-1)
change = change - current.isChanged()
createPoints(8,8)
p = link(points[2][2],points[5][2])
print p
相關(guān)文章
Python基于文件內(nèi)容實現(xiàn)查找文件功能
無論是Linux系統(tǒng)還是Windows系統(tǒng)都有基于文件名實現(xiàn)過濾、查找的功能。但是如果想要查找一些關(guān)于某些文件指定內(nèi)容的文件,好像它們明面上沒有這樣的功能了。這個時候就可以通過 Python 來實現(xiàn)這樣的功能,快跟隨小編一起學習一下吧2022-05-05python實現(xiàn)通過代理服務(wù)器訪問遠程url的方法
這篇文章主要介紹了python實現(xiàn)通過代理服務(wù)器訪問遠程url的方法,涉及Python使用urllib模塊操作URL的相關(guān)技巧,非常具有實用價值,需要的朋友可以參考下2015-04-04Python內(nèi)建數(shù)據(jù)結(jié)構(gòu)詳解
本文給大家匯總介紹了Python中的5種內(nèi)建數(shù)據(jù)結(jié)構(gòu)以及操作示例,非常的詳細,有需要的小伙伴可以參考下。2016-02-02