}
}
}
else {
clear();
boards.add(f);
}
}
return true;
}
static void calcMoves(){
moves.clear();
if(debug){
for(int i=0;i<diffTable.size();i++){
System.out.print(i + ":" + ((rdgtFendiff)diffTable.get(i)).toString() + " ");
}
System.out.print("\n");
}
int offset=0;
int length=diffTable.size();
while(offset<length){
int start=offset;
int end=-1;
boolean turn = isWhite( ((rdgtFendiff)diffTable.get(offset)).getPiece() );
int i=start;
while(end==-1){
rdgtFendiff test = (rdgtFendiff)diffTable.get(i);
if(turn != isWhite(test.getPiece()) && test.isAdded()){
end=i-1;
}
else{
i++;
if(i>=length)
end=length-1;
}
if(turn==isWhite(test.getPiece()) && test.isAdded()){
offset=i;
}
}
if(offset==start) offset++;
if(debug) System.out.print(start + "-"+end+" ");
movelist chunkMoves = new movelist(true,true);
for(int s=start;s<end;s++){
rdgtFendiff a = (rdgtFendiff)diffTable.get(s);
for(int e=s+1;e<=end;e++){
rdgtFendiff b = (rdgtFendiff)diffTable.get(e);
if(a.getPiece() == b.getPiece() && a.getSquare() != b.getSquare()){
if(!a.isAdded() && b.isAdded()){
String special="";
if(b.getPiece()=='P' && b.getSquare()/8==0){
for(int j=e+1;j<=end;j++){
rdgtFendiff prom = (rdgtFendiff)diffTable.get(j);
if(prom.isAdded() && prom.isWhite()){
if(a.getSquare()%8 != b.getSquare()%8)
special+=pos2xy(a.getSquare()).substring(0,1)+"x";
special+=pos2xy(b.getSquare())+"="+prom.getPiece();
b=prom;
}
}
}
if(b.getPiece()=='p' && b.getSquare()/8==7){
for(int j=e+1;j<=end;j++){
rdgtFendiff prom = (rdgtFendiff)diffTable.get(j);
if(prom.isAdded() && prom.isWhite()){
if(a.getSquare()%8 != b.getSquare()%8)
special+=pos2xy(a.getSquare()).substring(0,1)+"x";
special+=pos2xy(b.getSquare())+"="+prom.getPiece();
b=prom;
}
}
}
chunkMoves.add(new move(a,b,special));
}
}
}
}
if(chunkMoves.size()==0){
rdgtFendiff a = (rdgtFendiff)diffTable.get(start);
for(int s=start;s<=end;s++){
rdgtFendiff b = (rdgtFendiff)diffTable.get(s);
if(b.isAdded()){
if(a.getPiece()=='P' && a.getSquare()/8==1 && !a.isAdded()){
String special="";
if(a.getSquare()%8 != b.getSquare()%8)
special+=pos2xy(a.getSquare()).substring(0,1)+"x";
special+=pos2xy(b.getSquare())+"="+b.getPiece();
chunkMoves.add(new move(a,b,special));
}
else if(a.getPiece()=='p' && a.getSquare()/8==6 && !a.isAdded()){
String special="";
if(a.getSquare()%8 != b.getSquare()%8)
special+=pos2xy(a.getSquare()).substring(0,1)+"x";
special+=pos2xy(b.getSquare())+"="+b.getPiece();
chunkMoves.add(new move(a,b,special));
}
else
chunkMoves.add(new move(a,b,""+a.getPiece()+"@"+pos2xy(a.getSquare())));
}
}
}
for(int j=0;j<chunkMoves.size();j++){
if(debug) System.out.print( (chunkMoves.get(j)).toString() + " ");
moves.add(chunkMoves.get(j));
}
if(debug) System.out.print("\n");
}
}
static String pos2xy(int pos){
String s = "" + (char)((pos)%8+'a') + "" + (8-pos/8);
return s;
}
static boolean isWhite(char piece){
if(piece>'A' && piece < 'Z')
return true;
else
return false;
}
static movelist moves;
static ArrayList boards;
static ArrayList diffTable;
static String result;
static int plyCount;
}
class move {
rdgtFendiff from;
rdgtFendiff to;
boolean take;
String special;
public move(rdgtFendiff from, rdgtFendiff to){
this.from=from;
this.to=to;
take=false;
special="";
}
public move(rdgtFendiff from, rdgtFendiff to, String special){
this.from=from;
this.to=to;
take=false;
this.special=special;
}
public rdgtFendiff getFrom(){ return from; }
public rdgtFendiff getTo(){ return to; }
public char getPiece(){ return from.getPiece(); }
public int getFromSquare() { return from.getSquare(); }
public int getToSquare() { return to.getSquare(); }
public String getFromCor() { return pos2xy(getFromSquare()); }
public String getToCor() { return pos2xy(getToSquare()); }
public boolean isWhite() { return from.isWhite(); }
public String longNotation() { return moveString(false); }
public String shortNotation() { return moveString(true); }
public void setTake(boolean take){ this.take=take; }
public boolean getTake() { return take; }
String moveString(boolean shortNotation){
if(!special.equals("")) {
if(isCheck(isWhite()))
return special + "+";
else
return special;
}
boolean ep=false;
char takeBit='-';
if(take) takeBit='x';
String s="";
if(getPiece()!='p' && getPiece()!='P')
s+=new String(""+getPiece()).toUpperCase();
if(!shortNotation)
s+=getFromCor()+takeBit;
else {
if(getPiece()=='R' || getPiece()=='r')
if(findRookLength(getToSquare()%8,getToSquare()/8,getPiece()))
s+=getFromCor()+takeBit;
if(getPiece()=='N' || getPiece()=='n')
if(findNightLength(getToSquare()%8,getToSquare()/8,getPiece()))
s+=getFromCor()+takeBit;
if(getPiece()=='B' || getPiece()=='b')
if(findBishopLength(getToSquare()%8,getToSquare()/8,getPiece()))
s+=getFromCor()+takeBit;
if(getPiece()=='Q' || getPiece()=='q')
if(findQueenLength(getToSquare()%8,getToSquare()/8,getPiece()))
s+=getFromCor()+takeBit;
if(getPiece()=='P' || getPiece()=='p')
if( !getFromCor().substring(0,1).equals( getToCor().substring(0,1) ) ) {
s+=getFromCor().substring(0,1)+"x";
if(!take) ep=true;
}
if(take && s.length()>=1){
if(s.charAt(s.length()-1) != 'x')
s+="x";
}
}
s+=getToCor();
if(ep)
s+=" ep.";
/** Is it a check? **/
if(isCheck(isWhite())) s+='+';
return s;
}
boolean isCheck(boolean white){
int k=-1;
int K=-1;
for(int i=0;i<64;i++){
if(to.getAfter().getPieceAt(i%8,i/8) == 'k') k=i;
if(to.getAfter().getPieceAt(i%8,i/8) == 'K') K=i;
}
boolean check=false;
if(white){
if(findQueenLength(k%8,k/8,'Q')) check=true;
if(findRookLength(k%8,k/8,'R')) check=true;
if(findBishopLength(k%8,k/8,'B')) check=true;
if(findNightLength(k%8,k/8,'N')) check=true;
if(findPawnLength(k%8,k/8,'P')) check=true;
}
else{
if(findQueenLength(K%8,K/8,'q')) check=true;
if(findRookLength(K%8,K/8,'r')) check=true;
if(findBishopLength(K%8,K/8,'b')) check=true;
if(findNightLength(K%8,K/8,'n')) check=true;
if(findPawnLength(K%8,K/8,'p')) check=true;
}
return check;
}
/** Is there a night on a night-distance from square? **/
boolean findNightLength(int x, int y,char n){
rdgtFenboard b = to.getAfter();
if(b.getPieceAt(x-1,y-2) == n) return true;
if(b.getPieceAt(x+1,y-2) == n) return true;
if(b.getPieceAt(x-2,y-1) == n) return true;
if(b.getPieceAt(x+2,y-1) == n) return true;
if(b.getPieceAt(x-2,y+1) == n) return true;
if(b.getPieceAt(x+2,y+1) == n) return true;
if(b.getPieceAt(x-1,y+2) == n) return true;
if(b.getPieceAt(x+1,y+2) == n) return true;
return false;
}
boolean findRookLength(int x, int y, char r){
rdgtFenboard b = to.getAfter();
int xx=0;
int yy=0;
do{
xx++;
if(b.getPieceAt(x+xx,y+yy) == r) return true;
}while(b.getPieceAt(x+xx,y+yy) == '.');
xx=0;
do{
xx--;
if(b.getPieceAt(x+xx,y+yy) == r) return true;
}while(b.getPieceAt(x+xx,y+yy) == '.');
xx=0;
do{
yy--;
if(b.getPieceAt(x+xx,y+yy) == r) return true;
}while(b.getPieceAt(x+xx,y+yy) == '.');
yy=0;
do{
yy++;
if(b.getPieceAt(x+xx,y+yy) == r) return true;
}while(b.getPieceAt(x+xx,y+yy) == '.');
return false;
}
boolean findBishopLength(int x, int y, char r){
rdgtFenboard b = to.getAfter();
int xx=0;
int yy=0;
do{
xx++;
yy++;
if(b.getPieceAt(x+xx,y+yy) == r) return true;
}while(b.getPieceAt(x+xx,y+yy) == '.');
xx=0;
yy=0;
do{
xx--;
yy--;
if(b.getPieceAt(x+xx,y+yy) == r) return true;
}while(b.getPieceAt(x+xx,y+yy) == '.');
xx=0;
yy=0;
do{
yy--;
xx++;
if(b.getPieceAt(x+xx,y+yy) == r) return true;
}while(b.getPieceAt(x+xx,y+yy) == '.');
yy=0;
xx=0;
do{
yy++;
xx--;
if(b.getPieceAt(x+xx,y+yy) == r) return true;
}while(b.getPieceAt(x+xx,y+yy) == '.');
return false;
}
boolean findQueenLength(int x, int y, char q){
if(findRookLength(x,y,q)) return true;
if(findBishopLength(x,y,q)) return true;
return false;
}
boolean findPawnLength(int x, int y, char p){
rdgtFenboard b = to.getAfter();
if(p=='P'){
if(b.getPieceAt(x-1,y-1)==p) return true;
if(b.getPieceAt(x+1,y-1)==p) return true;
}
else {
if(b.getPieceAt(x-1,y-1)==p) return true;
if(b.getPieceAt(x+1,y-1)==p) return true;
}
return false;
}
public String toString(){
return ""+from.toString() + "-" + to.toString();
}
public boolean equals(move other){
if(!from.equals( other.getFrom() )) return false;
if(!to.equals( other.getTo() )) return false;
return true;
}
String pos2xy(int pos){
String s = "" + (char)((pos)%8+'a') + "" + (8-pos/8);
return s;
}
}
class movelist {
ArrayList moves;
boolean unique;
boolean noSmooth;
public void clear(){moves.clear(); }
public void remove(int n) { moves.remove(n); }
public movelist(){ moves=new ArrayList(); unique=false; }
public movelist(boolean unique, boolean noSmooth) {
moves=new ArrayList();
this.unique=unique;
this.noSmooth=noSmooth;
}
public move get(int n){ return (move)moves.get(n); }
public int size() { return moves.size(); }
public String toString() { return getAll(false,false); }
public void print(boolean shortNotation) {
System.out.println("Moves");
System.out.print(getAll(shortNotation,true));
}
void fixTakes(){
for(int i=1;i<moves.size();i++){
int toSquare = ((move)moves.get(i)).getToSquare();
char p = (char) ((move)moves.get(i-1)).getTo().getAfter().getBoard()[toSquare];
if(p!='.'){
move m=(move)moves.get(i);
m.setTake(true);
moves.set(i,m);
}
}
}
public String getAll(boolean shortNotation,boolean nice){
fixTakes();
String output="";
boolean lastColor=false;
int n=1;
for(int i=0;i<moves.size();i++){
move m=(move)moves.get(i);
if(m.isWhite() && lastColor==false){
if(nice)
output += n+".\t";
else
output += n+". ";
n++;
}
if(n==1 && !m.isWhite()) {
if(nice)
output += "1.\t...\t\t";
else
output += "1. ... ";
}
lastColor=m.isWhite();
int length=output.length();
if(shortNotation)
output += m.shortNotation()+" ";
else
output += m.longNotation()+" ";
if(nice){
if(!m.isWhite())
output += "\n";
else{
if(output.length()-length < 8) output += "\t";
if(output.length()-length < 12) output += "\t";
}
}
}
return output;
}
public void add(move aMove){
if(!unique){
moves.add(aMove);
return;
}
for(int i=0;i<moves.size();i++){
if( ((move)moves.get(i)).equals(aMove))
return;
}
if(moves.size()>=1){
move m=(move)moves.get(moves.size()-1);
// O-O
if(m.moveString(false).equals("Ke1-g1") && aMove.moveString(false).equals("Rh1-f1")){
moves.remove(moves.size()-1);
moves.add(new move(aMove.getFrom(),aMove.getTo(),"O-O"));
return;
}
// O-O-O
if(m.moveString(false).equals("Ke1-c1") && aMove.moveString(false).equals("Ra1-d1")){
moves.remove(moves.size()-1);
moves.add(new move(aMove.getFrom(),aMove.getTo(),"O-O-O"));
return;
}
// O-O
if(m.moveString(false).equals("Ke8-g8") && aMove.moveString(false).equals("Rh8-f8")){
moves.remove(moves.size()-1);
moves.add(new move(aMove.getFrom(),aMove.getTo(),"O-O"));
return;
}
// O-O-O
if(m.moveString(false).equals("Ke8-c8") && aMove.moveString(false).equals("Ra8-d8")){
moves.remove(moves.size()-1);
moves.add(new move(aMove.getFrom(),aMove.getTo(),"O-O-O"));
return;
}
}
moves.add(aMove);
}
public void removeSmooth(){
for(int a=0;a<moves.size();a++){
move aMove=(move)moves.get(a);
for(int i=0;i<moves.size();i++){
move test = (move)moves.get(i);
if( test.getPiece() == aMove.getPiece()){
if( aMove.getFrom().getSquare() == test.getTo().getSquare() ||
aMove.getTo().getSquare() == test.getFrom().getSquare() ){
if(a==i){
moves.remove(i);
i=moves.size();
a=0;
}
else if(i>a){
moves.remove(i);
moves.remove(a);
i=moves.size();
a=0;
}
else {
moves.remove(a);
moves.remove(i);
i=moves.size();
a=0;
}
}
}
}
}
}
}
rdgtHistory.java
---
class rdgtHistory {
Vector history = new Vector();
rdgtSnapshot lastadded = null;
rdgtSnapshot last = null;
rdgtChessboard board;
public rdgtHistory(rdgtChessboard _board) {
board = _board;
}
void append(rdgtSnapshot x) {
if(history.size()==0){
history.addElement(x.copy());
board.update_html();
}
else if(x.sameas((rdgtSnapshot)history.lastElement())==false ){
history.addElement(x.copy());
board.update_html();
}
}
void debugprint() {
System.out.println("======= History for board: "+board.address.toString());
for (Enumeration e = history.elements(); e.hasMoreElements() ;) {
((rdgtSnapshot)(e.nextElement())).debugprint();
}
}
}
rdgtHtml.java
---
class rdgtHtml extends rdgtProtocol {
static String extension = ".html";
static String indexfilename = "board_index";
static String historyprefix = "boardhistory_";
static String snapshotprefix = "boardsnapshot_";
static void print_index(rdgtDatabase db) {
StringBuffer s = new StringBuffer(2000);
s.append("<html>\n<head>\n <meta http-equiv=refresh content=3>\n</head>\n");
s.append("<body><h1>Chessboards</h1>\n<table border=1 cellspacing=0 cellpadding=10>\n");
s.append("<tr><th>Board id<th>Status<th>Time of last move<th>Snapshot<th>History\n");
for (Enumeration e = db.get_boards() ; e.hasMoreElements() ;) {
rdgtChessboard b = (rdgtChessboard)(e.nextElement());
s.append("<tr>\n<td valign=top>");
s.append(Integer.toString(b.get_address()));
s.append("\n<td>");
if (b.get_alive()==true) s.append("Online"); else s.append("Offline");
s.append("<td>");
s.append(b.get_snapshot().get_time().toString());