Обеспечение всемирной трансляции спортивных шахматных соревнований с применением разработанного в ходе проекта законченного программного продукта

Характеристика структурного подразделения "Шахматный клуб". Выбор основных методологий, инструментальных средств и расчет затрат на разработку специализированного шахматного программного обеспечения ИС "ШК". Оценка экономической эффективности проекта.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 29.06.2010
Размер файла 5,6 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

}

String[] outputBoard(int[] board){

String s="";

String[] out = new String[8];

for(int chr=0;chr<64;chr++){

if(board[chr]<0)

s += "-" + (char)(Math.abs(board[chr]));

else if(board[chr]==0)

s += ", ";

else

s += (char)board[chr] + " ";

if((chr+1)%8==0){

out[chr/8]=s;

s="";

}

}

return out;

}

void printBoard(int[] board){

String[] out = outputBoard(board);

for(int i=0;i<8;i++){

System.out.println(out[i]);

}

System.out.println();

}

int[] mask(int[] b1, int[] b2){

int[] output=new int[64];

for(int i=0;i<64;i++){

if(b2[i]!=b1[i]){

if(b2[i]=='.')

output[i]=-b1[i];

else

output[i]=b2[i];

}

else

output[i] = '.';//b2[i]-b1[i];

}

return output;

}

boolean validateFen(String aFen){

/* Only check board part of FEN */

if(aFen.indexOf(' ')>0){

aFen = aFen.substring(0,aFen.indexOf(' '));

}

int s=0;

for(int c=0;c<aFen.length();c++){

if(aFen.charAt(c) == '/') s++;

}

if(s!=7) return false;

int x=0;

for(int c=0;c<aFen.length();c++){

if(aFen.charAt(c) == '/'){

if(x!=8) return false;

else x=0;

}

else

{

if(aFen.charAt(c) >= '1' && aFen.charAt(c)<= '8')

x+= aFen.charAt(c)-'1' ;

x++;

}

}

if(x!=8) return false;

return true;

}

}

rdgtFendiff.java

---

class rdgtFendiff {

char piece;

boolean added;

int square;

rdgtFenboard before;

rdgtFenboard after;

public rdgtFenboard getBefore() { return before; }

public rdgtFenboard getAfter() { return after; }

public char getPiece() { return piece; }

public boolean isAdded() { return added; }

public int getSquare() { return square; }

public boolean isWhite(){

if(piece>'A' && piece < 'Z')

return true;

else

return false;

}

public boolean equals(rdgtFendiff other){

if(getPiece() != other.getPiece()) return false;

if(getSquare() != other.getSquare()) return false;

if(isAdded() != other.isAdded()) return false;

return true;

}

public rdgtFendiff() {

secured=false;

}

public rdgtFendiff(char piece, boolean added, int square){

set(piece,added,square);

}

public rdgtFendiff(int piece, int square){

if(piece<0){

this.piece = (char)(-piece);

added=false;

}

else {

this.piece=(char)piece;

added=true;

}

this.square=square;

}

public rdgtFendiff(int piece,int square, rdgtFenboard before, rdgtFenboard after){

this.before=before;

this.after=after;

if(piece<0){

this.piece = (char)(-piece);

added=false;

}

else {

this.piece=(char)piece;

added=true;

}

this.square=square;

}

public void set(char piece, boolean added, int square){

this.piece=piece;

this.added=added;

this.square=square;

}

public String toString() {

String output = ""+piece;

if(added) output += "@";

else output += "&";

output += (char)((square)%8+'a') + "" + (8-square/8);

return output;

}

}

rdgtFenhax.java

---

public class rdgtFenhax {

static boolean debug=false;

static boolean rotated=false;

public rdgtFenhax(){

boards=new ArrayList();

moves=new movelist();

diffTable=new ArrayList();

result="?-?";

plyCount=0;

}

static String getMoves(boolean shortNotation, boolean nice) {

calcMoves();

return moves.getAll(shortNotation,nice);

}

static String getMoves(){

return getMoves(false,false);

}

static int getPlyCount(){

calcMoves();

return moves.size();

}

static void clear(){

boards.clear();

moves.clear();

diffTable.clear();

result="?-?";

}

static String getResult() { return result; }

static boolean add(String aFen){

rdgtFenboard f = new rdgtFenboard();

if(!f.setBoard(aFen))

return false;

boards.add(f);

if(aFen.indexOf("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR")>=0){

clear();

boards.add(f);

}

if((aFen.indexOf("rnbq1bnr/pppppppp") >=0 && aFen.indexOf("PPPPPPPP/RNBQ1BNR") >= 0)||

(aFen.indexOf("rnbqkbnr/pppppppp") >=0 && aFen.indexOf("PPPPPPPP/RNBQ1BNR") >= 0)||

(aFen.indexOf("rnbq1bnr/pppppppp") >=0 && aFen.indexOf("PPPPPPPP/RNBQKBNR") >= 0)){

int[] b=f.getBoard();

boolean black=false;

boolean white=false;

for(int i=16;i<=47;i++){

if(b[i] == 'k') black=true;

if(b[i] == 'K') white=true;

}

if(black && white) result="1/2-1/2";

else if(black) result="0-1";

else if(white) result="1-0";

}

if(boards.size()>=2){

rdgtFenboard last = (rdgtFenboard)boards.get(boards.size()-1);

rdgtFenboard nextlast = (rdgtFenboard)boards.get(boards.size()-2);

if(last.diffCount(nextlast) < 5){

rdgtFenboard m=nextlast.mask(last);

int[] mask = m.getBoard();

for(int i=0;i<64;i++){

if(mask[i] != '.' && mask[i]<0){

diffTable.add(new rdgtFendiff(mask[i],i,nextlast,last));

}

}

for(int i=0;i<64;i++){

if(mask[i] != '.' && mask[i]>0){

diffTable.add(new rdgtFendiff(mask[i],i,nextlast,last));

}

}

}

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());

s.append("\n<td><a href=\"");

s.append(snapshotprefix);

s.append(Integer.toString(b.get_address()));

s.append(extension);

s.append("\">Link</a><td><a href=\"");

s.append(historyprefix);

s.append(Integer.toString(b.get_address()));

s.append(extension);

s.append("\">Link</a>\n");

}

s.append("</table>\n</body>\n</html>\n");

if (writefile(indexfilename+extension, s.toString()) == false) {

System.err.println("Error: Failed to write indexfile.");

return;

}

}

