找到奶酪


25

更新:有6个迷宫。它们包含在控制器中。还有就是迷宫的一个tar.gz和他们的.bmp文件在这里(Dropbox的)。还有一个实用程序,可在该链接上产生更多的迷宫(maze_4.txt文件在存档中不正确)。此时,请随时运行您自己的条目并更新您的分数。底部包含有关操作方法的详细信息。如果您有任何疑问或麻烦,请在聊天中ping我。


你是老鼠 你在迷宫中。找到奶酪。

概念

您处于矩形网格上存在的迷宫中。网格的每个空间都包含以下几项之一:

  • ! -不可逾越的墙
  • -一个可遍历的空白空间
  • O -你,老鼠
  • + -奶酪,您的目标

请使用相同的字符,这样我就不必修改控制器。

在每个回合中,您将获得当前位置的北,南,东和西瓷砖。然后,您必须输出想要行驶的方向。拿到奶酪,您就赢了。步骤越少越好。

输入项

您将通过stdin通过以下方式获得输入:nesw,其中每个字母代表该罗盘点处的图块。例如,如果当前状态看起来像

  !          <--- Wall
 !O          <--- You
  +          <--- Cheese

然后您将得到字符串! +!

在游戏结束时,控制器将向您发送四个零的字符串:0000收到此字符串后,您的程序应终止。给定的其他任何输入都不会包含该0字符。

请忽略所有其他输入。

输出量

你要输出一个字母nse,或w,以表明你想往哪个方向行驶,接着换行字符。

计分

您在每次测试中得到的分数是找到奶酪所需的步骤数。

您的总体得分将是一系列大小可变的迷宫中每个迷宫的平均得分的总和,所有这些迷宫都可以放入长度为50的正方形内。

例如,如果您的漫游器需要100次移动才能完成6个迷宫中的每一个,那么您的得分就是600。

如果您的漫游器不确定,请尝试每个迷宫10次,并使用平均值作为该迷宫的分数。您的最终分数将是所有平均值的总和。

规则

  • 每个迷宫都可以容纳50x50的正方形。
  • 从迷宫到奶酪,每个迷宫都有至少一条有效路径。
  • 每个迷宫都将完全围起来,但奶酪将始终位于外壁上,因此它实际上是迷宫的出口。
  • 如果碰壁,您的提交将被取消参赛资格。
  • 如果您提交的时间过长(由我确定,我开始测试的时间),则会被取消参赛资格。这在很大程度上是为了防止无限循环。尽管我保留随时在任一方向上更改此设置的权利,但每个迷宫的软限制为一分钟。
  • 参赛作品不一定是确定性的,但是如果您太随意,则以上几点可能会取消参赛资格。
  • 在某些时候,迷宫将被释放,未来的答案可能无法针对它们进行优化,并且它们可能会发生变化。

提交内容

您的提交是一个完整的程序,它通过stdin输入,通过stdout输出。这很重要,因为提交将与迷宫控制器进行交互。我不会禁止不免费提供的语言,但是我知道如果我无法使用该语言,则其他人将不得不花时间来运行测试。

请附上有关如何运行提交的说明。

请说明您的提交是否具有确定性,以便我知道是否需要多次运行。

测试迷宫

在测试迷宫中,.角色概述了到达奶酪的最短路径。它们与(空格)字符相同。它们对您的提交不可见。控制器将它们替换为空格。

!!!!!!!!+!
!O..!....!
! !.!.! !!
! !.!.!  !
! !.!.!! !
!!!.!.!! !
!  .!.! !!
!!!...   !
!!!!!!!!!!

31x31测试迷宫。无耻地被盗

 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
 ! O...!.......!   !  .....!.....!           !             !   ! 
 !!!!!.!.! !!!.! !!! !.!!!.!.!!!.!!!!!!! !!! !!!!!!!!! !!! ! ! ! 
 !   !...!   !.!     !.! !.!.! !.!       !   !         !   ! ! ! 
 ! !!!!! !!! !.!!!!!!!.! !.!.! !.! !!!!!!! !!! ! !!!!!!! !!! ! ! 
 !     !     !.........! !...!...!     !   !   ! !     !   ! ! ! 
 ! !!! !!!!!!!!!!!!!!!!! !!!!!.!!! !!! !!! ! ! !!! !!! !!! !!! ! 
 !   !         !     !   !.....!     !   ! ! ! !     !   !   ! ! 
 !!!!!!!!!!! ! ! !!! !!! !.!!!!!!!!!!!!! ! !!! ! !!!!!!! !!! ! ! 
 !           !   !       !.!             !   !     !     !     ! 
 ! !!!!!!! !!!!!!! !!!!!!!.! !!!!!!!!!!!!!!! !!!!!!! !!!!!!!!!!! 
 ! !     ! !   !     !...!.!           !   !       ! !         ! 
 ! !!! ! ! ! ! !!!!!!!.!.!.! !!!!!!!!! ! ! !!!!!!! ! ! !!!!!!! ! 
 !   ! !   ! !       !.!...! !         ! !       ! ! !   !   ! ! 
 !!! ! !!!!! !!!!!!! !.!!!!!!! !!!!!!!!! !!! !!!!! ! !!! ! !!! ! 
 !   !   ! ! !       !...!     !   !     ! !           ! !   ! ! 
 ! !!!!! ! ! ! !!!!!!!!!.! !!!!! !!! !!!!! !!!!!!!!!!! ! ! ! ! ! 
 ! !       ! !   !   !...! !       ! !       !   !     ! ! ! ! ! 
 ! !!!!!!!!! !!! ! ! !.!!! !!!!!!! ! !!!!!!! ! ! !!!!!!! !!! ! ! 
 !             !   ! !...!       ! !     !   ! !             ! ! 
 !!!!!!!!!!!!!!!!!!! !!!.!!!!!!! ! !!!!! ! !!! !!!!!!!!!!!!!!! ! 
 !               !   !...!       !         !   !     !   !     ! 
 ! !!!!!!!!!!!!! ! ! !.!!! !!!!!!! !!!!!!!!! !!! !!! !!! ! !!! ! 
 ! !   !       !   ! !.! !     ! ! ! !     !     !   !   !   ! ! 
 ! ! ! !!!!! !!!!!!! !.! ! !!! ! ! ! ! !!! !!!!!!! !!! !!!!! !!! 
 !   ! !   !       ! !.!     ! !     ! ! !     !   !       !   ! 
 !!!!! ! ! !!! !!! ! !.!!!!!!! !!!!!!! ! ! !!! ! !!!!!!!!! !!! ! 
 !     ! !   !   !   !.......!       ! ! ! !   !   !         ! ! 
 ! !!!!! !!! !!! !!!!!!!!!!!.!!!!!!! ! ! ! !!!!!!! ! !!!!!!! ! ! 
 !         ! !           !...!       ! ! !     !   ! !       ! ! 
 !!!!!!!!!!! !!!!!!!!!!! !.!!! !!!!!!! ! !!!!! ! !!! !!!!!!!!! ! 
 !         !     !     ! !.!       !   !     ! !     !         ! 
 ! !!!!!!! !!!!! ! !!! !!!.!!!!!!! ! !!!!! ! ! !!!!! ! !!!!!!!!! 
 ! !     !     !   ! !   !.......! !       ! !       !         ! 
 ! ! !!! !!!!! ! !!! !!! !!!!!!!.! !!!!!!!!! !!!!!!!!!!!!!!!!! ! 
 !     !     ! !   !   ! !     !.!       !   ! !     !         ! 
 !!!!!!!!!!! ! !!! !!! ! ! ! !!!.! ! !!!!! !!! ! !!! ! !!!!!!! ! 
 !           ! !       !   ! !...! !       !   ! ! ! !     !   ! 
 ! !!!!!!!!!!! !!!!!!!!!!!!! !.!!! !!!!!!!!!!! ! ! ! ! !!! ! !!! 
 !       !   !             ! !.! !   !         ! !   !   ! ! ! ! 
 !!!!!!! !!! !!!!!!!!!!!!! ! !.! !!! ! !!!!!!! ! !!! !!!!! ! ! ! 
 !       !         !     ! ! !.!   !   !     ! !   !       !   ! 
 ! !!!!!!! !!!!!!! ! !!!!! ! !.!!! !!!!!!! ! ! !!! !!!!!!!!!!!!! 
 !   !         ! !   !       !.!           ! !   !             ! 
 ! ! ! !!!!!!! ! ! !!! !!!!!!!.! !!!!!!!!!!! ! !!!!!!!!!!!!!!! ! 
 ! ! ! !     ! !   !   ! !.....!   !   !     ! !...............! 
 ! ! !!! !!! ! !!!!! !!! !.!!!!! ! ! ! !!!!!!! !.!!!!!!!!!!!!!.! 
 ! !   !   ! !   !       !...!   !   !         !.!         !...! 
 !!!!! !!! ! !!! ! !!!!!!!!!.!!!!!!! !!!!!!!!!!!.!!!!! !!!!!.!!! 
 !     !   !   !   !       !.......!       !...!.....!      .! ! 
 ! !!!!! !!!!! !!!!! !!!!! !!!!!!!.!!!!!!!!!.!.!!!!!.!!!!!!!.! ! 
 !           !     ! !   !   !   !...........!...!...!.....!...! 
 ! !!!!!!!!! !!!!! ! !!! ! !!! ! !!!!!!!!!!!!!!!.!.!!!.!!!.!!!.! 
 ! !     !       ! !     !     !     !         !.!.....  !...!.! 
 !!! !!! !!!!!!!!! !!!!! !!!!!!!!! ! !!!!!!! !!!.! !!!!!!!!!.!.! 
 !   !     !   !   !   ! !       ! !         !...! !.........!.! 
 ! !!!!!!! ! ! ! ! !!! ! !!!!!!! ! !!!!!!!!! !.!!!!!.!!!!!!!!!.! 
 !       !   !   ! !   !         !   ! !   ! !.!.....!       !.! 
 ! !!!!! !!!!!!!!! ! !!!!!!!!!!! !!! ! ! ! ! !.!.!!!!! !!!!! !.! 
 ! !     !           !         ! ! ! !   !   !.!...!   !     !.! 
 ! ! !!!!!!!!!!!!!!!!! !!! !!!!! ! ! !!!!!!!!!.!!!.! !!!!!!!!!.! 
 ! !                     !         !          .....!          .! 
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!+! 

控制者

控制器处于Rust状态(每晚1.11)

    type Maze = Vec<Vec<char>>;

fn str_to_maze(input: &str) -> Result<Maze,i32> {
    let mut maze: Vec<Vec<char>> = vec![ vec![] ];
    let mut row: Vec<char> = vec![];

    for c in input.chars() {
        if c == '!' || c == '+' || c == 'O'  || c == ' ' {
            row.push(c);
        }
        else if c =='.' {
            row.push(' ');
        }
        else if c == '#' {
            maze.push(row);
            row = vec![];
        }
        else if c =='\0' {
            break;
        }  
        else {
            println!("Bad character in maze: {}, exiting.", c);
            return Err(1);
        }
    }
    return Ok(maze);
}

fn display_maze(maze: &Maze, position: [usize;2]) {
    for y in 0..maze.len() {
        for x in 0..maze[y].len() {
            if [x,y] == position {
                print!("O");
            }
            else if maze[y][x] == '#' {
                println!("\n");
            }
            else {
                print!("{}",maze[y][x]);
            }
        }
        println!("");
    }
    println!("\n");
}

fn get_starting_position(maze: &mut Maze) -> Result<[usize;2],&str> {
    for y in 0..maze.len() {
        for x in 0..maze[y].len() {
            if maze[y][x] == 'O' {
                maze[y][x] = ' ';
                return Ok([x,y]);
            }
        }
    }
    return Err("No mouse found");
}

