图的应用---知行合一,连连看小游戏

图算法相关文章是上个月写的,但是现在回过头看,确感觉有点生疏了。作为一名程序员,可能一辈子用别人封装好的算法模块,就足够了。工作中运用不到,虽然一时学习了,但久了就生疏了。所以,今天想在博客,与大家探讨下,我的目标不是要生硬的学习的什么牛逼算法,希望能够简单的展示、学习好玩的创意。

一、广度优先搜索的应用

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()




你可能感兴趣的:(图的应用---知行合一,连连看小游戏)