static void print_history(rdgtHistory h) {

StringBuffer s = new StringBuffer(2000);

s.append("<html>\n<head></head>\n");

s.append("<body><h1>History for Chessboard: ");

s.append(Integer.toString(h.board.get_address()));

s.append("</h1>\n");

int i = 0;

for (Enumeration e = h.history.elements() ; e.hasMoreElements() ;) {

rdgtSnapshot ss = (rdgtSnapshot)(e.nextElement());

i=i+1;

s.append("<p><hr size=1><p><h3>Move: ");

s.append(Integer.toString(i));

s.append(" &nbsp; &nbsp;");

s.append(ss.get_time().toString());

s.append(boardview(ss));

s.append("\n");

}

s.append("</body>\n</html>\n");

if (writefile(historyprefix + Integer.toString(h.board.get_address()) + extension, s.toString()) == false) {

System.err.println("Error: Failed to write historyfile.");

return;

}

}

static String boardview(rdgtSnapshot b) {

StringBuffer s = new StringBuffer(1000);

s.append("<table border=0 cellpadding=0 cellspacing=0>\n");

boolean filled = true;

for (int i=0; i<8; i=i+1) {

s.append("<tr>");

for (int j=0; j<8; j=j+1) {

s.append("<td><img src=\"images/");

int p = b.pieces[(i*8)+j];

if (p==EMPTY ) s.append("empty");

else if (p==WPAWN ) s.append("w_pawn");

else if (p==WROOK ) s.append("w_rook");

else if (p==WKNIGHT) s.append("w_knight");

else if (p==WBISHOP) s.append("w_bishop");

else if (p==WKING ) s.append("w_king");

else if (p==WQUEEN ) s.append("w_queen");

else if (p==BPAWN ) s.append("b_pawn");

else if (p==BROOK ) s.append("b_rook");

else if (p==BKNIGHT) s.append("b_knight");

else if (p==BBISHOP) s.append("b_bishop");

else if (p==BKING ) s.append("b_king");

else if (p==BQUEEN ) s.append("b_queen");

if (filled) s.append("1"); else s.append("2");

filled = !filled;

s.append(".gif\">");

}

filled = !filled;

s.append("</tr>\n");

}

s.append("\n</table>");

return s.toString();

}

static void print_snapshot(rdgtSnapshot ss) {

StringBuffer s = new StringBuffer(2000);

s.append("<html>\n<head>\n <meta http-equiv=refresh content=4>\n</head>\n");

s.append("<body><h1>Snapshot of Chessboard: ");

s.append(Integer.toString(ss.board.get_address()));

s.append("</h1>\n<h3>");

s.append(ss.get_time().toString());

s.append("</h3>\n");

s.append(boardview(ss));

s.append("\n</body>\n</html>\n");

if (writefile(snapshotprefix + Integer.toString(ss.board.get_address()) + extension, s.toString()) == false) {

System.err.println("Error: Failed to write snapshotfile.");

return;

}

}

static boolean writefile(String filename, String content) {

FileWriter f = null;

for (int i=0; i<10; i=i+1) {

try {

f = new FileWriter(filename);

break;

}

catch (Throwable t) {

System.err.println("Error opening "+filename+" for writing. Retrying...");

}

}

if (f==null) {

System.out.println("Failed to open file "+filename);

return false;

}

try {

f.write(content);

f.close();

}

catch (Exception e) {

System.out.println("Error writing file "+filename+". ("+e.toString()+")");

return false;

}

return true;

}

}

rdgtInterpreter.java

---