enum State {
    Continue([char;4]),
    Win,
    Disqualify,
}

fn output(maze: &Maze, position: [usize;2]) -> State {
    let x = position[0];
    let y = position[1];
    if maze[y][x] == '+' {
        return State::Win;
    }
    else if maze[y][x] == '!' {
        return State::Disqualify;
    }

    let n = maze[y-1][x];

    assert!(y+1<maze.len());
    let s = maze[y+1][x];


    let w = maze[y][x-1];

    assert!(x+1<maze[y].len());
    let e = maze[y][x+1];

    return State::Continue([n,e,s,w]);
}

fn get_input() -> char {
    use std::io;
    use std::io::Read;
    let mut buffer: [u8;2] = [0;2];
    io::stdin().read_exact(&mut buffer).unwrap();
    //println!("{:?}", buffer); // to see exactly what the input is
    return buffer[0] as char;
}

fn next_position(current_position: [usize;2], direction: char) -> Result<[usize;2],char> {
    let mut x = current_position[0];
    let mut y = current_position[1];
    if direction == 'n' {
        y -= 1;
    }
    else if direction == 'e' {
        x += 1;
    }
    else if direction == 's' {
        y += 1;
    }
    else if direction == 'w' {
        x -= 1;
    }
    else {
        return Err(direction);
    }
    return Ok([x,y]);
}


fn play(maze: &mut Maze) -> (State, usize) {
    let mut position: [usize;2];
    match get_starting_position(maze) {
        Ok(pos) => position = pos,
        Err(s) => {
            println!("{}",s);
            std::process::exit(2);
        }
    }

    let mut moves = 0;

    loop {

        let state = output(maze, position);

        /* uncomment below to view the maze at each step  */
        //display_maze(&maze, position);                
        /* ----------------------------------------------*/

        match state {
            State::Win => {
                //println!("You found the cheese");
                return(State::Win, moves);
            }
            State::Disqualify => {
                //println!("You were disqualified");
                return(State::Disqualify, moves);
            }
            State::Continue(out) => {
                println!("{}{}{}{}",out[0],out[1],out[2],out[3]);
            }
        }
        // only get here with Continue
        let input = get_input();
        moves += 1;
        match next_position(position, input) {
            Err(c) => {
                println!("Invalid input: {}", c as u8);
                return (State::Disqualify, moves);
            }
            Ok(next_pos) => position = next_pos,
        }
    }    
}

fn main() {

    let mut arg_counter = 0; 
    for argument in std::env::args() {
        if arg_counter != 0 {

            let mut maze = match argument.as_str(){
                "1" => maze_1(),
                "2" => maze_2(),
                "3" => maze_3(),
                "4" => maze_4(),
                "5" => maze_5(),
                "6" => maze_6(),
                _ => {
                    println!("invalid input: {}, breaking", argument);
                    break;
                }

            };

            let game_result = play(&mut maze);

            println!("0000");
            match game_result.0 {
                State::Win => println!("WIN"),
                State::Disqualify => println!("DISQUALIFY"),
                _ => println!("Error"),
            }
            println!("moves: {}", game_result.1 );
        }
        arg_counter += 1;
    }

}

fn maze_1() -> Maze {
    let maze_str = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\
                    !O !                    !      !#\
                    !. ! !!!!!!!!!!!!!!!!!! ! !!!!!!#\
                    !. !                    ! !    !#\
                    !. ! !!!!!!!!!!!!!!!!!!!! ! !! !#\
                    !. !...........           ! !!.+#\
                    !. !.!!!!!!!!!.!!!!!!!!!!!!!!!.!#\
                    !.!..!        ...............!.!#\
                    !.!.!! !!!!!!!!!!!!!!!!!!!!!.!.!#\
                    !.!.!! !!!  !               .!.!#\
                    !.!.!! !!!  !!!!!!!!!!!!!!!!.!.!#\
                    !...!! !!!                  .!.!#\
                    ! ! !! !!!                  .!.!#\
                    ! ! !! !!!  !!!!!!!!! !!!!!!.!.!#\
                    ! ! !! !!!  !      !! !     .!.!#\
                    ! ! !! !!!  ! !!!!!!! !     .!.!#\
                    ! ! !! !!!  !      !! !     .!.!#\
                    ! ! !! !!!  !      !! !     .!.!#\
                    ! ! !!   !  !      !! !     .!.!#\
                    ! ! !! ! !  !!!!!! !! !     .!.!#\
                    ! ! !! ! !  !      !! !     ...!#\
                    ! ! !! ! !  !      !! !        !#\
                    ! ! !! ! !  !      !! !      ! !#\
                    ! ! !! ! !  !  !!!!!! !      ! !#\
                    ! ! !! ! !  !      !! !      ! !#\
                    ! !    !    !      !! !      ! !#\
                    ! !!!!!!  !!!!!!!! !! !      ! !#\
                    !                ! !! !      ! !#\
                    ! !!!!!!!!!!! !!!! !! !      ! !#\
                    !                     !      ! !#\
                    ! !!!!!!!! !!!!       !        !#\
                    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\
                    ";

    match str_to_maze(&maze_str) {
        Ok(x) => return x,
        Err(i) => std::process::exit(i),
    }
}

fn maze_2() -> Maze {
    let maze_str = "!!!!!!!!!!!!!!!#\
                    !      .......!#\
                    ! !!! !.!!!! .!#\
                    !   ! !.!!O!!.!#\
                    !!!   !....! .!#\
                    !   !!!!!!!!!.!#\
                    ! !!        ..!#\
                    !  !!!!!!!!!.!!#\
                    !           ..+#\
                    !!!!!!!!!!!!!!!#\
                    ";

    match str_to_maze(&maze_str) {
        Ok(x) => return x,
        Err(i) => std::process::exit(i),
    }
}

fn maze_3() -> Maze {
    let maze_str = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\
                    !                            !!!#\
                    ! !  !!!  !!!!!!!!!!!!!!!!!!   !#\
                    ! !  ! !!!              !!!  ! !#\
                    ! !  ! !!!!!!!!!!!!!!!!     !! !#\
                    ! !  !                  !!!!   !#\
                    ! !! !!!!!!!!!!        !!    ! !#\
                    !  ! !        !!!! !!!!!   !!! !#\
                    !! ! ! !!!!      !         !   !#\
                    !! ! ! !!!!   !!!!!!!!!!!!!! ! !#\
                    !! ! ! !!!! ! !              ! !#\
                    !! ! ! !!!! ! ! !!!!       ! ! !#\
                    !! ! ! !!!! ! ! !   !!!    ! ! !#\
                    !  ! ! !!!! ! ! !     !!!  ! ! !#\
                    !  ! ! !!!! ! ! !!!!!      !   !#\
                    !  ! ! !!!! !!! !   !!     ! !!!#\
                    !  ! !  !!!  !! !    !!!   ! !!!#\
                    !  ! !     ! !! !!!!   !!  ! !!!#\
                    !  ! !!    ! !! !  !!      ! !!!#\
                    !  !  !   !! !!     !!!    ! !!!#\
                    !  !! !!!!     !!!    !!   !   !#\
                    !!  ! !! !       !!!   !!  !!! !#\
                    !!  !    !    !    !           !#\
                    !!  !!!!!!    !!   !!!!!!!!!!! !#\
                    !             !!!! !!!!!!!!!!! !#\
                    !  ..........O!!!! !!!!!!!!!!!.+#\
                    !! .!!!!!!    !!   !!!!!!!!!!!.!#\
                    !! .!    !    !    !          .!#\
                    !!..! !! !       !!!   !!  !!!.!#\
                    ! .!! !!!!     !!!    !!   !...!#\
                    ! .!  !   !! !!     !!!    !.!!!#\
                    ! .! !!    ! !! !  !!      !.!!!#\
                    ! .! !     ! !! !!!!   !!  !.!!!#\
                    ! .! !  !!!  !! !    !!!   !.!!!#\
                    ! .! ! !!!! !!! !   !!     !.!!!#\
                    ! .! ! !!!! ! ! !!!!!      !...!#\
                    ! .! ! !!!! ! ! !     !!!  ! !.!#\
                    !!.! ! !!!! ! ! !   !!!    ! !.!#\
                    !!.! ! !!!! ! ! !!!!       ! !.!#\
                    !!.! ! !!!! ! !              !.!#\
                    !!.! ! !!!!   !!!!!!!!!!!!!! !.!#\
                    !!.! ! !!!!      !         !  .!#\
                    !..! !        !!!! !!!!!   !!!.!#\
                    !.!! !!!!!!!!!!        !!    !.!#\
                    !.!  !                  !!!!  .!#\
                    !.!  ! !!!!!!!!!!!!!!!!     !!.!#\
                    !.!  ! !!!              !!!  !.!#\
                    !.!  !!!  !!!!!!!!!!!!!!!!!!...!#\
                    !............................!!!#\
                    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\
                    ";

    match str_to_maze(&maze_str) {
        Ok(x) => return x,
        Err(i) => std::process::exit(i),
    }
}

fn maze_4() -> Maze {
    let maze_str = "!!!!!!!!!!!!!!!!!+!!!!!!!!!!!!!!#\
                    !.................           !!!#\
                    !.!  !!!  !!!!!!!!!!!!!!!!!!   !#\
                    !.!  ! !!!              !!!  ! !#\
                    !.!  ! !!!!!!!!!!!!!!!!     !! !#\
                    !.!  !                  !!!!   !#\
                    !.!! !!!!!!!!!!        !!    ! !#\
                    !..! !        !!!! !!!!!   !!! !#\
                    !!.! ! !!!!      !         !   !#\
                    !!.! ! !!!!   !!!!!!!!!!!!!! ! !#\
                    !!.! ! !!!! ! !              ! !#\
                    !!.! ! !!!! ! ! !!!!       ! ! !#\
                    !!.! ! !!!! ! ! !   !!!    ! ! !#\
                    ! .! ! !!!! ! ! !     !!!  ! ! !#\
                    ! .! ! !!!! ! ! !!!!!      !   !#\
                    ! .! ! !!!! !!! !   !!     ! !!!#\
                    ! .! !  !!!  !! !    !!!   ! !!!#\
                    ! .! !     ! !! !!!!   !!  ! !!!#\
                    ! .! !!    ! !! !  !!      ! !!!#\
                    ! .!  !   !! !!     !!!    ! !!!#\
                    ! .!! !!!!     !!!    !!   !   !#\
                    !!. ! !! !       !!!   !!  !!! !#\
                    !!. !    !    !    !           !#\
                    !!. !!!!!!    !!   !!!!!!!!!!! !#\
                    ! ........... !!!! !!!!!!!!!!! !#\
                    !           . !!!! !!!!!!!!!!! !#\
                    !!  !!!!!!  . !!   !!!!!!!!!!! !#\
                    !!  !    !  . !    !           !#\
                    !!  ! !! !  .    !!!   !!  !!! !#\
                    !  !! !!!!  .  !!!    !!   !   !#\
                    !  !  !   !!.!!     !!!    ! !!!#\
                    !  ! !!    !.!! !  !!      ! !!!#\
                    !  ! !     !.!! !!!!   !!  ! !!!#\
                    !  ! !  !!!..!! !    !!!   ! !!!#\
                    !  ! ! !!!!.!!! !   !!     ! !!!#\
                    !  ! ! !!!!.! ! !!!!!      !   !#\
                    !  ! ! !!!!.! ! !     !!!  ! ! !#\
                    !! ! ! !!!!.! ! !   !!!    ! ! !#\
                    !! ! ! !!!!.! ! !!!!       ! ! !#\
                    !! ! ! !!!!.! !              ! !#\
                    !! ! ! !!!!.  !!!!!!!!!!!!!! ! !#\
                    !! ! ! !!!!.....O!         !   !#\
                    !  ! !        !!!! !!!!!   !!! !#\
                    ! !! !!!!!!!!!!        !!    ! !#\
                    ! !  !                  !!!!   !#\
                    ! !  ! !!!!!!!!!!!!!!!!     !! !#\
                    ! !  ! !!!              !!!  ! !#\
                    ! !  !!!  !!!!!!!!!!!!!!!!!!   !#\
                    !                            !!!#\
                    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\
                    ";

    match str_to_maze(&maze_str) {
        Ok(x) => return x,
        Err(i) => std::process::exit(i),
    }
}


