⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modulate.java

📁 用JAVA开发的模拟企业间竞争与合作策略的生命周期游戏
💻 JAVA
字号:
package game;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;


import javax.swing.*;
import javax.swing.event.*;









public class Modulate extends JFrame implements Runnable{

	private int worldSize,refreshTime,displayModern,neighbourModern;
	private double companySize,coopSize,m;
	
	private int width=350,height=350;
	private int d,fringe;
	private int companyCount;
	private int grid[][];
	private Company[] com;
	private int vonNeuman[][]={{-1,0},{1,0},{0,-1},{0,1}};//vonNeuman的邻居类型
	private int Moore[][]={{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}};//Moore的邻居类型
	private int neighbor[][];
	private Color colors[]={ Color.white,Color.red,Color.green,Color.blue,Color.darkGray,Color.cyan,Color.white,Color.pink,Color.orange};//颜色数组
    private Color idColors[];//id的总数很多,把颜色信息储存到这个数组中
    private int coopCount;
    //private int cyclemax=2000;
    //boolean start=true;
    
    JLabel label1,label2;
    JTextField coopText,enemyText;
    
    Thread runner;
    
	public Modulate(Game game){
		//获得游戏参数
		initParmaters(game);
		//初始化数据显示界面
		dataGUI();
		//初始化模拟界面
		initCompant();
		//this.setBackground(Color.black);
		//设置图形界面窗口大小
		this.setSize(400,450);
		//设置窗口可见
		this.setVisible(true);
		//初始化线程
		runner=new Thread(this);
		//启动线程
		runner.start();
		
		
	}
	//获得设置的参数
	private void initParmaters(Game game){
		worldSize=game.getWorldSize();
		companySize=game.getCompanySize();
		coopSize=game.getCoopSize();
		refreshTime=100*game.getRefreshTime();
		displayModern=game.getDisplayModern();
		neighbourModern=game.getNeighbourModern();
		
		m=game.getM();
	}
	//初始化数据显示界面
	private void dataGUI(){

		setLayout(new BorderLayout());
		label1=new JLabel("合作者");
		coopText=new JTextField();
		coopText.setEnabled(false);
		label2=new JLabel("竞争者");
		enemyText=new JTextField();
		enemyText.setEnabled(false);
		
		JPanel p=new JPanel();
		p.setLayout(new GridLayout(1,4));
		p.setBackground(Color.lightGray);
		p.add(label1);
		p.add(coopText);
		p.add(label2);
		p.add(enemyText);
		getContentPane().add(p,BorderLayout.SOUTH);
	}
	//初始化模拟界面
	private void initCompant(){
		//计算和初始化一些游戏运行参数
		initGameParmater();
		/*
		//计算圆的直径
		d=(int)(7*width/(8*worldSize));
		//计算圆之间的间隔
		fringe=(int)(width/(8*worldSize));
		//初始化网格数组
		grid= new int[worldSize][worldSize];
		//计算企业数
		companyCount=(int)(worldSize*worldSize*companySize);
		 //临时数组,记录企业所在网格坐标
		  int x[]=new int[2*companyCount];
		  int y[]=new int[2*companyCount];
		  //x=new int[2*companyCount];
		  //y=new int[2*companyCount];
*/
//		临时数组,记录企业所在网格坐标
		  int x[]=new int[2*companyCount];
		  int y[]=new int[2*companyCount];
		
		//企业总数清0 
		  companyCount=0;

		   //随机选择企业的位置,企业总数开始计数
		    for(int i=0;i<worldSize;i++){
		      for(int j=0;j<worldSize;j++){
		          //获得一个随机数
		    	  double E = Math.random();
		          //若随机数属于有企业的概率
		    	  if(E>1-companySize){
		    		//在该网格分配一个企业id
		            grid[i][j]=companyCount;
		            //记录该网格的横坐标
		            x[companyCount]=i;
		            //记录该网格的纵坐标
		            y[companyCount]=j;
		            //企业总数+1
		            companyCount++;
		        }
		    	//随机数属于没有企业的比例
		    	else{
		          //空格的比例
		          grid[i][j]=0;
		        }
		      }
		    }


		    //初始化一个Color数组
		    idColors=new Color[companyCount];
		    int seg=(int)(256*256*256/companyCount);
		    //为每个id分配一种颜色
		    for(int i=1;i<=companyCount;i++){
		        idColors[i-1]=new Color(i*seg);
		    }

		    //新建Company个体,并付以初值
		    com=new Company[companyCount];
		    for(int i=0;i<companyCount;i++){
		      //初始化企业对象
		      com[i]=new Company();
		      //该企业所在网格的横坐标
		      com[i].x=x[i];
		      //该企业所在网格的纵坐标
		      com[i].y=y[i];
		      //分配企业id
		      com[i].id=i;
		      //设置博弈收益
		      com[i].m=m;
		      double E=Math.random();
		      //随机的选择合作与不合作的策略
		      if(E>coopSize){
		        //不合作
		        com[i].action=2;
		      }else{
		        //合作
		        com[i].action=1;
		      }
		      //总收益清0
		      com[i].all_profile=0;
		      //本次博弈收益清0
		      com[i].profile=0;
		    }

		  

		   
		    

		    //重画整个图面
		    repaint();
		    
		   
		
	}
	
	
	//public void update(Graphics g) {  paint(g);}
	public void paint (Graphics g) {
	    //调用父类的paint方法
		super.paint(g);
		//画图
	   /*if (start) {
		 g.clearRect(0,0,400,400);
	     g.setColor( colors [0]);
	     g.fillRect(0,0,400,400);
	     start = false;
	    }*/
	   

	     //对所有的坐标循环,如果坐标处的id为0就画背景色,否则按照显示模式画颜色
	     for (int X=0;X<worldSize;X++){
	       for (int Y=0;Y<worldSize;Y++) {
	           //若网格被企业占据  
	    	   if(grid[X][Y]!=0){
	                int theColor=0;
	                //若是以id模式显示
	                if(displayModern==1){
	                	//获得该网格中企业的id
	                	theColor=grid[X][Y];
	                	//该id所对应的颜色
	                    g.setColor(idColors[theColor]);
	                    //若以移动方向模式显示
	                }else if(displayModern==2){
	                	//获得该网格中企业的移动方向
	                	 theColor=com[grid[X][Y]].direction;
	                	 //该方向所对应的颜色
	                     g.setColor( colors [theColor+1]);
	                 //若以策略模式显示
	                }else if(displayModern==3){
	                	//获得该网格中企业的策略
	                	theColor=com[grid[X][Y]].action;
	                	//该所对应的颜色
	                    g.setColor( colors [theColor]);
	                }
	                
	             }else{
	               g.setColor(colors[0]);
	             }
	            //画圆
	            g.fillOval(X*(d+fringe)+d/2,Y*(d+fringe)+d/2+30,d,d);
	       }
	     }
	}
	