class rdgtInterpreter extends rdgtProtocol {

rdgtDatabase db;

public rdgtInterpreter(rdgtDatabase _db) {

db = _db;

}

public boolean interpret(int[] data) {

int len = ((int) data[1] * 0x80) + (int) data[2];

int address = ((int) data[3] * 0x80) + (int) data[4];

String tmp = "Len:" + Integer.toString(len) + " Address:" + Integer.toString(address);

if (data[0] == DGT_BUS_PING) {

System.out.println("Received message: PING " + tmp);

} else if (data[0] == DGT_BUS_UPDATE) {

System.out.println("Received message: UPDATE " + tmp);

} else if (data[0] == DGT_BUS_BWTIME) {

System.out.println("Received message: BWTIME " + tmp);

} else {

System.out.println("Received message: (some other message) " + tmp);

}

if (check_checksum(data) == false) {

System.out.println("Message failed checksum test");

return false;

}

if (data[0] == DGT_BUS_PING) {

if (data.length != 6) { // address+data

System.out.println("Illegal: Got a BUS_PING with wrong size");

return false;

}

db.get_board(address).set_alive(true);

return true;

} else if (data[0] == DGT_BUS_BRD_DUMP) {

if (data.length != (6 + 64)) {

System.out.println("Illegal: Got a BUS_BRD_DUMP with wrong size");

return false;

}

rdgtChessboard c = db.get_board(address);

c.set_boarddump(data, 5);

return true;

} else if (data[0] == DGT_BUS_UPDATE) {

byte pr[] = new byte[data.length - 5];

for (int i = 5; i < data.length; i++) {

pr[i - 5] = (byte) data[i];

}

System.out.println(new String(pr));

rdgtChessboard c = db.get_board(address);

for (int i = 5; i < data.length - 1; i++) {

if (data[i] == EE_POWERUP) {

}

else if (data[i] == EE_EOF) {

}

else if (data[i] == EE_FOURROWS) {

}

else if (data[i] == EE_EMPTYBOARD) {

c.set_emptyboard();

} else if (data[i] == EE_DOWNLOADED) {

}

else if (data[i] == EE_BEGINPOS) {

}

else if (data[i] == EE_BEGINPOS_ROT) {

}

else if (data[i] == EE_START_TAG) {

}

else if (data[i] == EE_WATCHDOG_ACTION) {

}

else if (data[i] == EE_NOP) {

}

else if (data[i] >= 0x40 && data[i] <= 0x5F) { // 2-byte piece update

c.set_fieldupdate(data[i] & 0x0F, data[i + 1]);

i++;

} else if ((data[i] >= 0x60 && data[i] <= 0x69) || (data[i] >= 0x70 && data[i] <= 0x79)) {

i += 2;

} else {

System.out.println("Unknown data in DGT_BUS_UPDATE command.");

return false;

}

}

c.set_updated(true);

return true;

}

else if (data[0] == DGT_BUS_BWTIME) {

if (data.length != 13) {

System.out.println("Illegal: Got a DGT_BUS_BWTIME with wrong size (!=10)");

return false;

}

if ((data[11] & 0x20) != 0) {

System.out.println("(No clock connected)");

return true;

}

boolean running = (data[11] & 0x01) != 0;

boolean batteryLow = (data[11] & 0x04) != 0;

boolean frontViewLeftSideHigh = (data[11] & 0x02) != 0;

boolean blackPlayersTurn = (data[11] & 0x08) != 0;

boolean whitePlayersTurn = (data[11] & 0x10) != 0;

int hoursW = data[5] & 0x0F;

int minutesW = (data[6] & 0x0F) + ((data[6] >> 4) * 10);

int secondsW = (data[7] & 0x0F) + ((data[7] >> 4) * 10);

int hoursB = data[8] & 0x0F;

int minutesB = (data[9] & 0x0F) + ((data[9] >> 4) * 10);

int secondsB = (data[10] & 0x0F) + ((data[10] >> 4) * 10);

secondsW = (((hoursW * 60) + minutesW) * 60) + secondsW;

secondsB = (((hoursB * 60) + minutesB) * 60) + secondsB;

db.get_board(address).set_clockdata(running, batteryLow, frontViewLeftSideHigh,

blackPlayersTurn, whitePlayersTurn, secondsW, secondsB);

return true;

} else if (data[0] == DGT_BUS_FROM_START) {

} else if (data[0] == DGT_BUS_START_GAME_WRITTEN) {

} else if (data[0] == DGT_BUS_VERSION) {

}

System.err.println("Unknown message (checksum was ok).");

return true;

}

boolean check_checksum(int[] data) {

int sum = 0;

for (int i = 0; i < (data.length - 1); i = i + 1) {

sum = (sum + data[i]) & 0x7F;

}

if (sum == data[data.length - 1]) {

return true;

}

return false;

}

}

rdgtMysql.java

---

class rdgtMysql extends rdgtProtocol {

static String server= "localhost";

static String user= "root";

static String pass= "zar1562";

static String dbase= "rdgt_development";

static String update_table= "games";

static Connection conn = null;

static Statement stmt = null;

static boolean rotated=false;

static String connect()

{

try

{

Class.forName("com.mysql.jdbc.Driver").newInstance();

conn = DriverManager.getConnection("jdbc:mysql://"+server+"/"+dbase+"?user="+user+"&password="+pass);

return "";

}

catch (SQLException e)

{

return e.getSQLState();

}

catch (Exception e)

{

return "0";

}

}

static boolean disconnect()

{

if (conn != null) {

try

{

conn.close();

return true;

}

catch (SQLException SQLE)

{

return false;

}

}

else

return false;

}

static String execute(String expr)

{

try

{

stmt = null;

stmt = conn.createStatement();

stmt.executeUpdate(expr);

return "";

}

catch (SQLException e)

{

return e.getSQLState();

}

catch (Exception e)

{

return "0";

}

finally

{

if (stmt != null) {

try

{

stmt.close();

}

catch (SQLException SQLE)

{

;

}

}

}

}

static String snapshot2fen (rdgtSnapshot b)

{

StringBuffer s = new StringBuffer(100);

int counter = 0;

for (int i=0; i<8; i++)

{

for (int j=0; j<8; j++)

{

if ((counter != 0) && (b.pieces[(i*8)+j] != EMPTY))

{

s.append(counter);

counter = 0;

}

switch(b.pieces[(i*8)+j])

{

case WPAWN:s.append("P"); break;

case WROOK: s.append("R"); break;

case WKNIGHT: s.append("N"); break;

case WBISHOP: s.append("B"); break;

case WKING: s.append("K"); break;

case WQUEEN: s.append("Q"); break;

case BPAWN: s.append("p"); break;

case BROOK: s.append("r"); break;

case BKNIGHT: s.append("n"); break;

case BBISHOP: s.append("b"); break;

case BKING: s.append("k"); break;

case BQUEEN: s.append("q"); break;

default: counter++; break;

}

}

if (counter != 0)

s.append(counter);

s.append("/");

counter = 0;

}

String outfen= s.toString().substring(0,s.toString().length()-1);

switch(b.board.address.intValue()){

case 3737:

case 3811:

case 2896:

case 3740:

case 3588:

case 2897:

default:

rotated=false; break;

}

if(rotated){

String newFen="";

for(int i=outfen.length()-1;i>=0;i--){

newFen += outfen.charAt(i);

}

outfen=newFen;

}

return outfen;

}

static void update_snapshot(rdgtSnapshot b)

{

if (conn != null)

{

String fen = snapshot2fen(b);

String turn;

if(rotated){

if(b.isWhiteTurn()) turn="Black";

else turn="White";

}

else{

if(b.isWhiteTurn()) turn="White";

else turn="Black";

}

String sql_command = "UPDATE "+update_table+" SET fen = '"+fen+"',wtime='"+b.getTimeWhite()+"',btime='"+b.getTimeBlack()+"',turn='"+turn+"' WHERE dgt_active like '%Fen%' AND dgt_board = "+b.board.address;

execute(sql_command);

System.out.println(b.board.address+" "+fen+" "+b.getTimeWhite()+" "+b.getTimeBlack()+" "+turn.substring(0,1));

}

}

static void update_moves(String moves, String movestable, int board_id)

{

if (conn != null)

{

int t=0;

if(moves.length()>20) t=moves.length()-20;

System.out.println(board_id + " Moves: " + moves.substring(t));

String sql_command = "UPDATE games SET moves = '"+moves+"' WHERE dgt_active like '%Moves%' AND dgt_board = "+board_id;

execute(sql_command);

}

}

}

