head	1.38;
access;
symbols
	tonic_4:1.38
	tonic_3:1.38
	tonic_2:1.38
	demo:1.37.0.2
	design_report:1.34
	oral_presentation_freeze:1.3.0.4
	DAVEG_CDP:1.3.0.2
	template_integ:1.2.0.2;
locks; strict;
comment	@ * @;


1.38
date	95.12.14.23.16.03;	author daveg;	state Exp;
branches;
next	1.37;

1.37
date	95.12.13.03.29.34;	author daveg;	state Exp;
branches;
next	1.36;

1.36
date	95.12.13.00.50.45;	author daveg;	state Exp;
branches;
next	1.35;

1.35
date	95.12.12.21.15.56;	author hartmans;	state Exp;
branches;
next	1.34;

1.34
date	95.12.11.20.19.45;	author rgmisra;	state Exp;
branches;
next	1.33;

1.33
date	95.12.11.19.54.18;	author rgmisra;	state Exp;
branches;
next	1.32;

1.32
date	95.12.11.16.41.44;	author daveg;	state Exp;
branches;
next	1.31;

1.31
date	95.12.11.15.45.00;	author daveg;	state Exp;
branches;
next	1.30;

1.30
date	95.12.11.13.24.54;	author hartmans;	state Exp;
branches;
next	1.29;

1.29
date	95.12.11.08.20.31;	author daveg;	state Exp;
branches;
next	1.28;

1.28
date	95.12.11.07.08.48;	author hartmans;	state Exp;
branches;
next	1.27;

1.27
date	95.12.10.10.16.47;	author hartmans;	state Exp;
branches;
next	1.26;

1.26
date	95.12.10.10.14.41;	author hartmans;	state Exp;
branches;
next	1.25;

1.25
date	95.12.10.09.55.10;	author hartmans;	state Exp;
branches;
next	1.24;

1.24
date	95.12.10.06.23.06;	author daveg;	state Exp;
branches;
next	1.23;

1.23
date	95.12.10.05.26.10;	author hartmans;	state Exp;
branches;
next	1.22;

1.22
date	95.12.10.00.48.53;	author daveg;	state Exp;
branches;
next	1.21;

1.21
date	95.12.08.03.17.02;	author jered;	state Exp;
branches;
next	1.20;

1.20
date	95.12.08.03.14.42;	author jered;	state Exp;
branches;
next	1.19;

1.19
date	95.12.07.23.43.35;	author hartmans;	state Exp;
branches;
next	1.18;

1.18
date	95.12.07.17.16.03;	author daveg;	state Exp;
branches;
next	1.17;

1.17
date	95.12.06.14.12.43;	author daveg;	state Exp;
branches;
next	1.16;

1.16
date	95.12.05.10.53.18;	author daveg;	state Exp;
branches;
next	1.15;

1.15
date	95.12.04.21.03.55;	author daveg;	state Exp;
branches;
next	1.14;

1.14
date	95.12.04.10.32.56;	author daveg;	state Exp;
branches;
next	1.13;

1.13
date	95.12.04.08.44.23;	author daveg;	state Exp;
branches;
next	1.12;

1.12
date	95.12.04.05.47.31;	author daveg;	state Exp;
branches;
next	1.11;

1.11
date	95.12.04.03.26.04;	author hartmans;	state Exp;
branches;
next	1.10;

1.10
date	95.12.04.02.44.12;	author daveg;	state Exp;
branches;
next	1.9;

1.9
date	95.12.04.02.29.45;	author hartmans;	state Exp;
branches;
next	1.8;

1.8
date	95.12.03.09.42.39;	author daveg;	state Exp;
branches;
next	1.7;

1.7
date	95.12.03.04.59.33;	author hartmans;	state Exp;
branches;
next	1.6;

1.6
date	95.12.03.01.17.15;	author hartmans;	state Exp;
branches;
next	1.5;

1.5
date	95.12.02.11.57.27;	author daveg;	state Exp;
branches;
next	1.4;

1.4
date	95.12.01.23.02.54;	author hartmans;	state Exp;
branches;
next	1.3;

1.3
date	95.11.25.00.47.09;	author daveg;	state Exp;
branches
	1.3.2.1;
next	1.2;

1.2
date	95.11.23.09.45.51;	author daveg;	state Exp;
branches;
next	1.1;

1.1
date	95.11.23.09.13.43;	author daveg;	state Exp;
branches;
next	;

1.3.2.1
date	95.11.28.01.43.10;	author daveg;	state Exp;
branches;
next	1.3.2.2;

1.3.2.2
date	95.11.30.10.26.18;	author daveg;	state Exp;
branches;
next	1.3.2.3;

1.3.2.3
date	95.12.01.04.53.15;	author daveg;	state Exp;
branches;
next	1.3.2.4;

1.3.2.4
date	95.12.01.13.58.10;	author daveg;	state Exp;
branches;
next	;


desc
@@


1.38
log
@fixed pawn promotion
@
text
@#include <6170.h>
#include <chess_display_board.h>
#include <ps5/url_ops.h>
#include <ps5/error_response.h>
#include <ctype.h>
#include <chess_capture_move.h>
#include <player.h>

typeinfo_t chess_display_board::typeinfo = new_typeinfo();

chess_display_board::~chess_display_board() {
}

