from __future__
import unicode_literals
import random
try:
from tkinter
import *
except ImportError
:
from Tkinter
import *
import matplotlib
.image
as mpimg
import numpy
class Block(object):
def __init__(self
, mmap
, x
, y
, direction
=None):
super(Block
, self
).__init__
()
self
.walls
= [True, True, True, True]
self
.mmap
= mmap
if mmap
:
mmap
.mmap
[x
][y
] = self
self
.x
, self
.y
= x
, y
if direction
is not None:
direction
= (direction
+ 2) % 4
self
.walls
[direction
] = False
def __unicode__(self
):
return "%s" % [1 if e
else 0 for e
in self
.walls
]
def __str__(self
):
return unicode(self
).encode
('utf-8')
def get_next_block_pos(self
, direction
):
x
= self
.x
y
= self
.y
if direction
== 0:
y
-= 1
elif direction
== 1:
x
+= 1
if direction
== 2:
y
+= 1
if direction
== 3:
x
-= 1
return x
, y
def get_next_block(self
):
directions
= list(range(4))
random
.shuffle
(directions
)
for direction
in directions
:
x
, y
= self
.get_next_block_pos
(direction
)
if x
>= self
.mmap
.max_x
or x
< 0 or y
>= self
.mmap
.max_y
or y
< 0:
continue
if self
.mmap
.mmap
[x
][y
]:
continue
self
.walls
[direction
] = False
return Block
(self
.mmap
, x
, y
, direction
)
return None
class Map(object):
def __init__(self
):
super(Map
, self
).__init__
()
def reset_map(self
):
self
.gen_map
(self
.max_x
, self
.max_y
)
def reset_map_changesize(self
, chang
, kuan
):
self
.max_x
= chang
self
.max_y
= kuan
self
.gen_map
(self
.max_x
, self
.max_y
)
def gen_map(self
, max_x
=10, max_y
=10):
self
.max_x
, self
.max_y
= max_x
, max_y
self
.mmap
= [[None for j
in range(self
.max_y
)] for i
in range(self
.max_x
)]
self
.solution
= []
block_stack
= [Block
(self
, 0, 0)]
while block_stack
:
block
= block_stack
.pop
()
next_block
= block
.get_next_block
()
if next_block
:
block_stack
.append
(block
)
block_stack
.append
(next_block
)
if next_block
.x
== self
.max_x
- 1 and next_block
.y
== self
.max_y
- 1:
for o
in block_stack
:
self
.solution
.append
((o
.x
, o
.y
))
def __unicode__(self
):
out
= ""
for y
in range(self
.max_y
):
for x
in range(self
.max_x
):
out
+= "%s" % self
.mmap
[x
][y
]
out
+= "\n"
return out
def __str__(self
):
return unicode(self
).encode
('utf-8')
class DrawMap(object):
def __init__(self
, mmap
, cell_width
=10):
super(DrawMap
, self
).__init__
()
self
.mmap
= mmap
self
.cell_width
= cell_width
def get_map_size(self
):
return (self
.mmap
.max_x
+ 2) * self
.cell_width
, (self
.mmap
.max_y
+ 2) * self
.cell_width
def create_line(self
, x1
, y1
, x2
, y2
, **kwarg
):
raise NotImplemented
()
def create_solution_line(self
, x1
, y1
, x2
, y2
):
self
.create_line
(x1
, y1
, x2
, y2
)
def draw_start(self
):
raise NotImplemented
()
def draw_end(self
):
raise NotImplemented
()
def get_cell_center(self
, x
, y
):
w
= self
.cell_width
return (x
+ 1) * w
+ w
// 2, (y
+ 1) * w
+ w
// 2
def draw_solution(self
):
pre
= (0, 0)
for o
in self
.mmap
.solution
:
p1
= self
.get_cell_center
(*pre
)
p2
= self
.get_cell_center
(*o
)
self
.create_solution_line
(p1
[0], p1
[1], p2
[0], p2
[1])
pre
= o
def draw_cell(self
, block
):
width
= self
.cell_width
x
= block
.x
+ 1
y
= block
.y
+ 1
walls
= block
.walls
if walls
[0]:
self
.create_line
(x
* width
, y
* width
, (x
+ 1) * width
+ 1, y
* width
)
if walls
[1]:
self
.create_line
((x
+ 1) * width
, y
* width
, (x
+ 1) * width
, (y
+ 1) * width
+ 1)
if walls
[2]:
self
.create_line
(x
* width
, (y
+ 1) * width
, (x
+ 1) * width
+ 1, (y
+ 1) * width
)
if walls
[3]:
self
.create_line
(x
* width
, y
* width
, x
* width
, (y
+ 1) * width
+ 1)
def draw_map(self
):
for y
in range(self
.mmap
.max_y
):
for x
in range(self
.mmap
.max_x
):
self
.draw_cell
(self
.mmap
.mmap
[x
][y
])
self
.draw_start
()
self
.draw_end
()
class TKDrawMap(DrawMap
):
def __init__(self
, mmap
):
super(TKDrawMap
, self
).__init__
(mmap
, cell_width
=10)
master
= Tk
()
master
.title
('hahaha')
master
.geometry
('900x600')
btn_start
= Button
(master
, text
='start', command
=self
.draw_solution
)
btn_start
.place
(x
=10, y
=10)
btn_change
= Button
(master
, text
='change', command
=self
.reset_map
)
btn_change
.place
(x
=10, y
=60)
self
.var
= StringVar
(master
)
self
.var
.set("choose width")
option
= OptionMenu
(master
, self
.var
, "50", "40", "30")
option
.place
(x
=10, y
=120)
self
.var2
= StringVar
(master
)
self
.var2
.set("choose height")
option
= OptionMenu
(master
, self
.var2
, "50", "40", "30")
option
.place
(x
=10, y
=150)
btn_size
= Button
(master
, text
="ok", command
=self
.ok
)
btn_size
.place
(x
=10, y
=180)
width
, height
= self
.get_map_size
()
self
.w
= Canvas
(master
, width
=width
, height
=width
)
self
.w
.pack
()
self
.draw_map
()
mainloop
()
def ok(self
):
change_size
= self
.var
.get
()
change_size2
= self
.var2
.get
()
change_size
= int(change_size
)
change_size2
= int(change_size2
)
self
.mmap
.reset_map_changesize
(change_size
, change_size2
)
self
.w
.delete
('all')
self
.draw_map
()
def draw_start(self
):
r
= self
.cell_width
// 3
x
, y
= self
.get_cell_center
(0, 0)
start
= self
.w
.create_rectangle
(x
- r
, y
- r
, x
+ r
, y
+ r
, dash
=(4, 4), fill
='pink')
self
.w
.tag_bind
(start
, '<ButtonPress-1>', lambda e
: self
.draw_solution
())
def draw_end(self
):
r
= self
.cell_width
// 3
x
, y
= self
.get_cell_center
(self
.mmap
.max_x
- 1, self
.mmap
.max_y
- 1)
end
= self
.w
.create_oval
(x
- r
, y
- r
, x
+ r
, y
+ r
, fill
="red")
self
.w
.tag_bind
(end
, '<ButtonPress-1>', lambda e
: self
.reset_map
())
def reset_map(self
):
self
.mmap
.reset_map
()
self
.w
.delete
('all')
self
.draw_map
()
def create_line(self
, x1
, y1
, x2
, y2
, **kwargs
):
self
.w
.create_line
(x1
, y1
, x2
, y2
, **kwargs
)
def create_solution_line(self
, x1
, y1
, x2
, y2
):
self
.create_line
(x1
, y1
, x2
, y2
, fill
="green")
def main():
m
= Map
()
m
.gen_map
(50, 50)
TKDrawMap
(m
)
if __name__
== '__main__':
main
()
左侧按钮可以控制开始和换地图布局,换地图尺寸,迷宫开始点和结束点也是按钮,也可以点击。
转载请注明原文地址:https://ipadbbs.8miu.com/read-17155.html