发布时间:2025-06-24 20:46:44  作者:北方职教升学中心  阅读量:608


代码分享

代码中一共4个.py文件,一个迷宫形状配置文件,如下:

1、走迷宫模拟软件中已实现功能

1、绪论

1、点击迷宫墙壁可编辑迷宫,并且可保存和加载迷宫形状文件;

2、maze.py

import numpy as npfrom tkinter import filedialogclass Maze(object):    def __init__(self, cv, windows_h, bd, win, map_size=32):        self.map_size = map_size        self.cv = cv        self.bd = bd        self.win = win        self.up = 0        self.down = 1        self.left = 2        self.right = 3        self.maze_map = np.ones((map_size, map_size, 4), dtype='int8')  # h/y, w/x, wall/up,down,left,right        self.cell_len = int((windows_h-2*self.bd)/map_size)        self.line_hand = []        self.win_point = None    def draw_win_point(self):        # clear win point        if self.win_point is not None:            self.cv.delete(self.win_point)        # draw win point        w, h = self.win        x, y = (w+0.5)*self.cell_len+self.bd, (h+0.5)*self.cell_len+self.bd        rate = self.cell_len/3        x0, y0 = x - rate, y - rate        x1, y1 = x + rate, y + rate        self.win_point = self.cv.create_oval(x0, y0, x1, y1, fill='red')    def draw_maze(self):        # clear maze        for tag in self.line_hand:            self.cv.delete(tag)        # draw maze        for h in range(self.map_size):            for w in range(self.map_size):                for index in range(4):                    # up and down for wall                    if index in [self.up, self.down]:                        x0, y0 = w*self.cell_len+self.bd, (h+index)*self.cell_len+self.bd                        x1, y1 = (w+1)*self.cell_len+self.bd, (h+index)*self.cell_len+self.bd                    # left and right for wall                    else:                        x0, y0 = (w+index-2)*self.cell_len+self.bd, h*self.cell_len+self.bd                        x1, y1 = (w+index-2)*self.cell_len+self.bd, (h+1)*self.cell_len+self.bd                    # no line draw white line                    if self.maze_map[h, w, index] == 1:                        color = 'black'                    else:                        color = 'Gainsboro'                    # draw line                    self.line_hand.append(self.cv.create_line(x0, y0, x1, y1, width=2, fill=color))                    self.cv.tag_bind(self.line_hand[-1], '<Button-1>', lambda event, c=[h, w, index]: self.change_cell(c))    def change_cell(self, c):        # click to hide or show line        h, w, index = c        # edge wall        if h == 0 and index == self.up:            return        if w == 0 and index == self.left:            return        # up wall        if index == self.up:            # deal clicked line            if self.maze_map[h, w, self.up] == 1:                self.maze_map[h, w, self.up] = 0            else:                self.maze_map[h, w, self.up] = 1            # deal adjoin line            if h-1 >= 0:                if self.maze_map[h, w, self.up] == 0:                    self.maze_map[h - 1, w, self.down] = 0                else:                    self.maze_map[h - 1, w, self.down] = 1        # left wall        if index == self.left:            # deal clicked line            if self.maze_map[h, w, self.left] == 1:                self.maze_map[h, w, self.left] = 0            else:                self.maze_map[h, w, self.left] = 1            # deal adjoin line            if w-1 >= 0:                if self.maze_map[h, w, self.left] == 0:                    self.maze_map[h, w - 1, self.right] = 0                else:                    self.maze_map[h, w - 1, self.right] = 1        self.draw_maze()    def save_maze(self):        fileSave = filedialog.asksaveasfilename(defaultextension='.txt', filetypes=[("txt files", ".txt")])        np.savetxt(fileSave, self.maze_map.reshape((1, self.map_size*self.map_size*4)), fmt='%d')    def load_maze(self):        filePath = filedialog.askopenfilename()        self.maze_map = np.loadtxt(filePath).reshape((self.map_size, self.map_size, 4))        self.draw_maze()    def get_maze_map(self):        return self.maze_map.copy()

4、

2、自动搜索迷宫,采用回溯算法搜索整个迷宫;

3、考验参赛选手软硬件结合的能力。简介

电脑鼠走迷宫是一种比赛,制作实物电脑鼠小车在迷宫找目标点,用时最短者获胜。软件截图

