python华容道最短路径_Python方法生成华容道所有开局

2024-02-18 15:30

本文主要是介绍python华容道最短路径_Python方法生成华容道所有开局,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

玩蛇网本文是关于Python语言解决游戏算法的相关文章。Python方法生成华容道所有求解的开局,其中含镜像263977种,不含镜像132156种。

e43190099429d78acfc194edbf5575d6.png

华容道所有开局求解的思路是:

1. 生成所有终局

2. 广度优先推出所有开局,形成一个树

3. 树中所有的节点都是开局,可以根据Level进行排序

#! /usr/bin/env python

# -*- coding: utf-8 -*-

#-----------www.iplaypy.com----------------------------

# Definitions

# B(4): Box, 2x2

# V(2): Vertical Bar, 1x2

# H(3): Horizontal Bar, 2x1

# D(1): Dot, 1x1

# E(0): the empty 1x1(or space)

# U(7): undefined, or (?)

Empty,Dot,Vbar,Hbar,Box,Undef = 0,1,2,3,4,7

row, col = 5, 4

#---------------------------------------------------------------

# Generates all the valid end matrix

#

C72 = ((0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6),

(1, 2), (1, 3), (1, 4), (1, 5), (1, 6),

(2, 3), (2, 4), (2, 5), (2, 6),

(3, 4), (3, 5), (3, 6),

(4, 5), (4, 6),

(5, 6))

#Possible endings(mirror ending is not included)

# Ending 1: ???? Ending 2: ????

# ???? ????

# ???? ?EE?

# EBB? ?BB?

# EBB? ?BB?

endings = ([7,7,7,7, 7,7,7,7, 7,7,7,7, 0,4,4,7, 0,4,4,7],

[7,7,7,7, 7,7,7,7, 7,0,0,7, 7,4,4,7, 7,4,4,7])

def print_matrix(m):

for i in range(5):

for j in range(4):

print m[4*i + j],

print

print

def all_ending_layouts():

"""Check all possible configurations when CaoCao is at the exit."""

values = {}

for end in endings:

#14 undefined cells, red & black, select 4, 2 red & 2 black

slot = [i for i in range(20) if Undef == end[i]]

red = [slot[i] for i in range(14) if (slot[i] % col + slot[i] / col) % 2 == 0]

black = [slot[i] for i in range(14) if (slot[i] % col + slot[i] / col) % 2]

# 21 = C(7,2)

for c1 in C72:

for c2 in C72:

matrix = end[:]

matrix[red[c1[0]]] = Dot

matrix[red[c1[1]]] = Dot

matrix[black[c2[0]]] = Dot

matrix[black[c2[1]]] = Dot

for layout in tile(matrix):

value = 0L

for t in layout:

value = value << 3 | t

if not values.has_key(value):

rvalue = 0L

for i in range(5):

for j in range(4):

rvalue = rvalue << 3 | layout[i*4 + 4-j-1]

values[value] = True

values[rvalue] = True

yield layout

def is_neighbor(slot, i, j):

xi, yi = slot[i] % col, slot[i] / col

xj, yj = slot[j] % col, slot[j] / col

if xj==xi and yj==yi+1:

return 2

if xj==xi+1 and yj==yi:

return 3

return 0

def tile(matrix):

"""return the valid layout to tile five 1x2/2x1 in 10 slots"""

matrix_list = [matrix]

index = 0

while index < len(matrix_list):

matrix = matrix_list[index]

slot = [i for i in range(20) if Undef == matrix[i]]

n = len(slot)

if n == 0:

return matrix_list[index:]

#for each undefined block, look up its adjacent undefined block's

p = [[] for i in range(n)]

min_p, k = n, -1

for i in range(n):

for j in range(i+1, n):

ret = is_neighbor(slot, i, j)

if ret:

p[i].append((j, ret))

p[j].append((i, ret))

if not p[i]:

k = -1

break #an isolated block is detected

if len(p[i]) < min_p:

min_p, k = len(p[i]), i

if k != -1:

#start with the position with the least adjacent undefined slots, enumerate all

# possible configurations after filling this position

for neighbor in p[k]:

new_matrix = matrix[:]

new_matrix[slot[k]] = neighbor[1]

new_matrix[slot[neighbor[0]]] = neighbor[1]

matrix_list.append(new_matrix)

#process next matrix

index += 1

return []

#---------------------------------------------------------------

# spawn all the layouts to be solved

#convert 4*5 DHVB into block layouts(totally 10 blocks)

def convert(matrix):

b = [0, 0, 0, 0]

c,d = 0,0

result = []

for i in range(20):

x = i % 4

y = i / 4

n = matrix[i]

if n == Dot:

result += [1, x, y]

elif n == Vbar:

if y == 0 or b[x] == 0:

