zoukankan      html  css  js  c++  java
  • 快手小游戏-两点之间 算法研究 python版

    快手小游戏中有一个游戏叫两点之间的,想要研究个算法能让程序自动计算出解决办法。

    基本思路就是使用dfs路径搜索,对每一类颜色求解所有的路径,直到填满为止。

    为了简化求解过程,我将图片转化为了6x6的矩阵,在代码中直接写了出来,0代表无颜色,1-5代表不同颜色。
    代码如下:

    import copy
    import datetime
    
    #6x6的矩阵
    myarr=[[0,0,0,0,3,2],
         [0,0,0,3,1,0],
         [1,0,0,0,0,0],
         [0,0,2,0,0,0],
         [0,4,5,0,0,5],
         [0,0,0,0,0,4]]
    #7x7的矩阵
    myarr=[[0, 2, 5, 0, 0, 0, 5],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 3, 2],
           [0, 0, 0, 0, 0, 0, 0],
           [3, 4, 1, 0, 0, 1, 4],
           [0, 0, 6, 0, 0, 0, 0],
           [6, 0, 0, 0, 0, 0, 0]]
    #8x8的矩阵
    myarr=[[3, 0, 0, 0, 0, 5, 0, 0],
           [0, 3, 0, 0, 1, 6, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0],
           [2, 0, 5, 0, 2, 0, 0, 0],
           [4, 0, 0, 0, 0, 0, 0, 6],
           [0, 0, 0, 4, 0, 0, 0, 7],
           [0, 0, 0, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 0, 7]]
    # myarr=[[1,1,2],
    #        [1,1,0],
    #        [1,1,2]]
    
    class dfs_solution():
    
        def __init__(self,arr):
            self.arr=arr
    
            #获取最大颜色种类
            self.maxtype=1
            for i in arr:
                for j in i:
                    if j>self.maxtype:
                        self.maxtype=j
            self.cols=len(arr[0])
            self.rows=len(arr)
            self.tempSteps=[]
            self.tempPaths=[]
            self.solutions=[]
        #找到当前类的起点和终点
        def findStart_end(self,className):
            point=[]
            for i in range(len(self.arr)):
                for j in range(len(self.arr[i])):
                    if self.arr[i][j]==className:
                        point.append([i,j])
            return  point[0],point[1]
    
        #获取可以走的下一个方块的坐标
        def getNextEle(self, now_row, now_col, className, endPoint):
            # 顺序是上,右,下,左边
            nextArr = []
            if now_row >= 1 and (self.arr[now_row - 1][now_col] == 0 or (
                    self.arr[now_row - 1][now_col] == className and [now_row - 1, now_col] == endPoint)):
                nextArr.append([now_row - 1, now_col])
            if now_col < self.cols - 1 and (self.arr[now_row][now_col + 1] == 0 or (
                    self.arr[now_row][now_col + 1] == className and [now_row, now_col + 1] == endPoint)):
                nextArr.append([now_row, now_col + 1])
            if now_row < self.rows - 1 and (self.arr[now_row + 1][now_col] == 0 or (
                    self.arr[now_row + 1][now_col] == className and [now_row + 1, now_col] == endPoint)):
                nextArr.append([now_row + 1, now_col])
            if now_col >= 1 and (self.arr[now_row][now_col - 1] == 0 or (
                    self.arr[now_row][now_col - 1] == className and [now_row, now_col - 1] == endPoint)):
                nextArr.append([now_row, now_col - 1])
            return nextArr
    
        #剪枝:如果结束点没有路径可以抵达,就返回False
        def jianzhi(self,endPoint):
            nextArr = []
            now_row=endPoint[0]
            now_col=endPoint[1]
            # temp=[]
            if now_row >= 1 and (self.arr[now_row - 1][now_col] == 0 or ([now_row - 1, now_col] == self.tempSteps[-1])):
                # temp.append([now_row - 1, now_col])
                return True
            if now_col < self.cols - 1 and (self.arr[now_row][now_col + 1] == 0 or ( [now_row, now_col + 1] == self.tempSteps[-1])):
                # temp.append([now_row, now_col + 1])
                return True
            if now_row < self.rows - 1 and (self.arr[now_row + 1][now_col] == 0 or ( [now_row + 1, now_col] == self.tempSteps[-1])):
                # temp.append([now_row + 1, now_col])
                return True
            if now_col >= 1 and (self.arr[now_row][now_col - 1] == 0 or ([now_row, now_col - 1] == self.tempSteps[-1])):
                # temp.append([now_row, now_col - 1])
                return True
            # if len(temp)>0:
            #     return True
            # else:
            #     return False
            return False
        #对剩下的所有起点和终点进行判断剪枝
        def jianzhiAll(self,num):
            result=True
            for i in range(num,self.maxtype+1):
                s,e=self.findStart_end(i)
                result=result and self.jianzhi(s) and self.jianzhi(e)
                if not result:
                    return False
            return result
    
        #迈步向下一个方块
        def step_to_next(self,num,start,end):
            nexts=self.getNextEle(self.tempSteps[-1][0],self.tempSteps[-1][1],num,end)
    
            for i in nexts:
                if i == end:
                    self.tempSteps.append(i)
                    self.tempPaths.append(copy.deepcopy(self.tempSteps))
                    self.tempSteps.pop()
                    continue
                self.arr[i[0]][i[1]]=num
                self.tempSteps.append(i)
                if self.jianzhi(end) and self.jianzhiAll(num+1):
                    self.step_to_next(num,start,end)
                else:
                    pass
                self.arr[i[0]][i[1]] = 0
                self.tempSteps.pop()
        #得到元素之间所有的路径走法
        def get_paths(self,num):
            self.tempPaths=[]
            start,end=self.findStart_end(num)
            self.tempSteps=[start]
            self.step_to_next(num,start,end)
            return copy.deepcopy(self.tempPaths)
    
        #填充
        def fillArr(self,paths,num):
            for i in paths[1:len(paths)-1]:
                self.arr[i[0]][i[1]]=num
        #去填充
        def unfillArr(self,paths,num):
            for i in paths[1:len(paths)-1]:
                self.arr[i[0]][i[1]]=0
    
        #判断是否完成
        def isFinished(self):
            for i in self.arr:
                if 0 in i:
                    return False
            return True
    
    
        #dfs求解所有种类的解
        def dfs(self,num):
            if self.isFinished() and num>self.maxtype:
                return True
            if num>self.maxtype:
                return False
    
            start,end = self.findStart_end(num)
            paths=self.get_paths(num)
            # print(len(paths))
            if len(paths)==0:
                return False
            for i in paths:
                self.fillArr(i,num)
                self.solutions.append(copy.deepcopy(i))
    
                # if i ==[[0, 1], [0, 0], [1, 0], [2, 0], [2, 1], [1, 1]]:
                # print(self.arr)
                if self.dfs(num+1):
                    return self.arr
                else:
                    # self.solutions.pop(copy.deepcopy(i))
                    self.unfillArr(i,num)
    
    
    
    starttime = datetime.datetime.now()
    s=dfs_solution(myarr)
    s.dfs(1)
    for i in s.arr:
        print(i)
    endtime = datetime.datetime.now()
    
    print((endtime - starttime).seconds)
    # print(len(s.solutions))

    虽然加了剪枝,但是效果还不是非常好。在计算6阶以下的时候速度很快,7阶的时候需要8秒,8阶的时候要569秒。以后想到了更好的办法会再更新。有人有更好的想法可以联系我,一起探讨哈哈。

    ===========================================================================================================================

  • 相关阅读:
    数制转换
    禁止用户复制网页的内容
    TdxDBTreeView的节点移动排序
    cxgrid根据字段设置颜色
    获取用户IP
    在sql server中用存储过程发送邮件
    Delphi的DTS编程
    使年份适用于做有浏览器(IE和FireFox)
    用Delphi写扬声器音乐
    过滤字符串中的HTML代码(VBScript)
  • 原文地址:https://www.cnblogs.com/NewsunLs/p/10715882.html
Copyright © 2011-2022 走看看