【React】迷路のスタートとゴールを設定する

迷路のスタートとゴールを座標によって設定し、
スタートを「S」、ゴールを「G」として出力する。

Canvas.tsx

import React, { useEffect } from 'react';
import p5 from 'p5';
import Maze from './maze';

const sketch = (p: p5) => {
  p.setup = () => {
    const maze1 = new Maze(p, 15, 15);
    maze1.set_maze_boutaoshi();
    maze1.set_start_goal([9,5], [7,11]);
    maze1.print_maze();
  }
}
    
const Canvas: React.FC = () => {
  useEffect(() => {
    new p5(sketch)
  })
  return (
    <React.Fragment>
    </React.Fragment>
  );
}
    
export default Canvas;

maze.ts

import p5 from 'p5';

type maze = number[][] | string[][];

class Maze {
  p: p5;
  PATH: number;
  WALL: number;
  width: number;
  height: number;
  maze: maze = [];
  start: number[] = [];
  goal: number[] = [];

  constructor(p: p5, width: number, height: number, seed: number = 0) {
    this.p = p;
    this.PATH = 0;
    this.WALL = 1;
    this.width = width;
    this.height = height;
    if (this.width < 5 || this.height < 5) {
      return;
    }
    if (this.width%2 === 0) {
      this.width++;
    }
    if (this.height%2 === 0) {
      this.height++;
    }
    this.maze = [...Array(this.height)].map(() => Array(this.width).fill(0));
    this.start = [1, 1];
    this.goal = [this.width-2, this.height-2];
    p.randomSeed(seed);
  }

  set_outer_wall(): maze {
    for (let y = 0; y < this.height; y++) {
      for (let x = 0; x < this.width; x++) {
        if (x === 0 || y === 0 || x === this.width-1 || y === this.height-1) {
          this.maze[y][x] = this.WALL;
        }
      }
    }
    return this.maze;
  }

  set_inner_wall(): maze {
    for (let y = 2; y <= this.height-3; y+=2) {
      for (let x = 2; x <= this.width-3; x+=2) {
        this.maze[y][x] = this.WALL;
      }
    }
    return this.maze;
  }

  set_maze_boutaoshi(): maze {
    let cell_x: number, cell_y: number, direction: number;
    this.set_outer_wall();
    this.set_inner_wall();
    for (let y = 2; y <= this.height-3; y+=2) {
      for (let x = 2; x <= this.width-3; x+=2) {
        while (true) {
          cell_x = x;
          cell_y = y;
          if (y === 2) {
            direction = this.p.floor(this.p.random(4));
          } else {
            direction = this.p.floor(this.p.random(3));
          }
          if (direction === 0) {
            cell_x += 1;
          } else if (direction === 1) {
            cell_y += 1;
          } else if (direction === 2) {
            cell_x -= 1;
          } else if (direction === 3) {
            cell_y -= 1;
          }
          if (this.maze[cell_y][cell_x] !== this.WALL) {
            this.maze[cell_y][cell_x] = this.WALL;
            break;
          }
        }
      }
    }
    return this.maze;
  }

  set_start_goal(start: number[], goal: number[]): maze {
    if (this.maze[start[1]][start[0]] === this.PATH) {
      this.start = start;
    }
    if (this.maze[goal[1]][goal[0]] === this.PATH) {
      this.goal = goal;
    }
    return this.maze;
  }

  print_maze(): void {
    let arr: string;
    this.maze[this.start[1]][this.start[0]] = 'S';
    this.maze[this.goal[1]][this.goal[0]] = 'G';
    for (let row of this.maze) {
      arr = '';
      for (let cell of row) {
        if (cell === this.WALL) {
          arr += '#';
        } else if (cell === this.PATH) {
          arr += ' ';
        } else if (cell === 'S') {
	  arr += 'S';
	} else if (cell === 'G') {
	  arr += 'G';
	}
      }
      console.log(arr);
    }
  }
}

export default Maze;

今回は、以下のように出力される。

###############
#     #       #
# ### ### ### #
#   #     #   #
# # # # ##### #
# # # # #S    #
# ### ##### ###
# #     #     #
# # # # # # ###
# # # # # #   #
# ##### # ### #
#     #G#   # #
# ### ### # # #
#   # #   # # #
###############
タイトルとURLをコピーしました