/* package whatever; // don't place package name! */
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
import javax.swing.Timer;
public class Tetris
extends JFrame { public Tetris() {
Tetrisblok a = new Tetrisblok();
addKeyListener(a);
add(a);
}
public static void main
(String[] args
) { Tetris frame = new Tetris();
frame.setJMenuBar(menu);
menu.add(game);
menu.add(help);
frame.setLocationRelativeTo(null);
frame.
setDefaultCloseOperation(JFrame.
EXIT_ON_CLOSE); frame.setSize(220, 275);
frame.setTitle("Tetris内测版");
// frame.setUndecorated(true);
frame.setVisible(true);
frame.setResizable(false);
}
}
// 创建一个俄罗斯方块类
// blockType 代表方块类型
// turnState代表方块状态
private int blockType;
private int score = 0;
private int turnState;
private int x;
private int y;
private int i = 0;
int j = 0;
int flag = 0;
// 定义已经放下的方块x=0-11,y=0-21;
int[][] map = new int[13][23];
// 方块的形状 第一组代表方块类型有S、Z、L、J、I、O、T 7种 第二组 代表旋转几次 第三四组为 方块矩阵
private final int shapes[][][] = new int[][][] {
// i
{ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 } },
// s
{ { 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 } },
// z
{ { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } },
// j
{ { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
// o
{ { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
// l
{ { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
// t
{ { 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 } } };
// 生成新方块的方法
public void newblock() {
blockType
= (int) (Math.
random() * 1000) % 7; turnState
= (int) (Math.
random() * 1000) % 4; x = 4;
y = 0;
if (gameover(x, y) == 1) {
newmap();
drawwall();
score = 0;
}
}
// 画围墙
public void drawwall() {
for (i = 0; i < 12; i++) {
map[i][21] = 2;
}
for (j = 0; j < 22; j++) {
map[11][j] = 2;
map[0][j] = 2;
}
}
// 初始化地图
public void newmap() {
for (i = 0; i < 12; i++) {
for (j = 0; j < 22; j++) {
map[i][j] = 0;
}
}
}
// 初始化构造方法
Tetrisblok() {
newblock();
newmap();
drawwall();
Timer timer
= new Timer(1000,
new TimerListener
()); timer.start();
}
// 旋转的方法
public void turn() {
int tempturnState = turnState;
turnState = (turnState + 1) % 4;
if (blow(x, y, blockType, turnState) == 1) {
}
if (blow(x, y, blockType, turnState) == 0) {
turnState = tempturnState;
}
repaint();
}
// 左移的方法
public void left() {
if (blow(x - 1, y, blockType, turnState) == 1) {
x = x - 1;
}
;
repaint();
}
// 右移的方法
public void right() {
if (blow(x + 1, y, blockType, turnState) == 1) {
x = x + 1;
}
;
repaint();
}
// 下落的方法
public void down() {
if (blow(x, y + 1, blockType, turnState) == 1) {
y = y + 1;
delline();
}
;
if (blow(x, y + 1, blockType, turnState) == 0) {
add(x, y, blockType, turnState);
newblock();
delline();
}
;
repaint();
}
// 是否合法的方法
public int blow(int x, int y, int blockType, int turnState) {
for (int a = 0; a < 4; a++) {
for (int b = 0; b < 4; b++) {
if (((shapes[blockType][turnState][a * 4 + b] == 1) && (map[x
+ b + 1][y + a] == 1))
|| ((shapes[blockType][turnState][a * 4 + b] == 1) && (map[x
+ b + 1][y + a] == 2))) {
return 0;
}
}
}
return 1;
}
// 消行的方法
public void delline() {
int c = 0;
for (int b = 0; b < 22; b++) {
for (int a = 0; a < 12; a++) {
if (map[a][b] == 1) {
c = c + 1;
if (c == 10) {
score += 10;
for (int d = b; d > 0; d--) {
for (int e = 0; e < 11; e++) {
map[e][d] = map[e][d - 1];
}
}
}
}
}
c = 0;
}
}
// 判断你挂的方法
public int gameover(int x, int y) {
if (blow(x, y, blockType, turnState) == 0) {
return 1;
}
return 0;
}
// 把当前添加map
public void add(int x, int y, int blockType, int turnState) {
int j = 0;
for (int a = 0; a < 4; a++) {
for (int b = 0; b < 4; b++) {
if (map[x + b + 1][y + a] == 0) {
map[x + b + 1][y + a] = shapes[blockType][turnState][j];
}
;
j++;
}
}
}
// 画方块的的方法
public void paintComponent
(Graphics g
) { super.paintComponent(g);
// 画当前方块
for (j = 0; j < 16; j++) {
if (shapes[blockType][turnState][j] == 1) {
g.fillRect((j % 4 + x + 1) * 10, (j / 4 + y) * 10, 10, 10);
}
}
// 画已经固定的方块
for (j = 0; j < 22; j++) {
for (i = 0; i < 12; i++) {
if (map[i][j] == 1) {
g.fillRect(i * 10, j * 10, 10, 10);
}
if (map[i][j] == 2) {
g.drawRect(i * 10, j * 10, 10, 10);
}
}
}
g.drawString("score=" + score, 125, 10);
g.drawString("抵制不良游戏,", 125, 50);
g.drawString("拒绝盗版游戏。", 125, 70);
g.drawString("注意自我保护,", 125, 90);
g.drawString("谨防受骗上当。", 125, 110);
g.drawString("适度游戏益脑,", 125, 130);
g.drawString("沉迷游戏伤身。", 125, 150);
g.drawString("合理安排时间,", 125, 170);
g.drawString("享受健康生活。", 125, 190);
}
// 键盘监听
switch (e.getKeyCode()) {
down();
break;
turn();
break;
right();
break;
left();
break;
}
}
// 无用
}
// 无用
}
// 定时器监听
repaint();
if (blow(x, y + 1, blockType, turnState) == 1) {
y = y + 1;
delline();
}
;
if (blow(x, y + 1, blockType, turnState) == 0) {
if (flag == 1) {
add(x, y, blockType, turnState);
delline();
newblock();
flag = 0;
}
flag = 1;
}
;
}
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwppbXBvcnQgamF2YS5hd3QuKjsKaW1wb3J0IGphdmEuYXd0LmV2ZW50LkFjdGlvbkV2ZW50OwppbXBvcnQgamF2YS5hd3QuZXZlbnQuQWN0aW9uTGlzdGVuZXI7CmltcG9ydCBqYXZhLmF3dC5ldmVudC5LZXlFdmVudDsKaW1wb3J0IGphdmEuYXd0LmV2ZW50LktleUxpc3RlbmVyOwppbXBvcnQgamF2YXguc3dpbmcuKjsKaW1wb3J0IGphdmF4LnN3aW5nLlRpbWVyOwogCnB1YmxpYyBjbGFzcyBUZXRyaXMgZXh0ZW5kcyBKRnJhbWUgewogICAgcHVibGljIFRldHJpcygpIHsKICAgICAgICBUZXRyaXNibG9rIGEgPSBuZXcgVGV0cmlzYmxvaygpOwogICAgICAgIGFkZEtleUxpc3RlbmVyKGEpOwogICAgICAgIGFkZChhKTsKICAgIH0KIAogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgICAgIFRldHJpcyBmcmFtZSA9IG5ldyBUZXRyaXMoKTsKICAgICAgICBKTWVudUJhciBtZW51ID0gbmV3IEpNZW51QmFyKCk7CiAgICAgICAgZnJhbWUuc2V0Sk1lbnVCYXIobWVudSk7CiAgICAgICAgSk1lbnUgZ2FtZSA9IG5ldyBKTWVudSgi5ri45oiPIik7CiAgICAgICAgSk1lbnVJdGVtIG5ld2dhbWUgPSBnYW1lLmFkZCgi5paw5ri45oiPIik7CiAgICAgICAgSk1lbnVJdGVtIHBhdXNlID0gZ2FtZS5hZGQoIuaaguWBnCIpOwogICAgICAgIEpNZW51SXRlbSBnb29uID0gZ2FtZS5hZGQoIue7p+e7rSIpOwogICAgICAgIEpNZW51SXRlbSBleGl0ID0gZ2FtZS5hZGQoIumAgOWHuiIpOwogICAgICAgIEpNZW51IGhlbHAgPSBuZXcgSk1lbnUoIuW4ruWKqSIpOwogICAgICAgIEpNZW51SXRlbSBhYm91dCA9IGhlbHAuYWRkKCLlhbPkuo4iKTsKICAgICAgICBtZW51LmFkZChnYW1lKTsKICAgICAgICBtZW51LmFkZChoZWxwKTsKICAgICAgICBmcmFtZS5zZXRMb2NhdGlvblJlbGF0aXZlVG8obnVsbCk7CiAgICAgICAgZnJhbWUuc2V0RGVmYXVsdENsb3NlT3BlcmF0aW9uKEpGcmFtZS5FWElUX09OX0NMT1NFKTsKICAgICAgICBmcmFtZS5zZXRTaXplKDIyMCwgMjc1KTsKICAgICAgICBmcmFtZS5zZXRUaXRsZSgiVGV0cmlz5YaF5rWL54mIIik7CiAgICAgICAgLy8gZnJhbWUuc2V0VW5kZWNvcmF0ZWQodHJ1ZSk7CiAgICAgICAgZnJhbWUuc2V0VmlzaWJsZSh0cnVlKTsKICAgICAgICBmcmFtZS5zZXRSZXNpemFibGUoZmFsc2UpOwogCiAgICB9Cn0KIAovLyDliJvlu7rkuIDkuKrkv4TnvZfmlq/mlrnlnZfnsbsKY2xhc3MgVGV0cmlzYmxvayBleHRlbmRzIEpQYW5lbCBpbXBsZW1lbnRzIEtleUxpc3RlbmVyIHsKIAogICAgLy8gYmxvY2tUeXBlIOS7o+ihqOaWueWdl+exu+WeiwogICAgLy8gdHVyblN0YXRl5Luj6KGo5pa55Z2X54q25oCBCiAgICBwcml2YXRlIGludCBibG9ja1R5cGU7CiAgICBwcml2YXRlIGludCBzY29yZSA9IDA7CiAKICAgIHByaXZhdGUgaW50IHR1cm5TdGF0ZTsKIAogICAgcHJpdmF0ZSBpbnQgeDsKIAogICAgcHJpdmF0ZSBpbnQgeTsKIAogICAgcHJpdmF0ZSBpbnQgaSA9IDA7CiAKICAgIGludCBqID0gMDsKICAgIGludCBmbGFnID0gMDsKICAgIC8vIOWumuS5ieW3sue7j+aUvuS4i+eahOaWueWdl3g9MC0xMSx5PTAtMjE7CiAgICBpbnRbXVtdIG1hcCA9IG5ldyBpbnRbMTNdWzIzXTsKIAogICAgLy8g5pa55Z2X55qE5b2i54q2IOesrOS4gOe7hOS7o+ihqOaWueWdl+exu+Wei+aciVPjgIFa44CBTOOAgUrjgIFJ44CBT+OAgVQgN+enjSDnrKzkuoznu4Qg5Luj6KGo5peL6L2s5Yeg5qyhIOesrOS4ieWbm+e7hOS4uiDmlrnlnZfnn6npmLUKICAgIHByaXZhdGUgZmluYWwgaW50IHNoYXBlc1tdW11bXSA9IG5ldyBpbnRbXVtdW10gewogICAgLy8gaQogICAgICAgICAgICB7IHsgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCB9LAogICAgICAgICAgICAgICAgICAgIHsgMCwgMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMSwgMCwgMCB9LAogICAgICAgICAgICAgICAgICAgIHsgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCB9LAogICAgICAgICAgICAgICAgICAgIHsgMCwgMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMSwgMCwgMCB9IH0sCiAgICAgICAgICAgIC8vIHMKICAgICAgICAgICAgeyB7IDAsIDEsIDEsIDAsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAgfSwKICAgICAgICAgICAgICAgICAgICB7IDEsIDAsIDAsIDAsIDEsIDEsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAgfSwKICAgICAgICAgICAgICAgICAgICB7IDAsIDEsIDEsIDAsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAgfSwKICAgICAgICAgICAgICAgICAgICB7IDEsIDAsIDAsIDAsIDEsIDEsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAgfSB9LAogICAgICAgICAgICAvLyB6CiAgICAgICAgICAgIHsgeyAxLCAxLCAwLCAwLCAwLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwIH0sCiAgICAgICAgICAgICAgICAgICAgeyAwLCAxLCAwLCAwLCAxLCAxLCAwLCAwLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwIH0sCiAgICAgICAgICAgICAgICAgICAgeyAxLCAxLCAwLCAwLCAwLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwIH0sCiAgICAgICAgICAgICAgICAgICAgeyAwLCAxLCAwLCAwLCAxLCAxLCAwLCAwLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwIH0gfSwKICAgICAgICAgICAgLy8gagogICAgICAgICAgICB7IHsgMCwgMSwgMCwgMCwgMCwgMSwgMCwgMCwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCB9LAogICAgICAgICAgICAgICAgICAgIHsgMSwgMCwgMCwgMCwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCB9LAogICAgICAgICAgICAgICAgICAgIHsgMSwgMSwgMCwgMCwgMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCB9LAogICAgICAgICAgICAgICAgICAgIHsgMSwgMSwgMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCB9IH0sCiAgICAgICAgICAgIC8vIG8KICAgICAgICAgICAgeyB7IDEsIDEsIDAsIDAsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAgfSwKICAgICAgICAgICAgICAgICAgICB7IDEsIDEsIDAsIDAsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAgfSwKICAgICAgICAgICAgICAgICAgICB7IDEsIDEsIDAsIDAsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAgfSwKICAgICAgICAgICAgICAgICAgICB7IDEsIDEsIDAsIDAsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAgfSB9LAogICAgICAgICAgICAvLyBsCiAgICAgICAgICAgIHsgeyAxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwIH0sCiAgICAgICAgICAgICAgICAgICAgeyAxLCAxLCAxLCAwLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwIH0sCiAgICAgICAgICAgICAgICAgICAgeyAxLCAxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAwLCAwLCAwIH0sCiAgICAgICAgICAgICAgICAgICAgeyAwLCAwLCAxLCAwLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwIH0gfSwKICAgICAgICAgICAgLy8gdAogICAgICAgICAgICB7IHsgMCwgMSwgMCwgMCwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCB9LAogICAgICAgICAgICAgICAgICAgIHsgMCwgMSwgMCwgMCwgMSwgMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCB9LAogICAgICAgICAgICAgICAgICAgIHsgMSwgMSwgMSwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCB9LAogICAgICAgICAgICAgICAgICAgIHsgMCwgMSwgMCwgMCwgMCwgMSwgMSwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCB9IH0gfTsKIAogICAgLy8g55Sf5oiQ5paw5pa55Z2X55qE5pa55rOVCiAgICBwdWJsaWMgdm9pZCBuZXdibG9jaygpIHsKICAgICAgICBibG9ja1R5cGUgPSAoaW50KSAoTWF0aC5yYW5kb20oKSAqIDEwMDApICUgNzsKICAgICAgICB0dXJuU3RhdGUgPSAoaW50KSAoTWF0aC5yYW5kb20oKSAqIDEwMDApICUgNDsKICAgICAgICB4ID0gNDsKICAgICAgICB5ID0gMDsKICAgICAgICBpZiAoZ2FtZW92ZXIoeCwgeSkgPT0gMSkgewogCiAgICAgICAgICAgIG5ld21hcCgpOwogICAgICAgICAgICBkcmF3d2FsbCgpOwogICAgICAgICAgICBzY29yZSA9IDA7CiAgICAgICAgICAgIEpPcHRpb25QYW5lLnNob3dNZXNzYWdlRGlhbG9nKG51bGwsICJHQU1FIE9WRVIiKTsKICAgICAgICB9CiAgICB9CiAKICAgIC8vIOeUu+WbtOWimQogICAgcHVibGljIHZvaWQgZHJhd3dhbGwoKSB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHsKICAgICAgICAgICAgbWFwW2ldWzIxXSA9IDI7CiAgICAgICAgfQogICAgICAgIGZvciAoaiA9IDA7IGogPCAyMjsgaisrKSB7CiAgICAgICAgICAgIG1hcFsxMV1bal0gPSAyOwogICAgICAgICAgICBtYXBbMF1bal0gPSAyOwogICAgICAgIH0KICAgIH0KIAogICAgLy8g5Yid5aeL5YyW5Zyw5Zu+CiAgICBwdWJsaWMgdm9pZCBuZXdtYXAoKSB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHsKICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IDIyOyBqKyspIHsKICAgICAgICAgICAgICAgIG1hcFtpXVtqXSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAKICAgIC8vIOWIneWni+WMluaehOmAoOaWueazlQogICAgVGV0cmlzYmxvaygpIHsKICAgICAgICBuZXdibG9jaygpOwogICAgICAgIG5ld21hcCgpOwogICAgICAgIGRyYXd3YWxsKCk7CiAgICAgICAgVGltZXIgdGltZXIgPSBuZXcgVGltZXIoMTAwMCwgbmV3IFRpbWVyTGlzdGVuZXIoKSk7CiAgICAgICAgdGltZXIuc3RhcnQoKTsKICAgIH0KIAogICAgLy8g5peL6L2s55qE5pa55rOVCiAgICBwdWJsaWMgdm9pZCB0dXJuKCkgewogICAgICAgIGludCB0ZW1wdHVyblN0YXRlID0gdHVyblN0YXRlOwogICAgICAgIHR1cm5TdGF0ZSA9ICh0dXJuU3RhdGUgKyAxKSAlIDQ7CiAgICAgICAgaWYgKGJsb3coeCwgeSwgYmxvY2tUeXBlLCB0dXJuU3RhdGUpID09IDEpIHsKICAgICAgICB9CiAgICAgICAgaWYgKGJsb3coeCwgeSwgYmxvY2tUeXBlLCB0dXJuU3RhdGUpID09IDApIHsKICAgICAgICAgICAgdHVyblN0YXRlID0gdGVtcHR1cm5TdGF0ZTsKICAgICAgICB9CiAgICAgICAgcmVwYWludCgpOwogICAgfQogCiAgICAvLyDlt6bnp7vnmoTmlrnms5UKICAgIHB1YmxpYyB2b2lkIGxlZnQoKSB7CiAgICAgICAgaWYgKGJsb3coeCAtIDEsIHksIGJsb2NrVHlwZSwgdHVyblN0YXRlKSA9PSAxKSB7CiAgICAgICAgICAgIHggPSB4IC0gMTsKICAgICAgICB9CiAgICAgICAgOwogICAgICAgIHJlcGFpbnQoKTsKICAgIH0KIAogICAgLy8g5Y+z56e755qE5pa55rOVCiAgICBwdWJsaWMgdm9pZCByaWdodCgpIHsKICAgICAgICBpZiAoYmxvdyh4ICsgMSwgeSwgYmxvY2tUeXBlLCB0dXJuU3RhdGUpID09IDEpIHsKICAgICAgICAgICAgeCA9IHggKyAxOwogICAgICAgIH0KICAgICAgICA7CiAgICAgICAgcmVwYWludCgpOwogICAgfQogCiAgICAvLyDkuIvokL3nmoTmlrnms5UKICAgIHB1YmxpYyB2b2lkIGRvd24oKSB7CiAgICAgICAgaWYgKGJsb3coeCwgeSArIDEsIGJsb2NrVHlwZSwgdHVyblN0YXRlKSA9PSAxKSB7CiAgICAgICAgICAgIHkgPSB5ICsgMTsKICAgICAgICAgICAgZGVsbGluZSgpOwogICAgICAgIH0KICAgICAgICA7CiAgICAgICAgaWYgKGJsb3coeCwgeSArIDEsIGJsb2NrVHlwZSwgdHVyblN0YXRlKSA9PSAwKSB7CiAgICAgICAgICAgIGFkZCh4LCB5LCBibG9ja1R5cGUsIHR1cm5TdGF0ZSk7CiAgICAgICAgICAgIG5ld2Jsb2NrKCk7CiAgICAgICAgICAgIGRlbGxpbmUoKTsKICAgICAgICB9CiAgICAgICAgOwogICAgICAgIHJlcGFpbnQoKTsKICAgIH0KIAogICAgLy8g5piv5ZCm5ZCI5rOV55qE5pa55rOVCiAgICBwdWJsaWMgaW50IGJsb3coaW50IHgsIGludCB5LCBpbnQgYmxvY2tUeXBlLCBpbnQgdHVyblN0YXRlKSB7CiAgICAgICAgZm9yIChpbnQgYSA9IDA7IGEgPCA0OyBhKyspIHsKICAgICAgICAgICAgZm9yIChpbnQgYiA9IDA7IGIgPCA0OyBiKyspIHsKICAgICAgICAgICAgICAgIGlmICgoKHNoYXBlc1tibG9ja1R5cGVdW3R1cm5TdGF0ZV1bYSAqIDQgKyBiXSA9PSAxKSAmJiAobWFwW3gKICAgICAgICAgICAgICAgICAgICAgICAgKyBiICsgMV1beSArIGFdID09IDEpKQogICAgICAgICAgICAgICAgICAgICAgICB8fCAoKHNoYXBlc1tibG9ja1R5cGVdW3R1cm5TdGF0ZV1bYSAqIDQgKyBiXSA9PSAxKSAmJiAobWFwW3gKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGIgKyAxXVt5ICsgYV0gPT0gMikpKSB7CiAKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gMTsKICAgIH0KIAogICAgLy8g5raI6KGM55qE5pa55rOVCiAgICBwdWJsaWMgdm9pZCBkZWxsaW5lKCkgewogICAgICAgIGludCBjID0gMDsKICAgICAgICBmb3IgKGludCBiID0gMDsgYiA8IDIyOyBiKyspIHsKICAgICAgICAgICAgZm9yIChpbnQgYSA9IDA7IGEgPCAxMjsgYSsrKSB7CiAgICAgICAgICAgICAgICBpZiAobWFwW2FdW2JdID09IDEpIHsKIAogICAgICAgICAgICAgICAgICAgIGMgPSBjICsgMTsKICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAxMCkgewogICAgICAgICAgICAgICAgICAgICAgICBzY29yZSArPSAxMDsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgZCA9IGI7IGQgPiAwOyBkLS0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGUgPSAwOyBlIDwgMTE7IGUrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcFtlXVtkXSA9IG1hcFtlXVtkIC0gMV07CiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjID0gMDsKICAgICAgICB9CiAgICB9CiAKICAgIC8vIOWIpOaWreS9oOaMgueahOaWueazlQogICAgcHVibGljIGludCBnYW1lb3ZlcihpbnQgeCwgaW50IHkpIHsKICAgICAgICBpZiAoYmxvdyh4LCB5LCBibG9ja1R5cGUsIHR1cm5TdGF0ZSkgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAKICAgIC8vIOaKiuW9k+WJjea3u+WKoG1hcAogICAgcHVibGljIHZvaWQgYWRkKGludCB4LCBpbnQgeSwgaW50IGJsb2NrVHlwZSwgaW50IHR1cm5TdGF0ZSkgewogICAgICAgIGludCBqID0gMDsKICAgICAgICBmb3IgKGludCBhID0gMDsgYSA8IDQ7IGErKykgewogICAgICAgICAgICBmb3IgKGludCBiID0gMDsgYiA8IDQ7IGIrKykgewogICAgICAgICAgICAgICAgaWYgKG1hcFt4ICsgYiArIDFdW3kgKyBhXSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgbWFwW3ggKyBiICsgMV1beSArIGFdID0gc2hhcGVzW2Jsb2NrVHlwZV1bdHVyblN0YXRlXVtqXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIDsKICAgICAgICAgICAgICAgIGorKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KIAogICAgLy8g55S75pa55Z2X55qE55qE5pa55rOVCiAgICBwdWJsaWMgdm9pZCBwYWludENvbXBvbmVudChHcmFwaGljcyBnKSB7CiAgICAgICAgc3VwZXIucGFpbnRDb21wb25lbnQoZyk7CiAgICAgICAgLy8g55S75b2T5YmN5pa55Z2XCiAgICAgICAgZm9yIChqID0gMDsgaiA8IDE2OyBqKyspIHsKICAgICAgICAgICAgaWYgKHNoYXBlc1tibG9ja1R5cGVdW3R1cm5TdGF0ZV1bal0gPT0gMSkgewogICAgICAgICAgICAgICAgZy5maWxsUmVjdCgoaiAlIDQgKyB4ICsgMSkgKiAxMCwgKGogLyA0ICsgeSkgKiAxMCwgMTAsIDEwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyDnlLvlt7Lnu4/lm7rlrprnmoTmlrnlnZcKICAgICAgICBmb3IgKGogPSAwOyBqIDwgMjI7IGorKykgewogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTI7IGkrKykgewogICAgICAgICAgICAgICAgaWYgKG1hcFtpXVtqXSA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgZy5maWxsUmVjdChpICogMTAsIGogKiAxMCwgMTAsIDEwKTsKIAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG1hcFtpXVtqXSA9PSAyKSB7CiAgICAgICAgICAgICAgICAgICAgZy5kcmF3UmVjdChpICogMTAsIGogKiAxMCwgMTAsIDEwKTsKIAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGcuZHJhd1N0cmluZygic2NvcmU9IiArIHNjb3JlLCAxMjUsIDEwKTsKICAgICAgICBnLmRyYXdTdHJpbmcoIuaKteWItuS4jeiJr+a4uOaIj++8jCIsIDEyNSwgNTApOwogICAgICAgIGcuZHJhd1N0cmluZygi5ouS57ud55uX54mI5ri45oiP44CCIiwgMTI1LCA3MCk7CiAgICAgICAgZy5kcmF3U3RyaW5nKCLms6jmhI/oh6rmiJHkv53miqTvvIwiLCAxMjUsIDkwKTsKICAgICAgICBnLmRyYXdTdHJpbmcoIuiwqOmYsuWPl+mql+S4iuW9k+OAgiIsIDEyNSwgMTEwKTsKICAgICAgICBnLmRyYXdTdHJpbmcoIumAguW6pua4uOaIj+ebiuiEke+8jCIsIDEyNSwgMTMwKTsKICAgICAgICBnLmRyYXdTdHJpbmcoIuayiei/t+a4uOaIj+S8pOi6q+OAgiIsIDEyNSwgMTUwKTsKICAgICAgICBnLmRyYXdTdHJpbmcoIuWQiOeQhuWuieaOkuaXtumXtO+8jCIsIDEyNSwgMTcwKTsKICAgICAgICBnLmRyYXdTdHJpbmcoIuS6q+WPl+WBpeW6t+eUn+a0u+OAgiIsIDEyNSwgMTkwKTsKICAgIH0KIAogICAgLy8g6ZSu55uY55uR5ZCsCiAgICBwdWJsaWMgdm9pZCBrZXlQcmVzc2VkKEtleUV2ZW50IGUpIHsKICAgICAgICBzd2l0Y2ggKGUuZ2V0S2V5Q29kZSgpKSB7CiAgICAgICAgY2FzZSBLZXlFdmVudC5WS19ET1dOOgogICAgICAgICAgICBkb3duKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgS2V5RXZlbnQuVktfVVA6CiAgICAgICAgICAgIHR1cm4oKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBLZXlFdmVudC5WS19SSUdIVDoKICAgICAgICAgICAgcmlnaHQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBLZXlFdmVudC5WS19MRUZUOgogICAgICAgICAgICBsZWZ0KCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KIAogICAgfQogCiAgICAvLyDml6DnlKgKICAgIHB1YmxpYyB2b2lkIGtleVJlbGVhc2VkKEtleUV2ZW50IGUpIHsKICAgIH0KIAogICAgLy8g5peg55SoCiAgICBwdWJsaWMgdm9pZCBrZXlUeXBlZChLZXlFdmVudCBlKSB7CiAgICB9CiAKICAgIC8vIOWumuaXtuWZqOebkeWQrAogICAgY2xhc3MgVGltZXJMaXN0ZW5lciBpbXBsZW1lbnRzIEFjdGlvbkxpc3RlbmVyIHsKICAgICAgICBwdWJsaWMgdm9pZCBhY3Rpb25QZXJmb3JtZWQoQWN0aW9uRXZlbnQgZSkgewogCiAgICAgICAgICAgIHJlcGFpbnQoKTsKICAgICAgICAgICAgaWYgKGJsb3coeCwgeSArIDEsIGJsb2NrVHlwZSwgdHVyblN0YXRlKSA9PSAxKSB7CiAgICAgICAgICAgICAgICB5ID0geSArIDE7CiAgICAgICAgICAgICAgICBkZWxsaW5lKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgOwogICAgICAgICAgICBpZiAoYmxvdyh4LCB5ICsgMSwgYmxvY2tUeXBlLCB0dXJuU3RhdGUpID09IDApIHsKIAogICAgICAgICAgICAgICAgaWYgKGZsYWcgPT0gMSkgewogICAgICAgICAgICAgICAgICAgIGFkZCh4LCB5LCBibG9ja1R5cGUsIHR1cm5TdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgZGVsbGluZSgpOwogICAgICAgICAgICAgICAgICAgIG5ld2Jsb2NrKCk7CiAgICAgICAgICAgICAgICAgICAgZmxhZyA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmbGFnID0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICA7CiAgICAgICAgfQogICAgfQp9