打开迷宫形状配置文件

点击迷宫墙壁编辑迷宫形状

搜索迷宫

搜索迷宫

搜索迷宫,并且回溯未到过的地方

搜索结束,找到最短距离的路径

三、main.py

import tkinter as tkimport maze as mazeimport micromouse as micromouseroot = tk.Tk()windows_w = 640*2+100windows_h = 640bd = 10map_size = 32win = [15, 15]root.title("MicroMouse")root.geometry("{}x{}".format(windows_w, windows_h))cv = tk.Canvas(root, width=windows_h*2, height=windows_h, bg='white')cv.place(x=0, y=0)mz = maze.Maze(cv, windows_h, bd, win, map_size)mz.draw_maze()mz.draw_win_point()mouse = micromouse.MicroMouse(cv, mz.cell_len, bd, win, windows_h, map_size)mouse.draw_mouse(0, 0)mouse.draw_win_oval()mouse.draw_search_maze()save = tk.Button(root, text='保存迷宫', command=mz.save_maze, height=1, width=8)save.place(x=windows_h*2+20, y=10)open = tk.Button(root, text='加载迷宫', command=mz.load_maze, height=1, width=8)open.place(x=windows_h*2+20, y=50)search = tk.Button(root, text='探索迷宫', command=lambda mz=mz: mouse.search_maze(mz), height=1, width=8)search.place(x=windows_h*2+20, y=90)setmouse = tk.Button(root, text='重置电脑鼠', command=mouse.reset_mouse, height=1, width=8)setmouse.place(x=windows_h*2+20, y=130)root.mainloop()

2、采用洪水算法查找迷宫的最短路径。tree.py

class Tree(object):    def __init__(self):        self.last_tree = None        self.next_tree = None        self.h = None        self.w = None

3、

一、micromouse.py

