• 随机生成路径


    问题:给定几个元动作及起始点、终止点、还有起始方向,生成一条随机行走的路径。

    暂时用最笨的解决方法,回溯法,找到一条就返回。

    现有元动作,左转,直行,右转.用pygame进行图形显示。

    扩展性有点差,每个方向都要根据当前的方向和元动作进行判断。

    import pygame
    import math
    import random

    black = (0, 0, 0)
    white = (255, 255, 255)
    red = (255, 0, 0)
    green = (0, 255, 0)
    blue = (0, 0, 255)
    yellow = (255, 255, 0)

    done = False

    #define move direction to local
    Move_Left, Move_Forward, Move_Right = range(0, 3)

    #define world direction
    Dir_Up, Dir_Right, Dir_Down, Dir_Left = range(0, 4)

    pygame.init()

    size = [800, 600]

    screen = pygame.display.set_mode(size)


    pygame.display.set_caption("Animation Path")

    def dir_str(cur_dir):
    dir_str = ""
    if cur_dir == Dir_Up:
    dir_str = ""
    elif cur_dir == Dir_Right:
    dir_str = ""
    elif cur_dir == Dir_Down:
    dir_str = ""
    elif cur_dir == Dir_Left:
    dir_str = ""

    return dir_str

    def movestate_str(move_state):
    move_str = ""
    if move_state == Move_Left:
    move_str = "Turn Left"
    elif move_state == Move_Forward:
    move_str = "Forward"
    elif move_state == Move_Right:
    move_str = "Turn Right"

    return move_str

    class AnimationPath:
    def __init__(self):
    self.width = 0
    self.height = 0
    self.cell_size = 50

    self.one_step = 1

    self.start_pos = [0,0]

    self.path_width = 2

    self.initialize()

    def initialize(self):
    self.is_find = False
    self.result_list = []
    self.count = 0

    def draw_board(self):
    start_pos = self.start_pos
    total_width = self.width * self.cell_size
    total_height = self.height * self.cell_size
    for i in range(0, self.width+1):
    begin_pos_x = start_pos[0] + i * self.cell_size
    end_pos_y = start_pos[1] - total_height
    pygame.draw.line(screen, white, [begin_pos_x,start_pos[1]],
    [begin_pos_x, end_pos_y], 1)

    for j in range(0, self.height+1):
    begin_pos_y = start_pos[1] - j * self.cell_size
    end_pos_x = start_pos[0] + total_width
    pygame.draw.line(screen, white, [start_pos[0], begin_pos_y],
    [end_pos_x, begin_pos_y], 1)

    def draw_line(self, start_pos, end_pos, color, width):
    base_x = self.start_pos[0]
    base_y = self.start_pos[1]
    pygame.draw.line(screen,color,
    [base_x + start_pos[0] * self.cell_size,
    base_y - start_pos[1] * self.cell_size],
    [base_x + end_pos[0] * self.cell_size,
    base_y - end_pos[1] * self.cell_size],
    width)

    #画出行走路线
    def draw_path(self, cur_pos, cur_dir, move_state, color, width):
    cur_x = cur_pos[0]
    cur_y = cur_pos[1]
    base_x = self.start_pos[0]
    base_y = self.start_pos[1]

    if cur_dir == Dir_Up:
    if move_state == Move_Left:
    pygame.draw.arc(screen, color,
    [(base_x + cur_x * self.cell_size - self.cell_size*2,
    base_y - cur_y * self.cell_size - self.cell_size),
    (self.cell_size * 2,
    self.cell_size * 2)],
    0,math.radians(90), width)

    elif move_state == Move_Forward:
    self.draw_line(cur_pos, [cur_pos[0], cur_pos[1]+self.one_step * 2], color, width)
    elif move_state == Move_Right:
    pygame.draw.arc(screen, color,
    [base_x + cur_x * self.cell_size,
    base_y - cur_y * self.cell_size - self.cell_size,
    self.cell_size * 2,
    self.cell_size * 2],
    math.radians(90), math.radians(180), width)

    elif cur_dir == Dir_Right:
    if move_state == Move_Left:
    pygame.draw.arc(screen, color,
    [base_x + cur_x * self.cell_size - self.cell_size,
    base_y - cur_y * self.cell_size - self.cell_size * 2,
    self.cell_size * 2,
    self.cell_size * 2],
    math.radians(270),
    math.radians(360),
    width)
    elif move_state == Move_Forward:
    self.draw_line(cur_pos, [cur_pos[0] + self.one_step * 2, cur_pos[1]], color, width)
    elif move_state == Move_Right:
    pygame.draw.arc(screen, color,
    [base_x + cur_x * self.cell_size - self.cell_size,
    base_y - cur_y * self.cell_size,
    self.cell_size * 2,
    self.cell_size * 2],
    0,
    math.radians(90),
    width)

    elif cur_dir == Dir_Down:
    if move_state == Move_Left:
    pygame.draw.arc(screen, color,
    [base_x + cur_x * self.cell_size,
    base_y - cur_y * self.cell_size - self.cell_size,
    self.cell_size * 2,
    self.cell_size * 2],
    math.radians(180),
    math.radians(270),
    width)

    elif move_state == Move_Forward:
    self.draw_line(cur_pos, [cur_pos[0], cur_pos[1] - self.one_step * 2], color, width)
    elif move_state == Move_Right:
    pygame.draw.arc(screen, color,
    [base_x + cur_x * self.cell_size - self.cell_size * 2,
    base_y - cur_y * self.cell_size - self.cell_size,
    self.cell_size * 2,
    self.cell_size * 2],
    math.radians(270),
    math.radians(360),
    width)

    elif cur_dir == Dir_Left:
    if move_state == Move_Left:
    pygame.draw.arc(screen, color,
    [base_x + cur_x * self.cell_size - self.cell_size,
    base_y - cur_y * self.cell_size,
    self.cell_size * 2,
    self.cell_size * 2],
    math.radians(90),
    math.radians(180),
    width)

    elif move_state == Move_Forward:
    self.draw_line(cur_pos, [cur_pos[0] - self.one_step * 2, cur_pos[1]], color, width)
    elif move_state == Move_Right:
    pygame.draw.arc(screen, color,
    [base_x + cur_x * self.cell_size - self.cell_size,
    base_y - cur_y * self.cell_size - self.cell_size * 2,
    self.cell_size * 2,
    self.cell_size * 2],
    math.radians(180),
    math.radians(270),
    width)

    else:
    pass

    pass

    #根据现在的方向和动作判断下一个位置
    def move_to_next(self, cur_pos, cur_dir, move_state):
    # new_pos = cur_pos
    cur_x = cur_pos[0]
    cur_y = cur_pos[1]
    new_dir = cur_dir
    canMove = False;
    if cur_dir == Dir_Up:
    if move_state == Move_Left:
    if cur_x == 0 or cur_y == self.height:
    #can't move this way
    pass
    else:
    cur_x = cur_x - self.one_step
    cur_y = cur_y + self.one_step
    new_dir = Dir_Left
    canMove = True

    elif move_state == Move_Forward:
    if cur_y >= self.height-1:
    #can't move up
    pass
    else:
    cur_y = cur_y + self.one_step*2
    canMove = True

    elif move_state == Move_Right:
    if cur_x == self.width or cur_y == self.height:
    #can't move this way
    pass
    else:
    cur_x = cur_x + self.one_step
    cur_y = cur_y + self.one_step
    new_dir = Dir_Right
    canMove = True

    elif cur_dir == Dir_Right:
    if move_state == Move_Left:
    if cur_x == self.width or cur_y == self.height:
    #can't move
    pass
    else:
    cur_x = cur_x + self.one_step
    cur_y = cur_y + self.one_step
    new_dir = Dir_Up
    canMove = True

    elif move_state == Move_Forward:
    if cur_x >= self.width -1:
    #can't move
    pass
    else:
    cur_x = cur_x + self.one_step*2
    canMove = True

    elif move_state == Move_Right:
    if cur_x == self.width or cur_y == 0:
    #can't move
    pass
    else:
    cur_x = cur_x + self.one_step
    cur_y = cur_y -1
    new_dir = Dir_Down
    canMove = True

    elif cur_dir == Dir_Down:
    if move_state == Move_Left:
    if cur_x == self.width or cur_y == 0:
    #can't move
    pass
    else:
    cur_x = cur_x + self.one_step
    cur_y = cur_y - self.one_step
    new_dir = Dir_Right
    canMove = True

    elif move_state == Move_Forward:
    if cur_y <= 1:
    #can't move
    pass
    else:
    cur_y = cur_y - self.one_step*2
    canMove = True

    elif move_state == Move_Right:
    if cur_x == 0 or cur_y == 0:
    #can't move
    pass
    else:
    cur_x = cur_x - self.one_step
    cur_y = cur_y - self.one_step
    new_dir = Dir_Left
    canMove = True

    elif cur_dir == Dir_Left:
    if move_state == Move_Left:
    if cur_x == 0 or cur_y == 0:
    #can't move
    pass
    else:
    cur_x = cur_x - self.one_step
    cur_y = cur_y - self.one_step
    new_dir = Dir_Down
    canMove = True
    elif move_state == Move_Forward:
    if cur_x <= 1:
    #can't move
    pass
    else:
    cur_x = cur_x - self.one_step*2
    canMove = True
    elif move_state == Move_Right:
    if cur_x == 0 or cur_y == self.height:
    #can't move
    pass
    else:
    cur_x = cur_x - self.one_step
    cur_y = cur_y + self.one_step
    new_dir = Dir_Up
    canMove = True



    new_pos = [cur_x, cur_y]
    return [canMove, new_pos, new_dir]
    pass

    def traceback_move(self, cur_pos, cur_dir):

    if not self.is_find:
    cur_x = cur_pos[0]
    cur_y = cur_pos[1]

    if cur_x == self.width and cur_y == self.height:
    self.count= self.count + 1
    print ("reach goal%s"%self.count)
    #reslut_list.append([cur_x, cur_y])
    self.is_find = True
    return True
    else:
    state_list = range(0,3)
    while len(state_list) > 0:
    state_left = len(state_list)
    state_index = random.randint(0, state_left-1)
    state = state_list[state_index]
    state_list.remove(state)
    move_result = self.move_to_next(cur_pos, cur_dir, state)
    if move_result[0]:
    cur_x = move_result[1][0]
    cur_y = move_result[1][1]

    new_dir = move_result[2]


    if self.traceback_move([cur_x,cur_y], new_dir) or self.is_find:
    print ("[%s,%s]:%s:%s"%(cur_pos[0], cur_pos[1],dir_str(cur_dir), movestate_str(state)))
    self.result_list.append([cur_pos,cur_dir,state])
    return True
    #if is_ok:
    #print ("[%s,%s]"%(cur_x,cur_y))

    #return is_ok

    return False
    else:
    return True
    pass


    def calc_board_size(self, start_pos, end_pos):
    width = abs(end_pos[0] - start_pos[0])/self.cell_size
    height = abs(end_pos[1] - start_pos[1])/self.cell_size

    self.height = height
    self.width = width

    def findPath(self, start_pos, end_pos, start_dir):
    cur_x = 0
    cur_y = 0

    cur_dir = start_dir
    self.start_pos = start_pos

    self.calc_board_size(start_pos, end_pos)

    self.initialize()
    self.traceback_move([cur_x, cur_y], cur_dir)


    def draw_result(self):
    for step in self.result_list:
    self.draw_path(step[0], step[1], step[2], green, 2)


    s_pos = [100,550]
    e_pos = [600,50]
    c_dir = Dir_Up
    anim_path = AnimationPath()
    anim_path.findPath(s_pos, e_pos, c_dir)

    results = anim_path.result_list
    results.reverse()
    step_index = 0

    one_step = False

    while done == False:
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    done = True

    if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_SPACE:
    one_step = not one_step
    elif event.key == pygame.K_LEFT:
    if step_index > 0:
    step_index = step_index - 1
    elif event.key == pygame.K_RIGHT:
    if step_index < len(results)-1:
    step_index = step_index + 1

    elif event.key == pygame.K_g:
    print ("G")
    anim_path.findPath(s_pos, e_pos, c_dir)
    results = anim_path.result_list
    results.reverse()
    step_index = 0


    screen.fill(black)
    anim_path.draw_board()

    anim_path.draw_result()

    if not one_step:
    for i in range(0,step_index+1):
    step = results[i]
    anim_path.draw_path(step[0],step[1],step[2], red, 3)
    else:
    step = results[step_index]
    anim_path.draw_path(step[0],step[1],step[2], red, 3)
    pygame.display.flip()
    #clock.tick(5)

    pygame.quit()


    截图:

    按左右键进行路径的跟踪,空格进行单步路径根据的切换。G键重新生成路径。

  • 相关阅读:
    [python] pprika:基于werkzeug编写的web框架(6) ——restful的错误处理
    [python] pprika:基于werkzeug编写的web框架(5) ——蓝图blueprint
    [python] pprika:基于werkzeug编写的web框架(4) ——请求上下文与helpers
    [python] pprika:基于werkzeug编写的web框架(3) ——错误处理
    [python] pprika:基于werkzeug编写的web框架(2) ——路由与请求响应
    [python] pprika:基于werkzeug编写的web框架(1) ——序言与简介
    2019寒假训练营第四次作业
    2019寒假训练营第三次作业
    【学习笔记】福州大学网络课程 网络空间安全概论(5)
    【学习笔记】福州大学网络课程 网络空间安全概论(1,4)
  • 原文地址:https://www.cnblogs.com/gameprogram/p/2277722.html
Copyright © 2020-2023  润新知