rdgtProtocol.java

---

class rdgtProtocol {

static int DGT_TO_BUSMODE = 0x4a;

static int DGT_BUS_SEND_CLK = 0x01 | 0x80;

static int DGT_BUS_SEND_BRD = 0x02 | 0x80;

static int DGT_BUS_SEND_CHANGES = 0x03 | 0x80;

static int DGT_BUS_REPEAT_CHANGES = 0x04 | 0x80;

static int DGT_BUS_SET_START_GAME = 0x05 | 0x80;

static int DGT_BUS_SEND_FROM_START = 0x06 | 0x80;

static int DGT_BUS_PING = 0x07 | 0x80;

static int DGT_BUS_END_BUSMODE = 0x08 | 0x80;

static int DGT_BUS_RESET = 0x09 | 0x80;

static int DGT_BUS_IGNORE_NEXT_BUS_PING = 0x0a | 0x80;

static int DGT_BUS_SEND_VERSION = 0x0b | 0x80;

static int DGT_BUS_BRD_DUMP = 0x03 | 0x80;

static int DGT_BUS_BWTIME = 0x04 | 0x80;

static int DGT_BUS_UPDATE = 0x05 | 0x80;

static int DGT_BUS_FROM_START = 0x06 | 0x80;

static int DGT_BUS_START_GAME_WRITTEN = 0x08 | 0x80;

static int DGT_BUS_VERSION = 0x09 | 0x80;

static boolean is_busmessage(int m) {

return (m== DGT_BUS_BRD_DUMP || m == DGT_BUS_BWTIME ||

m == DGT_BUS_UPDATE || m == DGT_BUS_FROM_START || m == DGT_BUS_PING ||

m == DGT_BUS_START_GAME_WRITTEN || m == DGT_BUS_VERSION);

}

static final int EMPTY = 0x00;

static final int WPAWN = 0x01;

static final int WROOK = 0x02;

static final int WKNIGHT = 0x03;

static final int WBISHOP = 0x04;

static final int WKING = 0x05;

static final int WQUEEN = 0x06;

static final int BPAWN = 0x07;

static final int BROOK = 0x08;

static final int BKNIGHT = 0x09;

static final int BBISHOP = 0x0a;

static final int BKING = 0x0b;

static final int BQUEEN = 0x0c;

boolean is_piece(int p) {

return (p==EMPTY || p==WPAWN || p==WROOK ||

p==WKNIGHT || p==WBISHOP || p==WKING ||

p==WQUEEN || p==BPAWN || p==BROOK ||

p==BKNIGHT || p==BBISHOP || p==BKING ||

p==BQUEEN);

}

static int EE_POWERUP = 0x6a;

static int EE_EOF = 0x6b;

static int EE_FOURROWS = 0x6c;

static int EE_EMPTYBOARD = 0x6d;

static int EE_DOWNLOADED = 0x6e;

static int EE_BEGINPOS = 0x6f;

static int EE_BEGINPOS_ROT = 0x7a;

static int EE_START_TAG = 0x7b;

static int EE_WATCHDOG_ACTION = 0x7c;

static int EE_NOP = 0x7f;

}

rdgtReceiver.java

---

class rdgtReceiver extends rdgtProtocol {

int messagetype;

int messagelen_msb;

int messagelen_lsb;

int[] data;

int useddata;

int state;

rdgtInterpreter interpreter;

public rdgtReceiver(rdgtInterpreter _interpreter) {

state = 0;

interpreter = _interpreter;

}

void receive(int[] d) {

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

StringBuffer x = new StringBuffer("Received: ");

for (int i=0; i<d.length; i=i+1) {

x.append(c[d[i]>>4]).append(c[d[i] & 0x0F]).append(" ");

}

if (rdgtChess.debug) System.out.println(x.toString());

_receive (d, 0);

}

void _receive(int[] d, int start) {

if (start == d.length) return;

if (state == 0) { // Find a known messageid.

while (start<d.length) {

if (is_busmessage(d[start])) {

messagetype = d[start];

state = 1;

_receive(d,start+1);

return;

}

System.err.println("Did not understand 1 byte of incoming data.");

start = start + 1;

}

return;

}

if (state == 1) {

if ((d[start] & 0x80) > 0) {

System.err.println("Did not understand 2 bytes of incoming data.");

state = 0;

_receive(d, start);

return;

}

messagelen_msb = d[start];

state = 2;

start = start + 1;

}

if (start == d.length) return;

if (state == 2) {

if ((d[start] & 0x80) > 0) {System.err.println("Did not understand 3 bytes of incoming data.");

state = 0;

_receive(d, start);

return;

}

messagelen_lsb = d[start];

state = 3;

start = start + 1;

int newlen = ((int)messagelen_msb * 0x80) + (int)messagelen_lsb;

if (newlen <5) {

System.out.println("Too small message length: " + Integer.toString(newlen));

state = 0;

_receive(d, start);

return;

}

data = new int[newlen];

data[0] = messagetype;

data[1] = messagelen_msb;

data[2] = messagelen_lsb;

useddata = 3;

}

if (start == d.length) return;

if (state == 3) {

while (start<d.length && useddata<data.length) {

data[useddata]=d[start];

start = start + 1;

useddata = useddata + 1;

}

if (useddata == data.length) {

interpreter.interpret(data);

start = start + 1;

data = null;

state = 0;}

}

_receive(d, start);

}

}

