1package aud.example.grid;
3import java.util.Comparator;
44 boolean show_parent_ =
false;
45 boolean ansi_term_ =
true;
50 "+-+ +----- --------+ +----+\n"+
51 "| | +------+----- ---+ | |\n"+
53 "| | +------+----- ---+ | |\n"+
55 " +----- --------+\n"+
82 Character.isWhitespace(
value) ||
83 Character.isLetterOrDigit(
value);
91 public double d = Double.POSITIVE_INFINITY;
93 public double f = Double.POSITIVE_INFINITY;
99 class CompareCellDistanceFromIndex
implements Comparator<Integer> {
101 CompareCellDistanceFromIndex(
Grid2 g) { grid=g; }
102 @Override
public int compare(Integer a,Integer b) {
103 Cell ca=grid.cell_[a.intValue()], cb=grid.cell_[b.intValue()];
105 return (d<0.0) ? -1 : (d>0.0 ? +1 : 0);
109 class CompareCellEstimatedDistanceFromIndex
implements Comparator<Integer> {
111 CompareCellEstimatedDistanceFromIndex(
Grid2 g) { grid=g; }
112 @Override
public int compare(Integer a,Integer b) {
113 Cell ca=grid.cell_[a.intValue()], cb=grid.cell_[b.intValue()];
115 return (d<0.0) ? -1 : (d>0.0 ? +1 : 0);
129 StringBuilder sb=
new StringBuilder();
131 FileReader fr=
new FileReader(filename);
132 BufferedReader in=
new BufferedReader(fr);
134 while ((line=in.readLine())!=
null) {
138 }
catch (Exception e) {
139 System.err.println(
"error while reading '"+filename+
"'");
140 System.err.println(e.toString());
143 setup(sb.toString());
148 num_rows_=lines.length;
150 for (String line : lines) {
151 num_columns_=(num_columns_<line.length() ? line.length() : num_columns_);
155 for (
int i=0;i<
size();++i)
159 for (String line : lines) {
160 for (
int j=0;j<line.length();++j) {
168 setup(text.split(
"\\n"));
176 public int size() {
return num_rows_*num_columns_; }
180 assert(0<=i && i<num_rows_);
181 assert(0<=j && j<num_columns_);
182 return i*num_columns_+j;
186 return _index/num_columns_;
190 return _index%num_columns_;
200 int north=-1,east=-1,south=-1,west=-1, k=0;
208 if (i>0) { north=index-num_columns_; ++k; }
209 if (j<num_columns_-1) { east =index+1; ++k; }
210 if (i<num_rows_-1) { south=index+num_columns_; ++k; }
211 if (j>0) { west =index-1; ++k; }
213 int[] nhd=
new int[k];
217 if (tunnel_nhd.length > 1) {
219 nhd=
new int[nhd.length + tunnel_nhd.length-1];
220 for (
int n=0;n<tunnel_nhd.length;++n) {
221 if (tunnel_nhd[n] != index) {
222 nhd[k++] = tunnel_nhd[n];
227 if (north>=0) nhd[k++]=north;
228 if (east>=0) nhd[k++]=east;
229 if (south>=0) nhd[k++]=south;
230 if (west>=0) nhd[k++]=west;
235 private aud.
HashMap<Character,
int[]> tunnels_ =
null;
244 if (tunnels_ ==
null)
245 tunnels_ =
new aud.
HashMap<Character,
int[]>();
261 for (
int i=0;i<cell_.length;++i) {
265 int[] nhd =
new int[n];
272 for (
int i=0;i<cell_.length;++i) {
281 boolean has_tunnels =
false;
282 for (
int i=0;i<cell_.length;i++) {
305 double weight(
int s,
int t) {
308 double s_level=Character.isDigit(cs) ? Character.getNumericValue(cs) : 0.0;
309 double t_level=Character.isDigit(ct) ? Character.getNumericValue(ct) : 0.0;
311 return Math.abs(t_level-s_level)+1.0;
318 for (
int i=0;i<
size();++i)
319 if (cell_[i].value==value)
323 System.err.println(
"Could not find a cell with value='"+value+
"'.");
334 term.
cls(frame_++==0);
348 if (term.
dumb() && ch==
' ') {
361 else if (show_parent_) {
363 else if (i<num_rows_ && c.
p==
cell_index(i+1,j)) ch=
'↑';
365 else if (j<num_columns_ && c.
p==
cell_index(i,j+1)) ch=
'←';
378 }
catch (InterruptedException e) {}
383 for (
int i=0;i<
size();++i) {
398 cell_[t].
d=cell_[s].
d+weight(s,t);
424 cell_[t].
d=cell_[s].
d+weight(s,t);
451 cell_[t].
d=cell_[s].
d+weight(s,t);
478 if (cell_[t].is_free()) {
480 double priority=cell_[s].
d+weight(s,t);
482 if (Double.isInfinite(cell_[t].
d)) {
493 else if (cell_[t].d>priority && open.
contains(t)) {
513 double estimate_distance(
int s,
int t) {
518 double d=Math.abs((
double) dx)+Math.abs((
double) dy);
520 if (tunnels_ !=
null) {
521 System.err.println(tunnels_.size());
523 for (
int index : tunnel.value) {
527 double dt=Math.abs((
double) dtx)+Math.abs((
double) dty);
544 (
size(),
new CompareCellEstimatedDistanceFromIndex(
this));
550 cell_[s0].
f=estimate_distance(s0,s1);
557 if (cell_[t].is_free()) {
559 double distance=cell_[s].
d+weight(s,t);
561 double priority = distance + estimate_distance(t,s1);
563 if (Double.isInfinite(cell_[t].
d)) {
575 else if (cell_[t].d>distance && open.
contains(t)) {
597 assert(cell_[s].p>=0);
612 (
"java aud.example.graph.TraversalExample "+
613 "[-g file] [-m method] [-s s0] [-d s1] [-v N]\n"+
614 " -g FILE read grid from FILE\n"+
615 " -m METHOD traversal {dfs,idfs,bfs,dijkstra,astar}\n"+
616 " -p show parent cell by an arrow (requires color)\n"+
617 " -s START start node (one character, default: 'A')\n"+
618 " -d DESTINATION destination node for A* (default: none)\n"+
619 " -delay MILLISECONDS set delay after each step\n"+
620 " -no-color don't use ANSI codes\n"+
621 " -color force use of ANSI codes (requires terminal emulation)\n"+
622 " -show display initial grid and exit"
627 public static void main(String[] args) {
629 Runtime.getRuntime().addShutdownHook(
new Thread() {
630 @Override
public void run() {
643 char start=
'A', destination=
'A';
645 for (
int i=0;i<args.length;++i) {
646 if (args[i].compareTo(
"-g")==0) {
649 System.err.println(
"error: grid is empty");
653 else if (args[i].compareTo(
"-m")==0)
655 else if (args[i].compareTo(
"-s")==0)
656 start=args[++i].charAt(0);
657 else if (args[i].compareTo(
"-d")==0)
658 destination=args[++i].charAt(0);
659 else if (args[i].compareTo(
"-delay")==0)
660 g.
delay=Integer.parseInt(args[++i]);
661 else if (args[i].compareTo(
"-p")==0)
663 else if (args[i].compareTo(
"-no-color")==0)
665 else if (args[i].compareTo(
"-color")==0)
667 else if (args[i].compareTo(
"-show")==0)
685 int s1=(destination!=start ? g.
find_first(destination) : -1);
687 if (method.compareTo(
"dfs")==0)
689 else if (method.compareTo(
"idfs")==0)
691 else if (method.compareTo(
"bfs")==0)
693 else if (method.compareTo(
"dijkstra")==0)
695 else if (method.compareTo(
"astar")==0) {
697 System.err.println(
"A* requires destination, use '-d'");
entry (key,value) in HashMap (iterator)
Implementation of an unordered map based on a hash table.
Value find(Key key)
find value for key @endiliteral
Priority queue based on binary min-heap.
boolean is_empty()
Is PQ empty?
void push(T x)
Add entry to PQ.
boolean contains(T x)
Is x contained in PQ?
T pop()
Pop minimal element from PQ.
void lower(T x)
update heap after lowering priority of x
Implementation of AbstractQueue as a (dynamically resized) circular buffer based on array.
void enqueue(T x)
Enqueue element at end of queue.
boolean is_empty()
Is queue empty?
T dequeue()
Remove front element from queue.
Implementation of a stack based on aud.Vector.
void push(T x)
Push x onto stack.
boolean is_empty()
Is stack empty?
T pop()
Pop element from stack.
int color
indexed color, see Terminal
boolean is_free()
Can we enter this cell?
char value
the value that is displayed
boolean is_tunnel()
letters a-z denote entries to tunnels: e.g., all 'a' are connected
double f
priority used by A* (distance + estimated distance to destination
int p
index of parent cell
double d
distance to source
Undirected graph that is defined implicitly by a regular 2d grid.
int size()
get total number of cells
void read_file(String filename)
read file and treat contents as cells, calls setup
void setup(String[] lines)
setup grid from string: create contents as grid cells
boolean create_all_tunnels()
create all tunnels (preprocess)
int delay
delay in display in milliseconds
int[] neighbors_from_tunnels(int index)
get neighbors of index from tunnels
Grid2(String filename)
construct grid by calling read_file
int get_row(int _index)
get row from cell index
int cell_index(int i, int j)
get cell index from coordinates
int find_first(char value)
find first cell in grid with value @endiliteral
void display()
display current grid
static final String EXAMPLE
example grid (argument to setup
void setup(String text)
setup from multi-line string, e.g., EXAMPLE
void astar(int s0, int s1)
A*.
void backtrack(int s)
backtrack and display path to source
int get_column(int _index)
get columns from cell index
void dijkstra(int s0, int s1)
Dijkstra.
int[] neighbors(int index)
get neighbors of cell index (4-neighborhood)
static void main(String[] args)
int[] create_tunnels_for(Cell cell)
create tunnels for specified entry at cell
void reset_cells()
reset all cells to default state but keep their values
Cell cell(int i, int j)
get cell (i,j)
int num_rows()
get number of rows
void dfs_iterative(int s0)
iterative DFS
Grid2()
construct an empty grid, use read_file or setup
int num_columns()
get number of columns
static void usage()
print help message and exit
void dfs_recursive(int s)
recusive DFS
double f
priority used by A* (distance + estimated distance to destination
double d
distance to source
PrintStream out
output stream, user is responsible for flush
void cls(boolean clear)
clear screen (for clear=false, move only cursor)
void hideCursor()
hide cursor
void showCursor()
show cursor
void reset()
reset to black on white, normal font
void fg(int color)
set foreground color
boolean dumb()
Is this a dumb terminal without colors?
static Terminal instance
singleton instance
void bg(int color)
set background color
utilities (not related to AuD lecture)
AuD lecture: Data structures, algorithms, examples.