Python方法生成华容道所有开局,python华容道开局,编橙之家本文是关于Pyt
Python方法生成华容道所有开局,python华容道开局,编橙之家本文是关于Pyt
编橙之家本文是关于Python语言解决游戏算法的相关文章。Python方法生成华容道所有求解的开局,其中含镜像263977种,不含镜像132156种。
华容道所有开局求解的思路是:
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,7row, 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 printdef 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 layoutdef 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 0def 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 resultfrom copy import deepcopyclass 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 matrixg_values = {}#print ending countend_count = 0for 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_countprint "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 countcount = solve_all_layouts()print "Total Layouts count(no mirror):", countprint "Everything is over, see result.log for detailed result"
编橙之家文章,
相关内容
- world统计用python实现的方法,worldpython,python实现统计w
- 用Python语言打印杨辉三角形方法示例,python杨辉,下面这
- python猜数字游戏快速求解解决方案,python猜数字求解
- python计算文字的Md5和Sha1的校验值,,Python完成计算文字
- Python方法完成农历日历功能代码,python农历,Python方法完
- Python编写的点灯小游戏代码,python点灯小游戏,Python语言
- 日期查询软件python源代码,日期查询python,用python语言编
- Python 完成IE调用的示例源码分享,python示例,Python 完成
- Python是如何完成数据导入的,python完成数据导入,想知道
- 一个简易的Python封装的FTP功能,python封装ftp,这是一个简
评论关闭