rdgtSender.java

---

class rdgtSender extends rdgtProtocol {

rdgtSerialport com;

public rdgtSender(rdgtSerialport _com) {

com = _com;

}

void send(int message, int address) {

String tmp = "Address:"+Integer.toString(address);

System.out.println();

if (message==DGT_TO_BUSMODE) System.out.println("Sending message: SWITCH TO BUSMODE "+tmp);

else if (message==DGT_BUS_SEND_BRD) System.out.println("Sending message: SEND BOARD "+tmp);

else if (message==DGT_BUS_SEND_CHANGES) System.out.println("Sending message: SEND CHANGES "+tmp);

else if (message==DGT_BUS_REPEAT_CHANGES) System.out.println("Sending message: REPEAT CHANGES "+tmp);

else if (message==DGT_BUS_PING) System.out.println("Sending message: PING "+tmp);

else if (message==DGT_BUS_IGNORE_NEXT_BUS_PING) System.out.println("Sending message: IGNORE NEXT PING "+tmp);

else System.out.println("Sending message: (some other message)");

byte x[] = new byte[4];

x[0] = (byte)message;

x[1] = (byte)((address>>7) & 0x7F);

x[2] = (byte)(address & 0x7F);

x[3] = (byte)(((int)x[0]+(int)x[1]+(int)x[2]) & 0x7F);

com.write(x);

}

}

rdgtSerialport.java

---

class rdgtSerialport implements SerialPortEventListener {

static CommPortIdentifier portid;

InputStream inStream;

OutputStream outStream;

SerialPort serialPort;

rdgtReceiver receiver;

public rdgtSerialport(rdgtReceiver r) {

receiver = r;

}

public boolean open(String portname) {

CommPortIdentifier id = null;

Enumeration portList;

portList = CommPortIdentifier.getPortIdentifiers();

System.out.println(portList.toString());

while (portList.hasMoreElements()) {

System.out.println("2");

id = (CommPortIdentifier) portList.nextElement();

if (id.getPortType() == CommPortIdentifier.PORT_SERIAL) {

System.out.println("Ports: "+id.getName());

if (id.getName().equals(portname)) break; // found

}

id = null;

}

if (id == null) return false; // not found

try {

serialPort = (SerialPort) id.open("ttchess", 2000);

inStream = serialPort.getInputStream();

outStream = serialPort.getOutputStream();

serialPort.addEventListener(this);

serialPort.notifyOnDataAvailable(true);

serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,

SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);

serialPort.setDTR(false);

serialPort.setRTS(false);

} catch (Exception e) { return false; }

return true;

}

public boolean write(byte[] data) {

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

StringBuffer x = new StringBuffer(" Sending: ");

for (int i=0; i<data.length; i=i+1) {

int d = data[i];

if (d<0) d=256+d;

x.append(c[d>>4]).append(c[d & 0x0F]).append(" ");

}

if (rdgtChess.debug) System.out.println(x.toString());

try {

outStream.write(data);

} catch (IOException e) { return false; }

return true;

}

public void serialEvent(SerialPortEvent event) {

switch(event.getEventType()) {

case SerialPortEvent.OUTPUT_BUFFER_EMPTY:

break;

case SerialPortEvent.DATA_AVAILABLE:

byte[] readBuffer = new byte[200];

try {

while (inStream.available() > 0) {

int numBytes = inStream.read(readBuffer);

if (numBytes>0) {

int[] buf = new int[numBytes];

for (int i=0; i<numBytes; i=i+1) {

int tmp = readBuffer[i];

if (tmp<0) tmp=256+tmp;

buf[i]=tmp;

}

receiver.receive(buf);

}

}

} catch (IOException e) {}

break;

}

}

}

rdgtSnapshot.java

---

