public class Main {
public static void main
( String [ ] args
) { VirtualScreen screen = new VirtualScreen( 40 , 10 ) ;
screen.box ( '+' , 3 , 0 , 20 , 9 ) ;
screen.line ( '#' , 5 , 2 , 3 , 9 ) ;
screen.line ( '#' , 7 , 2 , 10 , 9 ) ;
screen.line ( '#' , 9 , 1 , 9 , 3 ) ;
screen.line ( '#' , 11 , 1 , 11 , 3 ) ;
screen.line ( '#' , 14 , 2 , 19 , 2 ) ;
screen.line ( '#' , 18 , 2 , 19 , 9 ) ;
screen.line ( '#' , 19 , 8 , 17 , 8 ) ;
screen.line ( '#' , 16 , 1 , 13 , 9 ) ;
screen.circle ( '*' , 28 , 5 , 4 ) ;
screen.circle ( '*' , 28 , 5 , 2 ) ;
screen.print ( ) ;
}
}
class VirtualScreen {
protected int width;
protected int height;
VirtualScreen( ) {
this ( 80 , 25 ) ;
}
VirtualScreen( int width, int height) {
this ( ' ' , width, height) ;
}
VirtualScreen( char ch, int width, int height) {
reset( ch, width, height) ;
}
public void reset( char ch, int width, int height) {
this .width = width;
this .height = height;
this .
lines = new String [ height
] ; for ( int i = 0 ; i < height; ++ i) {
lines[ i] = "" ;
for ( int j = 0 ; j < width; ++ j) {
lines[ i] = lines[ i] + ch;
}
}
}
public void print( ) {
for ( int y = 0 ; y < height; ++ y) {
}
}
public void setPixel( char ch, int x, int y) {
if ( x < 0 || width <= x)
return ;
if ( y < 0 || height <= y)
return ;
lines[ y] = str.substring ( 0 , x) + ch + str.substring ( x + 1 ) ;
}
public void fillBox( char ch, int left, int top, int right, int bottom) {
for ( int y = top; y <= bottom; ++ y) {
for ( int x = left; x <= right; ++ x) {
setPixel( ch, x, y) ;
}
}
}
public void line( char ch, int x0, int y0, int x1, int y1) {
int dx = x1 - x0, dy = y1 - y0;
if ( dy < 0 ) {
for ( int y = y1; y <= y0; ++ y) {
int x = x1 + rdiv( ( y - y1) * dx / dy) ;
setPixel( ch, x, y) ;
}
} else if ( dy > 0 ) {
for ( int y = y0; y <= y1; ++ y) {
int x = x0 + rdiv( ( y - y0) * dx / dy) ;
setPixel( ch, x, y) ;
}
}
} else {
if ( dx < 0 ) {
for ( int x = x1; x <= x0; ++ x) {
int y = y1 + rdiv( ( x - x1) * dy / dx) ;
setPixel( ch, x, y) ;
}
} else if ( dx > 0 ) {
for ( int x = x0; x <= x1; ++ x) {
int y = y0 + rdiv( ( x - x0) * dy / dx) ;
setPixel( ch, x, y) ;
}
}
}
}
public void box( char ch, int x0, int y0, int x1, int y1) {
line( ch, x0, y0, x1, y0) ;
line( ch, x1, y0, x1, y1) ;
line( ch, x1, y1, x0, y1) ;
line( ch, x0, y1, x0, y0) ;
}
public void circle( char ch, int x, int y, double r) {
if ( r == 0 ) {
return ;
}
for ( double t
= 0 ; t
< 2 * Math .
PI ; t
+= 1 / ( 2 * Math .
PI * r
) ) { double px
= x
+ r
* Math .
cos ( t
) ; double py
= y
+ r
* Math .
sin ( t
) ; setPixel( ch, round( px) , round( py) ) ;
}
}
protected int round( double d) {
return ( int ) Math .
round ( d
) ; }
protected int rdiv( double a, double b) {
return round( a / b) ;
}
}
cHVibGljIGNsYXNzIE1haW4gewogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgICAgIFZpcnR1YWxTY3JlZW4gc2NyZWVuID0gbmV3IFZpcnR1YWxTY3JlZW4oNDAsIDEwKTsKCiAgICAgICAgc2NyZWVuLmJveCgnKycsIDMsIDAsIDIwLCA5KTsKCiAgICAgICAgc2NyZWVuLmxpbmUoJyMnLCA1LCAyLCAzLCA5KTsKICAgICAgICBzY3JlZW4ubGluZSgnIycsIDcsIDIsIDEwLCA5KTsKCiAgICAgICAgc2NyZWVuLmxpbmUoJyMnLCA5LCAxLCA5LCAzKTsKICAgICAgICBzY3JlZW4ubGluZSgnIycsIDExLCAxLCAxMSwgMyk7CgogICAgICAgIHNjcmVlbi5saW5lKCcjJywgMTQsIDIsIDE5LCAyKTsKICAgICAgICBzY3JlZW4ubGluZSgnIycsIDE4LCAyLCAxOSwgOSk7CiAgICAgICAgc2NyZWVuLmxpbmUoJyMnLCAxOSwgOCwgMTcsIDgpOwoKICAgICAgICBzY3JlZW4ubGluZSgnIycsIDE2LCAxLCAxMywgOSk7CgogICAgICAgIHNjcmVlbi5jaXJjbGUoJyonLCAyOCwgNSwgNCk7CiAgICAgICAgc2NyZWVuLmNpcmNsZSgnKicsIDI4LCA1LCAyKTsKCiAgICAgICAgc2NyZWVuLnByaW50KCk7CiAgICB9Cn0KCmNsYXNzIFZpcnR1YWxTY3JlZW4gewogICAgcHJvdGVjdGVkIGludCB3aWR0aDsKICAgIHByb3RlY3RlZCBpbnQgaGVpZ2h0OwogICAgcHJvdGVjdGVkIFN0cmluZ1tdIGxpbmVzOwoKICAgIFZpcnR1YWxTY3JlZW4oKSB7CiAgICAgICAgdGhpcyg4MCwgMjUpOwogICAgfQogICAgVmlydHVhbFNjcmVlbihpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKICAgICAgICB0aGlzKCcgJywgd2lkdGgsIGhlaWdodCk7CiAgICB9CiAgICBWaXJ0dWFsU2NyZWVuKGNoYXIgY2gsIGludCB3aWR0aCwgaW50IGhlaWdodCkgewogICAgICAgIHJlc2V0KGNoLCB3aWR0aCwgaGVpZ2h0KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCByZXNldChjaGFyIGNoLCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7CiAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7CiAgICAgICAgdGhpcy5saW5lcyA9IG5ldyBTdHJpbmdbaGVpZ2h0XTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGhlaWdodDsgKytpKSB7CiAgICAgICAgICAgIGxpbmVzW2ldID0gIiI7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgd2lkdGg7ICsraikgewogICAgICAgICAgICAgICAgbGluZXNbaV0gPSBsaW5lc1tpXSArIGNoOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHByaW50KCkgewogICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGxpbmVzW3ldKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0UGl4ZWwoY2hhciBjaCwgaW50IHgsIGludCB5KSB7CiAgICAgICAgaWYgKHggPCAwIHx8IHdpZHRoIDw9IHgpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBpZiAoeSA8IDAgfHwgaGVpZ2h0IDw9IHkpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBTdHJpbmcgc3RyID0gbGluZXNbeV07CiAgICAgICAgbGluZXNbeV0gPSBzdHIuc3Vic3RyaW5nKDAsIHgpICsgY2ggKyBzdHIuc3Vic3RyaW5nKHggKyAxKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBmaWxsQm94KGNoYXIgY2gsIGludCBsZWZ0LCBpbnQgdG9wLCBpbnQgcmlnaHQsIGludCBib3R0b20pIHsKICAgICAgICBmb3IgKGludCB5ID0gdG9wOyB5IDw9IGJvdHRvbTsgKyt5KSB7CiAgICAgICAgICAgIGZvciAoaW50IHggPSBsZWZ0OyB4IDw9IHJpZ2h0OyArK3gpIHsKICAgICAgICAgICAgICAgIHNldFBpeGVsKGNoLCB4LCB5KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBsaW5lKGNoYXIgY2gsIGludCB4MCwgaW50IHkwLCBpbnQgeDEsIGludCB5MSkgewogICAgICAgIGludCBkeCA9IHgxIC0geDAsIGR5ID0geTEgLSB5MDsKICAgICAgICBpZiAoTWF0aC5hYnMoZHgpIDw9IE1hdGguYWJzKGR5KSkgewogICAgICAgICAgICBpZiAoZHkgPCAwKSB7CiAgICAgICAgICAgICAgICBmb3IgKGludCB5ID0geTE7IHkgPD0geTA7ICsreSkgewogICAgICAgICAgICAgICAgICAgIGludCB4ID0geDEgKyByZGl2KCh5IC0geTEpICogZHggLyBkeSk7CiAgICAgICAgICAgICAgICAgICAgc2V0UGl4ZWwoY2gsIHgsIHkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKGR5ID4gMCkgewogICAgICAgICAgICAgICAgZm9yIChpbnQgeSA9IHkwOyB5IDw9IHkxOyArK3kpIHsKICAgICAgICAgICAgICAgICAgICBpbnQgeCA9IHgwICsgcmRpdigoeSAtIHkwKSAqIGR4IC8gZHkpOwogICAgICAgICAgICAgICAgICAgIHNldFBpeGVsKGNoLCB4LCB5KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChkeCA8IDApIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IHggPSB4MTsgeCA8PSB4MDsgKyt4KSB7CiAgICAgICAgICAgICAgICAgICAgaW50IHkgPSB5MSArIHJkaXYoKHggLSB4MSkgKiBkeSAvIGR4KTsKICAgICAgICAgICAgICAgICAgICBzZXRQaXhlbChjaCwgeCwgeSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZHggPiAwKSB7CiAgICAgICAgICAgICAgICBmb3IgKGludCB4ID0geDA7IHggPD0geDE7ICsreCkgewogICAgICAgICAgICAgICAgICAgIGludCB5ID0geTAgKyByZGl2KCh4IC0geDApICogZHkgLyBkeCk7CiAgICAgICAgICAgICAgICAgICAgc2V0UGl4ZWwoY2gsIHgsIHkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIGJveChjaGFyIGNoLCBpbnQgeDAsIGludCB5MCwgaW50IHgxLCBpbnQgeTEpIHsKICAgICAgICBsaW5lKGNoLCB4MCwgeTAsIHgxLCB5MCk7CiAgICAgICAgbGluZShjaCwgeDEsIHkwLCB4MSwgeTEpOwogICAgICAgIGxpbmUoY2gsIHgxLCB5MSwgeDAsIHkxKTsKICAgICAgICBsaW5lKGNoLCB4MCwgeTEsIHgwLCB5MCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgY2lyY2xlKGNoYXIgY2gsIGludCB4LCBpbnQgeSwgZG91YmxlIHIpIHsKICAgICAgICBpZiAociA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgZm9yKGRvdWJsZSB0ID0gMDsgdCA8IDIgKiBNYXRoLlBJOyB0ICs9IDEgLyAoMiAqIE1hdGguUEkgKiByKSkgewogICAgICAgICAgICBkb3VibGUgcHggPSB4ICsgciAqIE1hdGguY29zKHQpOwogICAgICAgICAgICBkb3VibGUgcHkgPSB5ICsgciAqIE1hdGguc2luKHQpOwogICAgICAgICAgICBzZXRQaXhlbChjaCwgcm91bmQocHgpLCByb3VuZChweSkpOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgaW50IHJvdW5kKGRvdWJsZSBkKSB7CiAgICAgICAgcmV0dXJuIChpbnQpTWF0aC5yb3VuZChkKTsKICAgIH0KICAgIAogICAgcHJvdGVjdGVkIGludCByZGl2KGRvdWJsZSBhLCBkb3VibGUgYikgeyAKCQlyZXR1cm4gcm91bmQoYSAvIGIpOyAKICAgIH0KfQ==