1package aud.example.grid;
3import java.util.Comparator;
39 boolean show_parent_ =
false;
40 boolean ansi_term_ =
true;
45 "+-+ +----- --------+ +----+\n"+
46 "| | +------+----- ---+ | |\n"+
48 "| | +------+----- ---+ | |\n"+
50 " +----- --------+\n"+
77 Character.isWhitespace(
value) ||
78 Character.isLetterOrDigit(
value);
86 public double d = Double.POSITIVE_INFINITY;
88 public double f = Double.POSITIVE_INFINITY;
94 class CompareCellDistanceFromIndex
implements Comparator<Integer> {
96 CompareCellDistanceFromIndex(
Grid g) { grid=g; }
97 @Override
public int compare(Integer a,Integer b) {
98 Cell ca=grid.cell_[a.intValue()], cb=grid.cell_[b.intValue()];
100 return (d<0.0) ? -1 : (d>0.0 ? +1 : 0);
104 class CompareCellEstimatedDistanceFromIndex
implements Comparator<Integer> {
106 CompareCellEstimatedDistanceFromIndex(
Grid g) { grid=g; }
107 @Override
public int compare(Integer a,Integer b) {
108 Cell ca=grid.cell_[a.intValue()], cb=grid.cell_[b.intValue()];
110 return (d<0.0) ? -1 : (d>0.0 ? +1 : 0);
124 StringBuilder sb=
new StringBuilder();
126 FileReader fr=
new FileReader(filename);
127 BufferedReader in=
new BufferedReader(fr);
129 while ((line=in.readLine())!=
null) {
133 }
catch (Exception e) {
134 System.err.println(
"error while reading '"+filename+
"'");
135 System.err.println(e.toString());
138 setup(sb.toString());
143 num_rows_=lines.length;
145 for (String line : lines) {
146 num_columns_=(num_columns_<line.length() ? line.length() : num_columns_);
150 for (
int i=0;i<
size();++i)
154 for (String line : lines) {
155 for (
int j=0;j<line.length();++j) {
163 setup(text.split(
"\\n"));
171 public int size() {
return num_rows_*num_columns_; }
175 assert(0<=i && i<num_rows_);
176 assert(0<=j && j<num_columns_);
177 return i*num_columns_+j;
181 return _index/num_columns_;
185 return _index%num_columns_;
195 int north=-1,east=-1,south=-1,west=-1, k=0;
203 if (i>0) { north=index-num_columns_; ++k; }
204 if (j<num_columns_-1) { east =index+1; ++k; }
205 if (i<num_rows_-1) { south=index+num_columns_; ++k; }
206 if (j>0) { west =index-1; ++k; }
208 int[] nhd=
new int[k];
212 if (tunnel_nhd.length > 1) {
214 nhd=
new int[nhd.length + tunnel_nhd.length-1];
215 for (
int n=0;n<tunnel_nhd.length;++n) {
216 if (tunnel_nhd[n] != index) {
217 nhd[k++] = tunnel_nhd[n];
222 if (north>=0) nhd[k++]=north;
223 if (east>=0) nhd[k++]=east;
224 if (south>=0) nhd[k++]=south;
225 if (west>=0) nhd[k++]=west;
230 private aud.
HashMap<Character,
int[]> tunnels_ =
null;
239 if (tunnels_ ==
null)
240 tunnels_ =
new aud.
HashMap<Character,
int[]>();
256 for (
int i=0;i<cell_.length;++i) {
260 int[] nhd =
new int[n];
267 for (
int i=0;i<cell_.length;++i) {
291 double weight(
int s,
int t) {
294 double s_level=Character.isDigit(cs) ? Character.getNumericValue(cs) : 0.0;
295 double t_level=Character.isDigit(ct) ? Character.getNumericValue(ct) : 0.0;
297 return Math.abs(t_level-s_level)+1.0;
304 for (
int i=0;i<
size();++i)
305 if (cell_[i].value==value)
309 System.err.println(
"Could not find a cell with value='"+value+
"'.");
320 term.
cls(frame_++==0);
334 if (term.
dumb() && ch==
' ') {
347 else if (show_parent_) {
349 else if (i<num_rows_ && c.
p==
cell_index(i+1,j)) ch=
'↑';
351 else if (j<num_columns_ && c.
p==
cell_index(i,j+1)) ch=
'←';
364 }
catch (InterruptedException e) {}
369 for (
int i=0;i<
size();++i) {
384 cell_[t].
d=cell_[s].
d+weight(s,t);
410 cell_[t].
d=cell_[s].
d+weight(s,t);
437 cell_[t].
d=cell_[s].
d+weight(s,t);
464 if (cell_[t].is_free()) {
466 double priority=cell_[s].
d+weight(s,t);
468 if (Double.isInfinite(cell_[t].
d)) {
479 else if (cell_[t].d>priority && open.
contains(t)) {
499 double estimate_distance(
int s,
int t) {
503 return Math.abs((
double) dx)+Math.abs((
double) dy);
511 (
size(),
new CompareCellEstimatedDistanceFromIndex(
this));
517 cell_[s0].
f=estimate_distance(s0,s1);
524 if (cell_[t].is_free()) {
526 double distance=cell_[s].
d+weight(s,t);
528 double priority = distance + estimate_distance(t,s1);
530 if (Double.isInfinite(cell_[t].
d)) {
542 else if (cell_[t].d>distance && open.
contains(t)) {
564 assert(cell_[s].p>=0);
579 (
"java aud.example.graph.TraversalExample "+
580 "[-g file] [-m method] [-s s0] [-d s1] [-v N]\n"+
581 " -g FILE read grid from FILE\n"+
582 " -m METHOD traversal {dfs,idfs,bfs,dijkstra,astar}\n"+
583 " -p show parent cell by an arrow (requires color)\n"+
584 " -s START start node (one character, default: 'A')\n"+
585 " -d DESTINATION destination node for A* (default: none)\n"+
586 " -delay MILLISECONDS set delay after each step\n"+
587 " -no-color don't use ANSI codes\n"+
588 " -color force use of ANSI codes (requires terminal emulation)\n"+
589 " -show display initial grid and exit"
594 public static void main(String[] args) {
596 Runtime.getRuntime().addShutdownHook(
new Thread() {
597 @Override
public void run() {
610 char start=
'A', destination=
'A';
612 for (
int i=0;i<args.length;++i) {
613 if (args[i].compareTo(
"-g")==0) {
616 System.err.println(
"error: grid is empty");
620 else if (args[i].compareTo(
"-m")==0)
622 else if (args[i].compareTo(
"-s")==0)
623 start=args[++i].charAt(0);
624 else if (args[i].compareTo(
"-d")==0)
625 destination=args[++i].charAt(0);
626 else if (args[i].compareTo(
"-delay")==0)
627 g.
delay=Integer.parseInt(args[++i]);
628 else if (args[i].compareTo(
"-p")==0)
630 else if (args[i].compareTo(
"-no-color")==0)
632 else if (args[i].compareTo(
"-color")==0)
634 else if (args[i].compareTo(
"-show")==0)
652 int s1=(destination!=start ? g.
find_first(destination) : -1);
654 if (method.compareTo(
"dfs")==0)
656 else if (method.compareTo(
"idfs")==0)
658 else if (method.compareTo(
"bfs")==0)
660 else if (method.compareTo(
"dijkstra")==0)
662 else if (method.compareTo(
"astar")==0) {
664 System.err.println(
"A* requires destination, use '-d'");
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.
double f
priority used by A* (distance + estimated distance to destination
char value
the value that is displayed
int p
index of parent cell
boolean is_tunnel()
letters a-z denote entries to tunnels: e.g., all 'a' are connected
boolean is_free()
Can we enter this cell?
int color
indexed color, see Terminal
double d
distance to source
Undirected graph that is defined implicitly by a regular 2d grid.
int get_column(int _index)
get columns from cell index
int num_rows()
get number of rows
void setup(String[] lines)
setup grid from string: create contents as grid cells
void setup(String text)
setup from multi-line string, e.g., EXAMPLE
int[] neighbors_from_tunnels(int index)
get neighbors of index from tunnels
void dfs_iterative(int s0)
iterative DFS
Grid(String filename)
construct grid by calling read_file
int get_row(int _index)
get row from cell index
int[] neighbors(int index)
get neighbors of cell index (4-neighborhood)
void display()
display current grid
int find_first(char value)
find first cell in grid with value @endiliteral
static final String EXAMPLE
example grid (argument to setup
int num_columns()
get number of columns
Cell cell(int i, int j)
get cell (i,j)
void reset_cells()
reset all cells to default state but keep their values
void backtrack(int s)
backtrack and display path to source
static void usage()
print help message and exit
int size()
get total number of cells
void dijkstra(int s0, int s1)
Dijkstra.
int[] create_tunnels_for(Cell cell)
create tunnels for specified entry at cell
static void main(String[] args)
int delay
delay in display in milliseconds
Grid()
construct an empty grid, use read_file or setup
void dfs_recursive(int s)
recusive DFS
int cell_index(int i, int j)
get cell index from coordinates
void astar(int s0, int s1)
A*.
void read_file(String filename)
read file and treat contents as cells, calls setup
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.