class rdgtSnapshot extends rdgtProtocol {

int[] pieces = new int[64];

Date time;

rdgtChessboard board;

boolean clkRunning, clkBatteryLow, clkFrontViewLeftSideHigh, clkBlackTurn, clkWhiteTurn;

int clkSecWhite, clkSecBlack;

public rdgtSnapshot(rdgtChessboard _board) {

time = new Date();

board = _board;

set_emptyboard();

}

public rdgtSnapshot(rdgtSnapshot x) {

for (int i=0; i<64; i=i+1) pieces[i] = x.pieces[i];

time = x.time;

board = x.board;

clkRunning = x.clkRunning;

clkBatteryLow = x.clkBatteryLow;

clkFrontViewLeftSideHigh = x.clkFrontViewLeftSideHigh;

clkBlackTurn = x.clkBlackTurn;

clkWhiteTurn = x.clkWhiteTurn;

clkSecWhite = x.clkSecWhite;

clkSecBlack = x.clkSecBlack;

}

rdgtSnapshot copy() {

return new rdgtSnapshot(this);

}

void set_clockdata(boolean running, boolean batteryLow, boolean frontViewLeftSideHigh,

boolean blackTurn, boolean whiteTurn, int secW, int secB) {

clkRunning = running;

clkBatteryLow = batteryLow;

clkFrontViewLeftSideHigh = frontViewLeftSideHigh;

clkBlackTurn = blackTurn;

clkWhiteTurn = whiteTurn;

clkSecWhite = secW;

clkSecBlack = secB;

}

public boolean sameas(rdgtSnapshot x) {

for (int i=0; i<64; i=i+1) if (pieces[i] != x.pieces[i]) return false;

return true;

}

Date get_time() { return time; }

void set_emptyboard() {

time = new Date();

for (int i=0; i<64; i=i+1) pieces[i]=EMPTY;

}

void set_boarddump(int[] all64, int startpos) {

time = new Date();

for (int i=0; i<64; i=i+1) {

int p = all64[i+startpos];

if (is_piece(p)==false) {

System.out.println("Confused: Boarddump contained an unknown piece");

pieces[i]=EMPTY;

} else {

pieces[i]=p;

}

}

}

void set_fieldupdate(int piece, int pos) {

time = new Date();

if (pos <0 || pos > 63) {

System.out.println("Confused: Fieldupdate for pos outside 0..63");

return;

}

if (is_piece(piece)==false) {

System.out.println("Confused: Fieldupdate with an unknown piece");

return;

}

pieces[pos]=piece;

}

String seconds2hms(int s) {

return Integer.toString(s/36000)+Integer.toString((s%36000)/3600)+":"+

Integer.toString((s%3600)/600)+Integer.toString((s%360)/60)+":"+

Integer.toString((s%60)/10)+Integer.toString(s%10);

}

String debugprint_clock() {

StringBuffer s = new StringBuffer(50);

s.append("Clock: White "); s.append(seconds2hms(clkSecWhite));

s.append(" Black "); s.append(seconds2hms(clkSecBlack));

System.out.println(s);

return s.toString();

}

String getTimeWhite(){

return seconds2hms(clkSecWhite);

}

String getTimeBlack(){

return seconds2hms(clkSecBlack);

}

boolean isWhiteTurn(){

return clkFrontViewLeftSideHigh;

}

String debugprint() {

debugprint_clock();

StringBuffer s = new StringBuffer(300);

for (int i=0; i<8; i=i+1) {

for (int j=0; j<8; j=j+1) {

int p = pieces[(i*8)+j];

if (p==EMPTY ) s.append(".");

if (p==WPAWN ) s.append("P");

if (p==WROOK ) s.append("R");

if (p==WKNIGHT) s.append("N");

if (p==WBISHOP) s.append("B");

if (p==WKING ) s.append("K");

if (p==WQUEEN ) s.append("Q");

if (p==BPAWN ) s.append("p");

if (p==BROOK ) s.append("r");

if (p==BKNIGHT) s.append("n");

if (p==BBISHOP) s.append("b");

if (p==BKING ) s.append("k");

if (p==BQUEEN ) s.append("q");

}

s.append("\n");

}

System.out.println(s);

return s.toString();

}

}

Приложение Е

Протокол DGT

#ifndef dgtbrd13

#define dgtbrd13

/*

Protocol description for DGT chess board.

Copyright 1998 DGT Projects B.V

Version: 1.03 Single computer and bus support in one .h file

*********************************************************

This protocol is protected under trade mark registration and copyrights.

It may not be used commercially without written permission

of DGT Projects B.V. It is illegal to transfer any registered trade mark

identifications by means of this protocol between any chessboard or other

application and any computer.

*********************************************************

Main functionality of the DGT Electronic Chess Board

----------------------------------------------------

The DGT board is basically a sensor which senses the presense of the special

chess set pieces on the squares of the board. The situation on the board is

measured and can be communicated with an average maximum time delay of

200 mS.

Besides this detection function, the board communicates with an optional

DGT TopMatch Chess Clock, to give the data of the clock available to the

general interface.

Finally the board is equipped with an internal storage of the measured

piece positions.

The board supports two methods of communication: for single-board situations

a protocol for communication between one board and one computer is available.

For situations with many boards a network communications protocol is

available, where many boards can be connected in a bus structure. A separate

communication protocol is available for this bus structure.

The communication protocol for single board connections is described

in the following paragraph "Single board communication protocol". This

paragraph describes much more than only the communication protocol. All

developers should read this paragraph, even if they would only use bus

communication.

The special bus communication protocol is derived from the single board

communication and functionality, where the main added feature is the

possibility to address a specific board on a shared communication bus.

The commands and data contens are described in the paragraph "Bus

Communication Protocol", Note however that the contens can not be understood

without reading the single board communication paragraph.

Paragraph: Single board communication protocol

----------------------------------------------

The main function of the board is to transfer piece position information.

For this, three modes are available:

1. IDLE mode. This cancelles any of the two UPDATE modes. No automatic

transfer of moves.

2. UPDATE_BOARD mode. On the moment that the board detects a removal, change

or placing of a piece, it outputs a DGT_SEND_UPDATE message

3. UPDATE mode. As UPDATE_BOARD mode, where additional the clock data are send

regularly (at least every second)

The board accepts command codes from the computer RS232. The commands are

1-byte codes, sometimes followed by data (see code definition)

The board can send data to the computer. Data always carries a message header.

The message header contains a message code and the total message size in bytes.

The start of the incoming message can be recognised by the MSB of the message

identifier set to 1 (see definition).

Board to computer communication interfaces:

RS232 for communication with computer, receiving commands, sending data

- 9600 Baud, 1 stopbit, 1 startbit, no parity

- No use of handshaking, neither software nor hardware

Connection between Digital Game Timer TopMatch Clock and the board:

Based on NEC SBI protocol. Adaption of the definition given in

the DGT TopMatch documentation.

Connector assignments for DGT Electronic Board: See User

and Programmers Manual

Related to the before mentioned modes, and to piece position information

transfer, the following commands to the board are available:

1. DGT_SEND_RESET

puts the DGT Board in IDLE mode

2. DGT_SEND_CLK

on which the DGT board responds with a DGT_MSG_BWTIME message containing clock

information

3. DGT_SEND_BRD

on which the DGT Board responds with a DGT_MSG_BOARD_DUMP message containing

the actual piece exising of all fields

4. DGT_SEND_UPDATE puts the DGT Board in the UPDATE mode, FRITZ5 compatible

5. DGT_SEND_UPDATE_BRD puts the DGT Board in the UPDATE_BOARD mode

6. DGT_SEND_UPDATE_NICE puts the board in UPDATE mode, however transferring only clocktimes when any time info changed.

The DGT_SEND_CLK command and the DGT_SEND_BOARD command do not affect the current board

mode: i.e. when in UPDATE mode, it continues sending DGT_SEND_UPDATE messages.

Board Identification:

Each DGT Electronic Board carries a unique serial number,

a EEPROM configuration version number and a embedded program version number.

These data are unalterable by the users.

Current identification is:

"DGT Projects - This DGT board is produced by DGT Projects.\n

DGT Projects is a registered trade mark.\n

220798 ISP/bus/8KP/8KE/P6/Fritz5 Vs 1.00. Serial nr. 00137 1.0"

The board can be loaded by the user with a non-volatile one-byte bus number,

for future use with multiple board configurations.

On-board EEPROM:

The board carries a 8 kB cyclic non-volatile memory, in which all position

changes and clock information is stored during all power-up time. This

file can be read and processed.

Start of Definitions:

---------------------*/