chess_display_board::chess_display_board(istream &initial_format) :brd(8) {
    char ch;
    int x;
    square insertion;
    column temp(8);

    for(x=0;x<8;x++){
	brd.append(temp);
    }
    
    initialization_success= true;
    x=63;
    while((x>=0) && (initial_format.good()) && (initial_format >> ch)) {
	insertion= ctosquare(ch);
	if (insertion.piece_color==white)
	    white_pieces++;
	else if (insertion.piece_color==black)
	    black_pieces++;
	
	if ((x / 8 + x) % 2)
	    insertion.square_color = black;
	else
	    insertion.square_color = white;
	if (insertion.piece_type == invalid) {
	    initialization_success = false;
	    break;
	}
	insertion.square_type = normal;
	brd[x / 8].append(insertion);
	x--;
    }
    
    if (x != -1)
	initialization_success = false;
    
    if (!initialization_success){
	cerr << "Invalid board format\n";
	for(x=0;x<8;x++)
	    brd[x].clear();
	black_pieces = 0;
	white_pieces = 0;
	for(x=0;x<64;x++){
	    if ((x / 8 + x) % 2)
		insertion.square_color = black;
	    else
		insertion.square_color = white;
	    insertion.piece_type = none;
	    insertion.piece_color = blank;
	    insertion.square_type = normal;
	    brd[x / 8].append(insertion);
	}
    }
    total_pieces = white_pieces + black_pieces;
    player_turn = 0;
    brd_state_changed = true;
    square_selected = false;
}

chess_display_board::chess_display_board() : brd (8) {
    int x;
    square insertion;
    column temp(8);

    for(x=0;x<8;x++){
	brd.append(temp);
    }
    for(x=0;x<64;x++){
	if (x % 2)
	    insertion.square_color = black;
	else
	    insertion.square_color = white;
	insertion.piece_type = none;
	insertion.piece_color = blank;
	insertion.square_type = normal;
	brd[x / 8].append(insertion);
    }
    initialization_success= true;
    player_turn = 0;
    brd_state_changed = true;
    square_selected = false;
}

void chess_display_board::clone_part(chess_display_board &cb) const {
    cb.initialization_success = initialization_success;
    cb.brd_state_changed = brd_state_changed;
    cb.white_pieces = white_pieces;
    cb.black_pieces = black_pieces;
    cb.player_turn = player_turn;
    cb.square_selected = square_selected;
    cb.sel_col = sel_col;
    cb.sel_row = sel_row;
    cb.brd = brd;
}

int chess_display_board::pieces_remaining(int player_num) const{
    if (player_num==0)
	return white_pieces;
    else if (player_num==1)
	return black_pieces;
    else
	return -1;
}

void chess_display_board::place_piece(int x, int y, chess_piece piece, 
				      color piece_color) {
    check(((x>=0) && (x<=7)),"place_piece: x out of range");
    check(((y>=0) && (y<=7)),"place_piece: y out of range");
    square temp = brd[y][x];
    check(temp.piece_type == none,"place_piece: square isn't empty");
    temp.piece_type = piece;
    temp.piece_color = piece_color;
    if (piece_color==white)
	white_pieces++;
    else if (piece_color==black)
	black_pieces++;
    brd[y][x] = temp;
    brd_state_changed = true;
}

void chess_display_board::remove_piece(int x, int y){
    check((x>=0) && (x<=7),"remove_piece: x out of range");
    check((y>=0) && (y<=7),"remove_piece: y out of range");
    square temp = brd[y][x];
    check(temp.piece_type != none,"remove_piece: square is empty");
    if (temp.piece_color==white)
	white_pieces--;
    else if (temp.piece_color==black)
	black_pieces--;
    temp.piece_type = none;
    temp.piece_color = blank;
    brd[y][x] = temp;
    brd_state_changed = true;
}

void chess_display_board::move_piece(int x1, int y1, int x2, int y2,
				     bool promotion) {
    check((x1>=0) && (x1<=7),"move_piece: x out of range");
    check((y1>=0) && (y1<=7),"move_piece: y out of range");
    check((x2>=0) && (x2<=7),"move_piece: x out of range");
    check((y2>=0) && (y2<=7),"move_piece: y out of range");
    square sq1 = brd[y1][x1];
    check(sq1.piece_type != none,"move_piece: source square is empty");
    brd[y1][x1].piece_type = none;
    brd[y1][x1].piece_color = blank;
    square sq2 = brd[y2][x2];
    if (sq2.piece_type != none){
	if (sq2.piece_color==white)
	    white_pieces--;
	else if (sq2.piece_color==black)
	    black_pieces--;
    }	
    if (promotion && (sq1.piece_type==pawn)) 
	brd[y2][x2].piece_type = queen;
    else if (promotion && (sq1.piece_type != pawn))
	brd[y2][x2].piece_type = pawn;
    else
	brd[y2][x2].piece_type = sq1.piece_type;
    brd[y2][x2].piece_color = sq1.piece_color;
    player_turn = !player_turn;  // Because players are 0 and 1
    brd_state_changed = true;
    square_selected = false;
}

