//returns if player with val has some valid move in this configuration
bool Alex_Ayerdi::has_valid_move(int val) {
	for(int i=0; i<8;i++)
		for(int j=0; j<8; j++)
			if(move_is_valid(i+1, j+1, val))
				return true;
	return false;
}
Esempio n. 2
0
move_t *fullalg_to_move(board_t *board, char *move_s)
{
    move_t *move;

    if ((strlen(move_s) < 4) || (strlen(move_s) > 5))
        return NULL;
    if ((move_s[0] < 'a') || (move_s[0] > 'h'))
        return NULL;
    if ((move_s[1] < '1') || (move_s[1] > '8'))
        return NULL;
    if ((move_s[2] < 'a') || (move_s[2] > 'h'))
        return NULL;
    if ((move_s[3] < '1') || (move_s[3] > '8'))
        return NULL;
    if ((strlen(move_s) == 5) && (move_s[4] != 'n')
            && (move_s[4] != 'b') && (move_s[4] != 'r')
            && (move_s[4] != 'q'))
        return NULL;

    move = (move_t *) malloc(sizeof(move_t));
    move->source = move_s[0] - 'a' + (move_s[1] - '1') * 8;
    move->destination = move_s[2] - 'a' + (move_s[3] - '1') * 8;

    if (strlen(move_s) == 5)
    {
        switch (move_s[4])
        {
        case 'n':
            move->promotion_piece = KNIGHT;
            break;
        case 'b':
            move->promotion_piece = BISHOP;
            break;
        case 'r':
            move->promotion_piece = ROOK;
            break;
        case 'q':
            move->promotion_piece = QUEEN;
        }
        move->promotion_piece += board->turn;
    }
    else
        move->promotion_piece = NONE;

    if (!move_is_valid(board, move))
    {
        free(move);
        return NULL;
    }

    move_set_attr(board, move);

    return move;
}
//executes move if it is valid.  Returns false and does not update Alex_Ayerdi otherwise
bool Alex_Ayerdi::play_square(int row, int col, int val) {
	
	if(!move_is_valid(row, col, val))
		return false;
	squares[row-1][col-1] = val;
	for(int rinc = -1; rinc <= 1; rinc++)
		for(int cinc = -1; cinc <= 1; cinc++) {
			check_or_flip_path(row-1, col-1, rinc, cinc, val, true);
		}
	return true;
}
/* This function ask a moves, save it, apply it and return 0 if the game is finish (won or tie) */
int next_move(struct game *myGame){
    struct move currMove;
    /* this is need for game_state_transtiction */
//    struct state s1;
    printf("Player: %c\n", myGame->players[myGame->current_player]);
    /* continue to ask until the move is correct */
    while(!move_is_valid(myGame, &currMove));
    game_update(myGame, &currMove);
//    game_state_transition(&myGame->state, &currMove, &s1, myGame);
    /* update the moves history */
//    TODO this can be used as history replay mode
//    if(update_moves(&currMove) !=0)
//        return 1;
    /* print the table */
    game_print(myGame);
    /* check if there is a winner or it is tie */
    return is_finish(myGame, &currMove);
}
Esempio n. 5
0
static int is_mated(board_t *board, int side)
{
    int src, dest;
    move_t move;

    for (src = 0; src < 64; src++)
        if (COLOUR(board->square[src]) == side)
            for (dest = 0; dest < 64; dest++)
            {
                move.source = src;
                move.destination = dest;
                if ((PIECE(board->square[src]) == PAWN) && ((dest < 8) || (dest >= 56)))
                    move.promotion_piece = QUEEN + side;
                else
                    move.promotion_piece = NONE;
                if (move_is_valid(board, &move))
                    return 0;
            }
    return 1;
}
Esempio n. 6
0
static move_t *find_unique_move(board_t *board, san_move_t *san_move)
{
    int square;
    int piece;
    int found = 0;
    move_t move, *retval;

    if (san_move->type == SAN_QUEENSIDE_CASTLE)
    {
        san_move->source_file = 4;
        san_move->source_rank = (board->turn == WHITE ? 0 : 7);
        san_move->destination = (board->turn == WHITE ? 2 : 58);
        piece = KING;
    }
    else if (san_move->type == SAN_KINGSIDE_CASTLE)
    {
        san_move->source_file = 4;
        san_move->source_rank = (board->turn == WHITE ? 0 : 7);
        san_move->destination = (board->turn == WHITE ? 6 : 62);
        piece = KING;
    }
    else
        piece = ui_piece(san_move->piece);

    piece += board->turn;

    for (square = 0; square < 64; square++)
    {
        move_t m;

        if (board->square[square] != piece)
            continue;

        /* We found a piece. */

        if (san_move->source_file != SAN_NOT_SPECIFIED)
            if (san_move->source_file != square % 8)
                continue;

        if (san_move->source_rank != SAN_NOT_SPECIFIED)
            if (san_move->source_rank != square / 8)
                continue;

        m.source = square;
        m.destination = san_move->destination;
        m.promotion_piece = ui_piece(san_move->promotion_piece);

        if (m.promotion_piece != NONE)
            m.promotion_piece += board->turn;

        if (move_is_valid(board, &m))
        {
            move = m;
            found++;
            if (found > 1)
                return NULL;
        }
    }

    if (!found)
    {
        DBG_ERROR("failed to find a legal move corresponding to SAN move");
        return NULL;
    }

    retval = (move_t *) malloc(sizeof(move_t));
    *retval = move;
    return retval;
}
int Alex_Ayerdi::eval(int cpuval) { // originally used score, but it led to bad ai
					// instead we evaluate based maximizing the
					// difference between computer's available move count
					// and the player's. Additionally, corners will be
					// considered as specially beneficial since they cannot ever be
					// flipped.

	int score = 0; // evaluation score

	// count available moves for computer and player
	int mc = 0; int mp = 0;
	for (int i=1; i<9;i++) {
		for (int j=1; j<9; j++) {
			if (move_is_valid(i, j, cpuval))
				mc++;
			if (move_is_valid(i, j, -1*cpuval))
				mp++;
		}
	}

	// add the difference to score (scaled)
	score += 20*(mc - mp); // the number is just some scale determined through playing
	//score += 7*mc;

	/*
	// additionally, if mp is 0 this is real good so add some more points,
	// and if mc is 0 this is real bad so subtract more points
	// because of skipped turns

	if (mp == 0)
		score += 50;
	if (mc == 0)
		score -= 50;
	*/

	// count corners for computer and player
	int cc = 0; int cp = 0;
	if (get_square(1, 1) == cpuval)
		cc++;
	else if (get_square(1, 1) == -1*cpuval)
		cp++;

	if (get_square(1, 8) == cpuval)
		cc++;
	else if (get_square(1, 8) == -1*cpuval)
		cp++;

	if (get_square(8, 1) == cpuval)
		cc++;
	else if (get_square(8, 1) == -1*cpuval)
		cp++;

	if (get_square(8, 8) == cpuval)
		cc++;
	else if (get_square(8, 8) == -1*cpuval)
		cp++;

	// add the difference to score (scaled)
	score += 200*(cc - cp);

	/*
	// squares adjacent to corners on edges also useful, but not as much since it could lead to a corner
	int ac = 0; int ap = 0;
	if (get_square(1, 2) == cpuval)
		ac++;
	else if (get_square(1, 2) == -1*cpuval)
		ap++;
	if (get_square(2, 1) == cpuval)
		ac++;
	else if (get_square(2, 1) == -1*cpuval)
		ap++;

	if (get_square(1, 7) == cpuval)
		ac++;
	else if (get_square(1, 7) == -1*cpuval)
		ap++;
	if (get_square(2, 8) == cpuval)
		ac++;
	else if (get_square(2, 8) == -1*cpuval)
		ap++;

	if (get_square(7, 1) == cpuval)
		ac++;
	else if (get_square(7, 1) == -1*cpuval)
		ap++;
	if (get_square(8, 2) == cpuval)
		ac++;
	else if (get_square(8, 2) == -1*cpuval)
		ap++;

	if (get_square(7, 8) == cpuval)
		ac++;
	else if (get_square(7, 8) == -1*cpuval)
		ap++;
	if (get_square(8, 7) == cpuval)
		ac++;
	else if (get_square(8, 7) == -1*cpuval)
		ap++;

	score += 30*(ac - ap);

	// scale so bigger depths are worth more
	score += 10*depth;

	*/

	// limit the amount of space around our pieces so we don't surround as much (which leads to big gains endgame for opponent)
	int sc = 0; int sp = 0; // counts for open spaces neighboring a player/comp's pieces
	for (int i=1; i<9;i++) {
		for (int j=1; j<9; j++) {
			if (get_square(i, j) == cpuval) {
				//add count to sc
				sc += free_neighbors(i, j);
			}
			if (get_square(i, j) == -1*cpuval) {
				//add count to sp
				sp += free_neighbors(i, j);
			}
		}
	}

	score -= 10*(sc - sp); // subtract because we are trying to minimize it
	return score;
}
Esempio n. 8
0
static int do_move(move_t *move, int ui_update) {
	char *move_s, *move_f, *move_san;
	board_t new_board;

	if (!move_is_valid(history->last->board, move)) {
		DBG_WARN("Move is illegal");
		return 0;
	}

	move_set_attr(history->last->board, move);
	new_board = *history->last->board;
	move_s = move_to_fullalg(&new_board, move);
	move_list_play(&fullalg_list, move_s);

	move_san = move_to_san(&new_board, move);
	move_f = san_to_fan(&new_board, move_san);

	DBG_LOG("Processing move %s (%s)", move_s, move_san);

	move_list_play(&san_list, move_san);
	move_list_play(&fan_list, move_f);

	free(move_san);
	free(move_f);
	free(move_s);

	make_move(&new_board, move);

	if (move->state == MOVE_CHECK)
		new_board.state = BOARD_CHECK;
	else if (move->state == MOVE_CHECKMATE)
		new_board.state = BOARD_CHECKMATE;
	else
		new_board.state = BOARD_NORMAL;

	history_play(history, move, &new_board);

	if (ui_update)
		ui->update(history->view->board, move);

	if (new_board.state == MOVE_CHECKMATE) {
		history->result = malloc(sizeof(result_t));

		if (new_board.turn == WHITE) {
			history->result->code = RESULT_BLACK_WINS;
			history->result->reason = strdup("Black mates");
		} else {
			history->result->code = RESULT_WHITE_WINS;
			history->result->reason = strdup("White mates");
		}

		if (ui_update)
			ui->show_result(history->result);
	} else if (new_board.state == MOVE_STALEMATE) {
		history->result = malloc(sizeof(result_t));

		history->result->code = RESULT_DRAW;
		history->result->reason = strdup("Stalemate");

		if (ui_update)
			ui->show_result(history->result);
	}

	return 1;
}