import numpy as npimport tree as treeclass MicroMouse(object):    def __init__(self, cv, cell_len, bd, win, offset, map_size=32):        self.cv = cv        self.map_size = map_size        self.cell_len = cell_len        self.bd = bd        self.win = win        self.offset = offset        self.after_id = None        self.current_h = 0        self.current_w = 0        self.up = 0        self.down = 1        self.left = 2        self.right = 3        self.current_dir = self.right        self.search_map = np.zeros((map_size, map_size, 4), dtype='int8')  # h/y, w/x, wall/up,down,left,right        self.after_cancel = False        # hand        self.maze_map = None        self.mouse_hand = None        self.win_oval = None        self.line_hand = []        self.shortest_line_hane = []        # search record        self.searched_list = []   # [h/y, w/x]        self.branch_list = []     # [h, w, dir]    def draw_win_oval(self):        # clear win point        if self.win_oval is not None:            self.cv.delete(self.win_oval)        # draw win point        w, h = self.win        x, y = (w + 0.5) * self.cell_len + 3 * self.bd + self.offset, (h + 0.5) * self.cell_len + self.bd        rate = self.cell_len / 3        x0, y0 = x - rate, y - rate        x1, y1 = x + rate, y + rate        self.win_oval = self.cv.create_oval(x0, y0, x1, y1, fill='red')    def draw_shortest_line(self, path):        # clear win point        for hane in self.shortest_line_hane:            self.cv.delete(hane)        # draw win point        for point in path:            h, w = point            x, y = (w + 0.5) * self.cell_len + 3 * self.bd + self.offset, (h + 0.5) * self.cell_len + self.bd            rate = self.cell_len / 5            x0, y0 = x - rate, y - rate            x1, y1 = x + rate, y + rate            self.shortest_line_hane.append(self.cv.create_oval(x0, y0, x1, y1, fill='red'))    def draw_mouse(self, w, h):        """画电脑鼠"""        if self.mouse_hand is not None:            self.cv.delete(self.mouse_hand)        x, y = (w + 0.5) * self.cell_len + 3 * self.bd + self.offset, (h + 0.5) * self.cell_len + self.bd        rate = self.cell_len / 3        # up        if self.current_dir == self.up:            x0, y0 = x - rate, y + rate            x1, y1 = x + rate, y + rate            x2, y2 = x, y - rate        # down        elif self.current_dir == self.down:            x0, y0 = x - rate, y - rate            x1, y1 = x + rate, y - rate            x2, y2 = x, y + rate        # left        elif self.current_dir == self.left:            x0, y0 = x + rate, y - rate            x1, y1 = x + rate, y + rate            x2, y2 = x - rate, y        # right        else:            x0, y0 = x - rate, y - rate            x1, y1 = x - rate, y + rate            x2, y2 = x + rate, y        self.mouse_hand = self.cv.create_polygon(x0, y0, x1, y1, x2, y2, fill='red')    def draw_search_maze(self):        # clear maze        for tag in self.line_hand:            self.cv.delete(tag)        # draw maze        for h in range(self.map_size):            for w in range(self.map_size):                for index in range(4):                    # up and down for wall                    if index in [self.up, self.down]:                        x0 = w * self.cell_len + 3 * self.bd + self.offset                        y0 = (h + index) * self.cell_len + self.bd                        x1 = (w + 1) * self.cell_len + 3 * self.bd + self.offset                        y1 = (h + index) * self.cell_len + self.bd                    # left and right for wall                    else:                        x0 = (w + index - 2) * self.cell_len + 3 * self.bd + self.offset                        y0 = h * self.cell_len + self.bd                        x1 = (w + index - 2) * self.cell_len + 3 * self.bd + self.offset                        y1 = (h + 1) * self.cell_len + self.bd                    # no line draw white line                    if self.search_map[h, w, index] == 1:                        color = 'black'                    else:                        color = 'white'                    # draw line                    self.line_hand.append(self.cv.create_line(x0, y0, x1, y1, width=2, fill=color))    def search_maze(self, mz):        """search maze, get maze information"""        self.maze_map = mz.get_maze_map()        self.after_cancel = True        self.by_step()    def by_step(self):        """search maze by step"""        if self.after_cancel:            # update search map, (maze's forward right left)            point_info = self.update_search_map()            # redraw search maze and win point            self.draw_search_maze()            self.draw_mouse(self.current_w, self.current_h)            self.cv.update()            # check forward and walk a step, do not walk back            self.step_search_maze(point_info)        # next step        self.cv.after(1000, func=self.by_step())    def step_search_maze(self, point_info):        # mouse search maze        # find exit point        # if self.current_h == self.win[0] and self.current_w == self.win[1]:        #     return        # can choise dir        # up        if self.current_dir == self.up:            point_info[self.down] = -1        # down        elif self.current_dir == self.down:            point_info[self.up] = -1        # left        elif self.current_dir == self.left:            point_info[self.right] = -1        # right        elif self.current_dir == self.right:            point_info[self.left] = -1        ccd = np.where(point_info==0)[-1]        ccd_len = len(ccd)        finded = False        # have dir to go        if ccd_len > 0:            for dir_ in range(ccd_len):                dir = ccd[dir_]                # up                if dir == self.up:                    # not searched                    if [self.current_h-1, self.current_w] not in self.searched_list:                        # search first dir, other append to branch list                        if not finded:                            h, w, d = self.current_h-1, self.current_w, dir                            finded = True                        else:                            self.branch_list.append([self.current_h, self.current_w, dir])                # down                elif dir == self.down:                    # not searched                    if [self.current_h+1, self.current_w] not in self.searched_list:                        # search first dir, other append to branch list                        if not finded:                            h, w, d = self.current_h+1, self.current_w, dir                            finded = True                        else:                            self.branch_list.append([self.current_h, self.current_w, dir])                # left                elif dir == self.left:                    # not searched                    if [self.current_h, self.current_w-1] not in self.searched_list:                        # search first dir, other append to branch list                        if not finded:                            h, w, d = self.current_h, self.current_w-1, dir                            finded = True                        else:                            self.branch_list.append([self.current_h, self.current_w, dir])                # right                elif dir == self.right:                    # not searched                    if [self.current_h, self.current_w+1] not in self.searched_list:                        # search first dir, other append to branch list                        if not finded:                            h, w, d = self.current_h, self.current_w+1, dir                            finded = True                        else:                            self.branch_list.append([self.current_h, self.current_w, dir])            # has search dir, but all have searched            if not finded:                if len(self.branch_list) > 0:                    self.current_h, self.current_w, self.current_dir = self.branch_list[-1]                    self.branch_list.pop()                else:                    print('search complete!')                    self.find_shortest_path(np.copy(self.search_map))            # at last have one dir have no search            else:                self.current_h, self.current_w, self.current_dir = h, w, d        # not dir to go, back to branch        else:            if len(self.branch_list) > 0:                self.current_h, self.current_w, self.current_dir = self.branch_list[-1]                self.branch_list.pop()            else:                print('search complete!')                self.find_shortest_path(np.copy(self.search_map))        # record searched list        self.searched_list.append([self.current_h, self.current_w])    def update_search_map(self):        # update search map current position, (maze's forward right left)        point_info = np.copy(self.maze_map[self.current_h][self.current_w])        self.search_map[self.current_h][self.current_w] = point_info        # update search map adjoin position, border control        if self.current_dir in [self.up, self.down]:            # up            if self.current_dir == self.up and self.current_h > 0:                self.search_map[self.current_h - 1][self.current_w][self.down] = point_info[self.up]            # down            elif self.current_dir == self.down and self.current_h < (self.map_size-1):                self.search_map[self.current_h + 1][self.current_w][self.up] = point_info[self.down]            # left and right            if self.current_w > 0:                self.search_map[self.current_h][self.current_w - 1][self.right] = point_info[self.left]            if self.current_w < (self.map_size-1):                self.search_map[self.current_h][self.current_w + 1][self.left] = point_info[self.right]        else:            # left            if self.current_dir == self.left and self.current_w > 0:                self.search_map[self.current_h][self.current_w - 1][self.right] = point_info[self.left]            # right            if self.current_dir == self.right and self.current_w < (self.map_size-1):                self.search_map[self.current_h][self.current_w + 1][self.left] = point_info[self.right]            # up and down            if self.current_h > 0:                self.search_map[self.current_h - 1][self.current_w][self.down] = point_info[self.up]            if self.current_h < (self.map_size-1):                self.search_map[self.current_h + 1][self.current_w][self.up] = point_info[self.down]        return point_info    def find_shortest_path(self, search_map):        """find shortest path"""        arrived_points = [[0, 0]]    # [h, w]        edge_trees = []        shortest_path = []           # [h, w]        # root tree        root = tree.Tree()        root.h = 0        root.w = 0        edge_trees.append(root)        while len(edge_trees) > 0:            append_trees = []            delete_trees = []            # all edge point to next step            for edge_tree in edge_trees:                # one edge point to next step                point_info = search_map[edge_tree.h][edge_tree.w]                # current point can go to dirs,  have dir(append)  or  not have dir(delete)                dirs = list(np.where(point_info == 0)[-1])                if len(dirs) > 0:                    for dir in dirs:                        if dir == self.up:                            h, w = edge_tree.h-1, edge_tree.w                        elif dir == self.down:                            h, w = edge_tree.h+1, edge_tree.w                        elif dir == self.left:                            h, w = edge_tree.h, edge_tree.w-1                        else:                            h, w = edge_tree.h, edge_tree.w+1                        # not go to this point before                        if [h, w] not in arrived_points:                            append_trees.append(tree.Tree())                            append_trees[-1].last_tree = edge_tree                            append_trees[-1].h = h                            append_trees[-1].w = w                            arrived_points.append([h, w])                            # find win point                            if h == self.win[0] and w == self.win[1]:                                edge_tree_ = append_trees[-1]                                while edge_tree_.last_tree is not None:                                    shortest_path.append([edge_tree_.h, edge_tree_.w])                                    edge_tree_ = edge_tree_.last_tree                                self.draw_shortest_line(shortest_path)                                return shortest_path                else:                    delete_trees.append(edge_tree)            # append            for edge_tree in append_trees:                edge_trees.append(edge_tree)            # delete            for delete_tree in delete_trees:                edge_trees.remove(delete_tree)        return shortest_path    def reset_mouse(self):        # reset mouse        self.after_cancel = False        self.current_h = 0        self.current_w = 0        self.current_dir = self.right        self.searched_list = []        self.searched_list = []        self.branch_list = []        self.search_map = np.zeros((self.map_size, self.map_size, 4), dtype='int8')        self.draw_search_maze()        self.draw_mouse(self.current_w, self.current_h)

另外附路线配置文件1101_01.txt

1 0 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 0 0 1 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 0 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

整体界面

二、