#include <antichess_board.h>

bool antichess_board::are_valid_move_available(int player_num, 
						bool check_turn) const {
    int x1, y1,x,y;
    bool is_queen = false;
    antichess_board *b = (antichess_board *) this;
    bool top_right_loop = true;
    bool top_left_loop = true;
    bool bottom_right_loop = true;
    bool bottom_left_loop = true;
    int dir;
    
    if (check_turn && (player_num != current_player()))
	return false;
     
    if (pieces_remaining(player_num) == 0)
	return false;
    
    color capture_color, this_color;
    if (player_num==0){
	capture_color = black;
	this_color = white;
	dir = 1;
    }
    else if (player_num==1){
	capture_color = white;
	this_color = black;
	dir = -1;
    }
    else
	check(player_num==1,"Invalid player");
        
    for(y1=0;y1<8;y1++)
	for(x1=0;x1<8;x1++){
	    
	    if (b->fetch(y1,x1).piece_color != this_color)
		continue;

	    is_queen = false;
	    
	    switch(b->fetch(y1,x1).piece_type){
	    case invalid:  break;  //this should never happen
	    case none:     break;
	    case pawn:
		// Check for 1 forward, not capture
		if ((y1+dir < 8) && (y1 +dir >=0) &&
		    (b->fetch(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 (((y1==1) && (this_color==white)) ||
		     ((y1==6) && (this_color==black)))
		    if ((y1+2*dir < 8) && (y1 +2*dir >=0) &&
			(b->fetch(y1+dir,x1).piece_type == none) &&
			(b->fetch(y1+2*dir,x1).piece_type == none)){
			return true;
		    }
		
		// Check for captures
		if ((y1+dir < 8) && (y1+dir>=0) && (x1+1 < 8) &&
		    (b->fetch(y1+dir,x1+1).piece_color == capture_color)){
		    return true;
		}
		if ((y1+dir < 8) && (y1+dir>=0) && (x1-1 >= 0) &&
		(b->fetch(y1+dir,x1-1).piece_color == capture_color)){
		    return true;
		}
		break;
		
	    case knight:
		if ((y1+2 < 8) && (x1+1 < 8) &&
		    (b->fetch(y1+2,x1+1).piece_color != this_color)){
		    return true;
		}
		if ((y1+2 < 8) && (x1-1 >= 0) &&
		    (b->fetch(y1+2,x1-1).piece_color != this_color)){
		    return true;
		}
		if ((y1-2 >=0) && (x1+1 <8) &&
		    (b->fetch(y1-2,x1+1).piece_color != this_color)){
		    return true;
		}
		if ((y1-2 >= 0) && (x1-1 >= 0) &&
		    (b->fetch(y1-2,x1-1).piece_color != this_color)){
		    return true;
		}
		if ((y1+1 < 8) && (x1+2 <8) &&
		    (b->fetch(y1+1,x1+2).piece_color != this_color)){
		    return true;
		}
		if ((y1-1 >= 0) && (x1+2 <8) &&
		    (b->fetch(y1-1,x1+2).piece_color != this_color)){
		    return true;
		}
		if ((y1+1 < 8) && (x1-2 >= 0) &&
		    (b->fetch(y1+1,x1-2).piece_color != this_color)){
		    return true;
		}
		if ((y1-1 >= 0) && (x1-2 >= 0) &&
		    (b->fetch(y1-1,x1-2).piece_color != this_color)){
		    return true;
		}
		break;
		
	    case queen:
		is_queen =true;
		// then fall through: queen = rook+bishop		
	    case rook:
		for(x=x1+1;x<8;x++){
		    if (b->fetch(y1,x).piece_type == none)
			return true;
		    else {
			if (b->fetch(y1,x).piece_color == capture_color)
			    return true;
			break;
		    }
		}

		for(x=x1-1;x>=0;x--){
		    if (b->fetch(y1,x).piece_type == none)
			return true;
		    else {
			if (b->fetch(y1,x).piece_color == capture_color)
			    return true;
			break;
		    }
		}

		for(x=y1+1;x<8;x++){
		    if (b->fetch(x,x1).piece_type == none)
			return true;
		    else {
			if (b->fetch(y1,x).piece_color == capture_color)
			    return true;
			break;
		    }
		}

		for(x=y1-1;x>=0;x--){
		    if (b->fetch(x,x1).piece_type == none)
			return true;
		    else {
			if (b->fetch(y1,x).piece_color == capture_color)
			    return true;
			break;
		    }
		}
		
		if (!is_queen)
		    break;
		
	    case bishop:
		
		for(x=1;x<8;x++){

		    if (top_right_loop && (x1+x<8) && (y1+x<8)) {
			if (b->fetch(y1+x,x1+x).piece_type == none)
			    return true;
			else if (b->fetch(y1+x,x1+x).piece_color == 
				  capture_color)
			    return true;
			else
			    top_right_loop = false;
		    }
		    
		    if (bottom_right_loop && (x1+x<8) && (y1-x>=0)){
			if (b->fetch(y1-x,x1+x).piece_type == none)
			    return true;
			else if (b->fetch(y1-x,x1+x).piece_color == 
				 capture_color)
			    return true;
			else
			    bottom_right_loop = false;
		    }
		    
		    if (top_left_loop && (x1-x>=0) && (y1+x<8)){
			if (b->fetch(y1+x,x1-x).piece_type == none)
			    return true;
			else if (b->fetch(y1+x,x1-x).piece_color == 
				 capture_color)
			    return true;
			else
			    top_left_loop = false;
		    }

		    if (bottom_left_loop && (x1-x>=0) && (y1-x>=0)){
			if (b->fetch(y1-x,x1-x).piece_type == none)
			    return true;
			else if (b->fetch(y1-x,x1-x).piece_color == 
				 capture_color)
			    return true;
			else
			    bottom_left_loop = false;
		    }
		}
		break;
		
	    case king:
		for(y=y1-1;y<=y1+1;y++)
		    for(x=x1-1;x<=x1+1;x++){
			if (((x==x1) && (y==y1)) ||
			    (y < 0) ||
			    (y > 7) ||
			    (x < 0) ||
			    (x > 7))
			    continue;
			if (b->fetch(y,x).piece_color != this_color){
			    return true;
			}
		    }
		break;
	    }
	}
    return false;
}

