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 { // dy == 0
int y = y0;
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);
}
} else { // dx == 0
int x = x0;
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);
}
}
cHVibGljIGNsYXNzIE1haW4gewogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgICAgIFZpcnR1YWxTY3JlZW4gc2NyZWVuID0gbmV3IFZpcnR1YWxTY3JlZW4oNDAsIDEwKTsKICAgICAgICAKICAgICAgICBzY3JlZW4uYm94KCcrJywgMywgMCwgMjAsIDkpOwoKICAgICAgICBzY3JlZW4ubGluZSgnIycsIDUsIDIsIDMsIDkpOwogICAgICAgIHNjcmVlbi5saW5lKCcjJywgNywgMiwgMTAsIDkpOwoKICAgICAgICBzY3JlZW4ubGluZSgnIycsIDksIDEsIDksIDMpOwogICAgICAgIHNjcmVlbi5saW5lKCcjJywgMTEsIDEsIDExLCAzKTsKCiAgICAgICAgc2NyZWVuLmxpbmUoJyMnLCAxNCwgMiwgMTksIDIpOwogICAgICAgIHNjcmVlbi5saW5lKCcjJywgMTgsIDIsIDE5LCA5KTsKICAgICAgICBzY3JlZW4ubGluZSgnIycsIDE5LCA4LCAxNywgOCk7CgogICAgICAgIHNjcmVlbi5saW5lKCcjJywgMTYsIDEsIDEzLCA5KTsKCiAgICAgICAgc2NyZWVuLmNpcmNsZSgnKicsIDI4LCA1LCA0KTsKICAgICAgICBzY3JlZW4uY2lyY2xlKCcqJywgMjgsIDUsIDIpOwoKICAgICAgICBzY3JlZW4ucHJpbnQoKTsKICAgIH0KfQoKY2xhc3MgVmlydHVhbFNjcmVlbiB7CiAgICBwcm90ZWN0ZWQgaW50IHdpZHRoOwogICAgcHJvdGVjdGVkIGludCBoZWlnaHQ7CiAgICBwcm90ZWN0ZWQgU3RyaW5nW10gbGluZXM7CgogICAgVmlydHVhbFNjcmVlbigpIHsKICAgICAgICB0aGlzKDgwLCAyNSk7CiAgICB9CiAgICBWaXJ0dWFsU2NyZWVuKGludCB3aWR0aCwgaW50IGhlaWdodCkgewogICAgICAgIHRoaXMoJyAnLCB3aWR0aCwgaGVpZ2h0KTsKICAgIH0KICAgIFZpcnR1YWxTY3JlZW4oY2hhciBjaCwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAgICAgICAgcmVzZXQoY2gsIHdpZHRoLCBoZWlnaHQpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHJlc2V0KGNoYXIgY2gsIGludCB3aWR0aCwgaW50IGhlaWdodCkgewogICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDsKICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodDsKICAgICAgICB0aGlzLmxpbmVzID0gbmV3IFN0cmluZ1toZWlnaHRdOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaGVpZ2h0OyArK2kpIHsKICAgICAgICAgICAgbGluZXNbaV0gPSAiIjsKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCB3aWR0aDsgKytqKSB7CiAgICAgICAgICAgICAgICBsaW5lc1tpXSA9IGxpbmVzW2ldICsgY2g7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgcHJpbnQoKSB7CiAgICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7ICsreSkgewogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obGluZXNbeV0pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRQaXhlbChjaGFyIGNoLCBpbnQgeCwgaW50IHkpIHsKICAgICAgICBpZiAoeCA8IDAgfHwgd2lkdGggPD0geCkKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIGlmICh5IDwgMCB8fCBoZWlnaHQgPD0geSkKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIFN0cmluZyBzdHIgPSBsaW5lc1t5XTsKICAgICAgICBsaW5lc1t5XSA9IHN0ci5zdWJzdHJpbmcoMCwgeCkgKyBjaCArIHN0ci5zdWJzdHJpbmcoeCArIDEpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIGZpbGxCb3goY2hhciBjaCwgaW50IGxlZnQsIGludCB0b3AsIGludCByaWdodCwgaW50IGJvdHRvbSkgewogICAgICAgIGZvciAoaW50IHkgPSB0b3A7IHkgPD0gYm90dG9tOyArK3kpIHsKICAgICAgICAgICAgZm9yIChpbnQgeCA9IGxlZnQ7IHggPD0gcmlnaHQ7ICsreCkgewogICAgICAgICAgICAgICAgc2V0UGl4ZWwoY2gsIHgsIHkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIGxpbmUoY2hhciBjaCwgaW50IHgwLCBpbnQgeTAsIGludCB4MSwgaW50IHkxKSB7CiAgICAgICAgaW50IGR4ID0geDEgLSB4MCwgZHkgPSB5MSAtIHkwOwogICAgICAgIGlmIChNYXRoLmFicyhkeCkgPD0gTWF0aC5hYnMoZHkpKSB7CiAgICAgICAgICAgIGlmIChkeSA8IDApIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IHkgPSB5MTsgeSA8PSB5MDsgKyt5KSB7CiAgICAgICAgICAgICAgICAgICAgaW50IHggPSB4MSArIHJkaXYoKHkgLSB5MSkgKiBkeCAsIGR5KTsKICAgICAgICAgICAgICAgICAgICBzZXRQaXhlbChjaCwgeCwgeSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZHkgPiAwKSB7CiAgICAgICAgICAgICAgICBmb3IgKGludCB5ID0geTA7IHkgPD0geTE7ICsreSkgewogICAgICAgICAgICAgICAgICAgIGludCB4ID0geDAgKyByZGl2KCh5IC0geTApICogZHggLCBkeSk7CiAgICAgICAgICAgICAgICAgICAgc2V0UGl4ZWwoY2gsIHgsIHkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewkvLyBkeSA9PSAwCgkJCQlpbnQgeSA9IHkwOwoJCQkJc2V0UGl4ZWwoY2gsIHgsIHkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKGR4IDwgMCkgewogICAgICAgICAgICAgICAgZm9yIChpbnQgeCA9IHgxOyB4IDw9IHgwOyArK3gpIHsKICAgICAgICAgICAgICAgICAgICBpbnQgeSA9IHkxICsgcmRpdigoeCAtIHgxKSAqIGR5ICwgZHgpOwogICAgICAgICAgICAgICAgICAgIHNldFBpeGVsKGNoLCB4LCB5KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChkeCA+IDApIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IHggPSB4MDsgeCA8PSB4MTsgKyt4KSB7CiAgICAgICAgICAgICAgICAgICAgaW50IHkgPSB5MCArIHJkaXYoKHggLSB4MCkgKiBkeSAsIGR4KTsKICAgICAgICAgICAgICAgICAgICBzZXRQaXhlbChjaCwgeCwgeSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CS8vIGR4ID09IDAKCQkJCWludCB4ID0geDA7CgkJCQlzZXRQaXhlbChjaCwgeCwgeSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgYm94KGNoYXIgY2gsIGludCB4MCwgaW50IHkwLCBpbnQgeDEsIGludCB5MSkgewogICAgICAgIGxpbmUoY2gsIHgwLCB5MCwgeDEsIHkwKTsKICAgICAgICBsaW5lKGNoLCB4MSwgeTAsIHgxLCB5MSk7CiAgICAgICAgbGluZShjaCwgeDEsIHkxLCB4MCwgeTEpOwogICAgICAgIGxpbmUoY2gsIHgwLCB5MSwgeDAsIHkwKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBjaXJjbGUoY2hhciBjaCwgaW50IHgsIGludCB5LCBkb3VibGUgcikgewogICAgICAgIGlmIChyID09IDApIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBmb3IoZG91YmxlIHQgPSAwOyB0IDwgMiAqIE1hdGguUEk7IHQgKz0gMSAvICgyICogTWF0aC5QSSAqIHIpKSB7CiAgICAgICAgICAgIGRvdWJsZSBweCA9IHggKyByICogTWF0aC5jb3ModCk7CiAgICAgICAgICAgIGRvdWJsZSBweSA9IHkgKyByICogTWF0aC5zaW4odCk7CiAgICAgICAgICAgIHNldFBpeGVsKGNoLCByb3VuZChweCksIHJvdW5kKHB5KSk7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBpbnQgcm91bmQoZG91YmxlIGQpIHsKICAgICAgICByZXR1cm4gKGludClNYXRoLnJvdW5kKGQpOwogICAgfQoKICAgIHByb3RlY3RlZCBpbnQgcmRpdihkb3VibGUgYSwgZG91YmxlIGIpIHsgCgkJcmV0dXJuIHJvdW5kKGEgLyBiKTsgCiAgICB9Cn0=