	public void nextStep() {

		  //记录采用合作策略的企业数
		  coopCount=0;
          //每个企业和周围的邻居进行博弈
		  for(int i=0;i<companyCount;i++){
			//总收益清0
		    com[i].all_profile=0;
		    //若采用合作策略
		    if(com[i].action==1){
		        //计数到cCount中
		    	coopCount++;
		    }
		    //进行博弈,根据邻居数组选择邻居
		    for(int j=0;j<neighbor.length;j++){
		    	//邻居所在网格的横坐标
		        int x=com[i].x+neighbor[j][0];
		        //邻居所在网格的纵坐标
		        int y=com[i].y+neighbor[j][1];

		        //让坐标循环起来
		        if(x<0)x+=worldSize;
		        x=x%worldSize;
		        if(y<0)y+=worldSize;
		        y=y%worldSize;
		        //获得x,y坐标处企业对象的id
		        int id=grid[x][y];
                //如果id不是0,就进行囚徒困境博弈
		        if(id!=0){
		          //获得id对应的企业对象
		          Company com1=com[id];
		          double m=com[i].rule(com1.action);

		          //根据博弈的规则更新当前企业的收益
		          com[i].profile=m;
		          com[i].all_profile+=m;
		        }
		    }
		  }

		  
		  //记录最大收益
		  double maxResource;		  		  
		  //遍历所有企业,寻找收益最大的企业的策略
		  for(int i=0;i<companyCount;i++){
			//获得当前企业的总收益
		    maxResource=com[i].all_profile;
		    //获得当前企业的策略
		    int new_state=com[i].action;
		    //遍历所有邻居
		    for(int j=0;j<neighbor.length;j++){
		        //邻居所在网格的横坐标
		        int x=com[i].x+neighbor[j][0];
		        //邻居所在网格的纵坐标
		        int y=com[i].y+neighbor[j][1];

		        //让坐标循环起来
		        if(x<0)x+=worldSize;
		        x=x%worldSize;
		        if(y<0)y+=worldSize;
		        y=y%worldSize;
		        int id=grid[x][y];
		        //如果id不是0
		        if(id!=0){
		          //获得id对应的企业对象
		          Company com1=com[id];

		          //寻找收益最大的企业的策略
		          if(com1.all_profile>maxResource){
		              new_state=com1.action;
		              maxResource=com1.all_profile;
		          }
		        }
		    }
		    //更新策略
		    com[i].action=new_state;
		    
		    
		    //随机选择移动的方向
		    com[i].direction=(int)(neighbor.length*Math.random());

		    //确定下一个时刻将要去的网格
		    com[i].nextX=com[i].x+neighbor[com[i].direction][0];
		    com[i].nextY=com[i].y+neighbor[com[i].direction][1];

		    //保证下一步的坐标循环起来
		    if(com[i].nextX<0)com[i].nextX+=worldSize;
		    com[i].nextX=com[i].nextX%worldSize;
		    if(com[i].nextY<0)com[i].nextY+=worldSize;
		    com[i].nextY=com[i].nextY%worldSize;
		  }


		  //遍历所有企业
		  for(int i=0;i<companyCount;i++){
			//获得当前企业目标网格的横坐标
		    int x=com[i].nextX;
		    //获得当前企业目标网格的纵坐标
		    int y=com[i].nextY;

		    //坐标循环起来
		    if(x<0)x+=worldSize;
		    x=x%worldSize;
		    if(y<0)y+=worldSize;
		    y=y%worldSize;

		    //获得目标网格的企业id
		    int id=grid[x][y];
		    //若网格没有被企业占据,即id=0
		    if(id==0){
		           //记录以该网格为目标的企业数
		           int objs=0;
		           //遍历该网格周围的邻居网格
		           for(int k=0;k<neighbor.length;k++){
		              //获得那个网格邻居的状态
		              int x1=x+neighbor[k][0];
		              int y1=y+neighbor[k][1];
		              //循环坐标
		              if(x1<0)x1+=worldSize;
		              x1=x1%worldSize;
		              if(y1<0)y1+=worldSize;
		              y1=y1%worldSize;
		              //获得邻居网格得企业id
		              int id1=grid[x1][y1];
		              //若id不为0,即被企业占据
		              if(id1!=0){
		                //如果邻居网格中的企业朝向的网格是当前这个格子,则开始冲突数计数
		                int x2=com[id1].nextX;
		                int y2=com[id1].nextY;
		                if(x2==x&&y2==y){
		                  objs++;
		                }
		              }
		            }
		        //如果冲突数计数<2,意味着只有当前企业朝向这个格子,则它可以占领,如果还有其他企业朝向,则不动
		        if(objs<2){
		            //当前企业移动到它朝向的网格
		            grid[com[i].x][com[i].y]=0;
		            com[i].x=x;
		            com[i].y=y;
		            grid[x][y]=com[i].id;
		        }
		    }
		  }
	}
	
