MagisterRain

Puzzle 2048

Jul 22nd, 2018
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.92 KB | None | 0 0
  1. package com;
  2.  
  3. import java.awt.Color;
  4. import java.awt.Dimension;
  5. import java.awt.Font;
  6. import java.awt.FontMetrics;
  7. import java.awt.Graphics;
  8. import java.awt.Graphics2D;
  9. import java.awt.RenderingHints;
  10. import java.awt.event.KeyAdapter;
  11. import java.awt.event.KeyEvent;
  12. import java.util.Random;
  13.  
  14. import javax.swing.JFrame;
  15. import javax.swing.JPanel;
  16. import javax.swing.WindowConstants;
  17.  
  18. public class Game extends JPanel {
  19.  
  20.     static JFrame frame;
  21.     Field field;
  22.     boolean inGame = true;
  23.     boolean theme = false;
  24.  
  25.     public Game() {
  26.         setPreferredSize(new Dimension(342, 364));
  27.         setFocusable(true);
  28.         addKeyListener(new KeyAdapter() {
  29.             @Override
  30.             public void keyPressed(KeyEvent e) {
  31.                 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
  32.                     init();
  33.                 } else {
  34.                     if (inGame) {
  35.                         if (e.getKeyCode() == KeyEvent.VK_LEFT) {
  36.                             field.shuffle(1);
  37.                             check();
  38.                         } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
  39.                             field.shuffle(2);
  40.                             check();
  41.                         } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
  42.                             field.shuffle(3);
  43.                             check();
  44.                         } else if (e.getKeyCode() == KeyEvent.VK_UP) {
  45.                             field.shuffle(0);
  46.                             check();
  47.                         }
  48.                     }
  49.                     inGame = field.check();
  50.                     if (inGame && !field.isFull()) {
  51.                         field.add();
  52.                     }
  53.                 }
  54.             }
  55.         });
  56.         init();
  57.     }
  58.  
  59.     void check() {
  60.         inGame = field.check();
  61.         if (inGame && !field.isFull())
  62.             field.add();
  63.         repaint();
  64.     }
  65.  
  66.     void init() {
  67.         field = new Field();
  68.         inGame = true;
  69.         repaint();
  70.     }
  71.  
  72.     int getTileColor(int i) {
  73.         switch (i) {
  74.         case 2:
  75.             return theme ? 0xad08aa : 0xeee4da;
  76.         case 4:
  77.             return theme ? 0xcc041e : 0xede0c8;
  78.         case 8:
  79.             return theme ? 0xf7de00 : 0xf2b179;
  80.         case 16:
  81.             return theme ? 0x00ad05 : 0xf59563;
  82.         case 32:
  83.             return theme ? 0x00967d : 0xf67c5f;
  84.         case 64:
  85.             return theme ? 0x910065 : 0xf65e3b;
  86.         case 128:
  87.             return theme ? 0xff7b0f : 0xedcf72;
  88.         case 256:
  89.             return theme ? 0x00ce71 : 0xedcc61;
  90.         case 512:
  91.             return theme ? 0x00005b : 0xedc850;
  92.         case 1024:
  93.             return theme ? 0xff2600 : 0xedc53f;
  94.         case 2048:
  95.             return theme ? 0x050030 : 0xedc22e;
  96.         }
  97.         return theme ? 0x510f66 : 0xcdc1b4;
  98.     }
  99.  
  100.     int getTextColor(int i) {
  101.         return theme ? 0xffffff : (i < 16 ? 0x776e65 : 0xf9f6f2);
  102.     }
  103.  
  104.     int getTextSize(int i) {
  105.         if (i < 100)
  106.             return 36;
  107.         if (i < 1000)
  108.             return 32;
  109.         if (i < 10000)
  110.             return 28;
  111.         return 22;
  112.     }
  113.  
  114.     @Override
  115.     public void paint(Graphics g) {
  116.         super.paint(g);
  117.         g.setColor(new Color(theme ? 0x262626 : 0xbbada0));
  118.         g.fillRect(0, 0, this.getSize().width, this.getSize().height);
  119.         frame.setTitle("Puzzle 2048. Score: " + field.getScore());
  120.         for (int x = 0; x < 4; x++) {
  121.             int i = x * 80 + 16;
  122.             for (int y = 0; y < 4; y++) {
  123.                 int j = y * 80 + 16;
  124.                 draw((Graphics2D) g, field.get(x, y), i, j);
  125.             }
  126.         }
  127.         if (!inGame)
  128.             fin((Graphics2D) g);
  129.     }
  130.  
  131.     void fin(Graphics2D g) {
  132.         frame.setTitle("Puzzle 2048");
  133.         g.setColor(new Color(255, 255, 255, 30));
  134.         g.fillRect(0, 0, getWidth(), getHeight());
  135.         g.setColor(new Color(0x000000));
  136.         Font font = new Font("Cambria", Font.BOLD, 48);
  137.         g.setFont(font);
  138.         g.drawString("Game over!", 43, 104);
  139.         g.drawString("Your score:", 44, 184);
  140.  
  141.         String s = String.valueOf(field.getScore());
  142.         FontMetrics fm = getFontMetrics(font);
  143.         int w = fm.stringWidth(s);
  144.  
  145.         g.drawString(s, (this.getSize().width - w) / 2, 264);
  146.  
  147.     }
  148.  
  149.     void draw(Graphics2D g, int val, int x, int y) {
  150.         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  151.         g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
  152.         g.setColor(new Color(getTileColor(val)));
  153.  
  154.         if (theme) {
  155.             g.fillRect(x, y, 64, 64);
  156.         } else {
  157.             g.fillRoundRect(x, y, 64, 64, 14, 14);
  158.         }
  159.  
  160.         if (val > 0) {
  161.             g.setColor(new Color(getTextColor(val)));
  162.             Font font = new Font("Cambria", Font.BOLD, getTextSize(val));
  163.             String s = String.valueOf(val);
  164.             g.setFont(font);
  165.             FontMetrics fm = getFontMetrics(font);
  166.             int w = fm.stringWidth(s);
  167.             int h = -(int) fm.getLineMetrics(s, g).getBaselineOffsets()[2];
  168.             g.drawString(s, x + (64 - w) / 2, y + 64 - (64 - h) / 2 - 2);
  169.         }
  170.     }
  171.  
  172.     static class Field {
  173.  
  174.         Random random = new Random();
  175.         int[][] field;
  176.         int score = 0;
  177.  
  178.         public Field() {
  179.             field = new int[4][4];
  180.             add();
  181.             add();
  182.         }
  183.  
  184.         public int getScore() {
  185.             return score;
  186.         }
  187.  
  188.         public int get(int x, int y) {
  189.             return field[x][y];
  190.         }
  191.  
  192.         // Upward orientation
  193.         public void shuffle(int times) {
  194.             if (times != 0)
  195.                 rotate(times);
  196.             for (int i = 0; i < 4; i++) {
  197.                 int[] in1 = new int[4];
  198.                 for (int j = 0; j < 4; j++)
  199.                     in1[j] = 0;
  200.                 int[] in2 = field[i];
  201.                 int j = 0;
  202.                 for (int k = 0; k < 4; k++) {
  203.                     if (in2[k] != 0) {
  204.                         in1[j] = in2[k];
  205.                         j++;
  206.                     }
  207.                 }
  208.                 if (in1[0] != 0) {
  209.                     for (int k = 0; k < 3; k++) {
  210.                         if (in1[k] == in1[k + 1]) {
  211.                             in1[k] *= 2;
  212.                             score += in1[k];
  213.                             in1[k + 1] = 0;
  214.                         }
  215.                     }
  216.                     j = 0;
  217.                     for (int k = 0; k < 4; k++) {
  218.                         if (in1[k] != 0) {
  219.                             in2[j] = in1[k];
  220.                             j++;
  221.                         }
  222.                     }
  223.                     while (j < 4) {
  224.                         in2[j] = 0;
  225.                         j++;
  226.                     }
  227.                     field[i] = in2;
  228.                 }
  229.             }
  230.             if (times != 0)
  231.                 rotate(4 - times);
  232.         }
  233.  
  234.         // Clockwise
  235.         private void rotate(int times) {
  236.             for (int i = 0; i < times; i++) {
  237.                 int temp;
  238.                 temp = field[1][1];
  239.                 field[1][1] = field[1][2];
  240.                 field[1][2] = field[2][2];
  241.                 field[2][2] = field[2][1];
  242.                 field[2][1] = temp;
  243.                 temp = field[1][0];
  244.                 field[1][0] = field[0][2];
  245.                 field[0][2] = field[2][3];
  246.                 field[2][3] = field[3][1];
  247.                 field[3][1] = temp;
  248.                 temp = field[2][0];
  249.                 field[2][0] = field[0][1];
  250.                 field[0][1] = field[1][3];
  251.                 field[1][3] = field[3][2];
  252.                 field[3][2] = temp;
  253.                 temp = field[0][0];
  254.                 field[0][0] = field[0][3];
  255.                 field[0][3] = field[3][3];
  256.                 field[3][3] = field[3][0];
  257.                 field[3][0] = temp;
  258.             }
  259.         }
  260.  
  261.         public void add() {
  262.             if (!isFull())
  263.                 while (true) {
  264.                     int x = random.nextInt(4);
  265.                     int y = random.nextInt(4);
  266.                     if (field[x][y] == 0) {
  267.                         field[x][y] = random.nextInt(100) > 24 ? 2 : 4;
  268.                         return;
  269.                     }
  270.                 }
  271.         }
  272.  
  273.         public boolean isFull() {
  274.             for (int x = 0; x < 4; x++)
  275.                 for (int y = 0; y < 4; y++)
  276.                     if (field[x][y] == 0)
  277.                         return false;
  278.             return true;
  279.         }
  280.  
  281.         public boolean check() {
  282.             if (!isFull())
  283.                 return true;
  284.             for (int x = 0; x < 4; x++)
  285.                 for (int y = 0; y < 4; y++)
  286.                     if ((x < 3 && field[x][y] == field[x + 1][y]) | (y < 3 && field[x][y] == field[x][y + 1]))
  287.                         return true;
  288.             return false;
  289.         }
  290.  
  291.     }
  292.  
  293.     public static void main(String[] args) {
  294.         frame = new JFrame();
  295.         frame.setTitle("Puzzle 2048");
  296.         frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
  297.         frame.setSize(342, 364);
  298.         frame.setResizable(false);
  299.  
  300.         frame.add(new Game());
  301.  
  302.         frame.setLocationRelativeTo(null);
  303.         frame.setVisible(true);
  304.     }
  305. }
Advertisement
Add Comment
Please, Sign In to add comment