fn maze_5() -> Maze {
    let maze_str = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\
                    +......!!!!       !!!        !!!       !!!!     !!#\
                    !     .!       !!                            !!!!!#\
                    !  !!!.! !!      !!!  !!!!  !!!!!!!!!      !!!   !#\
                    ! !!...!   !!!!!   !!    !          !!    !!     !#\
                    !!!..!!         !    !!  !           !    !     !!#\
                    !! .!!........        !! !!!     !    !   !  !  !!#\
                    !!!. !.  !  !.   !      !!!!!    !!   !   ! !! !!!#\
                    !!!. !.  !  !.   !       !!!!!    !   !!    !  !!!#\
                    !!.. !.  !  !..  !        !  !    !!   !    !   !!#\
                    !!.! !.!  ! ! ..  ! !!!!!!  !      !   !    !   !!#\
                    !!.! !.!  ! !! .  ! !      !        !  !    !   !!#\
                    !!.! !.!  !  ! .  ! !!   !!    !!!! !  !    !   !!#\
                    !!.! !.!! !  ! .  !  !!!   !!!!     !  !    !!  !!#\
                    !!.! !. ! !  ! .  !    !!        !  !   !    !  !!#\
                    ! .!!!. ! !  !!.   !    !        !  !   !    !   !#\
                    ! .!!!. ! !   !.   !     !       !   !  !    !   !#\
                    ! .! !. ! !   !.   !     !       !   !   !   !   !#\
                    ! .! !. ! !!  !....!!!   !      !!   !     ! !   !#\
                    ! .!  ..!  !  !   ...!!!!       !    !     ! ! ! !#\
                    ! .!   .!  !  !!!!!!.... !!!!!!!             ! ! !#\
                    ! .! !!.!  !! !  !!!!  .!                        !#\
                    ! .!!!!.!   !!!! !!!   .!   !!!!!   !!!!!!!!!!!  !#\
                    ! .. !!.!    !!!  !!  !.!!                       !#\
                    !!!.. !. !   !!!      !..!        !!!   !   !    !#\
                    !!! .... !  !!!!      ! .!        !             !!#\
                    !!!!!!!!!!!!!!!!!!!!!!! .! !!!!!!!!!!!!!!!!!!!! !!#\
                    !!!  !                  .!                     !!!#\
                    !!   !   !!!  !!        .!                      !!#\
                    !!   !  !     !!  !!!!!!.!  !!!!!!              !!#\
                    !!   !  !    !!   !!!!!!.! !!!!!!!!          !  !!#\
                    !!  !   !   !!   !!!!!!!.! !!!!!! !!   !  !     !!#\
                    !!  !   !   !   !!!!!!!!.! !!!  !  !   !        !!#\
                    !!  !   !   !  !!!!!!!!!.! !!!! !   !  !  !  !  !!#\
                    !!  !   !   !           .!  !!  !   !  !     !  !!#\
                    !! !!!  !   !   !!!!!!  .!      !    !!         !!#\
                    !! ! !   !  !   !     !!. !    !!!    !    !    !!#\
                    !! ! !   !  !   ! !     .  !   ! !!    !     !  !!#\
                    !! ! !   !  !   ! !!  !!.   !!!   !!   !   ! !  !!#\
                    !! ! !   !  !!  ! !!! ! .....     !!   !      ! !!#\
                    !! ! !   !   !  ! !!!!!!!   .     !    !        !!#\
                    !  ! !   !   !  !  !!!  !   .!!!!     !  !       !#\
                    !  ! !   !   !! !       !   .!      !!.......... !#\
                    ! !! !   !    !  !!!!!!!!!  .!    !!  .!   !!!!. !#\
                    ! !  !   !    !!       !!!  .!!!!!   ..   !    . !#\
                    ! !  !    !!   !!!     !!!  .......... !!!!    . !#\
                    ! !  !     !!     !!!!      !!!!!!!!!!!!      !. !#\
                    ! !         !         !!!!!!                  O. !#\
                    !           !                                    !#\
                    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\
                    ";

    match str_to_maze(&maze_str) {
        Ok(x) => return x,
        Err(i) => std::process::exit(i),
    }
}

fn maze_6() -> Maze {
    let maze_str = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\
                    !      !!!!   ....!!!        !!!       !!!!     !!#\
                    !      !      .!!..........                  !!!!!#\
                    !  !!! ! !!   ...!!!  !!!!. !!!!!!!!!      !!!   !#\
                    ! !!   !   !!!!!.. !!    !.         !!    !!     !#\
                    !!!  !!         !.   !!  !.....      !    !     !!#\
                    !!  !!          ..    !! !!!  .  !    !   !  !  !!#\
                    !!!  !   !  !   .!      !!!!! .  !!   !   ! !! !!!#\
                    !!!  !   !  !   .!       !!!!!.   !   !!    !  !!!#\
                    !!   !   !  !   .!        !  !.   !!   !    !   !!#\
                    !! ! ! !  ! !   . ! !!!!!!  ! ..   !   !    !   !!#\
                    !! ! ! !  ! !!  . ! !      !   .....!  !    !   !!#\
                    !! ! ! !  !  !  . ! !!   !!    !!!!.!  !    !   !!#\
                    !! ! ! !! !  !  ..!  !!!   !!!!    .!  !    !!  !!#\
                    !! ! !  ! !  !   .!    !!        ! .!   !    !  !!#\
                    !  !!!  ! !  !!  . !    !        ! .!   !    !   !#\
                    !  !!!  ! !   !  ..!     !       ! . !  !    !   !#\
                    !  ! !  ! !   !   .!     !       ! . !   !   !   !#\
                    !  ! !  ! !!  !   .!!!   !      !! . !     ! !   !#\
                    !  !    !  !  !   ...!!!!       !  . !     ! ! ! !#\
                    !  !    !  !  !!!!!!.... !!!!!!!   .         ! ! !#\
                    !  ! !! !  !! !  !!!!  .!          .             !#\
                    !  !!!! !   !!!! !!!   .!   !!!!!  .!!!!!!!!!!!  !#\
                    !    !! !    !!!  !!  !.!!..........             !#\
                    !!!   !  !   !!!      !. !.       !!!   !   !    !#\
                    !!!      !  !!!!      !. !.       !             !!#\
                    !!!!!!!!!!!!!!!!!!!!!!!. !.!!!!!!!!!!!!!!!!!!!! !!#\
                    !!!  !                 . !.....................!!!#\
                    !!   !   !!!  !!  O..... !                    ..!!#\
                    !!   !  !     !!  !!!!!! !  !!!!!!             .!!#\
                    !!   !  !    !!   !!!!!! ! !!!!!!!!          ! .!!#\
                    !!  !   !   !!   !!!!!!! ! !!!!!! !!   !  !    .!!#\
                    !!  !   !   !   !!!!!!!! ! !!!  !  !   !       .!!#\
                    !!  !   !   !  !!!!!!!!! ! !!!! !   !  !  !  ! .!!#\
                    !!  !   !   !            !  !!  !   !  !     ! .!!#\
                    !! !!!  !   !   !!!!!!   !      !    !!        .!!#\
                    !! ! !   !  !   !     !!  !    !!!    !    !   .!!#\
                    !! ! !   !  !   ! !        !   ! !!    !     ! .!!#\
                    !! ! !   !  !   ! !!  !!    !!!   !!   !   ! ! .!!#\
                    !! ! !   !  !!  ! !!! !           !!   !      !.!!#\
                    !! ! !   !   !  ! !!!!!!!         !    !       .!!#\
                    !  ! !   !   !  !  !!!  !    !!!!     !  !     . !#\
                    !  ! !   !   !! !       !    !      !!         . !#\
                    ! !! !   !    !  !!!!!!!!!   !    !!   !   !!!!. !#\
                    ! !  !   !    !!       !!!   !!!!!        !    . !#\
                    ! !  !    !!   !!!     !!!   !         !!!!    . !#\
                    ! !  !     !!     !!!!      !!!!!!!!!!!!      !..+#\
                    ! !         !         !!!!!!                     !#\
                    !           !              !                     !#\
                    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\
                    ";

    match str_to_maze(&maze_str) {
        Ok(x) => return x,
        Err(i) => std::process::exit(i),
    }
}

要测试更大的迷宫,只需在maze_1函数中替换迷宫字符串即可。确保将正确的#\字符添加到每一行。

测试您的输入

该脚本可用于测试条目

#!/bin/bash

mkfifo /tmp/pipe1
mkfifo /tmp/pipe2

for arg in "$@"; do
    <path to controller> $arg < /tmp/pipe1 | tee /tmp/pipe2 trascript.txt &
    ( <path to entry> < /tmp/pipe2 | tee /tmp/pipe1 ) > /dev/null
done

rm /tmp/pipe1
rm /tmp/pipe2

例如,我的脚本如下所示:

#!/bin/bash

mkfifo /tmp/pipe1
mkfifo /tmp/pipe2

for arg in "$@"; do
    ./maze/target/release/maze $arg < /tmp/pipe1 | tee /tmp/pipe2 trascript.txt &
    ( ./maze_test/main < /tmp/pipe2 | tee /tmp/pipe1 ) > /dev/null
done

rm /tmp/pipe1
rm /tmp/pipe2

它以以下方式使用:

./script <mazes to test>

例如

./script 1 2 3 4 5 6

它将所有内容打印到控制台,并将所有内容写入一个名为 transcript.txt

为了开发您的条目,您可以取消注释

display_maze(&maze, position)

行中的play功能。这将导致控制器在每个步骤中显示迷宫。


8
因此,墙壁是用老鼠夹制成的。得到它了。
mbomb007 '16

2
@JuliePelletier我认为我们不需要截止日期,我们可以独立运行程序。这里的大多数比赛都是开放式的。
瑕疵的

1
@Liam我认为保留测试电池毫无意义,因为针对测试用例进行优化会认为是一个标准漏洞,因此无论如何都不允许这样做。
瑕疵的

1
@JuliePelletier是的,我将尝试使其尽可能简单
Liam

1
@JuliePelletier完成。
利亚姆

Answers:


4

边界寻找机器人,Java 1.5+,124 + 37 + 206 + 324 + 248 + 223 = 1172个步骤

在此处输入图片说明

该机器人在知道​​奶酪将始终位于边界的情况下,尝试定位并跟随迷宫的边界。

它通过更新迷宫的内部视图并构造北,南,东和西边界墙的当前候选对象来做到这一点。

对这些墙中任何未探索的单元执行A *路径查找,并选择遵循最短路径。但是,只有不包含任何空白空间的候选边界墙才可以成为“真实”边界墙,因此,不包含那些包含空白单元格的边界墙将不被考虑用于路径查找。路径中未探索的单元格的评分较低,而连续未探索的单元格则增加了不希望的分数。

在此最新编辑中,该漫游器现在对已访问的单元格负重。这会带来一点改进。

存在故障安全运动选择机制,该机制可确保在找不到路径的情况下选择有效运动。

请注意,这种实现方式效率很低,在最坏的情况下,可能需要花费几秒钟来解决迷宫问题。

确定性的。与运行java BoundryFindingBot

import java.io.IOException;
import java.io.InputStream;