chess_display_board::square chess_display_board::ctosquare(char ch) const {
    square temp;
    
    switch(ch){
    case '-': temp.piece_type = none;
	temp.piece_color = blank;
	break;
    case 'p': temp.piece_type = pawn;
	temp.piece_color = black;
	break;	
    case 'r': temp.piece_type = rook;
	temp.piece_color = black;
	break;
    case 'n': temp.piece_type = knight;
	temp.piece_color = black;
	break;
    case 'b': temp.piece_type = bishop;
	temp.piece_color = black;
	break;
    case 'q': temp.piece_type = queen;
	temp.piece_color = black;
	break;
    case 'k': temp.piece_type = king;
	temp.piece_color = black;
	break;
    case 'P': temp.piece_type = pawn;
	temp.piece_color = white;
	break;
    case 'R': temp.piece_type = rook;
	temp.piece_color = white;
	break;
    case 'N': temp.piece_type = knight;
	temp.piece_color = white;
	break;
    case 'B': temp.piece_type = bishop;
	temp.piece_color = white;
	break;
    case 'Q': temp.piece_type = queen;
	temp.piece_color = white;
	break;
    case 'K': temp.piece_type = king;
	temp.piece_color = white;
	break;
    default: temp.piece_type = invalid;
	temp.piece_color = blank;
    }
    return temp;
}

char chess_display_board::squaretoc(square sq) const {
    switch(sq.piece_type){
    case none:
	return '-';
    case invalid:         // should never happen
	return '-';
    case pawn:
	if (sq.piece_color == black)
	    return 'p';
	else
	    return 'P';
    case rook:
	if (sq.piece_color == black)
	    return 'r';
	else
	    return 'R';
    case knight:
	if (sq.piece_color == black)
	    return 'n';
	else
	    return 'N';
    case bishop:
	if (sq.piece_color == black)
	    return 'b';
	else
	    return 'B';
    case queen:
	if (sq.piece_color == black)
	    return 'q';
	else
	    return 'Q';
    case king:
	if (sq.piece_color == black)
	    return 'k';
	else
	    return 'K';
    }
    return '-'; // default to turn off warning
}

void * chess_display_board::force (typeinfo_t &t) {
    if (t == typeinfo) return this;
    else return 0;
}

void chess_display_board::set_square(int x, int y, color square_color, 
				     square_t type) {
    check((x>=0) && (x<=7),"set_square: x out of range");
    check((y>=0) && (y<=7),"set_square: y out of range");    
    brd[y][x].square_color = square_color;
    brd[y][x].square_type = type;
    brd_state_changed = true;
}


void chess_display_board::save(ostream &out) const {
    int x,y;
    if (current_player() == 0)
	out <<"W\n";
    else out << "B\n";
    out<<get_game()->get_player(0)->get_time();
    out << " "<<get_game()->get_player(1)->get_time()<<endl;
    
    for(y=7;y>=0;y--){
	for(x=0;x<8;x++)
	    out << squaretoc(brd[y][x]);
	out << "\n";
    }    
}



bool chess_display_board::move_validity(int player_num, path &p, 
					chess_piece piece_taken) const {
    int x,xdiff, ydiff;
    int x_sign=1, y_sign=1;
    int dir;
        
    int x1 = p.x1;
    int x2 = p.x2;
    int y1 = p.y1;
    int y2 = p.y2;
    
    if ((x1<0)||(x1>7)||(x2<0)||(x2>7)||(y1<0)||(y1>7)||(y2<0)||(y2>7))
	return false;
    
    if ((x1==x2) && (y1==y2))
	return false;
    
    square from = brd[y1][x1];
    square to = brd[y2][x2];
    color c;
    
    if (player_num == 0){
	c = white;
	dir =1;
    }
    else{
	c = black;
	dir = -1;
    }	

    if ((from.piece_color != c) || (to.piece_color == c)|| 
	(piece_taken != to.piece_type))
	return false;
    
    xdiff = x2-x1;
    if (xdiff<0){
	x_sign = -1;
	xdiff = -xdiff;
    }
    
    ydiff = y2-y1;
    if (ydiff < 0){
	y_sign = -1;
	ydiff = -ydiff;
    }
    
    switch(from.piece_type){
    case invalid:  return false;  //this should never happen
    case none:     return false;
    case pawn:
	// Check for 1 forward, not capture
	if ((y2 == y1 +dir) && (x1 == x2)) 
	    if (brd[y1+dir][x1].piece_type == none)
		return true;

	// Check for moving 2 forward
	// There was already a check that x2,y2 was legal place to be
	if (y2 == y1+2*dir)
	    if ((x1 == x2) &&
		(to.piece_type == none) &&
		(brd[y1+dir][x2].piece_type == none))
		return true;
		
	// Check for captures
	if ((x2 == x1+1) || (x2==x1-1))
	    if (y2 == y1 + dir)
		if (to.piece_type != none)
		    return true;
	
	return false;
	break;
	
    case knight:
	if (((xdiff == 1) && (ydiff == 2)) ||
	    ((xdiff == 2) && (ydiff == 1)))
		return true;

	return false;
	break;
	
    case queen:
	if (xdiff == ydiff) {
	    for(x=1;x<=xdiff-1;x++)
		if (brd[y1+x*y_sign][x1+x*x_sign].piece_type != none)
		    return false;
	    return true;
	}	
	else if ((!xdiff && ydiff) ||
		 (!ydiff && xdiff)) {
	    if (xdiff){
		for(x=1;x<=xdiff-1;x++)
		    if (brd[y2][x1+x*x_sign].piece_type != none)
			return false;
	    }
	    else{
		for(x=1;x<=ydiff-1;x++)
		    if (brd[y1+x*y_sign][x1].piece_type != none)
			return false;
	    }
	    return true;
	}
	return false;
	break;
	
    case bishop:
	if (xdiff != ydiff)
	    return false;
	
	for(x=1;x<=xdiff-1;x++)
	    if (brd[y1+x*y_sign][x1+x*x_sign].piece_type != none)
		return false;
	return true;
	break;
	
    case rook:
	if (!((!xdiff && ydiff) || (!ydiff && xdiff)))
	    return false;
	
	if (xdiff){
	    for(x=1;x<=xdiff-1;x++)
		if (brd[y2][x1+x*x_sign].piece_type != none)
		    return false;
	}
	else{
	    for(x=1;x<=ydiff-1;x++)
		if (brd[y1+x*y_sign][x1].piece_type != none)
		    return false;
	}
	return true;
	break;
	
    case king:
	if ((xdiff >1) || (ydiff > 1))
	    return false;

	return true;
	break;
    }
    return false;
}


