码迷,mamicode.com
首页 > 编程语言 > 详细

2048游戏的Java实现

时间:2014-12-13 09:36:47      阅读:400      评论:0      收藏:0      [点我收藏+]

标签:2048   java   

写的比较匆忙,功能较为单一,界面丑,操作步数应该还能优化。

最终还是要写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);
	}

}






2048游戏的Java实现

标签:2048   java   

原文地址:http://blog.csdn.net/hgqqtql/article/details/41905777

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!