public class BoundryFindingBot {
    private static final char[] DIRECTION = {'n','e','s','w'};
    private static final int MAP_SIZE = 102;
    private static final int PATH_FINDING_MAX_STEPS = 50000;
    private static final int[][] offsets = new int[][]{{0,-1},{1,0},{0,1},{-1,0}};

    public static void main(String[] args) throws Exception
    {
        char[][] map = new char[MAP_SIZE][MAP_SIZE];
        int[][] visitCount = new int[MAP_SIZE][MAP_SIZE];
        int mx=MAP_SIZE/2-1, my=MAP_SIZE/2-1;
        int direction=0;

        String line=readLine(System.in);
        out:
        while (line!=null && !"0000".equals(line))
        {
            // update map with new information
            for (int i=0;i<4;i++)
            {
                map[mx+offsets[i][0]][my+offsets[i][1]] = line.charAt(i);

                // immediately move toward cheese if found.
                if (line.charAt(i) == '+')
                {
                    System.out.println(DIRECTION[i]);
                    break out;
                }
            }

            // determine the current boundary walls information
            int currentNorthWallY=-1,currentSouthWallY=-1,currentWestWallX=-1,currentEastWallX=-1;
            boolean currentNorthWallHasBlanks=false,currentSouthWallHasBlanks=false,currentEastWallHasBlanks=false,currentWestWallHasBlanks=false;
            for (int y=0;y<MAP_SIZE;y++)
            {
                for (int x=0;x<MAP_SIZE;x++)
                {
                    if (map[x][y]!=0)
                    {
                        if (currentNorthWallY > -1)
                        {
                            if (currentSouthWallY !=y)
                            {
                                currentSouthWallHasBlanks = false;
                            }
                            currentSouthWallY=y;
                            currentSouthWallHasBlanks|=map[x][y]==' ';
                        }
                        else
                        {
                            currentNorthWallY=y;
                        }

                        if (currentNorthWallY == y)
                        {
                            currentNorthWallHasBlanks|=map[x][y]==' ';
                        }

                    }
                }
            }
            for (int x=0;x<MAP_SIZE;x++)
            {
                for (int y=0;y<MAP_SIZE;y++)
                {
                    if (map[x][y]!=0)
                    {

                        if (currentWestWallX > -1)
                        {
                            if (currentEastWallX !=x)
                            {
                                currentEastWallHasBlanks = false;
                            }
                            currentEastWallX=x;
                            currentEastWallHasBlanks|=map[x][y]==' ';
                        }
                        else
                        {
                            currentWestWallX=x;
                        }

                        if (currentWestWallX == x)
                        {
                            currentWestWallHasBlanks|=map[x][y]==' ';
                        }

                    }
                }
            }

            int closestUnvisitedWallCellResult =0xFFFFFF; 

            // attempt to find paths to undiscovered cells in the current north wall, setting the shortest path if shortest of any path
            if (!currentNorthWallHasBlanks)
            {
                for (int x=currentWestWallX;x<=currentEastWallX;x++)
                {
                    if (map[x][currentNorthWallY] == 0)
                    {
                        int result = pathFind(mx, my, x, currentNorthWallY, map,visitCount,currentWestWallX,currentNorthWallY,currentEastWallX,currentSouthWallY);
                        if ((result &0xFFFFFF) <(closestUnvisitedWallCellResult &0xFFFFFF))
                        {
                            closestUnvisitedWallCellResult = result;
                        }
                    }

                }
            }

            // attempt to find paths to undiscovered cells in the current south wall, setting the shortest path if shortest of any path
            if (!currentSouthWallHasBlanks)
            {
                for (int x=currentWestWallX;x<=currentEastWallX;x++)
                {
                    if (map[x][currentSouthWallY] == 0)
                    {
                        int result = pathFind(mx, my, x, currentSouthWallY, map,visitCount,currentWestWallX,currentNorthWallY,currentEastWallX,currentSouthWallY);
                        if ((result &0xFFFFFF) <(closestUnvisitedWallCellResult &0xFFFFFF))
                        {
                            closestUnvisitedWallCellResult = result;
                        }
                    }

                }
            }

            // attempt to find paths to undiscovered cells in the current east wall, setting the shortest path if shortest of any path
            if (!currentEastWallHasBlanks)
            {
                for (int y=currentNorthWallY;y<=currentSouthWallY;y++)
                {
                    if (map[currentEastWallX][y] == 0)
                    {
                        int result = pathFind(mx, my, currentEastWallX, y, map,visitCount,currentWestWallX,currentNorthWallY,currentEastWallX,currentSouthWallY);
                        if ((result &0xFFFFFF) <(closestUnvisitedWallCellResult &0xFFFFFF))
                        {
                            closestUnvisitedWallCellResult = result;
                        }
                    }

                }
            }

            // attempt to find paths to undiscovered cells in the current west wall, setting the shortest path if shortest of any path
            if (!currentWestWallHasBlanks)
            {
                for (int y=currentNorthWallY;y<=currentSouthWallY;y++)
                {
                    if (map[currentWestWallX][y] == 0 )
                    {
                        int result = pathFind(mx, my, currentWestWallX, y, map,visitCount,currentWestWallX,currentNorthWallY,currentEastWallX,currentSouthWallY);
                        if ((result &0xFFFFFF) <(closestUnvisitedWallCellResult &0xFFFFFF))
                        {
                            closestUnvisitedWallCellResult = result;
                        }
                    }
                }
            }

            // fail-safe if we are unable to find a path to a wall (i.e. initial game frame or all current boundary walls are known to have blanks and thus
            // not wall to head for. Simply tries to go north if possible or failing that try to head east, south, west consecutively
            if (closestUnvisitedWallCellResult == 0xFFFFFF)
            {
                for (int i=0;i<4;i++)
                {
                    if (map[mx+offsets[i][0]][my+offsets[i][1]] == ' ')
                    {
                        direction = i;
                        break;
                    }
                }
            }
            else
            {
                direction = closestUnvisitedWallCellResult >> 24;
            }

            mx +=offsets[direction][0];
            my +=offsets[direction][1];
            visitCount[mx][my]+=5;

            System.out.println(DIRECTION[direction]);

//// uncomment to bot's view of maze solving
//          System.err.println();
//          for (int y=currentNorthWallY;y<=currentSouthWallY;y++)
//          {
//              for (int x=currentWestWallX;x<=currentEastWallX;x++)
//              {
//                  if (x==mx && y==my)
//                  {
//                      System.err.print("O");
//                  }
//                  else
//                  {
//                      System.err.print(map[x][y]);
//                  }
//              }
//              System.err.println();
//          }
            line=readLine(System.in);
        }
        System.err.println("Exited");
    }

/**
 * returns a result that is the combination of movement direction and path length of a path found from the given start position to the target
 * position for cells within the given bounding box. Only empty cells and unexplored cells are traversable. Sequential cells of unexplored cells 
 * are given increasing magnitude negative score to reduce desirability.
 */
static int pathFind(int startX, int startY, int targetX,int targetY,char[][] map,int[][] visitCount,int boundMinX,int boundMinY,int boundMaxX,int boundMaxY)
{
    // A*
    if (!(startX==targetX && startY==targetY))
    {

        int[] tileX = new int[PATH_FINDING_MAX_STEPS];
        int[] tileY = new int[PATH_FINDING_MAX_STEPS];
         int[] fscore = new int[PATH_FINDING_MAX_STEPS];
         int[] gscore = new int[PATH_FINDING_MAX_STEPS];
         int[] openList = new int[PATH_FINDING_MAX_STEPS];
         int[] tileParent = new int[PATH_FINDING_MAX_STEPS];
         int[] unexploredCellRun = new int[PATH_FINDING_MAX_STEPS];
         int[][] tileIsClosed = new int[MAP_SIZE][MAP_SIZE];
         int currentIndex = -1;     

        int openListSize=1;
        int tileId=1;

        tileX[0]=targetX;
        tileY[0]=targetY;
        fscore[0]=1;
        gscore[0]=1;



        do
        {
          int currentBestIndex=-1;
          int currentBestScore=Integer.MAX_VALUE;
          //  Look for the lowest F cost square on the open list
          for (int ii=0;ii<openListSize;ii++)
          {
            if (fscore[openList[ii]]<currentBestScore)
            {
              currentBestScore=fscore[openList[ii]];
              currentBestIndex=ii;
            }
          }
          if (currentBestIndex==-1)
          {
            break;
          }
          currentIndex=openList[currentBestIndex];
          int currentTileX=tileX[currentIndex];
          int currentTileY=tileY[currentIndex];

          // found path
          if (startX==currentTileX && startY==currentTileY)
          {
            break;
          }

          // if not in closed list
          if (tileIsClosed[currentTileX][currentTileY]==0)
          {
                // Switch it to the closed list.
                tileIsClosed[currentTileX][currentTileY]=1;
                // remove from openlist
                openList[currentBestIndex]=openList[--openListSize];   

                // add neigbours to the open list if necessary
                for (int i=0;i<4;i++)
                {

                        int surroundingCurrentTileX=currentTileX+offsets[i][0];
                        int surroundingCurrentTileY=currentTileY+offsets[i][1];
                        if (surroundingCurrentTileX>=boundMinX-1 && surroundingCurrentTileX<=boundMaxX+1 &&
                            surroundingCurrentTileY>=boundMinY-1 && surroundingCurrentTileY<=boundMaxY+1 )
                        {
                          tileX[tileId]=surroundingCurrentTileX;
                          tileY[tileId]=surroundingCurrentTileY;
                          if (map[surroundingCurrentTileX][surroundingCurrentTileY]==0)
                          {
                              unexploredCellRun[tileId]=0;
                          }
                          else if (map[surroundingCurrentTileX][surroundingCurrentTileY]=='!')
                          {
                              continue;
                          }
                          else
                          {
                              unexploredCellRun[tileId]=unexploredCellRun[currentIndex]+1;
                          }
                          int surroundingCurrentGscore=gscore[currentIndex]+visitCount[surroundingCurrentTileX][surroundingCurrentTileY]+1+((int) (unexploredCellRun[tileId]*10));
                          gscore[tileId]=surroundingCurrentGscore;
                          fscore[tileId]=surroundingCurrentGscore+Math.abs( surroundingCurrentTileX-startX)+Math.abs( surroundingCurrentTileY-startY);
                          tileParent[tileId]=currentIndex;
                          openList[openListSize++]=tileId++;
                     }
                }
          }
          else
          {
          // remove from openlist
          openList[currentBestIndex]=openList[--openListSize];    
          }
        } while(true);

        if (tileX[tileParent[currentIndex]]-startX<0) return (3 <<24) + currentIndex;
        else if (tileX[tileParent[currentIndex]]-startX>0) return (1 <<24) + currentIndex;
        else if (tileY[tileParent[currentIndex]]-startY<0) return (0 <<24) + currentIndex;
        else if (tileY[tileParent[currentIndex]]-startY>0) return (2 <<24) + currentIndex;
    }
    throw new RuntimeException("Path finding failed");
 }

    /**
     * Reads a line of text from the input stream. Blocks until a new line character is read.
     * NOTE: This method should be used in favor of BufferedReader.readLine(...) as BufferedReader buffers data before performing
     * text line tokenization. This means that BufferedReader.readLine() will block until many game frames have been received. 
     * @param in a InputStream, nominally System.in
     * @return a line of text or null if end of stream.
     * @throws IOException
     */
    private static String readLine(InputStream in) throws IOException
    {
       StringBuilder sb = new StringBuilder();
       int readByte = in.read();
       while (readByte>-1 && readByte!= '\n')
       {
          sb.append((char) readByte);
          readByte = in.read();
       }
       return readByte==-1?null:sb.toString();
    }

}

3

Python,132 + 23 + 228 + 218 + 764 + 213 = 1578步

