图算法相关文章是上个月写的,但是现在回过头看,确感觉有点生疏了。作为一名程序员,可能一辈子用别人封装好的算法模块,就足够了。工作中运用不到,虽然一时学习了,但久了就生疏了。所以,今天想在博客,与大家探讨下,我的目标不是要生硬的学习的什么牛逼算法,希望能够简单的展示、学习好玩的创意。
一、广度优先搜索的应用
1、连连看小游戏
玩过连连看游戏的都知道,都知道连连看的游戏规则,点击两个相同的图案,如果两个图形间存在一条路径,这条路径的拐弯少于3个,那么这两个图形可以消掉。这里我们可以通过广度优先搜索,来判断是否可以消掉。
图1 | ||||||
图2 | 图2 | 图2 | 图2 | 图2 | ||
图1 | 图2 | |||||
图2 |
如果情况如上图所示,两个图1可以相消
1.1、运用广度优先搜索来判断是否应该两个图形应该消掉?
广度优先搜索,可以获取两点的最短距离(最少边数),这里我们要取得最少拐弯数,所以我们可以对广度优先搜素算法,做一些改进。
首先我们回顾下广度优先搜索:
1、初始化,将所有点的距离设置为正无穷,父亲null
2、从出发点s出发,设置s的距离为0,父亲为NULL
3、将s插入最小堆que(距离最小的在最前面)
4、取que中距离最小的顶点v
5、搜索v相邻的顶点e,如果顶点e的距离 > d(v) + 1,那么顶点s到e的距离为d(v)+1,e的父亲为v,将e插入que
连连看相关修改
5、搜索v的相邻顶点e,如果顶点e的拐弯数 > guaiwan(v,e),那么顶点s到e的拐弯数为guaiwan(v,e),e的父亲为的v或者v的父亲,将e插入que
1.2 游戏代码(用cocos2d实现的游戏,算法部分比较乱,大家见谅)
'''
Created on 2013-1-7
@author: wolf
'''
#!/usr/bin/python
# -*- coding: utf-8 -*-
#coding=utf-8
#this linkgame body
import cocos
from cocos.director import director
import pyglet
from pyglet.gl import *
#backgroud x = 601 y = 801
class BackGroudLayer(cocos.layer.Layer):
def __init__(self):
super(BackGroudLayer,self).__init__()
self.img = pyglet.resource.image('background.png')
def draw(self):
#the back is black
glClearColor(1,1,1,0)
glColor3f(1.0,1, 1);
glPushMatrix()
self.transform()
self.img.blit(0,0)
glPopMatrix()
#X
COLUMNS=15
#Y
ROWS=28
#square size
SQUARE_SIZE = 29
'''
draw thr grid
'''
class gridLayer(cocos.layer.Layer):
def __init__(self):
super(gridLayer,self).__init__()
width, height = director.get_window_size()
self.xOffset = width/2.0 - COLUMNS * SQUARE_SIZE / 2.0
self.yOffset = 0
self.position = (self.xOffset, self.yOffset )
clayer = cocos.layer.ColorLayer( 112,66,20,50, width = COLUMNS * SQUARE_SIZE, height=ROWS * SQUARE_SIZE )
self.add( clayer, z= 0)
def draw(self):
super( gridLayer, self).draw()
glLineWidth (GLfloat(1.0));
glColor3f(0.5,0.5,1 );
x_s = self.xOffset
y_s = 0
width = COLUMNS * SQUARE_SIZE
height=ROWS * SQUARE_SIZE
for i in range(COLUMNS+1):
glBegin(GL_LINE_LOOP);
glVertex2f(x_s,height)
glVertex2f(x_s,0)
glEnd()
x_s = x_s + SQUARE_SIZE
for i in range(ROWS + 1):
glBegin(GL_LINE_LOOP);
glVertex2f(self.xOffset+width ,y_s)
glVertex2f(self.xOffset,y_s)
y_s = y_s + SQUARE_SIZE
glEnd()
return
class lattice:
pX = None
pY = None
parent = None
scores = 100
def __init__(self,gId,i,j,sp):
self.gId = gId
self.pX = i
self.pY = j
self.sp = sp
def printss(self):
print '%s\t%s\t%s' % (self.pX,self.pY,self.gId)
def latCmp(lat1,lat2):
return lat1.scores < lat2.scores
class gameLayer(cocos.layer.Layer):
is_event_handler = True
def __init__(self):
super(gameLayer,self).__init__()
self.borad = []
for i in range(COLUMNS):
t = []
for j in range(ROWS):
t.append(lattice(None,i,j,None))
self.borad.append(t)
self.times = 0
self.sp_name = ["block_blue.png","block_cyan.png","block_magenta.png"]
width, height = director.get_window_size()
self.xOffset = width/2.0 - COLUMNS * SQUARE_SIZE / 2.0
self.yOffset = 0
self.last_press = [None,None]
self.now_press = [None,None]
def on_mouse_press(self, x, y, buttons, modifiers):
px,py = director.get_virtual_coordinates (x, y)
num = self.times % 3
self.times = self.times + 1
x_n =(int) (px - self.xOffset) / SQUARE_SIZE
y_n =(int) (py - self.yOffset ) / SQUARE_SIZE
if x_n < 0 or x_n >= COLUMNS:
return
if y_n < 0 or y_n >= ROWS:
return
if self.borad[x_n][y_n].sp != None:
self.BSF_DISK(x_n,y_n)
return
newPng = cocos.sprite.Sprite(self.sp_name[num])
newPng.position = self.xOffset + (x_n+0.5)*SQUARE_SIZE ,self.yOffset + (y_n+0.5) * SQUARE_SIZE
self.borad[x_n][y_n].sp = newPng
self.borad[x_n][y_n].gId = num
self.add(newPng,z=0)
def draw1(self,x_n,y_n,num = 0):
newPng = cocos.sprite.Sprite(self.sp_name[num])
newPng.position = self.xOffset + (x_n+0.5)*SQUARE_SIZE ,self.yOffset + (y_n+0.5) * SQUARE_SIZE
self.add(newPng,z=0)
def BSF_DISK(self,x,y):
if self.last_press[0] != None:
self.now_press[0] = x
self.now_press[1] = y
else:
self.last_press[0] = x
self.last_press[1] = y
if self.last_press[0] != None and self.now_press[0] != None:
now = self.borad[self.now_press[0]][self.now_press[1]]
last = self.borad[self.last_press[0]][self.last_press[1]]
print now.printss()
print last.printss()
self.BFS_Lat(last,now)
self.last_press = [None,None]
self.now_press = [None,None]
return
def BFS_Lat(self,lat1,lat2):
if lat1.pX == lat2.pX and lat1.pY == lat2.pY or lat1.gId != lat2.gId :
return -1
for item1 in self.borad:
for item2 in item1:
item2.parent = None
item2.scores = 100
que = [lat1]
lat1.parent = lat1
lat1.scores = 0
#print "BFS_Lat***********************************1"
while len(que):
que.sort(latCmp)
item = que[0]
if item.scores > 2:
break
que = que[1:]
#print "BFS_Lat***********************************2"
for x,y in [(item.pX,item.pY+1),(item.pX,item.pY-1),
(item.pX+1,item.pY),(item.pX-1,item.pY)]:
if x >= COLUMNS or x < 0 or y >= ROWS or y < 0:
continue
newLat = self.borad[x][y]
if newLat.parent == item.parent:
continue
if newLat.gId != None and (newLat.pX == lat2.pX and newLat.pY == lat2.pY) != True:
continue
newLat.printss()
#print "BFS_Lat***********************************3"
if item.parent.pX == newLat.pX and newLat.pX == item.pX:
#print "BFS_Lat BFS***************************2"
self.BFS(que,newLat,"x",item.scores,item.parent,lat2)
elif item.parent.pY == newLat.pY and newLat.pY == item.pY:
#print "BFS_Lat BFS***************************3"
self.BFS(que,newLat,"y",item.scores,item.parent,lat2)
else:
if newLat.scores == None or newLat.scores > item.scores + 1:
newLat.scores = item.scores + 1
newLat.parent = item
que.append(newLat)
#self.draw1(x,y,num=1)
#print "BFS_Lat***********************************4"
if self.borad[lat2.pX][lat2.pY].scores < 3:
break
#print "BFS_Lat***********************************5"
#break
if self.borad[lat2.pX][lat2.pY].scores < 3:
break
if self.borad[lat2.pX][lat2.pY].scores < 3:
#print "BFS_Lat***********************************6"
self.borad[lat2.pX][lat2.pY].gId = None
self.borad[lat1.pX][lat1.pY].gId = None
self.remove(lat1.sp)
self.remove(lat2.sp)
lat1.sp = None
lat2.sp = None
#print "BFS_Lat***********************************7"
return
def BFS(self,que,lat,direction,socres,p,lat2):
if direction == "x":
if lat.pY < p.pY:
y = lat.pY
while y >= 0:
if self.borad[p.pX][y].gId != None and (p.pX == lat2.pX and y == lat2.pY) != True:
y = y - 1
return
if self.borad[p.pX][y].scores == None or self.borad[p.pX][y].scores > socres:
self.borad[p.pX][y].scores = socres
self.borad[p.pX][y].parent = p
que.append(self.borad[p.pX][y])
#self.draw1(p.pX,y)
y = y - 1
else:
y = lat.pY
while y < ROWS:
if self.borad[p.pX][y].gId != None and (p.pX == lat2.pX and y == lat2.pY) != True:
y = y + 1
return
if self.borad[p.pX][y].scores == None or self.borad[p.pX][y].scores > socres:
self.borad[p.pX][y].scores = socres
self.borad[p.pX][y].parent = p
que.append(self.borad[p.pX][y])
#self.draw1(p.pX,y)
y = y + 1
elif direction == "y":
if lat.pX < p.pX:
x = lat.pX
while x >= 0:
if self.borad[x][p.pY].gId != None and (x == lat2.pX and p.pY == lat2.pY) != True:
x = x - 1
return
if self.borad[x][p.pY].scores == None or self.borad[x][p.pY].scores > socres:
self.borad[x][p.pY].scores = socres
self.borad[x][p.pY].parent = p
que.append(self.borad[x][p.pY])
#self.draw1(x, p.pY)
x = x - 1
else:
x = lat.pX
while x < COLUMNS:
if self.borad[x][p.pY].gId != None and (x == lat2.pX and p.pY == lat2.pY) != True:
x = x + 1
return
if self.borad[x][p.pY].scores == None or self.borad[x][p.pY].scores > socres:
self.borad[x][p.pY].scores = socres
self.borad[x][p.pY].parent = p
que.append(self.borad[x][p.pY])
#self.draw1(x, p.pY)
x = x + 1
def main():
from cocos.director import director
#the init height is the size of BackGroudLayer
director.init(resizable=True, width=600, height=720)
scene = cocos.scene.Scene(BackGroudLayer())
scene.add(gridLayer(),z=1)
scene.add(gameLayer(),z= 2)
director.run(scene)
if __name__ == "__main__":
main()