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

相关文章

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1