b[x] = 2

result += [2, x, y]

else:

b[x] = 0

elif n == Hbar:

if c == 0:

result += [3, x, y]

c = 3

else:

c = 0

elif n == Box:

if d % 4 == 0:

result += [4, x, y]

d = 1

else:

d += 1

return result

from copy import deepcopy

class Board:

def __init__(self, layout):

#the moved index to generate this board

self.moved = -1

#init the matrix and items

self.items = [()] * 10 #BIT:type:3,x:2,y:3), x,y is zero-based

self.empty = [(0,0), (0,0)] #2 empty slot's position in matrix, (col, row)

#-1 mean's boundary

f = -1

#[1+5+1][1+4+1] of byte, each byte is the (index+1) in items

# the extra 1s is for the boundary

self.matrix = [ [f, f, f, f, f, f],

[f, 0, 0, 0, 0, f],

[f, 0, 0, 0, 0, f],

[f, 0, 0, 0, 0, f],

[f, 0, 0, 0, 0, f],

[f, 0, 0, 0, 0, f],

[f, f, f, f, f, f] ]

#calculate the items into cell-matrix

type, x, y = 0, 0, 0

for i in range(10):

type = layout[i*3]

x = layout[i*3+1]

y = layout[i*3+2]

self.items[i] = (type, x, y)

self.matrix[y+1][x+1] = i+1

if type == Vbar:

self.matrix[y+2][x+1] = i+1

elif type == Hbar:

self.matrix[y+1][x+2] = i+1

elif type == Box:

self.matrix[y+1][x+2] = i+1

self.matrix[y+2][x+1] = i+1

self.matrix[y+2][x+2] = i+1

#find out the empty blocks

count = 0

for i in range(7):

for j in range(6):

if not self.matrix[i][j]:

self.empty[count] = (j, i)

if not count: count += 1

else: return

def getValue(self):

val, bt = 0L, 0

for i in range(1, 6):

for k in range(1, 5):

index = self.matrix[i][k] - 1

if index < 0: bt = 0

else: bt = self.items[index][0]

val = val << 3 | bt

return val

def getRValue(self):

val, bt = 0L, 0

for i in range(1, 6):

for k in range(4, 0, -1):

index = self.matrix[i][k] - 1

if index < 0: bt = 0

else: bt = self.items[index][0]

val = val << 3 | bt

return val

#spawn new Board by moving the cells around empty cells

# changes global variable: g_values

def spawn(self):

global g_values

new_boards = []

#collect the cells around empty cells

around = [0] * 8

#DO NOT change the order of ulrd, it's been depended

# ulrd: Up/Left/Right/Down

ulrd = ((0,-1), (-1,0), (1,0), (0,1))

for e in self.empty: #two empty blocks, always 2

x, y = e

for k in range(4):

dir = ulrd[k]

nx = x + dir[0]

ny = y + dir[1]

1c40

index = self.matrix[ny][nx] - 1

if index >= 0:

newb = deepcopy(self)

newb.moved = index

if newb.tryAndMove(index, -dir[0], -dir[1]):

value = newb.getValue()

if not g_values.has_key(value):

if len(g_values) % 1000 == 0:

print len(g_values)

rvalue = newb.getRValue()

g_values[value] = rvalue

g_values[rvalue] = value

new_boards.append(newb)

return new_boards

def tryAndMove(self, index, dx, dy):

item = self.items[index]

type, x, y = item

ret = False

#ci is short for cell index

ci1 = ci2 = ci3 = ci4 = 0

if type == Dot:

ci1 = self.matrix[y+dy+1][x+dx+1]

ret = not ci1 or ci1 == index+1

if ret:

self.matrix[y+1][x+1] = 0

self.matrix[y+dy+1][x+dx+1] = index + 1

self.items[index] = (type, x+dx, y+dy)

self.setEmpty(x+1, y+1)

elif type == Vbar:

ci1 = self.matrix[y+dy+1][x+dx+1]

ci2 = self.matrix[y+dy+2][x+dx+1]

ret = (not ci1 or ci1==index+1) and (not ci2 or ci2==index+1)

if ret:

self.matrix[y+1][x+1] = 0

self.matrix[y+2][x+1] = 0

self.matrix[y+dy+1][x+dx+1] = index + 1

self.matrix[y+dy+2][x+dx+1] = index + 1

self.items[index] = (type, x+dx, y+dy)

if self.matrix[y+1][x+1] == 0: self.setEmpty(x+1, y+1)

if self.matrix[y+2][x+1] == 0: self.setEmpty(x+1, y+2)

elif type == Hbar:

ci1 = self.matrix[y+dy+1][x+dx+1]

ci2 = self.matrix[y+dy+1][x+dx+2]

ret = (not ci1 or ci1==index+1) and (not ci2 or ci2==index+1)