这是沿着最短的路径,它经过已知的空白空间和未知的空间,到达已知世界的边界矩形,直到可见奶酪为止。

确定性的。使用python SCRIPT或运行python3 SCRIPT(在2.7和3.5中测试)。

import collections, sys

def neighbors(p):
    x, y = p
    return [("n", (x, y + 1)), ("e", (x + 1, y)), ("s", (x, y - 1)), ("w", (x - 1, y))]

ne = sw = loc = 0, 0
maze = {loc: ' '}

while True:
    cells = sys.stdin.readline()
    if cells == '0000\n':
        break
    for (dir1, loc1), cell in zip(neighbors(loc), cells):
        maze[loc1] = cell
        if cell == ' ':
            ne = tuple(map(max, loc1, ne))
            sw = tuple(map(min, loc1, sw))
    visited = {loc}
    queue = collections.deque()
    for dir1, loc1 in neighbors(loc):
        visited.add(loc1)
        queue.append((dir1, loc1, loc1))
    while True:
        dir1, loc1, loc2 = queue.popleft()
        if maze.get(loc2, ' ') == ' ':
            if loc2 not in maze and \
               (any(a >= b for a, b in zip(loc2, ne)) or
                any(a <= b for a, b in zip(loc2, sw))):
                break
            for dir3, loc3 in neighbors(loc2):
                if loc3 not in visited:
                    visited.add(loc3)
                    queue.append((dir1, loc1, loc3))
        elif maze[loc2] == '+':
            break
    sys.stdout.write(dir1 + "\n")
    sys.stdout.flush()
    loc = loc1

2

MATLAB,210 + 23 + 394 + 270 + 1272 + 707 = 2876步

这种方法是对我其他MATLAB提交的修改。(但是,它们使用完全相同的控制器。)

在这种方法中,鼠标遵循一条可能的路径,直到找到死角为止。然后返回到先前的路口,那里有尚未探索的路径。但是,在每一步中,鼠标都会在此处检查是否有封闭的未开发区域。在这些奶酪中,显然不可能(因为奶酪总是在边界上)。如果找到这样的区域,则此后将被忽略。

它是确定性的。从可用路径中,总是按顺序选择NESW

由于无法编译matlab脚本,因此将控制器转换为MATLAB。现在,“程序”只是一个访问全局变量以在步间存储的函数。

function find_the_cheese_controller()
clc;clear;
    global State;
    clearvars -global State;
    %uncomment the maze you want to test
    %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'!O !                    !      !';'!. ! !!!!!!!!!!!!!!!!!! ! !!!!!!';'!. !                    ! !    !';'!. ! !!!!!!!!!!!!!!!!!!!! ! !! !';'!. !...........           ! !!.+';'!. !.!!!!!!!!!.!!!!!!!!!!!!!!!.!';'!.!..!        ...............!.!';'!.!.!! !!!!!!!!!!!!!!!!!!!!!.!.!';'!.!.!! !!!  !               .!.!';'!.!.!! !!!  !!!!!!!!!!!!!!!!.!.!';'!...!! !!!                  .!.!';'! ! !! !!!                  .!.!';'! ! !! !!!  !!!!!!!!! !!!!!!.!.!';'! ! !! !!!  !      !! !     .!.!';'! ! !! !!!  ! !!!!!!! !     .!.!';'! ! !! !!!  !      !! !     .!.!';'! ! !! !!!  !      !! !     .!.!';'! ! !!   !  !      !! !     .!.!';'! ! !! ! !  !!!!!! !! !     .!.!';'! ! !! ! !  !      !! !     ...!';'! ! !! ! !  !      !! !        !';'! ! !! ! !  !      !! !      ! !';'! ! !! ! !  !  !!!!!! !      ! !';'! ! !! ! !  !      !! !      ! !';'! !    !    !      !! !      ! !';'! !!!!!!  !!!!!!!! !! !      ! !';'!                ! !! !      ! !';'! !!!!!!!!!!! !!!! !! !      ! !';'!                     !      ! !';'! !!!!!!!! !!!!       !        !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'];
    %maze=['!!!!!!!!!!!!!!!';'!      .......!';'! !!! !.!!!! .!';'!   ! !.!!O!!.!';'!!!   !....! .!';'!   !!!!!!!!!.!';'! !!        ..!';'!  !!!!!!!!!.!!';'!           ..+';'!!!!!!!!!!!!!!!'];
    %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'!                            !!!';'! !  !!!  !!!!!!!!!!!!!!!!!!   !';'! !  ! !!!              !!!  ! !';'! !  ! !!!!!!!!!!!!!!!!     !! !';'! !  !                  !!!!   !';'! !! !!!!!!!!!!        !!    ! !';'!  ! !        !!!! !!!!!   !!! !';'!! ! ! !!!!      !         !   !';'!! ! ! !!!!   !!!!!!!!!!!!!! ! !';'!! ! ! !!!! ! !              ! !';'!! ! ! !!!! ! ! !!!!       ! ! !';'!! ! ! !!!! ! ! !   !!!    ! ! !';'!  ! ! !!!! ! ! !     !!!  ! ! !';'!  ! ! !!!! ! ! !!!!!      !   !';'!  ! ! !!!! !!! !   !!     ! !!!';'!  ! !  !!!  !! !    !!!   ! !!!';'!  ! !     ! !! !!!!   !!  ! !!!';'!  ! !!    ! !! !  !!      ! !!!';'!  !  !   !! !!     !!!    ! !!!';'!  !! !!!!     !!!    !!   !   !';'!!  ! !! !       !!!   !!  !!! !';'!!  !    !    !    !           !';'!!  !!!!!!    !!   !!!!!!!!!!! !';'!             !!!! !!!!!!!!!!! !';'!  ..........O!!!! !!!!!!!!!!!.+';'!! .!!!!!!    !!   !!!!!!!!!!!.!';'!! .!    !    !    !          .!';'!!..! !! !       !!!   !!  !!!.!';'! .!! !!!!     !!!    !!   !...!';'! .!  !   !! !!     !!!    !.!!!';'! .! !!    ! !! !  !!      !.!!!';'! .! !     ! !! !!!!   !!  !.!!!';'! .! !  !!!  !! !    !!!   !.!!!';'! .! ! !!!! !!! !   !!     !.!!!';'! .! ! !!!! ! ! !!!!!      !...!';'! .! ! !!!! ! ! !     !!!  ! !.!';'!!.! ! !!!! ! ! !   !!!    ! !.!';'!!.! ! !!!! ! ! !!!!       ! !.!';'!!.! ! !!!! ! !              !.!';'!!.! ! !!!!   !!!!!!!!!!!!!! !.!';'!!.! ! !!!!      !         !  .!';'!..! !        !!!! !!!!!   !!!.!';'!.!! !!!!!!!!!!        !!    !.!';'!.!  !                  !!!!  .!';'!.!  ! !!!!!!!!!!!!!!!!     !!.!';'!.!  ! !!!              !!!  !.!';'!.!  !!!  !!!!!!!!!!!!!!!!!!...!';'!............................!!!';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'];
    %maze=['!!!!!!!!!!!!!!!!!+!!!!!!!!!!!!!!';'!.................           !!!';'!.!  !!!  !!!!!!!!!!!!!!!!!!   !';'!.!  ! !!!              !!!  ! !';'!.!  ! !!!!!!!!!!!!!!!!     !! !';'!.!  !                  !!!!   !';'!.!! !!!!!!!!!!        !!    ! !';'!..! !        !!!! !!!!!   !!! !';'!!.! ! !!!!      !         !   !';'!!.! ! !!!!   !!!!!!!!!!!!!! ! !';'!!.! ! !!!! ! !              ! !';'!!.! ! !!!! ! ! !!!!       ! ! !';'!!.! ! !!!! ! ! !   !!!    ! ! !';'! .! ! !!!! ! ! !     !!!  ! ! !';'! .! ! !!!! ! ! !!!!!      !   !';'! .! ! !!!! !!! !   !!     ! !!!';'! .! !  !!!  !! !    !!!   ! !!!';'! .! !     ! !! !!!!   !!  ! !!!';'! .! !!    ! !! !  !!      ! !!!';'! .!  !   !! !!     !!!    ! !!!';'! .!! !!!!     !!!    !!   !   !';'!!. ! !! !       !!!   !!  !!! !';'!!. !    !    !    !           !';'!!. !!!!!!    !!   !!!!!!!!!!! !';'! ........... !!!! !!!!!!!!!!! !';'!           . !!!! !!!!!!!!!!! !';'!!  !!!!!!  . !!   !!!!!!!!!!! !';'!!  !    !  . !    !           !';'!!  ! !! !  .    !!!   !!  !!! !';'!  !! !!!!  .  !!!    !!   !   !';'!  !  !   !!.!!     !!!    ! !!!';'!  ! !!    !.!! !  !!      ! !!!';'!  ! !     !.!! !!!!   !!  ! !!!';'!  ! !  !!!..!! !    !!!   ! !!!';'!  ! ! !!!!.!!! !   !!     ! !!!';'!  ! ! !!!!.! ! !!!!!      !   !';'!  ! ! !!!!.! ! !     !!!  ! ! !';'!! ! ! !!!!.! ! !   !!!    ! ! !';'!! ! ! !!!!.! ! !!!!       ! ! !';'!! ! ! !!!!.! !              ! !';'!! ! ! !!!!.  !!!!!!!!!!!!!! ! !';'!! ! ! !!!!.....O!         !   !';'!  ! !        !!!! !!!!!   !!! !';'! !! !!!!!!!!!!        !!    ! !';'! !  !                  !!!!   !';'! !  ! !!!!!!!!!!!!!!!!     !! !';'! !  ! !!!              !!!  ! !';'! !  !!!  !!!!!!!!!!!!!!!!!!   !';'!                            !!!';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'];
    %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'+......!!!!       !!!        !!!       !!!!     !!';'!     .!       !!                            !!!!!';'!  !!!.! !!      !!!  !!!!  !!!!!!!!!      !!!   !';'! !!...!   !!!!!   !!    !          !!    !!     !';'!!!..!!         !    !!  !           !    !     !!';'!! .!!........        !! !!!     !    !   !  !  !!';'!!!. !.  !  !.   !      !!!!!    !!   !   ! !! !!!';'!!!. !.  !  !.   !       !!!!!    !   !!    !  !!!';'!!.. !.  !  !..  !        !  !    !!   !    !   !!';'!!.! !.!  ! ! ..  ! !!!!!!  !      !   !    !   !!';'!!.! !.!  ! !! .  ! !      !        !  !    !   !!';'!!.! !.!  !  ! .  ! !!   !!    !!!! !  !    !   !!';'!!.! !.!! !  ! .  !  !!!   !!!!     !  !    !!  !!';'!!.! !. ! !  ! .  !    !!        !  !   !    !  !!';'! .!!!. ! !  !!.   !    !        !  !   !    !   !';'! .!!!. ! !   !.   !     !       !   !  !    !   !';'! .! !. ! !   !.   !     !       !   !   !   !   !';'! .! !. ! !!  !....!!!   !      !!   !     ! !   !';'! .!  ..!  !  !   ...!!!!       !    !     ! ! ! !';'! .!   .!  !  !!!!!!.... !!!!!!!             ! ! !';'! .! !!.!  !! !  !!!!  .!                        !';'! .!!!!.!   !!!! !!!   .!   !!!!!   !!!!!!!!!!!  !';'! .. !!.!    !!!  !!  !.!!                       !';'!!!.. !. !   !!!      !..!        !!!   !   !    !';'!!! .... !  !!!!      ! .!        !             !!';'!!!!!!!!!!!!!!!!!!!!!!! .! !!!!!!!!!!!!!!!!!!!! !!';'!!!  !                  .!                     !!!';'!!   !   !!!  !!        .!                      !!';'!!   !  !     !!  !!!!!!.!  !!!!!!              !!';'!!   !  !    !!   !!!!!!.! !!!!!!!!          !  !!';'!!  !   !   !!   !!!!!!!.! !!!!!! !!   !  !     !!';'!!  !   !   !   !!!!!!!!.! !!!  !  !   !        !!';'!!  !   !   !  !!!!!!!!!.! !!!! !   !  !  !  !  !!';'!!  !   !   !           .!  !!  !   !  !     !  !!';'!! !!!  !   !   !!!!!!  .!      !    !!         !!';'!! ! !   !  !   !     !!. !    !!!    !    !    !!';'!! ! !   !  !   ! !     .  !   ! !!    !     !  !!';'!! ! !   !  !   ! !!  !!.   !!!   !!   !   ! !  !!';'!! ! !   !  !!  ! !!! ! .....     !!   !      ! !!';'!! ! !   !   !  ! !!!!!!!   .     !    !        !!';'!  ! !   !   !  !  !!!  !   .!!!!     !  !       !';'!  ! !   !   !! !       !   .!      !!.......... !';'! !! !   !    !  !!!!!!!!!  .!    !!  .!   !!!!. !';'! !  !   !    !!       !!!  .!!!!!   ..   !    . !';'! !  !    !!   !!!     !!!  .......... !!!!    . !';'! !  !     !!     !!!!      !!!!!!!!!!!!      !. !';'! !         !         !!!!!!                  O. !';'!           !                                    !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'];
    %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'!      !!!!   ....!!!        !!!       !!!!     !!';'!      !      .!!..........                  !!!!!';'!  !!! ! !!   ...!!!  !!!!. !!!!!!!!!      !!!   !';'! !!   !   !!!!!.. !!    !.         !!    !!     !';'!!!  !!         !.   !!  !.....      !    !     !!';'!!  !!          ..    !! !!!  .  !    !   !  !  !!';'!!!  !   !  !   .!      !!!!! .  !!   !   ! !! !!!';'!!!  !   !  !   .!       !!!!!.   !   !!    !  !!!';'!!   !   !  !   .!        !  !.   !!   !    !   !!';'!! ! ! !  ! !   . ! !!!!!!  ! ..   !   !    !   !!';'!! ! ! !  ! !!  . ! !      !   .....!  !    !   !!';'!! ! ! !  !  !  . ! !!   !!    !!!!.!  !    !   !!';'!! ! ! !! !  !  ..!  !!!   !!!!    .!  !    !!  !!';'!! ! !  ! !  !   .!    !!        ! .!   !    !  !!';'!  !!!  ! !  !!  . !    !        ! .!   !    !   !';'!  !!!  ! !   !  ..!     !       ! . !  !    !   !';'!  ! !  ! !   !   .!     !       ! . !   !   !   !';'!  ! !  ! !!  !   .!!!   !      !! . !     ! !   !';'!  !    !  !  !   ...!!!!       !  . !     ! ! ! !';'!  !    !  !  !!!!!!.... !!!!!!!   .         ! ! !';'!  ! !! !  !! !  !!!!  .!          .             !';'!  !!!! !   !!!! !!!   .!   !!!!!  .!!!!!!!!!!!  !';'!    !! !    !!!  !!  !.!!..........             !';'!!!   !  !   !!!      !. !.       !!!   !   !    !';'!!!      !  !!!!      !. !.       !             !!';'!!!!!!!!!!!!!!!!!!!!!!!. !.!!!!!!!!!!!!!!!!!!!! !!';'!!!  !                 . !.....................!!!';'!!   !   !!!  !!  O..... !                    ..!!';'!!   !  !     !!  !!!!!! !  !!!!!!             .!!';'!!   !  !    !!   !!!!!! ! !!!!!!!!          ! .!!';'!!  !   !   !!   !!!!!!! ! !!!!!! !!   !  !    .!!';'!!  !   !   !   !!!!!!!! ! !!!  !  !   !       .!!';'!!  !   !   !  !!!!!!!!! ! !!!! !   !  !  !  ! .!!';'!!  !   !   !            !  !!  !   !  !     ! .!!';'!! !!!  !   !   !!!!!!   !      !    !!        .!!';'!! ! !   !  !   !     !!  !    !!!    !    !   .!!';'!! ! !   !  !   ! !        !   ! !!    !     ! .!!';'!! ! !   !  !   ! !!  !!    !!!   !!   !   ! ! .!!';'!! ! !   !  !!  ! !!! !           !!   !      !.!!';'!! ! !   !   !  ! !!!!!!!         !    !       .!!';'!  ! !   !   !  !  !!!  !    !!!!     !  !     . !';'!  ! !   !   !! !       !    !      !!         . !';'! !! !   !    !  !!!!!!!!!   !    !!   !   !!!!. !';'! !  !   !    !!       !!!   !!!!!        !    . !';'! !  !    !!   !!!     !!!   !         !!!!    . !';'! !  !     !!     !!!!      !!!!!!!!!!!!      !..+';'! !         !         !!!!!!                     !';'!           !              !                     !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!']



    %replace dot with space
    maze(maze=='.')=' ';
    %position of mouse
    [u,v]=find(maze=='O'); 
    maze(maze=='O') = ' ';
    step_counter = 0;
    while true; %game loop
        %test if mouse found cheese
        if maze(u,v) == '+';
            disp(['mouse found cheese after ', num2str(step_counter), ' steps']);
            break;
        end

        %extract NESW tiles
        nesw = [maze(u-1,v),maze(u,v+1),maze(u+1,v),maze(u,v-1)];

        %get result and move accordingly
        answer = find_the_cheese(nesw);
        switch answer;
            case 'n';
                u = u-1;
            case 'e';
                v = v+1;
            case 's';
                u = u+1;
            otherwise;
                v = v-1;
        end

        %make sure, mouse did not run into wall
        assert(maze(u,v) ~= '!','mouse ran into wall!');
        step_counter = step_counter + 1;
    end