http_response * chess_display_board::get (string request, extensions *ext)
{
if (!is_associated())
    return new error_response(http_response::INTERNAL_ERROR,"Tried sending request to unassociated board--this is impossible!");

    string first ;
    if (unescape_uri(first_component(request),first) ) {
	if (first == "move") {
	    map <string,string> *q = parse_query(extract_query(request));
	    string sq1,sq2;
	    int x1,y1,x2,y2;
	    
	    if (q&&q->find("from", sq1)&&q->find("to",sq2)
		&&parse_square(sq1,y1,x1)&&parse_square(sq2,y2,x2)) {
		chess_capture_move m(x1, y1, x2, y2, this);
		string player_num_s;
		if (q&&!q->find("player", player_num_s))
		    return new error_response(http_response::BAD_REQUEST,"Requests to move must include a player number.");
		int pnum = atoi(player_num_s.get_chars());
		if (0 <= pnum < get_game()->players()) {
		    switch(get_game()->apply(m,pnum)) {
			    case game::move_invalid:
				get_game()->message(get_game()->get_player(pnum)->get_name()+
						    " made an invalid move.");
				break;
			    case game::game_already_done:
				get_game()->message("You can move after the game is over!");
				break;
		    default:
		    break;}	// OK is fine
		    
		    
		    return get_game()->display(ext, pnum);
		}
		else return new error_response(http_response::BAD_REQUEST,"Player number out of range");
	    }
	    else return new error_response(http_response::BAD_REQUEST, "Improper move specification.");
	}
	else if (first == "select") {
	    map <string, string> *q = parse_query(extract_query(request));
	    if  (!(q->contains("player")&&q->contains("square"))) 
		return new error_response(http_response::BAD_REQUEST, "A selection request must contain botha square and player");
	    int player_num = atoi(q->fetch("player").get_chars());
	    int row,column;
	    if (parse_square(q->fetch("square"),row,column)) {
		if ((player_num < 0)||(player_num > get_game()->players()))
		    return new error_response(http_response::BAD_REQUEST,"Player number out of range.");
		if (player_num == current_player()) {
		    square_selected = true;
		    sel_row = row;
		    sel_col = column;
		}
		else get_game()->message(get_game()->get_player(player_num)->
				       get_name()+" selected a square out of turn.");
		return get_game()->display(ext,player_num);
	    }
	    else return new error_response(http_response::BAD_REQUEST, "Couldn't find square and player number.");
	}
	else if (first == "dest") 
	    {
		map <string, string> *q = parse_query(extract_query(request));
		if  (!(q&&q->contains("player")&&q->contains("square"))) 
		    return new error_response(http_response::BAD_REQUEST, "A selection request must contain botha square and player");
		int player_num = atoi(q->fetch("player").get_chars());
		int row,column;
		if (parse_square(q->fetch("square"),row,column)) {
		    if ((player_num < 0)||(player_num > get_game()->players()))
			return new error_response(http_response::BAD_REQUEST,"Player number out of range.");
		    if (player_num == current_player()) {
			if (!square_selected)
			    return new error_response(http_response::BAD_REQUEST, "You can't dest a square until you select a source.");
			if ((column == sel_col)&&(row == sel_row)) {
			    get_game()->message("Deselected square at user request.");
			    square_selected = false;
			}
			else {
			    chess_capture_move m(sel_col,sel_row, column, row, this);
			    switch (get_game()->apply(m,player_num)) {
			    case game::move_invalid:
				get_game()->message(get_game()->get_player(player_num)->get_name()+
						    " made an invalid move.");
				break;
			    case game::game_already_done:
				get_game()->message("You can move after the game is over!");
				break;
			    default:
			    break;
			    }
			}
		    }
		    else get_game()->message(get_game()->get_player(player_num)->
					   get_name()+" selected a square out of turn.");
		    return get_game()->display(ext,player_num);
		}
		else return new error_response(http_response::BAD_REQUEST, "Couldn't find square and player number.");
	      }
	else if (first == "save")
	  {
	    map <string, string> *q = parse_query(extract_query(request));
	    if (!(q&&q->contains("file"))) return new error_response(http_response::BAD_REQUEST, "Must specify a file to save to.");
	    string filename = safeify_filename(q->fetch("file"));
	    ofstream strm;
	    strm.open(filename.get_chars());
//	    if (!(strm.good)) return new error_response(http_response::BAD_REQUEST, "File already exists.");
//	    else {
	    save(strm);
	    return new normal_response(true);
//	    }
	  }
	else			// additional request above this line
	  return new error_response(http_response::NOT_FOUND, "The requested operation was not found.");
      }
    else return new error_response(http_response::BAD_REQUEST,"Unable to decode escaped URI.");
}

bool parse_square (string square, int &row, int &col)
{
    if (square.length() !=2 )
	return false;
    switch(tolower(square[0])) {
    case 'a':
	col = 0; break;
    case 'b': col = 1; break;
    case 'c': col=2; break;
    case 'd': col = 3; break;
    case 'e': col = 4; break;
    case 'f': col = 5; break;
    case 'g': col = 6; break;
    case  'h': col = 7; break;
    default:
	return false;
    }
    if (('1' <= square[1])&&(square[1] <= '8')) {
	row =(int) (square[1]-'1');
	return true;
    }
    return false;
}

