📄 modulate.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 + -