end


function step = find_the_cheese(nesw)
    global State;
    NESW = 'nesw';
    NESW_REVERSE = 'swne';

    if all(nesw == '0000');
        return;
    elseif ~isfield(State,'maze');
        State = struct('maze', zeros(140)+' ','u',75,'v',75,'state','E');
        State.maze(State.u,State.v) = 'S';
    end    
    if State.maze(State.u-1,State.v) == ' '
        State.maze(State.u-1,State.v) = nesw(1);
    end
    if State.maze(State.u,State.v+1) == ' '
        State.maze(State.u,State.v+1) = nesw(2);
    end
    if State.maze(State.u+1,State.v) == ' '
        State.maze(State.u+1,State.v) = nesw(3);
    end
    if State.maze(State.u,State.v-1) == ' '
        State.maze(State.u,State.v-1) = nesw(4);
    end

    current_nesw = [State.maze(State.u-1,State.v),State.maze(State.u,State.v+1),State.maze(State.u+1,State.v),State.maze(State.u,State.v-1)];

    if any(current_nesw == '+'); % if there is cheese, go there
        nesw_index = find(current_nesw == '+',1);

    elseif any(current_nesw == ' '); % if there is a path that we did not walk, go there
        nesw_index = find(current_nesw == ' ',1);
        State.state = 'E';

    else % return to previous crossing
        nesw_index = find(NESW == State.maze(State.u,State.v),1);
        assert(numel(nesw_index)>0,'not enough indices')

        State.state = 'R';
    end

    %execute the step
    if State.state == 'E';
        step = NESW(nesw_index);
    else %State.state = 'R'
        step = State.maze(State.u, State.v);
    end

    switch step;
        case 'n';
            State.u = State.u-1;
        case 'e';
            State.v = State.v+1;
        case 's';
            State.u = State.u+1;
        otherwise;
            State.v = State.v-1;
    end

    if State.maze(State.u,State.v) == ' '; %if we do not have a reverse poniter yet
        State.maze(State.u,State.v) = NESW_REVERSE(nesw_index); %reverse pointer
    end

    %check whether we have any enclosed areas, where the cheese obviously cannot be
    M = imfill(State.maze ~= ' ','holes'); 
    %fill those areas with walls
    State.maze(M & State.maze == ' ') = '!';


    %disp_important(State.maze); %uncomment for display
end


function disp_important(m) %just show the important stuff of the maze
    if any(m(:) ~= ' ');
        for k=1:4
            m = rot90(m);
            while all(m(:,1) == ' ');
                m = m(:,2:end);
            end
        end
    end
    if numel(m) == 0;
        m = 'X';
    end
    m = padarray(m,[1,1],35,'both');
    disp([m,'']);
end

仅供参考,这些迷宫不是您被打分的迷宫。“可能总共有10个迷宫,并且每个提交都可能会从几个不同的起始位置和奶酪位置尝试每个迷宫几次。”
mbomb007 '16

我知道,但是没有什么别的我可以在标题写:d没有真正的,我只是觉得这两个测试案例至少给一些所提交的材料进行怎样的印象。
瑕疵的

现在已经释放了电池
Liam

太好了,谢谢!我将在工作完成后立即更新=)
更加模糊的

@Liam我更新了它们!
瑕疵的

1

Python 3,156字节,37692 + 715 + 50626 + 27806 + 148596 + 172675 = 438110步骤

这不是,但是高尔夫仍然很有趣。这类似于mbomb007的想法(未完全实现),但是朝着奶酪走或走的路线最少,但通过转到字母顺序的最新方向名称来打破联系。

确定性的。运行python3 SCRIPT(在3.5中测试)。

x=y=0
f={}
for l in iter(input,'0000'):c,d,x,y=p=max((f.setdefault(p,0),p)for p in zip(l,'nesw',[x,x+1,x,x-1],[y+1,y,y-1,y])if'!'!=p[0])[1];print(d);f[p]-=1

@ mbomb007 f跟踪使用空间之间的哪些步骤以及使用频率。例如,-f[' ', 'n', 3, 6]是我们从(3,5)到(3,6)向北走的次数。
Anders Kaseorg '16

所以它也跟踪方向吗?
mbomb007 '16

@ mbomb007是的,但这仅是因为这恰好节省了几个字节-记住方向实际上使它需要执行更多的步骤。
Anders Kaseorg '16

1

PHP 362 + 37 + 1638 + 1508 + 6696 + 1613 = 11854步

在错误修复的代码上运行基准测试:

<?php

class Maze {
    public $map, $pos;
    public $prevPos = FALSE;
    public $intersections = [];

    public $n = 75, $e = 75, $w = 75, $s = 75;

    public function __construct() {
        // since we don't know where we start, build a 150x150 map and position ourselves at the middle
        $this->map = array_pad([], 150, array_pad([], 150, 0)); // 0 is unknown
        $this->pos = ['x'=> 75, 'y'=> 75];
    }

    public function play($input){
        $this->updateMap($input);
        $this->move();
    }

    private function updateField($x, $y, $inData) {
        if ($inData == '!' || $this->map[$x][$y] >= 1000) {                 // avoid overwriting our observations
            $this->map[$x][$y] = 1000;
            return;
        }

        // update our known borders
        if ($x <= $this->w) {
            $this->w = $x - 1;
        }
        elseif ($x >= $this->e) {
            $this->e = $x + 1;
        }
        elseif ($y <= $this->n) {
            $this->n = $y - 1;
        }
        elseif ($y >= $this->s) {
            $this->s = $y + 1;
        }

        if (!$this->map[$x][$y]) {
            $this->map[$x][$y] = $inData == '+' ? -1 : 1;
        }
    }

