/*
* Ecology.java
*
* $Id: jprison.el,v 1.1 1999/03/03 15:12:17 beaufils Exp $
*
JPRISON_COPYRIGHT
*/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;
import fr.lifl.prison.*;
import fr.lifl.prison.util.*;
import fr.lifl.prison.strategies.*;
/**
* This applet may take two parameters for localization :
*
*
* At that time the default language is english, and the following ones are
* set up in MatchMessages Properties files :
*
*/
public class Ecology extends Applet {
// Declaration of basic attributes
int stage;
boolean may_have_changed;
Matrix populations;
Matrix payoff;
PlayerList players;
Tournament t;
Evolutions e;
BasicStrategies s;
int strategies_indexes[];
// Declaration of the differents graphics components
BorderLayout mainLayout;
Panel mainPanel;
Label title;
FlowLayout buttonLayout;
Panel buttonPanel;
Button button_prev;
Button button_next;
CardLayout choiceLayout;
Panel choicePanel;
BorderLayout card0Layout;
Panel card0Panel;
Label title0;
List list_of_strategies;
BorderLayout card1Layout;
Panel card1Panel;
FlowLayout card1bLayout;
Panel card1bPanel;
Label title1;
Label text1;
TextField length_of_match;
Label text2;
BorderLayout card2Layout;
Panel card2Panel;
Label title2;
GridLayout card2bLayout;
Panel card2bPanel;
CheckboxGroup cbg;
Checkbox prisonerCheckbox;
Checkbox leaderCheckbox;
Checkbox liftCheckbox;
BorderLayout card3Layout;
Panel card3Panel;
Label title3;
ScrollPane card3ScrollPane;
BorderLayout card4Layout;
Panel card4Panel;
Label title4;
ScrollPane card4ScrollPane;
FlowLayout card5Layout;
Panel card5Panel;
Label title5;
// Declaration of localised needed object
ResourceBundle messages;
// Initialisation of the applet
public void init() {
setBackground(Color.white);
may_have_changed = false;
// Set the locale string
set_locale();
// Create all the needed components
create_components();
// Create the basic strategies
s = new BasicStrategies(getLocale());
// Add all the strategies in the two choices
for (Enumeration e = s.players(); e.hasMoreElements();) {
list_of_strategies.addItem(e.nextElement().toString());
}
// add the mainPanel to the applet
add(mainPanel);
set_stage(0);
}
// Set the locale informations
private void set_locale() {
String language;
String country;
// Changed the locale only if asked
if (getParameter("language") != null
&& getParameter("country") != null) {
setLocale(new Locale(getParameter("language"),
getParameter("country")));
}
// Creating the ressources
messages = ResourceBundle.getBundle("EcologyMessages", getLocale());
}
// Creation of the differents components
private void create_components() {
// -- Main Panel
mainLayout = new BorderLayout();
mainPanel = new Panel();
mainPanel.setLayout(mainLayout);
// -- -- Title
title = new Label(messages.getString("title"));
title.setAlignment(Label.CENTER);
mainPanel.add(title, "North");
// -- -- Buttons Panel
buttonLayout = new FlowLayout();
buttonLayout.setAlignment(FlowLayout.RIGHT);
buttonPanel = new Panel();
buttonPanel.setLayout(buttonLayout);
// -- -- -- Button Prev
button_prev = new Button(messages.getString("prev"));
button_prev.setBackground(Color.orange);
button_prev.addActionListener(new Ecology.ButtonPrev());
buttonPanel.add(button_prev);
// -- -- -- Button Next
button_next = new Button(messages.getString("next"));
button_next.setBackground(Color.orange);
button_next.addActionListener(new Ecology.ButtonNext());
buttonPanel.add(button_next);
mainPanel.add(buttonPanel, "South");
// -- -- Choice panel with cards
choiceLayout = new CardLayout();
choicePanel = new Panel();
choicePanel.setLayout(choiceLayout);
// -- -- -- Card for stage 0 :
card0Layout = new BorderLayout();
card0Panel = new Panel();
card0Panel.setLayout(card0Layout);
// -- -- -- -- Title of card 0
title0 = new Label(messages.getString("title0"));
title0.setAlignment(Label.CENTER);
card0Panel.add(title0, "South");
// -- -- -- -- List of strategies
list_of_strategies = new List(15, true);
card0Panel.add(list_of_strategies, "Center");
choicePanel.add("stage0", card0Panel);
// -- -- -- Card for stage 1
card1Layout = new BorderLayout();
card1Panel = new Panel();
card1Panel.setLayout(card1Layout);
// -- -- -- -- Title of card 1
title1 = new Label(messages.getString("title1"));
title1.setAlignment(Label.CENTER);
card1Panel.add(title1, "South");
// -- -- -- -- Length of matches
card1bLayout = new FlowLayout();
card1bLayout.setAlignment(FlowLayout.CENTER);
card1bPanel = new Panel();
card1bPanel.setLayout(card1bLayout);
text1 = new Label(messages.getString("length"));
text1.setAlignment(Label.RIGHT);
card1bPanel.add(text1);
length_of_match = new TextField("100", 4);
card1bPanel.add(length_of_match);
text2 = new Label(messages.getString("moves"));
text2.setAlignment(Label.LEFT);
card1bPanel.add(text2);
card1Panel.add(card1bPanel, "Center");
choicePanel.add("stage1", card1Panel);
// -- -- -- Card for stage 2
card2Layout = new BorderLayout();
card2Panel = new Panel();
card2Panel.setLayout(card2Layout);
// -- -- -- -- Title of card 2
title2 = new Label(messages.getString("title2"));
title2.setAlignment(Label.CENTER);
card2Panel.add(title2, "South");
// -- -- -- -- Panel for choosing the payoff
card2bLayout = new GridLayout(4,1);
card2bPanel = new Panel();
card2bPanel.setLayout(card2bLayout);
// -- -- -- -- -- Payoff Matrix
payoff = new Matrix(2,2);
payoff.setElementAt(0,0, new Integer(3));
payoff.setElementAt(1,0, new Integer(5));
payoff.setElementAt(0,1, new Integer(0));
payoff.setElementAt(1,1, new Integer(1));
payoff.setEditable(true);
payoff.setRowHeaderAt(0, messages.getString("cooperation"));
payoff.setRowHeaderAt(1, messages.getString("defection"));
payoff.setColumnHeaderAt(0, messages.getString("cooperation"));
payoff.setColumnHeaderAt(1, messages.getString("defection"));
card2bPanel.add(payoff.getPanel(true, true));
// -- -- -- -- -- Predefined payoff matrix
cbg = new CheckboxGroup();
prisonerCheckbox = new Checkbox(messages.getString("cbprisoner"),
cbg,
true);
prisonerCheckbox.addItemListener(new Ecology.Checkboxes());
card2bPanel.add(prisonerCheckbox);
leaderCheckbox = new Checkbox(messages.getString("cbleader"),
cbg,
false);
leaderCheckbox.addItemListener(new Ecology.Checkboxes());
card2bPanel.add(leaderCheckbox);
liftCheckbox = new Checkbox(messages.getString("cblift"),
cbg,
false);
liftCheckbox.addItemListener(new Ecology.Checkboxes());
card2bPanel.add(liftCheckbox);
card2Panel.add(card2bPanel, "Center");
choicePanel.add("stage2", card2Panel);
// -- -- -- Card for stage 3
card3Layout = new BorderLayout();
card3Panel = new Panel();
card3Panel.setLayout(card3Layout);
// -- -- -- -- Title of card 3
title3 = new Label(messages.getString("title3"));
title3.setAlignment(Label.CENTER);
card3Panel.add(title3, "South");
// -- -- -- -- Place for the scores matrix
card3ScrollPane = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
card3Panel.add(card3ScrollPane, "Center");
choicePanel.add("stage3", card3Panel);
// -- -- -- Card for stage 4
card4Layout = new BorderLayout();
card4Panel = new Panel();
card4Panel.setLayout(card4Layout);
// -- -- -- -- Title of card 4
title4 = new Label(messages.getString("title4"));
title4.setAlignment(Label.CENTER);
card4Panel.add(title4, "South");
// -- -- -- -- Place for the population matrix
card4ScrollPane = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
card4Panel.add(card4ScrollPane, "Center");
choicePanel.add("stage4", card4Panel);
// -- -- -- Card for stage 5
card5Layout = new FlowLayout();
card5Layout.setAlignment(FlowLayout.CENTER);
card5Panel = new Panel();
card5Panel.setLayout(card5Layout);
// -- -- -- -- Title of card 5
title5 = new Label("");
title5.setAlignment(Label.CENTER);
card5Panel.add(title5, "South");
choicePanel.add("stage5", card5Panel);
mainPanel.add(choicePanel, "Center");
}
// Get the length of the match with some constraints
private int getLength() {
// Get the value in the text field
int n = Integer.valueOf(length_of_match.getText()).intValue();
// If not in the range 1..100 set it to 1000
if (n < 1 || n > 1000) {
length_of_match.setText("1000");
return 1000;
} else {
return n;
}
}
// Get the Payoff parameters
private Parameters getParameters() {
return new Parameters(getLength(),
Util.o2i(payoff.elementAt(1,0)),
Util.o2i(payoff.elementAt(0,0)),
Util.o2i(payoff.elementAt(1,1)),
Util.o2i(payoff.elementAt(0,1)),
0);
}
// The method setting the stage
private void set_stage(int st) {
int old_stage = stage;
stage = st;
strategies_indexes = list_of_strategies.getSelectedIndexes();
// Update players if needed
if (may_have_changed) {
players = new PlayerList();
for (int i = 0; i < strategies_indexes.length; i += 1) {
players.addPlayer(s.playerAt(strategies_indexes[i]));
}
}
// Make the stage
switch (stage) {
case 0:
// STAGE 0 : Strategies list --------------------------------
button_prev.setEnabled(false);
button_next.setEnabled(true);
choiceLayout.show(choicePanel, "stage0");
may_have_changed = true;
break;
case 1:
// STAGE 1 : Game length ------------------------------------
button_prev.setEnabled(true);
button_next.setEnabled(true);
choiceLayout.show(choicePanel, "stage1");
break;
case 2:
// STAGE 2 : Payoff -----------------------------------------
button_prev.setEnabled(true);
if (strategies_indexes.length == 0) {
button_next.setEnabled(false);
} else {
button_next.setEnabled(true);
}
choiceLayout.show(choicePanel, "stage2");
break;
case 3:
// STAGE 3 : Tournament results -----------------------------
button_prev.setEnabled(true);
button_next.setEnabled(true);
choiceLayout.show(choicePanel, "stage3");
if (old_stage == 2) {
// warn computing is on
card3Panel.removeAll();
title3.setText(messages.getString("wait"));
card3Panel.add(title3, "South");
validate();
// create and compute the tournament
t = new Tournament(players, getParameters());
int winner = players.indexOf(t.compute());
// show results
card3Panel.removeAll();
title3.setText(messages.getString("title3"));
card3Panel.add(title3, "South");
Matrix m = t.getPayoff();
Matrix r = new Matrix(players.size(), 1);
r.setColumnAt(0, t.getFinalScores());
r.setColumnHeaderAt(0, messages.getString("score"));
m.setRowBackground(winner, Color.orange);
r.setRowBackground(winner, Color.orange);
Panel p = new Panel();
p.add(m.getPanel(true, true));
p.add(r.getPanel(false, true));
card3ScrollPane.removeAll();
card3ScrollPane.add(p);
card3Panel.add(card3ScrollPane, "Center");
}
break;
case 4:
// STAGE 4 : Population setting -----------------------------
button_prev.setEnabled(true);
button_next.setEnabled(true);
choiceLayout.show(choicePanel, "stage4");
if (may_have_changed) {
// Create a basic population matrix with 100 individual for
// each strategies
populations = new Matrix(players.size(),1);
populations.setColumnHeaderAt(0, messages.getString("size"));
populations.setEditable(true);
String names[] = list_of_strategies.getSelectedItems();
for (int i = 0; i < strategies_indexes.length; i += 1) {
populations.setElementAt(i, 0, new Integer(100));
populations.setRowHeaderAt(i, names[i]);
}
Panel p = new Panel();
p.add(populations.getPanel(true, true));
card4ScrollPane.removeAll();
card4ScrollPane.add(p);
}
break;
case 5:
// STAGE 5 : Evolution results ------------------------------
may_have_changed = false;
button_prev.setEnabled(true);
button_next.setEnabled(false);
choiceLayout.show(choicePanel, "stage5");
// warn computing is on
card5Panel.removeAll();
title5.setText(messages.getString("wait"));
card5Panel.add(title5);
validate();
// Create and compute the evolution
e = new Evolutions(t, 1000, 100);
for (int i = 0; i < strategies_indexes.length; i += 1) {
e.setInitialPopulation(players.playerAt(i),
Util.o2i(populations.elementAt(i,0)));
}
e.compute();
// Shows the results
LineGraph2D g = new LineGraph2D(e.getSortedEvolutions());
g.setSize(400,280);
g.with_grid = false;
g.x_step = 5;
g.x_label = new String("generations");
g.y_label = new String("population");
card5Panel.removeAll();
card5Panel.add(g);
card5Panel.add(g.getVLegendPanel());
break;
}
// Validate all changes
validate();
}
// The prev button listener
public class ButtonPrev implements ActionListener {
// Method called when the button is pressed
public void actionPerformed(ActionEvent e) {
if (stage > 0) {
set_stage(stage - 1);
}
}
}
// The next button listener
public class ButtonNext implements ActionListener {
// Method called when the button is pressed
public void actionPerformed(ActionEvent e) {
if (stage < 5) {
set_stage(stage + 1);
}
}
}
// The next button listener
public class Checkboxes implements ItemListener {
// Method called when the Checkbox's state changed
public void itemStateChanged(ItemEvent e) {
if (prisonerCheckbox.getState() == true) {
payoff.setElementAt(0,0,Util.i2o(3));
payoff.setElementAt(0,1,Util.i2o(0));
payoff.setElementAt(1,0,Util.i2o(5));
payoff.setElementAt(1,1,Util.i2o(1));
} else if (leaderCheckbox.getState() == true) {
payoff.setElementAt(0,0,Util.i2o(1));
payoff.setElementAt(0,1,Util.i2o(3));
payoff.setElementAt(1,0,Util.i2o(5));
payoff.setElementAt(1,1,Util.i2o(0));
} else if (liftCheckbox.getState() == true) {
payoff.setElementAt(0,0,Util.i2o(3));
payoff.setElementAt(0,1,Util.i2o(0));
payoff.setElementAt(1,0,Util.i2o(8));
payoff.setElementAt(1,1,Util.i2o(1));
}
validate();
}
}
}
/* End of Ecology.java. */