/* 返回true 为树高旋转后未更改,返回false,为树高降低 */ static AR_INLINE bool_t __rotate_twice(avlNode_t *node, avlNode_t **proot, avlDir_t dir) { AR_ASSERT(node != NULL && proot != NULL && *proot != NULL); AR_ASSERT(node->child[OPPOSITE(dir)] != NULL); __rotate_once(node->child[OPPOSITE(dir)], proot, OPPOSITE(dir)); __rotate_once(node, proot, dir); return true; }
int legalDirect(int x, int y, int xoffest, int yoffset, int flag, int who) { int oppo = OPPOSITE(who); x += xoffest; y += yoffset; if (x < 0 || x >= 8 || y < 0 || y >= 8)// 超出棋盘范围 { return 0; } if (board[x][y] == oppo) { /* (x,y)某个方向的有相邻的对手棋子,继续检查这个方向是否 * 可以吃对方子,递归调用 */ flag = 1; return legalDirect(x, y, xoffest, yoffset, flag, who); } else if (board[x][y] == who) { /* 遇到自己的棋子,判断这个方向之前的棋子是否全为反方的即 legal=1*/ return flag; } else return 0; return 0; }
void optimize(char *code, int options) { unsigned int i, j; /* We're calling strlen here because it is brought up more than once in the code below */ unsigned int len = strlen(code); /* We're only setting options to know if we need to optimize debug symbols */ SET_OPTIONS_VARIABLE(options); /* Return if code is empty string */ if (len == 0) return; /* Loop through code and add the OK characters */ for (i = 0, j = 0; i < len; i++) { /* Add pairless valid characters */ if (i < (len - 2) && code[i] == OPPOSITE(code[i + 1])) { /* Skip next character */ i += 1; } else if (VALID_CHAR(code[i])) { /* Add character */ code[j] = code[i]; j++; } } /* Add null terminator */ code[j] = '\0'; /* Recurse */ if (len != j) { optimize(code, options); } }
char* StringMoveHistory(MemorySlice *history, bool abbrev) { Move move; Memory *curr; Side side = White; StringBuilder builder = NewStringBuilder(); int fullMoveCount = 1; for(curr = history->Vals; curr != history->Curr; curr++) { move = curr->Move; if(abbrev) { AppendString(&builder, "%s ", StringMove(move)); } else { switch(side) { case White: AppendString(&builder, "%d. %s", fullMoveCount, StringMove(move)); break; case Black: AppendString(&builder, " %s\n", StringMove(move)); fullMoveCount++; break; } } side = OPPOSITE(side); } return builder.Length == 0 ? NULL : BuildString(&builder, true); }
/* **AI的核心,得到当前走法的权重 */ int weigh_move(int x, int y, int who, int max_depth, int add) { int bottom, top, i, move_weight = 0, depth_weight = 0, temp; bottom = flips_next; make_move(x, y, who); top = flips_next; for (i = bottom; i < top; ++i) move_weight += (add ? 1 : (-1)) * weight[flips_x[i]][flips_y[i]]; if (max_depth && empties()) { who = OPPOSITE(who); add = !add; bottom = moves_next; get_all(who); top = moves_next; for(i = bottom; i < top; ++i) { temp = weigh_move(moves_x[i], moves_y[i], who, max_depth - 1, add); if(temp < depth_weight) depth_weight = temp; } unget_all(); } undo_move(); return move_weight + depth_weight; }
int solution_piece_matches_edge(solution_t* s, piece_t* p, int pos) { int r,c,m=0; dir edge_dir; dir d; piece_t*** mat; int colA,colB; r=pos/(s->n); c=pos%(s->n); mat=s->mat; if (p==NULL) { p=mat[r][c]; } edge_dir=direction_edge(pos,s->n); for(d=DOWN;d<=RIGHT;d++) { if (d!=edge_dir) { colA=PIECE_COLOUR(p,d); //colA=squares[p->square_index]->colour[ROTATE(p->rotation,d)]; colB=PIECE_COLOUR(mat[r+ADJACENT[d*2]] [c+ADJACENT[d*2+1]],OPPOSITE(d)); /*colB=squares[mat[r+ADJACENT[d*2]][c+ADJACENT[d*2+1]]->square_index]->colour [ROTATE(mat[r+ADJACENT[d*2]][c+ADJACENT[d*2+1]]->rotation, (d+2)%4)];*/ if (colA==colB) m++; } } return (m); }
static AR_INLINE void __rotate_node(avlNode_t *node, avlNode_t **proot, avlDir_t dir) { avlNode_t *tmp; AR_ASSERT(node != NULL && proot != NULL && *proot != NULL); AR_ASSERT(node->child[OPPOSITE(dir)] != NULL); tmp = node->child[OPPOSITE(dir)]; node->child[OPPOSITE(dir)] = tmp->child[dir]; if(node->child[OPPOSITE(dir)] != NULL)node->child[OPPOSITE(dir)]->parent = node; tmp->child[dir] = node; tmp->parent = node->parent; if(node == *proot) { *proot = tmp; }else if(node == node->parent->child[AVL_LEFT]) { node->parent->child[AVL_LEFT] = tmp; }else { node->parent->child[AVL_RIGHT] = tmp; } node->parent = tmp; if(dir == AVL_LEFT) { /* NewBal(A) = OldBal(A) - 1 - max (OldBal(B), 0) NewBal(B) = OldBal(B) - 1 + min(NewBal(A), 0) */ node->bf = node->bf - 1 - AR_MAX(tmp->bf, 0); tmp->bf = tmp->bf - 1 + AR_MIN(node->bf, 0); }else { /* NewBal(A) = OldBal(A) + 1 - min(OldBal(B), 0) NewBal(B) = OldBal(B) + 1 + max(NewBal(A), 0) */ node->bf = node->bf + 1 - AR_MIN(tmp->bf, 0); tmp->bf = tmp->bf + 1 + AR_MAX(node->bf, 0); } }
void undo_move(void) { int i, who, top = flips_next; flips_next -= flips_stack_block[--flips_stack_next]; board[flips_x[flips_next]][flips_y[flips_next]] = 0; who = OPPOSITE(flips_stack_who[flips_stack_next]); for(i = flips_next + 1; i < top; i++) board[flips_x[i]][flips_y[i]] = who; }
char* StringBitBoard(BitBoard bitBoard) { const int LINE_LENGTH = 36; const int LINE_COUNT = 18; // TODO: Reduce duplication from StringChessSet. // Include space for newlines. char ret[LINE_LENGTH * LINE_COUNT + 1 + 1000]; int file, offset, rank; Position pos; Side lineSide = Black; char *topLine = " A B C D E F G H \n"; char *dottedLine = " ---------------------------------\n"; char *blackLine = " | |...| |...| |...| |...|\n"; char *whiteLine = " |...| |...| |...| |...| |\n"; // Add top lines. strncpy(ret, topLine, LINE_LENGTH); strncpy(ret+LINE_LENGTH, dottedLine, LINE_LENGTH); for(rank = Rank8; rank >= Rank1; rank--) { offset = 2*LINE_LENGTH + 2*LINE_LENGTH*(Rank8-rank); // Add line. strncpy(ret + offset, lineSide == White ? whiteLine : blackLine, LINE_LENGTH); // Add number. ret[offset] = '1'+rank; // Add pieces. // For the sake of debugging, avoid PieceAt() in case it is buggy. offset += 4; for(file = FileA; file <= FileH; file++) { pos = POSITION(rank, file); if((bitBoard&POSBOARD(pos)) == POSBOARD(pos)) { ret[offset] = 'X'; } offset += 4; } // Add dotted line. strncpy(ret + offset, dottedLine, LINE_LENGTH); lineSide = OPPOSITE(lineSide); } ret[LINE_LENGTH * LINE_COUNT] = '\0'; return strdup(ret); }
/* 返回true 为树高旋转后未更改,返回false,为树高降低 */ static AR_INLINE bool_t __rotate_once(avlNode_t *node, avlNode_t **proot, avlDir_t dir) { bool_t height_changed = true; AR_ASSERT(node != NULL && proot != NULL && *proot != NULL); if(node->child[OPPOSITE(dir)]->bf == 0)height_changed = false; __rotate_node(node, proot, dir); return height_changed; }
int move_matches_diff_inner(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2, *p1_old, *p2_old; dir d; p1=piece_new(move->square_index1,move->rotation1); p2=piece_new(move->square_index2,move->rotation2); //rotation of the same piece //p1==p2 if it is the same piece if (move->pos1==move->pos2) { tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos1) + solution_piece_matches_inner(s, p1, move->pos1); } else { //non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos1) - solution_piece_matches_inner(s,NULL,move->pos2); //new pieces matches are added tot+=solution_piece_matches_inner(s, p1, move->pos1) + solution_piece_matches_inner(s,p2, move->pos2); d=is_adjacent(move->pos2,move->pos1,s->n); //swap_pos->other_pos //adjacent swap if (d!=NONE) { p1_old=s->mat[(move->pos2)/(s->n)][(move->pos2)%(s->n)]; p2_old=s->mat[(move->pos1)/(s->n)][(move->pos1)%(s->n)]; if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) //the match has been subtracted twice tot++; //to avoid counting matches with the previous version of themselves if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) tot--; if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) ) tot--; //to count the match between the new versions if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) ) tot++; } } piece_free(p1); piece_free(p2); return(tot); }
int move_matches_diff_inner(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2, *p1_old, *p2_old; dir d; p1=s->mat[1][1]; p2=piece_new(move->square_index,move->rotation); //rotation of the first piece if (s->n+1==move->pos) { tot=s->matches - solution_piece_matches_inner(s,NULL,s->n+1) + solution_piece_matches_inner(s, p2, s->n+1); } else { //non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos) - solution_piece_matches_inner(s,NULL,s->n+1); //new pieces matches are added tot+=solution_piece_matches_inner(s, p2, s->n+1) + solution_piece_matches_inner(s,p1, move->pos); d=is_adjacent(s->n+1,move->pos,s->n); //adjacent swap if (d!=NONE) { p1_old=p1; p2_old=s->mat[(move->pos)/(s->n)][(move->pos)%(s->n)]; if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) //the match has been subtracted twice tot++; //to avoid counting matches with the previous version of themselves if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) tot--; if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) ) tot--; //to count the match between the new versions if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) ) tot++; } } //piece_free(p1); //placeholder for enhanced versions piece_free(p2); return(tot); }
int move_matches_diff_edge(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2, *p1_old, *p2_old; dir d; d=direction_edge(move->pos,s->n); p1=piece_new(s->mat[0][1]->square_index,square_rotate_edge(squares[s->mat[0][1]->square_index],d)); p2=piece_new(move->square_index,move->rotation); //non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_edge(s,NULL,move->pos) - solution_piece_matches_edge(s,NULL,1); //new pieces matches are added tot+=solution_piece_matches_edge(s,p2,1) + solution_piece_matches_edge(s,p1,move->pos); d=is_adjacent(1,move->pos,s->n); //adjacent swap if (d!=NONE) { p1_old=s->mat[0][1]; p2_old=s->mat[(move->pos)/(s->n)][(move->pos)%(s->n)]; if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) //the match has been subtracted twice tot++; //to avoid counting matches with the previous version of themselves if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) tot--; if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) ) tot--; //to count the match between the new versions if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) ) tot++; } piece_free(p1); piece_free(p2); return(tot); }
/* **走这一步 */ void make_move(int x, int y, int who) { int dx, dy, i, j, opp = OPPOSITE(who); board[x][y] = who; flips_x[flips_next] = x; flips_y[flips_next] = y; flips_next++; flips_stack_block[flips_stack_next] = 1; flips_stack_who[flips_stack_next] = who; for(dx = -1; dx < 2; dx++) for(dy = -1; dy < 2; dy++) { i = x + dx; j = y + dy; /* branch in each direction */ if((dx || dy) && VALID_CELL(i, j) && board[i][j] == opp) { do { i += dx; j += dy; } while(VALID_CELL(i, j) && (board[i][j] == opp)); /* if this direction is to be flipped */ if(VALID_CELL(i, j) && (board[i][j] == who)) { i -= dx; j -= dy; /* go back and flip each piece */ while(board[i][j] == opp) { board[i][j] = who; flips_x[flips_next] = i; flips_y[flips_next] = j; flips_next++; flips_stack_block[flips_stack_next]++; i -= dx; j -= dy; }; } } } flips_stack_next++; }
void setup_routing_tables(uint my_x, uint my_y, uint cores_per_chip) { uint entry; uint xyz[3] = { XY_TO_MIN_X(my_x,my_y), XY_TO_MIN_Y(my_x,my_y), XY_TO_MIN_Z(my_x,my_y) }; // Add entries to multicast out nearest-neighbour messages from this chip ADD_RTR_ENTRY( NEAREST_NEIGHBOUR_KEY(XY_TO_COLOUR(my_x,my_y), 0) , NEAREST_NEIGHBOUR_KEY(0xFF, 0) , EAST|NORTH|NORTH_EAST|WEST|SOUTH_WEST|SOUTH ); // Add entry to catch all incoming nearest neighbour messages (i.e. those with // a different colour for (int p = 1; p <= cores_per_chip; p++) ADD_RTR_ENTRY( NEAREST_NEIGHBOUR_KEY(0, p-1) , NEAREST_NEIGHBOUR_KEY(0, 0xF) , CORE(p) ); // Add entries to accept master<->slave packets destined for this core for (int p = 1; p <= cores_per_chip; p++) ADD_RTR_ENTRY( XYZPD_TO_KEY(xyz[0],xyz[1],xyz[2], p-1,0) , XYZPD_TO_KEY( 0xFF, 0xFF, 0xFF,0x0F,0) , CORE(p) ); // Add entries to accept master<->slave packets destined for this core for (int p = 1; p <= cores_per_chip; p++) ADD_RTR_ENTRY( XYZPD_TO_KEY(xyz[0],xyz[1],xyz[2], p-1,0) , XYZPD_TO_KEY( 0xFF, 0xFF, 0xFF,0x0F,0) , CORE(p) ); // Add entry to pick up return packets for the master if (my_x == 0 && my_y == 0) ADD_RTR_ENTRY( RETURN_KEY(XYZPD_TO_KEY(0,0,0,0,0)) , RETURN_MASK(XYZPD_TO_KEY(0,0,0,0,0)) , CORE(1) ); // Add routes which allow dimension-order routing with any dimension order for (int dim_order = 0; dim_order < NUM_DIM_ORDERS; dim_order++) { if (my_x == 0 && my_y == 0) { // Start packets off on the right dimension from the master // If the first/second dimensions are zero, route in the third dimension ADD_RTR_ENTRY( XYZPD_TO_KEY( 0, 0, 0, 0, dim_order) , XYZPD_TO_KEY(DX1F,DY1F,DZ1F,0x00, 0x07) , DIM_DIRECTIONS[DIM_ORDERS[dim_order][2]] ); // If the first dimension is zero, route in the second dimension ADD_RTR_ENTRY( XYZPD_TO_KEY( 0, 0, 0, 0, dim_order) , XYZPD_TO_KEY(DX0F,DY0F,DZ0F,0x00, 0x07) , DIM_DIRECTIONS[DIM_ORDERS[dim_order][1]] ); // If no dimension is zero, route in the first dimension ADD_RTR_ENTRY( XYZPD_TO_KEY( 0, 0, 0, 0, dim_order) , XYZPD_TO_KEY(0x00,0x00,0x00,0x00, 0x07) , DIM_DIRECTIONS[DIM_ORDERS[dim_order][0]] ); } else { // Send packets in the opposite dimension order when returning to the // master. // If the third dimension is not zero, route along it first if (xyz[DIM_ORDERS[dim_order][2]]) ADD_RTR_ENTRY( RETURN_KEY(XYZPD_TO_KEY(0,0,0,0,dim_order)) , RETURN_MASK(XYZPD_TO_KEY(0,0,0,0,0x7)) , OPPOSITE(DIM_DIRECTIONS[DIM_ORDERS[dim_order][2]]) ); else if (xyz[DIM_ORDERS[dim_order][1]]) ADD_RTR_ENTRY( RETURN_KEY(XYZPD_TO_KEY(0,0,0,0,dim_order)) , RETURN_MASK(XYZPD_TO_KEY(0,0,0,0,0x7)) , OPPOSITE(DIM_DIRECTIONS[DIM_ORDERS[dim_order][1]]) ); else if (xyz[DIM_ORDERS[dim_order][0]]) ADD_RTR_ENTRY( RETURN_KEY(XYZPD_TO_KEY(0,0,0,0,dim_order)) , RETURN_MASK(XYZPD_TO_KEY(0,0,0,0,0x7)) , OPPOSITE(DIM_DIRECTIONS[DIM_ORDERS[dim_order][0]]) ); } // Dimension order route packets (x, then y, then z) ADD_RTR_ENTRY( XYZPD_TO_KEY(xyz[0]&DX1F, xyz[1]&DY1F,xyz[2]&DZ1F, 0,dim_order) , XYZPD_TO_KEY( DX1F, DY1F, DZ1F,0x00,0x07) , DIM_DIRECTIONS[DIM_ORDERS[dim_order][2]] ); ADD_RTR_ENTRY( XYZPD_TO_KEY(xyz[0]&DX0F, xyz[1]&DY0F,xyz[2]&DZ0F, 0,dim_order) , XYZPD_TO_KEY( DX0F, DY0F, DZ0F,0x00,0x07) , DIM_DIRECTIONS[DIM_ORDERS[dim_order][1]] ); } }
char pose(t_board *board, t_pos *move, char current, char rules) { int i; char get; int iget; /* printf("At %i-%i: ", cor.move->x, cor.move->y); */ // Pose get = get_board(board, move->x, move->y); if ((get == EMPTY) && (!(rules & RULE3) || (rule3(board, move->x, move->y, current)))) { set_board(board, move->x, move->y, current); printf("Placed a "); if (current == BLACK) { printf("Black"); current = WHITE; } else { printf("White"); current = BLACK; } printf(" Stone at %i:%i\n", move->x, move->y); // Prise iget = getprise(board, move->x, move->y, current); if (iget) { printf("Taken %i ", iget*2); if (current == BLACK) { board->blacks += iget; printf("Black Stones (%i total)\n", board->blacks*2); } else { board->whites += iget; printf("Whites Stones (%i total)\n", board->whites*2); } prise(board, move->x, move->y, current); } // Règle de 5 // (rules & RULE5) && for (i = 0; i < 19*19; i++) { move->x = i / 19; move->y = i % 19; // if ((get_board(board, move->x, move->y) == OPPOSITE(current)) && (rule5(board, move->x, move->y, OPPOSITE(current), rules))) { if (current == WHITE) printf("Blacks wins with a row!\n"); if (current == BLACK) printf("Whites wins with a row!\n"); return (OPPOSITE(current) + 10); } } } else { printf("There's "); switch (get) { case BLACK: printf("a Black Stone"); break; case WHITE: printf("a White Stone"); break; case EMPTY: printf("nothing"); break; } printf(" at %i:%i\n", move->x, move->y); } return (current); }
char game_loop(t_board *board, t_surfaces *surf, char mode) { t_pos moveIA; t_pos moveHint; t_pos move; char rules; char hint; SDL_Rect pos; // Pour les placements dans la fenêtre SDL_Rect cor; // Pour les placements dans le board SDL_Event event; char current; current = BLACK; SDL_ShowCursor(0); init_board(board); rules = RULE3 | RULE5; cor.x = 0; cor.y = 0; hint = 0; SDL_WaitEvent(&event); printf("New Game\n"); while (current) { // Fuite if (((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_ESCAPE)) || (event.type == SDL_QUIT)) current = 0; // Background show_background(surf->background, surf->screen); // Click if (event.type == SDL_MOUSEBUTTONUP) { // Mouvements sur le board: position du curseur if ((cor.x >= 0) && (cor.x < 19) && (cor.y >= 0) && (cor.y < 19)) { move.x = cor.x; move.y = cor.y; current = pose(board, &move, current, rules); // IA if (mode && (current == WHITE)) { callIA(board, rules, &moveIA, current); current = pose(board, &moveIA, current, rules); } if (hint) hint = 2; } // Mouvements en bas du board: sélection des règles else if (event.motion.y > 632) { if (event.motion.x < 160) rules = rules ^ RULE3; else if (event.motion.x < 320) rules = rules ^ RULE5; else if (event.motion.x < 480) { hint = !hint; if (hint) hint++; } else if (event.motion.x < 640) return (42); } // Calcul du hint if ((hint > 1) && (current < 3)) { callIA(board, rules, &moveHint, current); /* printf("Hint at %i:%i\n", moveHint.x, moveHint.y); */ hint--; } } // Affichage de l'état des règles pos.w = 320; pos.h = 56; pos.y = 630; if (rules & RULE3) { pos.x = 1; SDL_BlitSurface(surf->rule3, NULL, surf->screen, &pos); } if (rules & RULE5) { pos.x = 161; SDL_BlitSurface(surf->rule5, NULL, surf->screen, &pos); } if (hint) { pos.x = 320; SDL_BlitSurface(surf->hint, NULL, surf->screen, &pos); } // Affichage du Hint if (hint) { pos.x = moveHint.x * 32 +16; pos.y = moveHint.y * 32 +16; pos.w = 32; pos.h = 32; SDL_BlitSurface(surf->cursor, NULL, surf->screen, &pos); } // Affichage des pions place_pawns(board, surf); // Move if ((event.type == SDL_MOUSEMOTION) || (event.type == SDL_MOUSEBUTTONUP)) { pos.w = 32; pos.h = 32; pos.x = (event.motion.x / 32) * 32 - 16; pos.y = (event.motion.y / 32) * 32 - 16; cor.x = event.motion.x / 32 - 1; cor.y = event.motion.y / 32 - 1; /* printf("x:%i y:%i\n", pos.x / 32, pos.y / 32); */ if ((cor.x >= 0) && (cor.x < 19) && (cor.y >= 0) && (cor.y < 19)) { if (get_board(board, cor.x, cor.y) == EMPTY) { if (!getprise(board, cor.x, cor.y, current) && (rules & RULE3) && (!rule3(board, cor.x, cor.y, current))) SDL_BlitSurface(surf->nopestone, NULL, surf->screen, &pos); else if (current == BLACK) { SDL_BlitSurface(surf->blackstone, NULL, surf->screen, &pos); SDL_BlitSurface(surf->cursor, NULL, surf->screen, &pos); } else { SDL_BlitSurface(surf->whitestone, NULL, surf->screen, &pos); SDL_BlitSurface(surf->cursor, NULL, surf->screen, &pos); } } else SDL_BlitSurface(surf->nopestone, NULL, surf->screen, &pos); SDL_ShowCursor(0); } else if (event.motion.y > 632) SDL_ShowCursor(1); } SDL_Flip(surf->screen); // Victoire par capture if (board->whites >= 5) { printf("Blacks wins with captures!\n"); current = BLACK + 10; } if (board->blacks >= 5) { printf("Whites wins with captures!\n"); current = WHITE + 10; } // Quit de victoire while (current > 10) { SDL_ShowCursor(1); show_background(surf->exit, surf->screen); place_pawns(board, surf); SDL_Flip(surf->screen); SDL_WaitEvent(&event); if (event.type == SDL_MOUSEBUTTONUP) return (current - 10); if (((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_ESCAPE)) || (event.type == SDL_QUIT)) { current -= 10; current = OPPOSITE(current); break; } } SDL_WaitEvent(&event); } return (42); }
// ASCII-art representation of chessboard. char* StringChessSet(ChessSet *chessSet) { const int LINE_LENGTH = 36; const int LINE_COUNT = 18; // Include space for newlines. char ret[LINE_LENGTH * LINE_COUNT + 1 + 1000]; char pieceChr; int file, offset, rank; Piece piece; Position pos; Side side; Side lineSide = Black; char *topLine = " A B C D E F G H \n"; char *dottedLine = " ---------------------------------\n"; char *blackLine = " | |...| |...| |...| |...|\n"; char *whiteLine = " |...| |...| |...| |...| |\n"; // Add top lines. strncpy(ret, topLine, LINE_LENGTH); strncpy(ret+LINE_LENGTH, dottedLine, LINE_LENGTH); // Outputs chess set as ascii-art. // pieces are upper-case if white, lower-case if black. // P=pawn, R=rook, N=knight, B=bishop, Q=queen, K=king, .=empty square. // e.g., the initial position is output as follows:- // A B C D E F G H // --------------------------------- // 8 | r |.n.| b |.q.| k |.b.| n |.r.| // --------------------------------- // 7 |.p.| p |.p.| p |.p.| p |.p.| p | // --------------------------------- // 6 | |...| |...| |...| |...| // --------------------------------- // 5 |...| |...| |...| |...| | // --------------------------------- // 4 | |...| |...| |...| |...| // --------------------------------- // 3 |...| |...| |...| |...| | // --------------------------------- // 2 | P |.P.| P |.P.| P |.P.| P |.P.| // --------------------------------- // 1 |.R.| N |.B.| Q |.K.| B |.N.| R | // --------------------------------- for(rank = Rank8; rank >= Rank1; rank--) { offset = 2*LINE_LENGTH + 2*LINE_LENGTH*(Rank8-rank); // Add line. strncpy(ret + offset, lineSide == White ? whiteLine : blackLine, LINE_LENGTH); // Add number. ret[offset] = '1'+rank; // Add pieces. // For the sake of debugging, avoid PieceAt() in case it is buggy. offset += 4; for(file = FileA; file <= FileH; file++) { pos = POSITION(rank, file); pieceChr = '\0'; for(side = White; side <= Black; side++) { for(piece = Pawn; piece <= King; piece++) { if((chessSet->Sets[side].Boards[piece]&POSBOARD(pos)) == POSBOARD(pos)) { switch(piece) { case Pawn: pieceChr = 'P'; break; case Rook: pieceChr = 'R'; break; case Knight: pieceChr = 'N'; break; case Bishop: pieceChr = 'B'; break; case Queen: pieceChr = 'Q'; break; case King: pieceChr = 'K'; break; default: panic("Impossible."); } goto loop; } } } loop: if(pieceChr != '\0') { if(side == Black) { pieceChr += 32; } ret[offset] = pieceChr; } offset += 4; } // Add dotted line. strncpy(ret + offset, dottedLine, LINE_LENGTH); lineSide = OPPOSITE(lineSide); } ret[LINE_LENGTH * LINE_COUNT] = '\0'; return strdup(ret); }