	private void displayParmater(){
		System.out.println("w:"+worldSize);
		System.out.println("com:"+companySize);
		System.out.println("c:"+coopSize);
		System.out.println("t:"+refreshTime);
		System.out.println("m:"+m);	
		System.out.println("n:"+neighbourModern);
		System.out.println("d:"+displayModern);
	}
	
	private void setCompany(){
		
	}
	
	private void initGameParmater(){
//		计算圆的直径
		d=(int)(7*width/(8*worldSize));
		//计算圆之间的间隔
		fringe=(int)(width/(8*worldSize));
		//初始化网格数组
		grid= new int[worldSize][worldSize];
		//计算企业数
		companyCount=(int)(worldSize*worldSize*companySize);
		
		  //根据设置的邻居类型给邻居数组赋值
		    switch(neighbourModern){
		    //选择冯.扭曼型
		    case(1):
		      neighbor=new int[vonNeuman.length][2];
		      for(int i=0;i<2;i++){
		        for(int j=0;j<vonNeuman.length;j++){
		          neighbor[j][i]=vonNeuman[j][i];
		        }
		      }
		      break;
		     //选择摩尔型
		    case(2):
		      neighbor=new int[Moore.length][2];
		      for(int i=0;i<2;i++){
		        for(int j=0;j<Moore.length;j++){
		          neighbor[j][i]=Moore[j][i];
		        }
		      }
		      
		    
		      }
		 
	}
	
	public static void main(String args[]){
		
	}

	public void run() {
		
		
		 //不断的循环
		 while(true){
			 //运行游戏逻辑
			 nextStep();
			 //显示合作者总数
			 coopText.setText(""+coopCount);
			 int z=companyCount-coopCount;
			 //显示竞争者总数
			 enemyText.setText(""+z);
			 //更新游戏模拟界面
			 repaint();
			 //System.out.println("next");  
			 //暂停线程一段时间
			 try{Thread.sleep(refreshTime);}catch(InterruptedException e){};
		 }
	     
		  
	}

	

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -