import java.awt.*; import java.util.*; import java.io.*; /* * full contact info: * Sieuwert van Otterloo * Rijnlaan 33bis * 3522BB Utrecht * homepage www.bluering.nl or go.to/sieuwert * phone +31615524227 * coauthor Ernst van Rheenen */ /** * reversi.java is an applet for playing the reversi othello board game against the computer. * Designed by * bluering software development . * You can send questions about this source to * sieuwert@bluering.nl * this applet can be freely used for whatever you want if you first ask permission from * the author. *
the javadoc files contain much of the comment, but not all of it. Check the sourcecode * for the last details. The list of all classes is: *
*/ public class reversi extends java.applet.Applet{ /** * the interface components in this applet. slabel means status label. */ Label slabel=new Label("please do a move"); board b=new board(); boardview bview=new boardview(b,this); Button newgame=new Button("new game"), undo=new Button("undo move"); /** * constructor for running this applet as an application */ public reversi(){} /** * the init method is called when the applet is loaded by the browser. */ public void init(){ setBackground(Color.white);//you can set the background color of the applet in this line //resize(bview.SX+30,bview.SY+100); //this line not needed in applets, they cannot resize Panel buttonpanel=new Panel();//panel to keep buttons together buttonpanel.setLayout(new GridLayout(1,3));//add three buttons beside each other buttonpanel.add(newgame); buttonpanel.add(undo); Panel superpanel=new Panel(); superpanel.setLayout(new GridLayout(3,1)); superpanel.add(slabel); superpanel.add(buttonpanel); setLayout(new BorderLayout()); add("North",bview); add("South",superpanel); } /**the start method of the applet. It is called any time the window re-appears on the * screen. All we do here is start the animation. */ public void start() {bview.start();} /** * here we stop the animation */ public void stop() {bview.stop();} /** * the action method is called when a button is pressed. It first checks whether * bview might be busy. In that case, it does nothing. Else it undoes a move or * launches a new game window. * @return true to indicate success */ public boolean action(Event ev, Object O){ if(bview.wait)return true; if(ev.target==newgame) new newgamewindow(this); else if(ev.target==undo) undo(); return true; } /** * this method is called by newgamewindow. */ public void newgame(){ b.clear();//b.clear() restores the opening position on the board. bview.repaint();//this updates the screen } /** * this method undoes a move, if possible. */ public void undo(){ if(b.moves!=0) bview.undomove(); } /** * sets a given text in the message label. * @param s the message to display. */ public void message(String s){ slabel.setText(s);//set a message in the status label. } /** * this method is quick & dirty trick for running this applet as * an application. It is not used when a browser runs this class * as an applet. */ public static void main(String[] ps) {Frame f=new Frame("reversi"); reversi r=new reversi(); f.resize(500,500); f.add("Center",r); r.init(); r.start(); f.show(); } } /** * this is a window for popping up to create a new game. the user * can set what kind of game he wants, and then press cancel or start. */ class newgamewindow extends Frame{ reversi r; Choice[] cm={new Choice(),new Choice()}; Button start=new Button("start"); Button cancel=new Button("cancel"); /** * create a new newgamewindow. It shown immediately. You can use this * dialog only once. * @param ir the applet that wants a new game. */ public newgamewindow(reversi ir){ super("new game"); r=ir; r.bview.wait=true; setLayout(new GridLayout(2,3)); cm[0].add("human"); cm[0].add("computer"); cm[1].add("computer"); cm[1].add("human"); add(cm[0]); add(new Label(" versus ")); add(cm[1]); add(start); add(cancel); resize(250,100); setLocation(100,100); show(); } /** * this method is called any time a button is pressed or an option selected. */ public boolean action(Event ev, Object o){ if(ev.target==start){ r.newgame(); r.bview.setplayers( cm[0].getSelectedIndex()==1, cm[1].getSelectedIndex()==0); r.bview.wait=false; dispose(); } else if(ev.target==cancel){ r.bview.wait=false; dispose(); } return true; } } /** * a boardview is a canvas (a rectangle that can be displayed on the screen and painted on) * that can display a board. It can be used in two ways *
* If you add a certain feature that you think is important for
* winning chances, do it here and change evalvectorlength. The
* genetictrain and weightvectorclasses will automatically adjust if you recompile them.
* you must retrain before you use the applet, beacuse the standard weigth vector in the
* player class will then be too short.
* @param out an optional array you want the result in (reusing memory improves the speed)
* You can make it null if you do not have such array.
* @return returns an evalvector. It will be out if that was not null.
*/
public int[] getevalvector(int[] out){
if(out==null)
out=new int[evalvectorlength];
for(int i=0;i
* The exact description of a round is this: there is a fixed population size
* (the number of weightvectors). They are randomly ordered, and the odd even numbers
* play against the next odd number. The winner is stored in the even position, the odd
* position is empty. Now per group of four a random decision is made: if they mutate,
* the odd positions are filled with mutated copies of the winners. If crossover is chosen,
* the winners are crossed over, producing two children that are random mixtures of the
* parents. Remember that individuals are just lists of numbers. For example:
* parent1:-3 -5 2 6 0
* parent2 -7 0 -4 1 2
* could give:
* child1: -3 0 -4 6 2
* child2: -7 -5 2 1 0
* In the literature this is called uniform crossover. There are other kinds of crossover.
* the last position (which is odd) is filled with the average of all other individuals.
*/
class genetictrain
{
int popsize;
weightvector[] pop;
board b=new board();
boardview bv;
player[] P={new player(b,b.P1),new player(b,b.P2)};
boolean onscreen=true;
/**
* @param p the population size for the genetic algorithm.
*/
public genetictrain(int p){
setpopsize(p);
for(int i=0;i
*
*/
class file{
BufferedReader in;
PrintWriter out;
boolean OK;
/**
* open a file for reading.
*/
public void readopen(String f1)
{readopen(new File(f1));}
/**
* open a file for reading.
*/
public void readopen(File f1){
try{
in=new BufferedReader(new FileReader(f1));
OK=true;
}catch(Exception e)
{e.printStackTrace();OK=false;}
}
/**
* read one line of the input file.
*/
public String read(){
if(!OK)
return null;
try{
return in.readLine().trim();
}catch(Exception e)
{e.printStackTrace();}
return null;
}
/**
* close the file opened for reading.
*/
public void readclose(){
try{
if(in!=null)in.close();
}catch(Exception e)
{e.printStackTrace();}
}
/**
* open a file for writing. Note that it is allowed to have both a file to
* read and a file to write with the same file object.
*/
public void writeopen(String f1)
{writeopen(new File(f1));}
/**
* open a file for writing. Note that it is allowed to have both a file to
* read and a file to write with the same file object.
*/
public void writeopen(File f1){
try{
out=new PrintWriter(new FileOutputStream(f1));
OK=true;
}catch(Exception e)
{e.printStackTrace();OK=false;}
}
/**
* Write out the given string as a separate line.
*/
public void write(String s)
{if(OK)out.println(s);}
/**
* close the writefile
*/
void writeclose()
{if(out!=null)out.close();}
/**
* close both the file opened for reading and the one for writing (if any)
*/
public void close()
{readclose();writeclose();}
/**
* converts a String to an int.
*/
public static int num(String s){
return Integer.parseInt(s.trim());
}
/**
* converts a String to a double.
*/
public static double dnum(String s){
return new Double(s).doubleValue();
}
}