/* COMMAND CODES FROM PC TO BOARD: */

/* resulting in returning message(s): */

#define DGT_SEND_CLK 0x41

/* results in a DGT_MSG_BWTIME message */

#define DGT_SEND_BRD 0x42

/* results in a DGT_MSG_BOARD_DUMP message */

#define DGT_SEND_UPDATE 0x43

/* results in DGT_MSG_FIELD_UPDATE messages and DGT_MSG_BWTIME messages

as long as the board is in UPDATE mode */

#define DGT_SEND_UPDATE_BRD 0x44

/* results in DGT_MSG_FIELD_UPDATE messages

as long as the board is in UPDATE_BOARD mode */

#define DGT_RETURN_SERIALNR 0x45

/* results in a DGT_MSG_SERIALNR message */

#define DGT_RETURN_BUSADRES 0x46

/* results in a DGT_MSG_BUSADRES message */

#define DGT_SEND_TRADEMARK 0x47

/* results in a DGT_MSG_TRADEMARK message */

#define DGT_SEND_VERSION 0x4d

/* results in a DGT_MSG_VERSION message */

#define DGT_SEND_UPDATE_NICE 0x4b

/* results in DGT_MSG_FIELD_UPDATE messages and DGT_MSG_BWTIME messages,

the latter only at time changes,

as long as the board is in UPDATE_NICE mode*/

#define DGT_SEND_EE_MOVES 0x49

/* results in a DGT_MSG_EE_MOVES message */

/* not resulting in returning messages: */

#define DGT_SEND_RESET 0x40

/* puts the board in IDLE mode, cancelling any UPDATE mode */

/* DESCRIPTION OF THE MESSAGES FROM BOARD TO PC

A message consists of three header bytes:

MESSAGE ID one byte, MSB (MESSAGE BIT) always 1

MSB of MESSAGE SIZE one byte, MSB always 0, carrying D13 to D7 of the total message length, including the 3 header byte

LSB of MESSAGE SIZE one byte, MSB always 0, carrying D6 to D0 of the

total message length, including the 3 header bytes

followed by the data:

0 to ((2 EXP 14) minus 3) data bytes, of which the MSB is always zero.

*/

/* DEFINITION OF THE BOARD-TO-PC MESSAGE ID CODES and message descriptions */

/* the Message ID is the logical OR of MESSAGE_BIT and ID code */

#define MESSAGE_BIT 0x80

/* ID codes: */

#define DGT_NONE 0x00

#define DGT_BOARD_DUMP 0x06

#define DGT_BWTIME 0x0d

#define DGT_FIELD_UPDATE 0x0e

#define DGT_EE_MOVES 0x0f

#define DGT_BUSADRES 0x10

#define DGT_SERIALNR 0x11

#define DGT_TRADEMARK 0x12

#define DGT_VERSION 0x13

/* Macros for message length coding (to avoid MSB set to 1) */

#define BYTE char

#define LLL_SEVEN(a) ((BYTE)(a&0x7f)) /* 0000 0000 0111 1111 */

#define LLH_SEVEN(a) ((BYTE)((a & 0x3F80)>>7)) /* 0011 1111 1000 0000 */

/* DGT_MSG_BOARD_DUMP is the message that follows on a DGT_SEND_BOARD

command */

#define DGT_MSG_BOARD_DUMP (MESSAGE_BIT|DGT_BOARD_DUMP)

#define DGT_SIZE_BOARD_DUMP 67

