通行证
- 积分
- 599
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2014-10-12
- 最后登录
- 1970-1-1
|
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
class Point {
public int x;
public int y;
public Point( int x, int y ) {
this.x = x;
this.y = y;
}
// Override these two methods for the collection method .contains(Object o)
@Override
public boolean equals( Object o ) {
if ( o instanceof Point ) {
Point p = (Point) o;
return p.x == this.x && p.y == this.y;
}
return false;
}
@Override
public int hashCode(){
final int prime1 = 31, prime2 = 19;
return prime1 * x + prime2 * y;
}
}
// Only for record output, Name "Wall" sounds much more appropriate than line
class Wall {
Point p1;
Point p2;
public Wall( Point p1, Point p2 ) {
this.p1 = p1;
this.p2 = p2;
}
}
public class MazeGenerator {
Set< Point > closed = new HashSet< Point >(); // Collection of points processed
List< Wall > res = new ArrayList< Wall >();
int randomMod = 2; // We can control the average number of walls by setting up this mod
int MazeX = 7;
int MazeY = 7;
int hit = 0; // Times hit on bound
public List< Wall > drawMaze () throws IllegalArgumentException{
for ( int i = 0; i <= MazeX; ++i ) {
for ( int j = MazeY; j >= 0; --j ) {
// For each point not in closed set do a BFS to add lines
// by this way, walls can be distributed paths instead of single-root path
Point p = new Point( i , j );
if ( closed.contains(p) || new Random().nextInt(1000) %randomMod == 0) {
continue;
}
if ( p.x == 0 || p.y == 0 || p.x == MazeX || p.y == MazeY ) {
if ( hit != 0 ) {
continue;
}
++hit;
}
int sz = res.size();
Queue< Point > q = new LinkedList< Point >();
closed.add(p);
q.add(p);
while( !q.isEmpty() ) {
Point cur = q.poll();
List< Point > ops = getOps(cur);
for ( Point pp : ops ) {
if ( new Random().nextInt(1000) % randomMod == 0 && !closed.contains(pp)) {
connect( cur , pp );
closed.add(pp);
q.offer(pp);
}
}
}
if ( sz == res.size() ) {
if ( p.x == 0 || p.y == 0 || p.x == MazeX || p.y == MazeY ) {
hit = hit - 1;
}
}
}
}
return res;
}
private List< Point > getOps( Point p ) {
List< Point > res = new ArrayList< Point >();
if ( (p.x > 1 || ( p.x == 1 && hit < 1 ) )&& p.y != 0 && p.y != MazeY) {
Point t = new Point( p.x - 1 , p.y);
if ( !closed.contains(t) )
res.add( t );
}
if (( p.y > 1 || ( p.y == 1 && hit < 1 ) ) && p.x != 0 && p.x != MazeX) {
Point t = new Point( p.x , p.y - 1);
if ( !closed.contains(t) )
res.add( t );
}
if ( ( p.x < MazeX - 1 || ( p.x == MazeX - 1 && hit < 1 ) )&& p.y != 0 && p.y != MazeY) {
Point t = new Point( p.x + 1 , p.y);
if ( !closed.contains(t) )
res.add( t );
}
if ( (p.y < MazeY - 1 || ( p.y == MazeY - 1 && hit < 1 )) && p.x != 0 && p.x != MazeX) {
Point t = new Point( p.x , p.y + 1);
if ( !closed.contains(t) )
res.add( t );
}
return res;
}
private void connect( Point p1 , Point p2 ) {
if ( p2.x == 0 || p2.y == 0 || p2.x == MazeX || p2.y == MazeY ) {
if ( hit != 0 ) {
return;
}
++hit;
}
res.add( new Wall( p1 , p2 ) );
}
public static void main(String args[]){
List< Wall > lines = new MazeGenerator().drawMaze();
for ( Wall l : lines ) {
System.out.println( String.format("( %s, %s ) -> (%s , %s )", l.p1.x, l.p1.y,l.p2.x,l.p2.y) );
}
}
}
|
|