Example #1
0
/*
返回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;
}
Example #3
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);
	}
}
Example #4
0
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;
}
Example #6
0
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);
}
Example #7
0
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;
}
Example #9
0
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);
}
Example #10
0
/*
返回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;
}
Example #11
0
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++;
}
Example #15
0
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]]
		             );
	}
}
Example #16
0
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);
}
Example #17
0
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);
}
Example #18
0
// 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);
}