/* message format:

byte 0: DGT_MSG_BOARD_DUMP

byte 1: LLH_SEVEN(DGT_SIZE_BOARD_DUMP) (=0 fixed)

byte 2: LLL_SEVEN(DGT_SIZE_BOARD_DUMP) (=67 fixed)

byte 3-66: Pieces on position 0-63

Board fields are numbered from 0 to 63, row by row, in normal reading

sequence. When the connector is on the left hand, counting starts at

the top left square. The board itself does not rotate the numbering,

when black instead of white plays with the clock/connector on the left hand.

In non-rotated board use, the field numbering is as follows:

Field A8 is numbered 0

Field B8 is numbered 1

Field C8 is numbered 2

..

Field A7 is numbered 8

..

Field H1 is numbered 63

So the board always numbers the black edge field closest to the connector

as 57.

Piece codes for chess pieces: */

#define EMPTY 0x00

#define WPAWN 0x01

#define WROOK 0x02

#define WKNIGHT 0x03

#define WBISHOP 0x04

#define WKING 0x05

#define WQUEEN 0x06

#define BPAWN 0x07

#define BROOK 0x08

#define BKNIGHT 0x09

#define BBISHOP 0x0a

#define BKING 0x0b

#define BQUEEN 0x0c

#define PIECE1 0x0d /* future use: pointing device in rest */

#define PIECE2 0x0e /* future use: pointing device right button */

#define PIECE3 0x0f /* future use: pointing device left button */

/* message format DGT_MSG_BWTIME */

#define DGT_MSG_BWTIME (MESSAGE_BIT|DGT_BWTIME)

#define DGT_SIZE_BWTIME 10

/*

byte 0: DGT_MSG_BWTIME

byte 1: LLH_SEVEN(DGT_SIZE_BWTIME) (=0 fixed)

byte 2: LLL_SEVEN(DGT_SIZE_BWTIME) (=10 fixed)

byte 3:

D4: 1 = Flag fallen for left player, and clock blocked to zero

0 = not the above situation

D5: 1 = Time per move indicator on for left player ( i.e. Bronstein, Fischer)

0 = Time per move indicator off for left player

D6: 1 = Left players flag fallen and indicated on display

0 = not the above situation

(D7 is MSB)

D0-D3: Hours (units, 0-9 Binary coded) white player (or player at the A side of the board)

byte 4: Minutes (0-59, BCD coded)

byte 5: Seconds (0-59, BCD coded)

byte 6-8: the same for the other player

byte 9: Clock status byte: 7 bits

D0 (LSB): 1 = Clock running

0 = Clock stopped by Start/Stop

D1: 1 = tumbler position high on (white) player (front view: \ , left side high)

0 = tumbler position high on the other player (front view: /, right side high)

D2: 1 = Battery low indication on display

0 = no battery low indication on display

D3: 1 = Black players turn

0 = not black players turn

D4: 1 = White players turn

0 = not white players turn

D5: 1 = No clock connected; reading invalid

0 = clock connected, reading valid

D6: not used (read as 0)

D7: Always 0

The function of the information bits are derived from the full information

as described in the programmers reference manual for the DGT TopMatch

*/

/* message format DGT_MSG_FIELD_UPDATE: */

#define DGT_MSG_FIELD_UPDATE (MESSAGE_BIT|DGT_FIELD_UPDATE)

#define DGT_SIZE_FIELD_UPDATE 5

/*

byte 0: DGT_MSG_FIELD_UPDATE

byte 1: LLH_SEVEN(DGT_SIZE_FIELD_UPDATE) (=0 fixed)

byte 2: LLL_SEVEN(DGT_SIZE_FIELD_UPDATE) (=5 fixed)

byte 3: field number (0-63) which changed the piece code

byte 4: piece code including EMPTY, where a non-empty field became empty

*/

/* message format: DGT_MSG_TRADEMARK which returns a trade mark message */

#define DGT_MSG_TRADEMARK (MESSAGE_BIT|DGT_TRADEMARK)

/*

byte 0: DGT_MSG_TRADEMARK

byte 1: LLH_SEVEN(DGT_SIZE_TRADEMARK)

byte 2: LLL_SEVEN(DGT_SIZE_TRADEMARK)

byte 3-end: ASCII TRADEMARK MESSAGE, codes 0 to 0x3F

The value of DGT_SIZE_TRADEMARK is not known beforehand, and may be in the

range of 0 to 256

Current trade mark message: ...

*/

/* Message format DGT_MSG_BUSADRES return message with bus adres */

#define DGT_MSG_BUSADRES (MESSAGE_BIT|DGT_BUSADRES)

#define DGT_SIZE_BUSADRES 5

/*

byte 0: DGT_MSG_BUSADRES

byte 1: LLH_SEVEN(DGT_SIZE_BUSADRES)

byte 2: LLL_SEVEN(DGT_SIZE_BUSADRES)

byte 3,4: Busadres in 2 bytes of 7 bits hexadecimal value

Byte 3: 0bbb bbbb with bus adres MSB 7 bits

byte 4: 0bbb bbbb with bus adres LSB 7 bits

The value of the 14-bit busadres is het hexadecimal representation

of the (decimal coded) serial number

i.e. When the serial number is "01025 1.0" the busadres will be

byte 3: 0000 1000 (0x08)

byte 4: 0000 0001 (0x01)

*/

/* Message format DGT_MSG_SERIALNR return message with bus adres */

#define DGT_MSG_SERIALNR (MESSAGE_BIT|DGT_SERIALNR)

#define DGT_SIZE_SERIALNR 12

/* returns 5 ASCII decimal serial number + space + 3 byte version string: */

/* byte 0-5 serial number string, sixth byte is LSByte */

/* byte 6: space */

/* byte 7-9: Internal storage version nr: format "1.0" */

/* Message format DGT_MSG_EE_MOVES, which is the contens of the storage array */

/* Message format DGT_MSG_VERSION return message with bus adres */

#define DGT_MSG_VERSION (MESSAGE_BIT|DGT_VERSION)


Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.