写的比较匆忙,功能较为单一,界面丑,操作步数应该还能优化。
最终还是要写AI,但好像没那么简单,写了几个关于格局评价的函数,还得继续学习。。。
上下左右方向键操作。
源代码:
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.GridLayout; import java.awt.event.*; import java.util.Random; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.TitledBorder; public class My2048 extends JFrame { JPanel numpanel = new JPanel(); JPanel scorepanel = new JPanel(); JLabel numlabellist[][] = new JLabel[4][4];// 数字格子 int numlist[][] = new int[4][4];// 数组格子对应数值 int blanks = 16;// 空白格子数 int score=0;//总得分 JLabel scorelabel=new JLabel(); int numlist2[][] = new int[4][4];//用于格局评价时的数组 int smoothweight=1; int monoweight=10; int emptyweight=27; int maxweight=10; public static void main(String[] args) { new My2048().launchFrame(); } public void AddNumArea() { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { numlabellist[i][j] = new JLabel(); numlist[i][j] = 0; numlabellist[i][j].setBackground(Color.LIGHT_GRAY); numlabellist[i][j].setBorder(new TitledBorder("")); numlabellist[i][j].setFont(new Font("Romantic", Font.BOLD, 35)); numlabellist[i][j].setHorizontalAlignment(JTextField.CENTER); numpanel.add(numlabellist[i][j]); } } public void AddScoreLabel(){ scorelabel.setBackground(Color.MAGENTA); scorelabel.setFont(new Font("Romantic", Font.BOLD, 35)); scorelabel.setHorizontalAlignment(JTextField.CENTER); scorelabel.setText("score:"+Integer.toString(score)); scorepanel.add(scorelabel); } // 随机选一个空白格子 public int RandomIndex(int blanks) { Random random = new Random(System.currentTimeMillis()); int result = random.nextInt(blanks)+1; return result; } // 2,4随机选一个 public int RandomValue() { Random random = new Random(); int result = random.nextInt(2); return (result+1)*2; } //空白处产生一新值,自带refresh功能 public void NewValue() { int newvalue = RandomValue();// 新值 int index = RandomIndex(blanks);// 新值得位置 blanks--;// 空白格子数-1 for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { if (numlist[i][j] == 0) index--; if (index == 0) { numlist[i][j] = newvalue; // 相应label上显示新值 numlabellist[i][j].setText(Integer.toString(newvalue)); return; } } } public boolean LeftReduce() { boolean changed=false;//是否有改变(移动和相加),作为后续是否产生新值得依据 boolean has0before; int p;// 行指针 int value;//当前值 for (int i = 0; i < 4; i++) { p=0; value=0; has0before=false; for (int j = 0; j < 4; j++) { if(numlist[i][j]>0&&has0before)//移动方向上之前有空格,可移动,changed为true changed=true; if(numlist[i][j]==0) has0before=true; if (numlist[i][j] > 0) { if(numlist[i][j]==value)//相加放p位置 { int sum=value*2; numlist[i][j]=0; numlist[i][p]=sum; value=0; p++; score+=sum; changed=true;//相加,changed为true } else { if(value>0)//value放p中,当前值放value中 { numlist[i][p]=value; p++; } value=numlist[i][j]; numlist[i][j]=0; } } } if(value>0)//到最后value中可能有值 numlist[i][p]=value; } return changed; } public boolean RightReduce() { boolean changed=false;//是否有改变(移动和相加),作为后续是否产生新值得依据 boolean has0before; int p;// 行指针 int value;//当前值 for (int i = 0; i <4; i++) { p=3; value=0; has0before=false; for (int j = 3; j >= 0; j--) { if(numlist[i][j]>0&&has0before)//移动方向上之前有空格,可移动,changed为true changed=true; if(numlist[i][j]==0) has0before=true; if (numlist[i][j] > 0) { if(numlist[i][j]==value)//相加放p位置 { int sum=value*2; numlist[i][j]=0; numlist[i][p]=sum; value=0; p--; score+=sum; changed=true;//相加,changed为true } else { if(value>0)//value放p中,当前值放value中 { numlist[i][p]=value; p--; } value=numlist[i][j]; numlist[i][j]=0; } } } if(value>0)//到最后value中可能有值 numlist[i][p]=value; } return changed; } public boolean UpReduce() { boolean changed=false;//是否有改变(移动和相加),作为后续是否产生新值得依据 boolean has0before; int p;// 行指针 int value;//当前值 for (int j = 0; j <4; j++) { p=0; value=0; has0before=false; for (int i = 0; i <4; i++) { if(numlist[i][j]>0&&has0before)//移动方向上之前有空格,可移动,changed为true changed=true; if(numlist[i][j]==0) has0before=true; if (numlist[i][j] > 0) { if(numlist[i][j]==value)//相加放p位置 { int sum=value*2; numlist[i][j]=0; numlist[p][j]=sum; value=0; p++; score+=sum; changed=true;//相加,changed为true } else { if(value>0)//value放p中,当前值放value中 { numlist[p][j]=value; p++; } value=numlist[i][j]; numlist[i][j]=0; } } } if(value>0)//到最后value中可能有值 numlist[p][j]=value; } return changed; } public boolean DownReduce() { boolean changed=false;//是否有改变(移动和相加),作为后续是否产生新值得依据 boolean has0before; int p;// 行指针 int value;//当前值 for (int j = 0; j <4; j++) { p=3; value=0; has0before=false; for (int i = 3; i >=0; i--) { if(numlist[i][j]>0&&has0before)//移动方向上之前有空格,可移动,changed为true changed=true; if(numlist[i][j]==0) has0before=true; if (numlist[i][j] > 0) { if(numlist[i][j]==value)//相加放p位置 { int sum=value*2; numlist[i][j]=0; numlist[p][j]=sum; value=0; p--; score+=sum; changed=true;//相加,changed为true } else { if(value>0)//value放p中,当前值放value中 { numlist[p][j]=value; p--; } value=numlist[i][j]; numlist[i][j]=0; } } } if(value>0)//到最后value中可能有值 numlist[p][j]=value; } return changed; } public void Refresh(){ blanks=0; scorelabel.setText("score:"+Integer.toString(score)); for(int i=0;i<4;i++) for(int j=0;j<4;j++) { if(numlist[i][j]!=0) numlabellist[i][j].setText(Integer.toString(numlist[i][j])); else { numlabellist[i][j].setText(null); blanks++; } } } public boolean CheckOut(){ if(blanks>0) return false; for(int i=0;i<4;i++) for(int j=0;j<3;j++) { if(numlist[i][j]==numlist[i][j+1]) return false; } for(int j=0;j<4;j++) for(int i=0;i<3;i++) { if(numlist[i][j]==numlist[i+1][j]) return false; } return true; } public void Out(){ JOptionPane.showMessageDialog(null, "游戏结束!", "2048PC版", 2); System.exit(0); } public void PrintNumlist() { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { System.out.print(numlist[i][j]); System.out.print(' '); } System.out.println(); } System.out.println("***********************"); } //单调率,后期乘以monoweight(干脆方法内乘了) public int Mononess(){ int result1=0;//从右往左递增度量 int result2=0;//从上往下递增度量 int lastvalue=0; for(int i=0;i<4;i++) { lastvalue=0; for(int j=0;j<4;j++) { if(numlist[i][j]>0) { if(lastvalue>0) if(numlist[i][j]<lastvalue) result1++; if(numlist[i][j]>lastvalue) result1--; lastvalue=numlist[i][j]; } } } lastvalue=0; for(int j=0;j<4;j++) { lastvalue=0; for(int i=0;i<4;i++) { if(numlist[i][j]>0) { if(lastvalue>0) if(numlist[i][j]>lastvalue) result2++; if(numlist[i][j]<lastvalue) result2--; lastvalue=numlist[i][j]; } } } if(result2>result1) return result2*monoweight; return result1*monoweight; } //平滑率,是负数,是差的和的相反数,后期乘以smoothweight(干脆方法内乘了) public int Smoothness(){ int result1=0;//水平方向 int result2=0;//竖直方向 int lastvalue=0; for(int i=0;i<4;i++) { lastvalue=0; for(int j=0;j<4;j++) { if(numlist[i][j]>0) { if(lastvalue>0) result1+=Math.abs(numlist[i][j]-lastvalue); lastvalue=numlist[i][j]; } } } lastvalue=0; for(int j=0;j<4;j++) { lastvalue=0; for(int i=0;i<4;i++) { if(numlist[i][j]>0) { if(lastvalue>0) result2+=Math.abs(numlist[i][j]-lastvalue); lastvalue=numlist[i][j]; } } } if(result2>result1) return (0-result1)*smoothweight; return (0-result2)*smoothweight; } //最大数,后期乘以maxweight(干脆方法内乘了) public int Maxness(){ int max=0; for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(numlist[i][j]>max) max=numlist[i][j]; return max*maxweight; } public int Emptyness(){ return blanks*emptyweight; } public void launchFrame() { setTitle("2048PC版"); // 设置窗体标题 setBounds(700, 100, 400, 475); setLayout(new BorderLayout()); setResizable(false); // 禁止调整窗体大小 numpanel.setLayout(new GridLayout(4, 4)); // 设置空布局 numpanel.setLocation(0,200); AddScoreLabel();//添加计分器 AddNumArea();// 添加数字格子 getContentPane().add(scorepanel,BorderLayout.NORTH); getContentPane().add(numpanel,BorderLayout.CENTER); NewValue(); NewValue(); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); this.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if (e.getKeyCode() == 37)// 左键 { if(LeftReduce()) { Refresh();//更新blank,numlabellist NewValue(); } } if (e.getKeyCode() == 39)// 右键 { if(RightReduce()) { Refresh();//更新blank,numlabellist NewValue(); } } if (e.getKeyCode() == 38)// 上键 { if(UpReduce()) { Refresh();//更新blank,numlabellist NewValue(); } } if (e.getKeyCode() == 40)// 上键 { if(DownReduce()) { Refresh();//更新blanks,numlabellist,scorelabel NewValue(); } } if (e.getKeyCode() == 32)// 空格键 { if(LeftReduce()) { Refresh();//更新blanks,numlabellist,scorelabel NewValue(); } else if(RightReduce()) { Refresh();//更新blanks,numlabellist,scorelabel NewValue(); } else if(UpReduce()) { Refresh();//更新blanks,numlabellist,scorelabel NewValue(); } else if(DownReduce()) { Refresh();//更新blanks,numlabellist,scorelabel NewValue(); } } System.out.println(e.getKeyCode()); if(CheckOut())//检查游戏是否结束 Out(); PrintNumlist(); System.out.println("mononess:"+Integer.toString(Mononess())); System.out.println("smoothness:"+Integer.toString(Smoothness())); System.out.println("maxnum:"+Integer.toString(Maxness())); System.out.println("blanks:"+Integer.toString(Emptyness())); } }); setVisible(true); } }
时间: 2024-10-13 22:27:21