bool stomove(string s, chess_capture_move &m, const chess_display_board *b){
    int x1, x2, y1, y2;
    if (s.length() != 5)
	return false;
    if (!b)
	return false;
    
    if (!parse_square(s.substring(0,2), y1, x1))
	return false;
    if (!parse_square(s.substring(3,2), y2, x2))
	return false;

    chess_capture_move copied(x1,y1,x2,y2, b);
    m = copied;
    return true;
}
@


1.37
log
@bug fix
@
text
@d148 2
a149 1
void chess_display_board::move_piece(int x1, int y1, int x2, int y2) {
d165 1
a165 1
    if (((y2==0) || (y2==7)) && (sq1.piece_type == pawn))
d167 2
@


1.36
log
@bug fix
@
text
@d576 1
a576 1
bool stomove(string s, chess_capture_move &m, board *b){
d580 4
a583 2

    if (!parse_square(s.substring(0,2), x1, y1))
d585 1
a585 1
    if (!parse_square(s.substring(3,4), x2, y2))
d588 1
a588 6
    chess_display_board *cb =(chess_display_board *)
	b->force(chess_display_board::typeinfo);
    if (!cb)
	return false;
        
    chess_capture_move copied(x1,y1,x2,y2, cb);
@


1.35
log
@Fix off-by-one error in queens, rooks and bishops;
Dave please check this over.
@
text
@d583 1
a583 1
    if (!parse_square(s.substring(3,5), x2, y2))
@


1.34
log
@oops... I forgot to comment some stuff out
@
text
@d349 1
a349 1
		
d377 1
a377 1
	    for(x=1;x<xdiff-1;x++)
d385 1
a385 1
		for(x=1;x<xdiff-1;x++)
d390 1
a390 1
		for(x=1;x<ydiff-1;x++)
d403 1
a403 1
	for(x=1;x<xdiff-1;x++)
d414 1
a414 1
	    for(x=1;x<xdiff-1;x++)
d419 1
a419 1
	    for(x=1;x<ydiff-1;x++)
@


1.33
log
@save stuff...
@
text
@d541 4
a544 4
	    else {
	      save(strm);
	      return new normal_response(true);
	    }
@


1.32
log
@bug fix
@
text
@a524 1
			    
a525 1
		     
d532 12
d545 1
d547 2
a548 2
	    return new error_response(http_response::NOT_FOUND, "The requested operation was not found.");
    }
@


1.31
log
@bug fix
@
text
@d354 1
a354 1
		(to.piece_type != none) &&
d359 4
a362 4
	if (((x2 == x1+1) || (x2==x1-1)) &&
	    (y2 == y1 + dir))
 	    if (to.piece_type != none)
		return true;
@


1.30
log
@Fix move form at tottom of page.
@
text
@d315 1
a315 1

d353 2
a354 2
	    if ((x1 != x2) || 
		(to.piece_type != none) ||
d359 3
a361 2
	if ((x2 == x1+1) || (x2==x1-1))
	    if (to.piece_type != none)
@


1.29
log
@fixed square colors
@
text
@d449 1
a449 1
		&&parse_square(sq1,x1,y1)&&parse_square(sq2,x2,y2)) {
@


1.28
log
@Implement save correctly.
@
text
@d33 1
a33 1
	if (x % 2)
d53 2
d56 1
a56 1
	    if (x % 2)
d66 1
d438 1
a438 1
if (is_associated())
@


1.27
log
@Fix bugs preventing compilation
@
text
@d275 1
a275 1
void chess_display_board::save(ostream out) const {
d277 6
a282 1

@


1.26
log
@ouweoirj2u34oiu798fsdujdsa;dk
@
text
@@


1.25
log
@Web fixes
@
text
@d450 2
a451 2
				get_game()->message(get_game()->get_player(player_num)->get_name()+
						    " made an invalid move.")
d453 1
a453 1
			    case game::game_already_won:
d456 3
a458 1
		    }
d508 1
a508 1
						    " made an invalid move.")
d510 1
a510 1
			    case game::game_already_won:
d513 2
@


1.24
log
@bug fix
@
text
@d440 1
a440 1
	    if (q->find("from", sq1)&&q->find("to",sq2)
d444 1
a444 1
		if (!q->find("player", player_num_s))
d448 10
a457 1
		    get_game()->apply(m,pnum);
d487 1
a487 1
		if  (!(q->contains("player")&&q->contains("square"))) 
d503 10
a512 1
			    get_game()->apply(m,player_num);
@


1.23
log
@foo
@
text
@d151 1
a153 1
    check(sq1.piece_type != none,"move_piece: source square is empty");
@


1.22
log
@added stomove
@
text
@d534 1
a534 1
bool stomove(string s, chess_capture_move &m, board &b){
d545 1
a545 1
	b.force(chess_display_board::typeinfo);
@


1.21
log
@Fixed off-by-one in parse_square
@
text
@d533 20
@


1.20
log
@Fixed row/col swaps a display off-by-ones
@
text
@d527 2
a528 2
    if (('0' <= square[1])&&(square[1] <= '8')) {
	row =(int) (square[1]-'0');
@


1.19
log
@Only choke if we aren't associated
@
text
@d510 1
a510 1
bool parse_square (string square, int &col, int &row)
@


1.18
log
@and even more bug fixes
@
text
@d430 1
a430 1
if (!is_associated())
@


1.17
log
@bug fixes
@
text
@a290 1
    bool is_queen = false;
d321 1
a321 1
    xdiff = p.x2-p.x1;
d327 1
a327 1
    ydiff = p.y2-p.y1;
d367 23
a389 3
	is_queen = true;
	// Queen is a rook+bishop.  Thefore, just does fall_throgh

d394 1
a394 1
	for(x=0;x<xdiff-1;x++)
d398 1
a398 4
		
	// This is to deal with queen's fall through
	if (!is_queen)
	    break;
d401 1
a401 1
	if ( !((!xdiff && ydiff) || (!ydiff && xdiff)))
d405 1
a405 1
	    for(x=0;x<xdiff-1;x++)
d410 1
a410 1
	    for(x=0;x<ydiff-1;x++)
@


1.16
log
@a few more bug fixes
@
text
@d150 1
a150 1
    square temp = brd[y1][x1];
d153 4
a156 4
    check(temp.piece_type != none,"move_piece: source square is empty");
    square temp2 = brd[y2][x2];
    if (temp2.piece_type != none){
	if (temp2.piece_color==white)
d158 1
a158 1
	else if (temp2.piece_color==black)
d161 2
a162 2
    if (((y2==0) || (y2==7)) && (temp.piece_type == pawn))
	temp2.piece_type = queen;
d164 2
a165 3
	temp2.piece_type = temp.piece_type;
    temp2.piece_color = temp.piece_color;
    brd[y2][x2] = temp2;
d196 1
a196 1
    case 'P': temp.piece_type = rook;
@


1.15
log
@more bug fixes...
@
text
@d34 2
a36 2
	else
	    insertion.square_color = black;
d45 1
d55 2
a57 2
	    else
		insertion.square_color = black;
d79 2
a81 2
	else
	    insertion.square_color = black;
d140 1
d151 2
d161 2
a162 2
    if (((y2==0) || (y2==9)) && (temp.piece_type == pawn))
	brd[y2][x2].piece_type = queen;
d164 3
a166 2
	brd[y2][x2].piece_type = temp.piece_type;
    brd[y2][x2].piece_color = temp.piece_color;
d169 1
a169 2
square_selected = false;
    
d279 1
a279 1
    for(y=0;y<8;y++){
@


1.14
log
@bug fixes
@
text
@d45 1
a45 1
    if (x != 0)
@


1.13
log
@bug fixes
@
text
@d284 2
a285 3
bool chess_display_board::move_validity(int player_num, chess_piece piece, 
					color c, path &p) const {
    
d299 9
a307 1
    if (player_num==0)
d309 3
a311 1
    else 
d313 5
d331 1
a331 1
    switch(piece){
d336 2
a337 4
	if ((y2 == y1 +dir) && (x1 == x2)) {
	    if (brd[y1+dir][x1].piece_type != none)
		return false;
	    else
a338 1
	}
d342 1
a342 1
	if (y2 == y1+2*dir){
d344 2
a345 4
		(brd[y2][x2].piece_type != none) ||
		(brd[y1+dir][x2].piece_type != none))
		return false;
	    else 
a346 5
	}
	
	// if not 1 or 2 forward, definitely illegal
	if (y2 != y1 + dir)
	    return false;
d349 2
a350 4
	if ((x2 == x1+1) || (x2==x1-1)) {
	    if (brd[y2][x2].piece_type == none)
		return false;
	    else
d352 2
a353 1
	}
d358 1
a358 4
	    ((xdiff == 2) && (ydiff == 1))){
	    if (brd[y2][x2].piece_color == c)
		return false;
	    else
d360 2
a361 1
	}
d368 1
a368 1
    case rook:
a374 4
	
	if (brd[y2][x2].piece_color == c)
	    return false;
	
d381 1
a381 1
    case bishop:
a394 4
	
	if (brd[y2][x2].piece_color == c)
	    return false;
	
a395 1
	
a400 2
	if (brd[y2][x2].piece_color == c)
	    return false;
a402 1
	
@


1.12
log
@bug fixes and cloning stuff
@
text
@d25 2
a26 2
    x=0;
    while((x<64) && (initial_format.good()) && (initial_format >> ch)) {
d43 1
a43 1
	x++;
d45 1
a45 1
    if (x != 64)
d65 1
a65 1
square_selected = false;
@


1.11
log
@fixes
@
text
@d9 1
d11 2
a12 1
typeinfo_t chess_display_board::typeinfo = new_typeinfo();
d14 1
a14 1
chess_display_board::chess_display_board(istream &initial_format) {
d18 1
a18 1
    column temp;
a19 1
    brd.predict(8);
a21 1
	brd[x].predict(8);
d66 36
@


1.10
log
@bug fixes
@
text
@d5 3
d387 1
a387 1
    return new error_response(http_response::SERVER_ERROR,"Tried sending request to unassociated board--this is impossible!");
d415 1
a415 1
	    int player_num = atoi(q->fetch("player"));
d425 1
a425 1
		else get_game->message(get_game->get_player(player_num)->
d436 1
a436 1
		int player_num = atoi(q->fetch("player"));
d450 1
a450 1
			    get_game->apply(m,player_num);
d454 1
a454 1
		    else get_game->message(get_game->get_player(player_num)->
d483 1
a483 1
    if (('0' e<= square[1])&&(square[1] <= '8')) {
@


1.9
log
@Add select support to get
@
text
@d7 1
a7 1
chess_display_board::typeinfo = new_typeinfo();
d55 1
a55 1
	    insertion.piece_color = none;
d173 1
a173 1
	type.piece_color = blank;
d215 1
d233 1
a233 1
void save(ostream out) const {
d245 2
a246 1
bool chess_display_board::move_validity(chess_piece piece, color c, path &p) const {
a249 1
    bool is_legal = false;
d251 2
a252 1
    
d261 5
d377 1
@


1.8
log
@added promotion checking, and turn alternating
@
text
@d62 1
d125 2
d400 49
@


1.7
log
@Fix up get.
@
text
@d60 1
d117 4
a120 1
    brd[y2][x2].piece_type = temp.piece_type;
d122 1
d380 1
a380 1
int x1,y1,x2,y2;
d388 6
a393 6
	    int pnum = atoi(player_num_s.get_chars());
			    if (0 <= pnum < get_game()->players()) {
				get_game()->apply(m,pnum);
				return get_game()->display(ext, pnum);
			    }
			    else return new error_response(http_response::BAD_REQUEST,"Player number out of range");
@


1.6
log
@Add chess_display_board::get; add
new constructor to chess_capture_move for use by get.
@
text
@d367 3
@


1.5
log
@added save and squaretoc methods
@
text
@d1 1
d3 3
d365 53
@


1.4
log
@Integrate Antichess boarrd from DAVEG_CPD
@
text
@d166 39
d219 13
a231 1
// This needs to somehow get a direction (for pawns)
@


1.3
log
@added capture_piece
@
text
@d3 2
d10 1
a10 1
    
d21 5
d30 1
a30 1
	if (insertion.piece_type == invalid)
d32 2
d38 4
a41 1
    if (x != 64){
a42 1
	initialization_success = false;
d50 3
d56 1
a56 4
    
    if (initialization_success ==  false)
	for(x=0;x<64;x++)
	    brd[x/8][x%8].piece_type = none;
d59 7
a65 1
chess_display_board::~chess_display_board() {
d76 4
d81 1
d89 4
d95 1
d103 1
a103 4
    square temp = brd[y2][x2];
    check(temp.piece_type == none,
	  "move_piece: destination square isn't empty");
    temp = brd[y1][x1];
d105 7
a111 21
    brd[y2][x2].piece_type = temp.piece_type;
    brd[y2][x2].piece_color = temp.piece_color;
}

chess_display_board::chess_piece chess_display_board::capture_piece(int x1, 
								    int y1, 
								    int x2, 
								    int y2) {
    chess_pice rval;
    square temp;
    
    check((x1>=0) && (x1<=7),"capture_piece: x out of range");
    check((y1>=0) && (y1<=7),"capture_piece: y out of range");
    check((x2>=0) && (x2<=7),"capture_piece: x out of range");
    check((y2>=0) && (y2<=7),"capture_piece: y out of range");
    temp = brd[y2][x2];
    check(temp.piece_type != none,
	  "capture_piece: destination square is empty");
    rval = temp.piece_type;
    temp = brd[y1][x1];
    check(temp.piece_type != none,"capture_piece: source square is empty");
d114 1
a114 1
    return rval;
a116 1

d122 1
d160 2
a161 2
    default:
	temp.piece_type = invalid;
a165 1
// I still need to do this
d167 2
d177 130
d308 2
@


1.3.2.1
log
@test move validation code
@
text
@a2 2
chess_display_board::typeinfo = new_typeinfo();

d8 1
a8 1

d23 1
a23 1
	if (insertion.piece_type == invalid) {
a24 2
	    break;
	}
d29 2
a30 1
    if (x != 64)
a31 3
    
    if (!initialization_success){
	cerr << "Invalid board format\n";
a38 2
	    insertion.piece_type = none;
	    insertion.square_type = normal;
d42 4
d156 1
a157 2
    if (t == typeinfo) return this;
    else return 0;
a165 96
}

bool chess_display_board::move_validity(chess_piece piece, color c, path &p) const {
	 
    int x,xdiff, ydiff;
    int x_sign=1, y_sign=1;
    bool is_legal = false;
    bool is_queen = false;
    
    xdiff = p.x2-p.x1;
    if (xdiff<0)
	x_sign = -1;
    ydiff = p.y2-p.y1;
    if (ydiff < 0)
	y_sign = -1;
    
    switch(piece){
    case invalid:  return false;  //this should never happen
    case none:     return false;
    case pawn:
	for(x=0;x<pawn_list.length();x+=2){
	    if((abs(xdiff) == pawn_list[x]) && (abs(ydiff) ==pawn_list[x+1])){
		is_legal =true;
		
		// Check for 1 forward, not capture
//		if ((p.y2 == p.y1 +dir) && (x1 == x2))
//		    if (brd[y1+dir][x1].piece_type != none)
//			return false;
		
		// Check for moving 2 forward
		// There was already a check that x2,y2 was legal place to be
//		if (p.y2 == p.y1+2*dir){
//		    if ((x1 != x2) || 
//			(brd[y2][x2].piece_type != none) ||
//			(brd[y1+dir][x2].piece_type != none))
//			return false;
//		    else 
//			return true;
//		}
		
		// if not 1 or 2 forward, definitely illegal
//		if (p.y2 != p.y1 + dir)
//		    return false;
		
		// Check for captures
//		if (x2 == x1+1) {
//		    if (brd[y2][x2].piece_type == none)
//			return false;
//		}
	    }
	}
	break;
	
    case knight:
	if (((xdiff == 1) && (ydiff == 2)) ||
	    ((xdiff == 2) && (ydiff == 1)))
	    is_legal = true;
	break;
	
    case queen:
	is_queen = true;
	// Queen is a rook+bishop.  Thefore, just does fall_throgh

    case rook:
	for(x=0;x<rook_list.length();x+=2){
	    if((abs(xdiff) == rook_list[x]) && 
	       (abs(ydiff) == rook_list[x+1])){
		is_legal =true;
	    }
	}
	
	// This is to deal with queen's fall through
	if (!is_queen)
	    break;
	
    case bishop:
	for(x=0;x<bishop_list.length();x+=2){
	    if((abs(xdiff) == bishop_list[x]) && 
	       (abs(ydiff) == bishop_list[x+1])){
		is_legal =true;
		

	    }
	}
	break;
	
    case king:
	for(x=0;x<king_list.length();x+=2){
	    if((abs(xdiff) == king_list[x]) && 
	       (abs(ydiff) == king_list[x+1])){
		is_legal =true;
	    }
	}
	break;
    }
    return is_legal;
@


1.3.2.2
log
@updated headers
@
text
@a45 1
	    insertion.piece_color = none;
d80 4
a83 1
    square temp = brd[y1][x1];
d89 23
a116 1
	temp.piece_color = blank;
d154 2
a155 2
    default: temp.piece_type = invalid;
	type.piece_color = blank;
a172 1
// This needs to somehow get a direction (for pawns)
d174 1
a174 1
    
a179 8
    int x1 = p.x1;
    int x2 = p.x2;
    int y1 = p.y1;
    int y2 = p.y2;
    
    if ((x1<0)||(x1>7)||(x2<0)||(x2>7)||(y1<0)||(y1>7)||(y2<0)||(y2>7))
	return false;
    
d181 1
a181 1
    if (xdiff<0){
a182 3
	xdiff = -xdiff;
    }
    
d184 1
a184 1
    if (ydiff < 0){
a185 2
	ydiff = -ydiff;
    }
d191 19
a209 7
	// Check for 1 forward, not capture
	if ((y2 == y1 +dir) && (x1 == x2)) {
	    if (brd[y1+dir][x1].piece_type != none)
		return false;
	    else
		return true;
	}
d211 3
a213 14
	// Check for moving 2 forward
	// There was already a check that x2,y2 was legal place to be
	if (y2 == y1+2*dir){
	    if ((x1 != x2) || 
		(brd[y2][x2].piece_type != none) ||
		(brd[y1+dir][x2].piece_type != none))
		return false;
	    else 
		return true;
	}
	
	// if not 1 or 2 forward, definitely illegal
	if (y2 != y1 + dir)
	    return false;
d215 6
a220 6
	// Check for captures
	if ((x2 == x1+1) || (x2==x1-1)) {
	    if (brd[y2][x2].piece_type == none)
		return false;
	    else
		return true;
d226 2
a227 6
	    ((xdiff == 2) && (ydiff == 1))){
	    if (brd[y2][x2].piece_color == c)
		return false;
	    else
		return true;
	}
d235 6
a240 6
	if (xdiff != ydiff)
	    return false;
	
	for(x=0;x<xdiff-1;x++)
	    if (brd[y1+x*y_sign][x1+x*x_sign].piece_type != none)
		return false;
a241 5
	if (brd[y2][x2].piece_color == c)
	    return false;
	
	return true;
		
d247 7
a253 12
	if ( !((!xdiff && ydiff) || (!ydiff && xdiff)))
	    return false;
	
	if (xdiff){
	    for(x=0;x<xdiff-1;x++)
		if (brd[y2][x1+x*x_sign].piece_type != none)
		    return false;
	}
	else{
	    for(x=0;x<ydiff-1;x++)
		if (brd[y1+x*y_sign][x1].piece_type != none)
		    return false;
a254 6
	
	if (brd[y2][x2].piece_color == c)
	    return false;
	
	return true;
	
d258 6
a263 7
	if ((xdiff >1) || (ydiff > 1))
	    return false;
	if (brd[y2][x2].piece_color == c)
	    return false;

	return true;
	
d266 1
a267 2


@


1.3.2.3
log
@general clean up
@
text
@a20 5
	if (insertion.piece_color==white)
	    white_pieces++;
	else if (insertion.piece_color==black)
	    black_pieces++;
	
d53 1
a53 7
int chess_display_board::pieces_remaining(int player_num) const{
    if (player_num==0)
	return white_pieces;
    else if (player_num==1)
	return black_pieces;
    else
	return -1;
a63 4
    if (piece_color==white)
	white_pieces++;
    else if (piece_color==black)
	black_pieces++;
a71 4
    if (temp.piece_color==white)
	white_pieces--;
    else if (temp.piece_color==black)
	black_pieces--;
a82 7
    square temp2 = brd[y2][x2];
    if (temp2.piece_type != none){
	if (temp2.piece_color==white)
	    white_pieces--;
	else if (temp2.piece_color==black)
	    black_pieces--;
    }	
@


1.3.2.4
log
@finished evaluate
@
text
@a55 1
    brd_state_changed = true;
a79 1
    brd_state_changed = true;
a92 1
    brd_state_changed = true;
a110 1
    brd_state_changed = true;
a172 1
    brd_state_changed = true;
@


1.2
log
@fixed minor bug
@
text
@d85 23
@


1.1
log
@Version 0.9 of chess_display_board
@
text
@a15 1
    initial_format.eat_space();
@