    private function checkForIntersection($input) {
        if (array_key_exists('x' . $this->pos['x'] . 'y' . $this->pos['y'], $this->intersections)) {
            if ($this->intersections['x' . $this->pos['x'] . 'y' . $this->pos['y']] > 0) {
                $this->intersections['x' . $this->pos['x'] . 'y' . $this->pos['y']] --;
                return TRUE;                                        // intersection already crossed
            }
        }
        elseif ($c = substr_count($input, ' ') > 2) {
            $this->intersections['x' . $this->pos['x'] . 'y' . $this->pos['y']] = $c - 1;
        }

        return FALSE;
    }

    private function updateMap($input) {
        if ($this->checkForIntersection($input)) {
            // if we're at a known intersection, we know that the path we come from lead nowhere
            $this->updateField($this->prevPos['x'], $this->prevPos['y'], '!');
        }

        // update discovered information
        $this->updateField($this->pos['x'], $this->pos['y'] - 1, $input[0]);
        $this->updateField($this->pos['x'] + 1, $this->pos['y'], $input[1]);
        $this->updateField($this->pos['x'], $this->pos['y'] + 1, $input[2]);
        $this->updateField($this->pos['x'] - 1, $this->pos['y'], $input[3]);
    }

    private function move() {
        if ($this->prevPos) {

            $this->map[$this->prevPos['x']][$this->prevPos['y']] ++;    // count times stepped on   
        }

        $best = ['w' => 1000];

        foreach ([
            ['x' => $this->pos['x'], 'y' => $this->pos['y'] - 1, 'w' => $this->map[$this->pos['x']][$this->pos['y'] - 1], 'd' => 'n'],
            ['x' => $this->pos['x'] + 1, 'y' => $this->pos['y'], 'w' => $this->map[$this->pos['x'] + 1][$this->pos['y']], 'd' => 'e'],
            ['x' => $this->pos['x'], 'y' => $this->pos['y'] + 1, 'w' => $this->map[$this->pos['x']][$this->pos['y'] + 1], 'd' => 's'],
            ['x' => $this->pos['x'] - 1, 'y' => $this->pos['y'], 'w' => $this->map[$this->pos['x'] - 1][$this->pos['y']], 'd' => 'w']]
        as $direction) {
            if ($direction['w'] < $best['w'] || ($direction['w'] == $best['w'] && $best['w'] < 1000 && max($this->e - $direction['x'],  $direction['x'] - $this->w, $direction['y'] - $this->n, $this->s - $direction['y']) > max($best['x'] - $this->e, $this->w - $best['x'], $best['y'] - $this->n, $this->s - $best['y']))) { 
            // encourage searching for borders which will later allow to block certain dead end paths without walking them
            // testing with middle search instead
                $best = $direction;
            }
        }

        echo $best['d'] . "\n";

        $this->prevPos = $this->pos;
        $this->pos = $best;
    }
}

$maze = new Maze();

while (strncmp(($input = fgets(STDIN)), '0000', 4)) {
    $len = strlen($input);
    if (($len > 6) || $len < 3) { continue; }

    $maze->play($input);
}

1

MATLAB,212 + 23 + 416 + 300 + 1806 + 757 = 3514步

在这种方法中,鼠标遵循一条可能的路径,直到找到死角为止。然后返回到先前的路口,那里有尚未探索的路径。它是确定性的。从可用路径中,它总是按顺序选择NESW(而不是NSFW,因为我总是很想写=)

由于无法编译matlab脚本,因此将控制器转换为MATLAB。现在,“程序”只是一个访问全局变量以在步间存储的函数。

function find_the_cheese_controller()
clc;clear;
    global State;
    clearvars -global State;
    %uncomment the maze you want to test
    %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'!O !                    !      !';'!. ! !!!!!!!!!!!!!!!!!! ! !!!!!!';'!. !                    ! !    !';'!. ! !!!!!!!!!!!!!!!!!!!! ! !! !';'!. !...........           ! !!.+';'!. !.!!!!!!!!!.!!!!!!!!!!!!!!!.!';'!.!..!        ...............!.!';'!.!.!! !!!!!!!!!!!!!!!!!!!!!.!.!';'!.!.!! !!!  !               .!.!';'!.!.!! !!!  !!!!!!!!!!!!!!!!.!.!';'!...!! !!!                  .!.!';'! ! !! !!!                  .!.!';'! ! !! !!!  !!!!!!!!! !!!!!!.!.!';'! ! !! !!!  !      !! !     .!.!';'! ! !! !!!  ! !!!!!!! !     .!.!';'! ! !! !!!  !      !! !     .!.!';'! ! !! !!!  !      !! !     .!.!';'! ! !!   !  !      !! !     .!.!';'! ! !! ! !  !!!!!! !! !     .!.!';'! ! !! ! !  !      !! !     ...!';'! ! !! ! !  !      !! !        !';'! ! !! ! !  !      !! !      ! !';'! ! !! ! !  !  !!!!!! !      ! !';'! ! !! ! !  !      !! !      ! !';'! !    !    !      !! !      ! !';'! !!!!!!  !!!!!!!! !! !      ! !';'!                ! !! !      ! !';'! !!!!!!!!!!! !!!! !! !      ! !';'!                     !      ! !';'! !!!!!!!! !!!!       !        !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'];
    %maze=['!!!!!!!!!!!!!!!';'!      .......!';'! !!! !.!!!! .!';'!   ! !.!!O!!.!';'!!!   !....! .!';'!   !!!!!!!!!.!';'! !!        ..!';'!  !!!!!!!!!.!!';'!           ..+';'!!!!!!!!!!!!!!!'];
    %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'!                            !!!';'! !  !!!  !!!!!!!!!!!!!!!!!!   !';'! !  ! !!!              !!!  ! !';'! !  ! !!!!!!!!!!!!!!!!     !! !';'! !  !                  !!!!   !';'! !! !!!!!!!!!!        !!    ! !';'!  ! !        !!!! !!!!!   !!! !';'!! ! ! !!!!      !         !   !';'!! ! ! !!!!   !!!!!!!!!!!!!! ! !';'!! ! ! !!!! ! !              ! !';'!! ! ! !!!! ! ! !!!!       ! ! !';'!! ! ! !!!! ! ! !   !!!    ! ! !';'!  ! ! !!!! ! ! !     !!!  ! ! !';'!  ! ! !!!! ! ! !!!!!      !   !';'!  ! ! !!!! !!! !   !!     ! !!!';'!  ! !  !!!  !! !    !!!   ! !!!';'!  ! !     ! !! !!!!   !!  ! !!!';'!  ! !!    ! !! !  !!      ! !!!';'!  !  !   !! !!     !!!    ! !!!';'!  !! !!!!     !!!    !!   !   !';'!!  ! !! !       !!!   !!  !!! !';'!!  !    !    !    !           !';'!!  !!!!!!    !!   !!!!!!!!!!! !';'!             !!!! !!!!!!!!!!! !';'!  ..........O!!!! !!!!!!!!!!!.+';'!! .!!!!!!    !!   !!!!!!!!!!!.!';'!! .!    !    !    !          .!';'!!..! !! !       !!!   !!  !!!.!';'! .!! !!!!     !!!    !!   !...!';'! .!  !   !! !!     !!!    !.!!!';'! .! !!    ! !! !  !!      !.!!!';'! .! !     ! !! !!!!   !!  !.!!!';'! .! !  !!!  !! !    !!!   !.!!!';'! .! ! !!!! !!! !   !!     !.!!!';'! .! ! !!!! ! ! !!!!!      !...!';'! .! ! !!!! ! ! !     !!!  ! !.!';'!!.! ! !!!! ! ! !   !!!    ! !.!';'!!.! ! !!!! ! ! !!!!       ! !.!';'!!.! ! !!!! ! !              !.!';'!!.! ! !!!!   !!!!!!!!!!!!!! !.!';'!!.! ! !!!!      !         !  .!';'!..! !        !!!! !!!!!   !!!.!';'!.!! !!!!!!!!!!        !!    !.!';'!.!  !                  !!!!  .!';'!.!  ! !!!!!!!!!!!!!!!!     !!.!';'!.!  ! !!!              !!!  !.!';'!.!  !!!  !!!!!!!!!!!!!!!!!!...!';'!............................!!!';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'];
    %maze=['!!!!!!!!!!!!!!!!!+!!!!!!!!!!!!!!';'!.................           !!!';'!.!  !!!  !!!!!!!!!!!!!!!!!!   !';'!.!  ! !!!              !!!  ! !';'!.!  ! !!!!!!!!!!!!!!!!     !! !';'!.!  !                  !!!!   !';'!.!! !!!!!!!!!!        !!    ! !';'!..! !        !!!! !!!!!   !!! !';'!!.! ! !!!!      !         !   !';'!!.! ! !!!!   !!!!!!!!!!!!!! ! !';'!!.! ! !!!! ! !              ! !';'!!.! ! !!!! ! ! !!!!       ! ! !';'!!.! ! !!!! ! ! !   !!!    ! ! !';'! .! ! !!!! ! ! !     !!!  ! ! !';'! .! ! !!!! ! ! !!!!!      !   !';'! .! ! !!!! !!! !   !!     ! !!!';'! .! !  !!!  !! !    !!!   ! !!!';'! .! !     ! !! !!!!   !!  ! !!!';'! .! !!    ! !! !  !!      ! !!!';'! .!  !   !! !!     !!!    ! !!!';'! .!! !!!!     !!!    !!   !   !';'!!. ! !! !       !!!   !!  !!! !';'!!. !    !    !    !           !';'!!. !!!!!!    !!   !!!!!!!!!!! !';'! ........... !!!! !!!!!!!!!!! !';'!           . !!!! !!!!!!!!!!! !';'!!  !!!!!!  . !!   !!!!!!!!!!! !';'!!  !    !  . !    !           !';'!!  ! !! !  .    !!!   !!  !!! !';'!  !! !!!!  .  !!!    !!   !   !';'!  !  !   !!.!!     !!!    ! !!!';'!  ! !!    !.!! !  !!      ! !!!';'!  ! !     !.!! !!!!   !!  ! !!!';'!  ! !  !!!..!! !    !!!   ! !!!';'!  ! ! !!!!.!!! !   !!     ! !!!';'!  ! ! !!!!.! ! !!!!!      !   !';'!  ! ! !!!!.! ! !     !!!  ! ! !';'!! ! ! !!!!.! ! !   !!!    ! ! !';'!! ! ! !!!!.! ! !!!!       ! ! !';'!! ! ! !!!!.! !              ! !';'!! ! ! !!!!.  !!!!!!!!!!!!!! ! !';'!! ! ! !!!!.....O!         !   !';'!  ! !        !!!! !!!!!   !!! !';'! !! !!!!!!!!!!        !!    ! !';'! !  !                  !!!!   !';'! !  ! !!!!!!!!!!!!!!!!     !! !';'! !  ! !!!              !!!  ! !';'! !  !!!  !!!!!!!!!!!!!!!!!!   !';'!                            !!!';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'];
    %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'+......!!!!       !!!        !!!       !!!!     !!';'!     .!       !!                            !!!!!';'!  !!!.! !!      !!!  !!!!  !!!!!!!!!      !!!   !';'! !!...!   !!!!!   !!    !          !!    !!     !';'!!!..!!         !    !!  !           !    !     !!';'!! .!!........        !! !!!     !    !   !  !  !!';'!!!. !.  !  !.   !      !!!!!    !!   !   ! !! !!!';'!!!. !.  !  !.   !       !!!!!    !   !!    !  !!!';'!!.. !.  !  !..  !        !  !    !!   !    !   !!';'!!.! !.!  ! ! ..  ! !!!!!!  !      !   !    !   !!';'!!.! !.!  ! !! .  ! !      !        !  !    !   !!';'!!.! !.!  !  ! .  ! !!   !!    !!!! !  !    !   !!';'!!.! !.!! !  ! .  !  !!!   !!!!     !  !    !!  !!';'!!.! !. ! !  ! .  !    !!        !  !   !    !  !!';'! .!!!. ! !  !!.   !    !        !  !   !    !   !';'! .!!!. ! !   !.   !     !       !   !  !    !   !';'! .! !. ! !   !.   !     !       !   !   !   !   !';'! .! !. ! !!  !....!!!   !      !!   !     ! !   !';'! .!  ..!  !  !   ...!!!!       !    !     ! ! ! !';'! .!   .!  !  !!!!!!.... !!!!!!!             ! ! !';'! .! !!.!  !! !  !!!!  .!                        !';'! .!!!!.!   !!!! !!!   .!   !!!!!   !!!!!!!!!!!  !';'! .. !!.!    !!!  !!  !.!!                       !';'!!!.. !. !   !!!      !..!        !!!   !   !    !';'!!! .... !  !!!!      ! .!        !             !!';'!!!!!!!!!!!!!!!!!!!!!!! .! !!!!!!!!!!!!!!!!!!!! !!';'!!!  !                  .!                     !!!';'!!   !   !!!  !!        .!                      !!';'!!   !  !     !!  !!!!!!.!  !!!!!!              !!';'!!   !  !    !!   !!!!!!.! !!!!!!!!          !  !!';'!!  !   !   !!   !!!!!!!.! !!!!!! !!   !  !     !!';'!!  !   !   !   !!!!!!!!.! !!!  !  !   !        !!';'!!  !   !   !  !!!!!!!!!.! !!!! !   !  !  !  !  !!';'!!  !   !   !           .!  !!  !   !  !     !  !!';'!! !!!  !   !   !!!!!!  .!      !    !!         !!';'!! ! !   !  !   !     !!. !    !!!    !    !    !!';'!! ! !   !  !   ! !     .  !   ! !!    !     !  !!';'!! ! !   !  !   ! !!  !!.   !!!   !!   !   ! !  !!';'!! ! !   !  !!  ! !!! ! .....     !!   !      ! !!';'!! ! !   !   !  ! !!!!!!!   .     !    !        !!';'!  ! !   !   !  !  !!!  !   .!!!!     !  !       !';'!  ! !   !   !! !       !   .!      !!.......... !';'! !! !   !    !  !!!!!!!!!  .!    !!  .!   !!!!. !';'! !  !   !    !!       !!!  .!!!!!   ..   !    . !';'! !  !    !!   !!!     !!!  .......... !!!!    . !';'! !  !     !!     !!!!      !!!!!!!!!!!!      !. !';'! !         !         !!!!!!                  O. !';'!           !                                    !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'];
    %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'!      !!!!   ....!!!        !!!       !!!!     !!';'!      !      .!!..........                  !!!!!';'!  !!! ! !!   ...!!!  !!!!. !!!!!!!!!      !!!   !';'! !!   !   !!!!!.. !!    !.         !!    !!     !';'!!!  !!         !.   !!  !.....      !    !     !!';'!!  !!          ..    !! !!!  .  !    !   !  !  !!';'!!!  !   !  !   .!      !!!!! .  !!   !   ! !! !!!';'!!!  !   !  !   .!       !!!!!.   !   !!    !  !!!';'!!   !   !  !   .!        !  !.   !!   !    !   !!';'!! ! ! !  ! !   . ! !!!!!!  ! ..   !   !    !   !!';'!! ! ! !  ! !!  . ! !      !   .....!  !    !   !!';'!! ! ! !  !  !  . ! !!   !!    !!!!.!  !    !   !!';'!! ! ! !! !  !  ..!  !!!   !!!!    .!  !    !!  !!';'!! ! !  ! !  !   .!    !!        ! .!   !    !  !!';'!  !!!  ! !  !!  . !    !        ! .!   !    !   !';'!  !!!  ! !   !  ..!     !       ! . !  !    !   !';'!  ! !  ! !   !   .!     !       ! . !   !   !   !';'!  ! !  ! !!  !   .!!!   !      !! . !     ! !   !';'!  !    !  !  !   ...!!!!       !  . !     ! ! ! !';'!  !    !  !  !!!!!!.... !!!!!!!   .         ! ! !';'!  ! !! !  !! !  !!!!  .!          .             !';'!  !!!! !   !!!! !!!   .!   !!!!!  .!!!!!!!!!!!  !';'!    !! !    !!!  !!  !.!!..........             !';'!!!   !  !   !!!      !. !.       !!!   !   !    !';'!!!      !  !!!!      !. !.       !             !!';'!!!!!!!!!!!!!!!!!!!!!!!. !.!!!!!!!!!!!!!!!!!!!! !!';'!!!  !                 . !.....................!!!';'!!   !   !!!  !!  O..... !                    ..!!';'!!   !  !     !!  !!!!!! !  !!!!!!             .!!';'!!   !  !    !!   !!!!!! ! !!!!!!!!          ! .!!';'!!  !   !   !!   !!!!!!! ! !!!!!! !!   !  !    .!!';'!!  !   !   !   !!!!!!!! ! !!!  !  !   !       .!!';'!!  !   !   !  !!!!!!!!! ! !!!! !   !  !  !  ! .!!';'!!  !   !   !            !  !!  !   !  !     ! .!!';'!! !!!  !   !   !!!!!!   !      !    !!        .!!';'!! ! !   !  !   !     !!  !    !!!    !    !   .!!';'!! ! !   !  !   ! !        !   ! !!    !     ! .!!';'!! ! !   !  !   ! !!  !!    !!!   !!   !   ! ! .!!';'!! ! !   !  !!  ! !!! !           !!   !      !.!!';'!! ! !   !   !  ! !!!!!!!         !    !       .!!';'!  ! !   !   !  !  !!!  !    !!!!     !  !     . !';'!  ! !   !   !! !       !    !      !!         . !';'! !! !   !    !  !!!!!!!!!   !    !!   !   !!!!. !';'! !  !   !    !!       !!!   !!!!!        !    . !';'! !  !    !!   !!!     !!!   !         !!!!    . !';'! !  !     !!     !!!!      !!!!!!!!!!!!      !..+';'! !         !         !!!!!!                     !';'!           !              !                     !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!']