if ret:

self.matrix[y+1][x+1] = 0

self.matrix[y+1][x+2] = 0

self.matrix[y+dy+1][x+dx+1] = index + 1

self.matrix[y+dy+1][x+dx+2] = index + 1

self.items[index] = (type, x+dx, y+dy)

if self.matrix[y+1][x+1] == 0: self.setEmpty(x+1, y+1)

if self.matrix[y+1][x+2] == 0: self.setEmpty(x+2, y+1)

elif type == Box:

ci1 = self.matrix[y+dy+1][x+dx+1]

ci2 = self.matrix[y+dy+1][x+dx+2]

ci3 = self.matrix[y+dy+2][x+dx+1]

ci4 = self.matrix[y+dy+2][x+dx+2]

ret = (not ci1 or ci1==index+1) and (not ci2 or ci2==index+1) and \

(not ci3 or ci3==index+1) and (not ci4 or ci4==index+1)

if ret:

self.matrix[y+1][x+1] = 0

self.matrix[y+1][x+2] = 0

self.matrix[y+2][x+1] = 0

self.matrix[y+2][x+2] = 0

self.matrix[y+dy+1][x+dx+1] = index+1

self.matrix[y+dy+1][x+dx+2] = index+1

self.matrix[y+dy+2][x+dx+1] = index+1

self.matrix[y+dy+2][x+dx+2] = index+1

self.items[index] = (type, x+dx, y+dy)

if self.matrix[y+1][x+1] == 0: self.setEmpty(x+1, y+1)

if self.matrix[y+1][x+2] == 0: self.setEmpty(x+2, y+1)

if self.matrix[y+2][x+1] == 0: self.setEmpty(x+1, y+2)

if self.matrix[y+2][x+2] == 0: self.setEmpty(x+2, y+2)

return ret

def setEmpty(self, ex, ey):

x, y = self.empty[0]

if (self.matrix[y][x]):

self.empty[0] = (ex, ey)

else:

self.empty[1] = (ex, ey)

#-----------------------------------------

#global variables

#all end matrix

#all non-end matrix

#values for all end and non-end matrix

g_values = {}

#print ending count

end_count = 0

for matrix in all_ending_layouts():

end_count += 1

#check if this board has been touched

value = 0L

for t in matrix:

value = value << 3 | t

if g_values.has_key(value):

continue

rvalue = 0L

for i in range(5):

for j in range(4):

rvalue = rvalue << 3 | matrix[i*4 + 4-j-1]

layout = convert(matrix)

g_values[value] = rvalue

g_values[rvalue] = value

#start spawn

board = Board(layout)

board_pool = [board]

index = 0

while index < len(board_pool):

board_pool += board_pool[index].spawn()

index += 1

print len(g_values)

print "Total Endings count:", end_count

print "Total Layouts count:", len(g_values)

def solve_all_layouts():

g_nondups = {}

count = 0

from os import popen

outfile = open("input.log", "w+")

for value in g_values:

if count % 1000 == 0:

print count

if g_nondups.has_key(value):

continue

count += 1

rvalue = g_values[value]

g_nondups[value] = True

g_nondups[rvalue] = True

matrix = [0] * 20

val = value

for i in range(20):

matrix[20-i-1] = val & 7

val = val >> 3

layout = convert(matrix)

layout_str = "".join([str(i) for i in layout])

print >>outfile, layout_str, value, rvalue, layout

return count

count = solve_all_layouts()

print "Total Layouts count(no mirror):", count

print "Everything is over, see result.log for detailed result"

玩蛇网文章,转载请注明出处和文章网址:https://www.iplaypy.com/code/game/g2611.html

相关文章 Recommend

这篇关于python华容道最短路径_Python方法生成华容道所有开局的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/721600

相关文章

SQL Server配置管理器无法打开的四种解决方法

《SQLServer配置管理器无法打开的四种解决方法》本文总结了SQLServer配置管理器无法打开的四种解决方法,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录方法一:桌面图标进入方法二:运行窗口进入检查版本号对照表php方法三:查找文件路径方法四:检查 S

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文

golang中reflect包的常用方法

《golang中reflect包的常用方法》Go反射reflect包提供类型和值方法,用于获取类型信息、访问字段、调用方法等,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值... 目录reflect包方法总结类型 (Type) 方法值 (Value) 方法reflect包方法总结

Python设置Cookie永不超时的详细指南

《Python设置Cookie永不超时的详细指南》Cookie是一种存储在用户浏览器中的小型数据片段,用于记录用户的登录状态、偏好设置等信息,下面小编就来和大家详细讲讲Python如何设置Cookie... 目录一、Cookie的作用与重要性二、Cookie过期的原因三、实现Cookie永不超时的方法(一)

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优