(一)、python程序--模拟电脑鼠走迷宫

一、绪论

1、简介

电脑鼠走迷宫是一种比赛,制作实物电脑鼠小车在迷宫找目标点,用时最短者获胜。考验参赛选手软硬件结合的能力。

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

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

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

3、采用洪水算法查找迷宫的最短路径。

整体界面

二、软件截图

打开迷宫形状配置文件

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

搜索迷宫

搜索迷宫

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

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

三、代码分享

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

1、main.py

import tkinter as tk
import maze as maze
import micromouse as micromouse

root = tk.Tk()
windows_w = 640*2+100
windows_h = 640
bd = 10
map_size = 32
win = [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、maze.py

import numpy as np
from tkinter import filedialog


class 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、micromouse.py

import numpy as np
from tkinter import filedialog


class 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()


  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值