;

    %replace dot with space
    maze(maze=='.')=' ';
    %position of mouse
    [u,v]=find(maze=='O'); 
    maze(maze=='O') = ' ';
    step_counter = 0;
    while true; %game loop
        %test if mouse found cheese
        if maze(u,v) == '+';
            disp(['mouse found cheese after ', num2str(step_counter), ' steps']);
            break;
        end

        %extract NESW tiles
        nesw = [maze(u-1,v),maze(u,v+1),maze(u+1,v),maze(u,v-1)];

        %get result and move accordingly
        answer = find_the_cheese(nesw);
        switch answer;
            case 'n';
                u = u-1;
            case 'e';
                v = v+1;
            case 's';
                u = u+1;
            otherwise;
                v = v-1;
        end

        %make sure, mouse did not run into wall
        assert(maze(u,v) ~= '!','mouse ran into wall!');
        step_counter = step_counter + 1;
    end
end


function step = find_the_cheese(nesw)
    global State;
    NESW = 'nesw';
    NESW_REVERSE = 'swne';

    if all(nesw == '0000');
        return;
    elseif ~isfield(State,'maze');
        State = struct('maze', zeros(140)+' ','u',75,'v',75,'state','E');
        State.maze(State.u,State.v) = 'S';
    end    
    if State.maze(State.u-1,State.v) == ' '
        State.maze(State.u-1,State.v) = nesw(1);
    end
    if State.maze(State.u,State.v+1) == ' '
        State.maze(State.u,State.v+1) = nesw(2);
    end
    if State.maze(State.u+1,State.v) == ' '
        State.maze(State.u+1,State.v) = nesw(3);
    end
    if State.maze(State.u,State.v-1) == ' '
        State.maze(State.u,State.v-1) = nesw(4);
    end

    current_nesw = [State.maze(State.u-1,State.v),State.maze(State.u,State.v+1),State.maze(State.u+1,State.v),State.maze(State.u,State.v-1)];

    if any(current_nesw == '+'); % if there is cheese, go there
        nesw_index = find(current_nesw == '+',1);

    elseif any(current_nesw == ' '); % if there is a path that we did not walk, go there
        nesw_index = find(current_nesw == ' ',1);
        State.state = 'E';

    else % return to previous crossing
        nesw_index = find(NESW == State.maze(State.u,State.v),1);
        assert(numel(nesw_index)>0,'not enough indices')

        State.state = 'R';
    end

    %execute the step
    if State.state == 'E';
        step = NESW(nesw_index);
    else %State.state = 'R'
        step = State.maze(State.u, State.v);
    end

    switch step;
        case 'n';
            State.u = State.u-1;
        case 'e';
            State.v = State.v+1;
        case 's';
            State.u = State.u+1;
        otherwise;
            State.v = State.v-1;
    end

    if State.maze(State.u,State.v) == ' '; %if we do not have a reverse poniter yet
        State.maze(State.u,State.v) = NESW_REVERSE(nesw_index); %reverse pointer
    end

    %disp_important(State.maze); %uncomment for display
end


function disp_important(m) %just show the important stuff of the maze
    if any(m(:) ~= ' ');
        for k=1:4
            m = rot90(m);
            while all(m(:,1) == ' ');
                m = m(:,2:end);
            end
        end
    end
    if numel(m) == 0;
        m = 'X';
    end
    m = padarray(m,[1,1],35,'both');
    disp([m,'']);
end

1

简单机器人,Java 1.4+,176 + 25 + 1118 + 486 + 10944 + 1847 = 14596步

该机器人计数并记录到达每个访问的单元格所采取的步骤数,然后在确定移动方向时,选择步骤数最少的方向。如果出现平局,则以N,E,S,W顺序选择方向。

我没有安装锈,所以我不得不在Java中实现控制器,这是我用来测试它的机器人。我将很快尝试更聪明的求解器。

确定性的。与运行java SimpleBot

import java.io.IOException;
import java.io.InputStream;

public class SimpleBot 
{
    private static final char[] DIRECTION = {'n','e','s','w'};
    public static void main(String[] args) throws Exception
    {
        int[][] stepMap = new int[100][100];
        int mx=49, my=49;
        int[][] offsets = new int[][]{{0,-1},{1,0},{0,1},{-1,0}};

        String line=readLine(System.in);
        int step=0;
        while (line!=null && !"0000".equals(line))
        {
            stepMap[mx][my]=step++;

            int minStep = Integer.MAX_VALUE;
            int minIndex = -1;
            for (int i=0;i<4;i++)
            {
                if (line.charAt(i) == '+')
                {
                    minIndex=i;
                    break;
                }
                else if (line.charAt(i) == ' ')
                {
                    if (stepMap[mx+offsets[i][0]][my+offsets[i][1]]<minStep)
                    {
                        minStep = stepMap[mx+offsets[i][0]][my+offsets[i][1]];
                        minIndex=i;
                    }
                }
            }
            mx +=offsets[minIndex][0];
            my +=offsets[minIndex][1];

            System.out.println(DIRECTION[minIndex]);
            line=readLine(System.in);
        }
    }

    /**
     * Reads a line of text from the input stream. Blocks until a new line character is read.
     * NOTE: This method is used in favor of BufferedReader.readLine(...) as BufferedReader buffers data before performing
     * text line tokenization. This means that BufferedReader.readLine() will block until sufficient input have been received. 
     * @param in a InputStream, nominally System.in
     * @return a line of text or null if end of stream.
     * @throws IOException
     */
    private static String readLine(InputStream in) throws IOException
    {
       StringBuilder sb = new StringBuilder();
       int readByte = in.read();
       while (readByte>-1 && readByte!= '\n')
       {
          sb.append((char) readByte);
          readByte = in.read();
       }
       return readByte==-1?null:sb.toString();
    }

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.