コード例 #1
0
ファイル: eval.c プロジェクト: GordCaswell/lucaschessportable
static __inline int eval_b_mobility(int sq, int color)
{
  int dest,r = 0,score = 0;
  int opcolor = color ^ 1;
  
  dest = sq + 17;
  while(IsEmpty(dest))
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
    dest += 17;
  }
  if(PieceColor(dest) == opcolor)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }
  dest = sq - 17;
  while(IsEmpty(dest))
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
    dest -= 17;
  }
  if(PieceColor(dest) == opcolor)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }
  dest = sq + 15;
  while(IsEmpty(dest))
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
    dest += 15;
  }
  if(PieceColor(dest) == opcolor)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }
  dest = sq - 15;
  while(IsEmpty(dest))
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
    dest -= 15;
  }
  if(PieceColor(dest) == opcolor)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }

  score += (mobility[BISHOP][r]);
  return score;
}
コード例 #2
0
ファイル: eval.c プロジェクト: GordCaswell/lucaschessportable
static __inline int eval_n_mobility(int sq, int color)
{
  int dest,r = 0,score = 0;
  int opcolor = color ^ 1;
  
  dest = sq + 14;
  if(!IsOutside(dest) && PieceColor(dest) != color)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }	
  dest = sq - 14;
  if(!IsOutside(dest) && PieceColor(dest) != color)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }
  dest = sq + 18;
  if(!IsOutside(dest) && PieceColor(dest) != color)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }
  dest = sq - 18;
  if(!IsOutside(dest) && PieceColor(dest) != color)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }
  dest = sq + 31;
  if(!IsOutside(dest) && PieceColor(dest) != color)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }
  dest = sq - 31;
  if(!IsOutside(dest) && PieceColor(dest) != color)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }
  dest = sq + 33;
  if(!IsOutside(dest) && PieceColor(dest) != color)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }
  dest = sq - 33;
  if(!IsOutside(dest) && PieceColor(dest) != color)
  { r++;
    score += sq_ctrl[dest];
    score += *(safety[opcolor] + dest);
  }

  score += (mobility[KNIGHT][r]);
  return score;
}
コード例 #3
0
ファイル: main.cpp プロジェクト: Haziba/GBA-Chess
void MovePiece(int cx, int cy, int nx, int ny)
{
    DrawFourTilesAt(nx * 2 + BOARD_OFFSET_X, ny * 2 + BOARD_OFFSET_Y, 29, _pieces[PieceColor(cx, cy)][PieceType(cx, cy)]);
    EraseFourTilesAt(cx * 2 + BOARD_OFFSET_X, cy * 2 + BOARD_OFFSET_Y, 29);

    _pieceLayout[ny][nx] = _pieceLayout[cy][cx];
    _pieceLayout[cy][cx] = -1;
}
コード例 #4
0
ファイル: main.cpp プロジェクト: Haziba/GBA-Chess
void HorizontalMovesFrom(int x, int y, int* moves, int &nextMoveSlot, int* takingMoves, int &nextTMoveSlot)
{
    for(int i = x + 1; i < 8; i++)
        if(!PieceAt(i, y))
            moves[nextMoveSlot++] = y * 8 + i;
        else if(PieceColor(i, y) != PieceColor(x, y))
        {
            takingMoves[nextTMoveSlot++] = y * 8 + i;
            break;
        }
        else
            break;
    for(int i = x - 1; i >= 0; i--)
        if(!PieceAt(i, y))
            moves[nextMoveSlot++] = y * 8 + i;
        else if(PieceColor(i, y) != PieceColor(x, y))
        {
            takingMoves[nextTMoveSlot++] = y * 8 + i;
            break;
        }
        else
            break;
    for(int i = y + 1; i < 8; i++)
        if(!PieceAt(x, i))
            moves[nextMoveSlot++] = i * 8 + x;
        else if(PieceColor(x, i) != PieceColor(x, y))
        {
            takingMoves[nextTMoveSlot++] = i * 8 + x;
            break;
        }
        else
            break;
    for(int i = y - 1; i >= 0; i--)
        if(!PieceAt(x, i))
            moves[nextMoveSlot++] = i * 8 + x;
        else if(PieceColor(x, i) != PieceColor(x, y))
        {
            takingMoves[nextTMoveSlot++] = i * 8 + x;
            break;
        }
        else
            break;
}
コード例 #5
0
ファイル: see.cpp プロジェクト: Hasimir/arasan-chess
int see( const Board &board, Move move ) {
   ASSERT(!IsNull(move));
#ifdef ATTACK_TRACE
   cout << "see ";
   MoveImage(move,cout);
   cout << endl;
#endif
   ColorType my_side = PieceColor(board[StartSquare(move)]);
   ColorType side = my_side;
   ColorType oside = OppositeColor(side);
   Square square = DestSquare(move);
   Square attack_square = StartSquare(move);
   Piece attacker = board[attack_square];
   Piece on_square = (TypeOfMove(move) == EnPassant) ? 
       MakePiece(Pawn,oside) : board[square];
   Bitboard opp_attacks(board.calcAttacks(square,oside));
   if (opp_attacks.isClear()) {
       // piece is undefended
#ifdef ATTACK_TRACE
       cout << "undefended, returning " << Gain(move) << endl;
#endif
       return Gain(move);
   }
   int score_list[20];
   int swap_score = 0;
   int gain;
   Bitboard attacks[2]; 
   Square last_attack_sq[2] = {InvalidSquare, InvalidSquare};
   attacks[side] = board.calcAttacks(square,side);
   attacks[oside] = opp_attacks;
   int count = 0;

   for (;;) {
      last_attack_sq[side] = attack_square; 
      attacker = board[attack_square];
#ifdef ATTACK_TRACE
      cout << " " << PieceImage(TypeOfPiece(attacker))
           << " on " <<
           FileImage(attack_square) <<
           RankImage(attack_square) <<
           " takes " << PieceImage(TypeOfPiece(on_square))
           << endl;
#endif
      gain = PieceValue(on_square);
      if (TypeOfPiece(attacker) == Pawn && Rank(square,side) == 8) {
          if (count == 0) {
             // initial capture is a promotion (could be under-promotion)
             gain += (PieceValues[PromoteTo(move)] - PAWN_VALUE);
             on_square = MakePiece(PromoteTo(move),side);
          }
          else {
             // assume Queen promotion
             gain += QUEEN_VALUE-PAWN_VALUE;
             on_square = MakePiece(Queen,side);
          }
      }
      else {
          on_square = attacker;
      }
      if (side == my_side)
          swap_score += gain;
      else
          swap_score -= gain;

      ASSERT(count < 20);
      score_list[count++] = swap_score;
      // remove piece we used from attacks
      attacks[side].clear(attack_square);
      // switch sides
      side = OppositeColor(side);
      const Square atk = last_attack_sq[side];
      if (atk != InvalidSquare &&
          TypeOfPiece(board[atk]) != Knight) {
          // add in x-ray attacks if any
          Square xray = board.getDirectionalAttack(atk,
                                                   -Attacks::directions[atk][square],
                                                   side);
          if (xray != InvalidSquare) {
             attacks[side].set(xray);
          }
      }
      if (attacks[side]) {
          // get next opponent attacker
          attack_square = minAttacker(board,attacks[side],side);
      } else {
          // no more attackers (including x-rays)
          break;
      }
   }
   ASSERT(count >= 1);
   // minimax over the score list 
   for (int i = count-1; i > 0; --i) {
       if (i % 2 == 0) {
           score_list[i-1] = max(score_list[i],score_list[i-1]);
       } else {
           score_list[i-1] = min(score_list[i],score_list[i-1]);
       }
   }
#ifdef ATTACK_TRACE
   cout << "returning " << score_list[0] << endl;
#endif
   return score_list[0];
}
コード例 #6
0
ファイル: see.cpp プロジェクト: Hasimir/arasan-chess
int seeSign( const Board &board, Move move, int threshold ) {
   ASSERT(!IsNull(move));
#ifdef ATTACK_TRACE
   cout << "see ";
   MoveImage(move,cout);
   cout << endl;
#endif
   ColorType my_side = PieceColor(board[StartSquare(move)]);
   ColorType side = my_side;
   ColorType oside = OppositeColor(side);
   Square square = DestSquare(move);
   Square attack_square = StartSquare(move);
   Piece attacker = board[attack_square];
   Piece on_square = (TypeOfMove(move) == EnPassant) ? 
       MakePiece(Pawn,oside) : board[square];
   Bitboard opp_attacks(board.calcAttacks(square,oside));
   if (opp_attacks.isClear()) {
       // piece is undefended
#ifdef ATTACK_TRACE
       cout << "undefended, returning " << (Gain(move) >= threshold) << endl;
#endif
       return Gain(move) >= threshold;
   }
   int score_list[20];
   int swap_score = 0;
   int gain;
   Bitboard attacks[2]; 
   Square last_attack_sq[2] = {InvalidSquare, InvalidSquare};
   attacks[side] = board.calcAttacks(square,side);
   attacks[oside] = opp_attacks;
   int count = 0;

   for (;;) {
      last_attack_sq[side] = attack_square; 
      attacker = board[attack_square];
#ifdef ATTACK_TRACE
      cout << " " << PieceImage(TypeOfPiece(attacker))
           << " on " <<
           FileImage(attack_square) <<
           RankImage(attack_square) <<
           " takes " << PieceImage(TypeOfPiece(on_square))
           << endl;
#endif
      gain = PieceValue(on_square);
      if (TypeOfPiece(attacker) == Pawn && Rank(square,side) == 8) {
          if (count == 0) {
             // initial capture is a promotion (could be under-promotion)
             gain += (PieceValues[PromoteTo(move)] - PAWN_VALUE);
             on_square = MakePiece(PromoteTo(move),side);
          }
          else {
             // assume Queen promotion
             gain += QUEEN_VALUE-PAWN_VALUE;
             on_square = MakePiece(Queen,side);
          }
      }
      else {
          on_square = attacker;
      }
      if (side == my_side)
          swap_score += gain;
      else
          swap_score -= gain;

      ASSERT(count < 20);
      score_list[count++] = swap_score;
      // remove piece we used from attacks
      attacks[side].clear(attack_square);
      // switch sides
      side = OppositeColor(side);
      if (count % 2 == 0) {
          // If it is our turn to move and we are above the threshold
          // then we can exit - if we capture it only improves the score.
          if (swap_score >= threshold) {
              ASSERT(see(board,move) >= threshold);
              return 1;
          }
          // Futility: If capturing the opponent piece for free does
          // not bring us up to the threshold, exit. (Do not cut off
          // if we have a potential promotion).
          if ((Rank(square,side) != 8 ||
               !(attacks[side] & board.pawn_bits[side])) &&
              swap_score + PieceValue(on_square) < threshold) {
              ASSERT(see(board,move) < threshold);
              return 0;
          }
      } else {
          // See if opponent already has captured enough that SEE is
          // below threshold
          if (swap_score < threshold) {
              ASSERT(see(board,move) < threshold);
              return 0;
          }
          // Futility: opponent capture cannot get us below threshold
          if ((Rank(square,side) != 8 ||
               !(attacks[side] & board.pawn_bits[side])) &&
              swap_score - PieceValue(on_square) >= threshold) {
              ASSERT(see(board,move) >= threshold);
              return 1;
          }
      }
      const Square atk = last_attack_sq[side];
      if (atk != InvalidSquare &&
          TypeOfPiece(board[atk]) != Knight) {
          // add in x-ray attacks if any
          Square xray = board.getDirectionalAttack(atk,
                                                   -Attacks::directions[atk][square],
                                                   side);
          if (xray != InvalidSquare) {
             attacks[side].set(xray);
          }
      }
      if (attacks[side]) {
          // get next opponent attacker
          attack_square = minAttacker(board,attacks[side],side);
      } else {
          // no more attackers (including x-rays)
          break;
      }
   }
   ASSERT(count >= 1);
   // minimax over the score list 
   for (int i = count-1; i > 0; --i) {
       if (i % 2 == 0) {
           score_list[i-1] = max(score_list[i],score_list[i-1]);
       } else {
           score_list[i-1] = min(score_list[i],score_list[i-1]);
       }
   }
#ifdef ATTACK_TRACE
   cout << "returning " << (score_list[0]>=threshold) << endl;
#endif
   ASSERT((score_list[0] >= threshold) == (see(board,move) >= threshold));
   return score_list[0] >= threshold;
}
コード例 #7
0
ファイル: notation.cpp プロジェクト: Hasimir/arasan-chess
Move Notation::value(const Board & board, ColorType side, InputFormat format, const string &image) 
{
    int rank = 0;
    int file = 0;

    PieceType piece = Empty;
    PieceType promotion = Empty;
    Square dest = InvalidSquare, start = InvalidSquare;
    int capture = 0;

    stringstream s(image);
    string::const_iterator it = image.begin();
    int i = 0;
    while (it != image.end() && isspace(*it)) {
        it++;
        i++;
    }
    if (it == image.end() || !isalpha(*it)) return NullMove;
    string img(image,i); // string w/o leading spaces
    ASSERT(img.length());
    it = img.begin();
    if (*it == 'O' || *it == '0') {
       // castling, we presume
       return parseCastling(board, side, img);
    } else if (format == WB_IN) {
       if (img.length() < 4) return NullMove;
       Square start = SquareValue(img.substr(0,2));
       if (!OnBoard(start)) return NullMove;
       Square dest = SquareValue(img.substr(2,2));
       if (!OnBoard(dest)) return NullMove;
       PieceType promotion = Empty;
       if (img.length() > 4) {
          promotion = PieceCharValue(toupper(img[4]));
       }
       return CreateMove(board,start,dest,promotion);
    }
    int have_start = 0;
    if (isupper(*it)) {
       piece = PieceCharValue(*it);
       it++;
    }
    else {
       piece = Pawn;
       if ((it+1) != img.end()) {
          char next = *it;
          file = next-'a'+1;
          if (file < 1 || file > 8) return NullMove;
          char next2 = *(it+1);
          if (next2 == 'x' || is_file(next2)) {
             // allow "dc4" as in Informant, instead of dxc4
             it++;
             capture = 1;
          }
          else if (isdigit(next2) && img.length()>2) {
             char next3 = *(it+2);
             if ((next3 == 'x' || next3 == '-') && img.length()>=5) {
                // long algebraic notation
                have_start++;
                start = SquareValue(next,next2);
                if (start == InvalidSquare) return NullMove;
                it+=3; // point to dest
                piece = TypeOfPiece(board[start]);
             }
          }
       }
    }
    if (piece == Empty) {
       return NullMove;
    }
    if (piece != Pawn && !have_start && it != img.end()) {
       char next = *it;
       char next2 = '\0';
       if (it + 1 != img.end()) next2 = *(it+1);
       if (is_file(next) && isdigit(next2) && img.length()>=5) {
          // long algebraic notation, or a SAN move like Qd1d3
          start = SquareValue(next,next2);
          if (IsInvalid(start)) return NullMove;
          it+=2;
          have_start++;
       }
       // also look for disambiguating rank, e.g. '2' in "N2e4".
       else if (isdigit(next)) {
          rank = next - '0';
          if (rank < 1 || rank > 8) return NullMove;
          it++;
       }
       else if (is_file(next) && isalpha(next2)) {
          // disamiguating rank, e.g. "Rfd1"
          file = next - 'a' + 1;
          if (file < 1 || file > 8) return NullMove;
          it++;
       }
    }

    if (it != img.end() && *it == 'x') {
       capture = 1;
       it++;
    }
    if (it != img.end() && (it+1) != img.end()) {
       // remainder of move should be a square identifier, e.g. "g7"
       dest = SquareValue(*it,*(it+1));
       it += 2;
    }
    if (IsInvalid(dest)) {
       return NullMove;
    }
    if (it != img.end() && *it == '=') {
       it++;
       if (it == img.end()) {
          return NullMove;
       } else {
          promotion = PieceCharValue(*it);
          if (piece != Pawn || promotion == Empty)
             return NullMove;
          it++;
       }
    }
    else if (piece == Pawn && it != img.end() && isupper(*it)) {
       // Quite a few "PGN" files have a8Q instead of a8=Q.
       promotion = PieceCharValue(*it);
       if (promotion == Empty || Rank(dest,side) != 8)
          return NullMove;
    } else if (piece == Pawn && Rank(dest,side) == 8) {
       // promotion but no piece specified, treat as error
       return NullMove;
    }

    // Informant does not use "x" for captures.  Assume that if the destination
    // is occupied, this is a capture move.
    if (board[dest] != EmptyPiece) {
       capture = 1;
    }
    // Do a sanity check on capture moves:
    if (capture && !IsEmptyPiece(board[dest]) && PieceColor(board[dest]) == board.sideToMove()) {
       return NullMove;
    }

    // Ok, now we need to figure out where the start square is. For pawn
    // moves this is implicit.

    int dups = 0;

    if (!have_start) {
       if (capture && piece == Pawn && IsEmptyPiece(board[dest]) &&
           Rank(dest,board.sideToMove()) != 8) {
          // en passant capture, special case
          int start_rank = (board.sideToMove() == White) ?
             Rank(dest,White) - 1 :
             Rank(dest,White) + 1;

          start = MakeSquare(file, start_rank, White);
          dups = 1;
       }
       else if (piece == Pawn && board[dest] == EmptyPiece) {
          start = MakeSquare(file,Rank(dest,board.sideToMove())-1,board.sideToMove());
          if (board[start] == EmptyPiece && Rank(dest,board.sideToMove())==4) {
             start = MakeSquare(file,Rank(dest,board.sideToMove())-2,board.sideToMove());
          }
          if (board[start] == EmptyPiece) return NullMove;
          dups = 1;
       }
       else {
          Bitboard attacks = board.calcAttacks(dest,side);
          Square maybe;
          while (attacks.iterate(maybe)) {
             if (TypeOfPiece(board[maybe]) == piece &&
                 PieceColor(board[maybe]) == board.sideToMove()) {
                if (file && File(maybe) != file)
                   continue;
                if (rank && Rank(maybe,White) != rank)
                   continue;
                if (PieceColor(board[maybe]) == board.sideToMove()) {
                   // Possible move to this square.  Make sure it is legal.
                   Board board_copy(board);
                   Move emove = CreateMove(board,maybe,dest,
                                           promotion);
                   board_copy.doMove(emove);
                   if (!board_copy.anyAttacks(
                          board_copy.kingSquare(board_copy.oppositeSide()),
                          board_copy.sideToMove())) {
                      ++dups;
                      start = maybe;
                   }
                }
             }
          }
       }
    }
    if (dups == 1 || have_start) {
       if (start == InvalidSquare || board[start] == EmptyPiece)
          return NullMove;
       else
          return CreateMove(board, start, dest, promotion);
    }
    else                                           // ambiguous move
       return NullMove;
}
コード例 #8
0
ファイル: boardio.cpp プロジェクト: Hasimir/arasan-chess
void BoardIO::writeFEN( const Board &board, ostream &o, int addMoveInfo)
{
   // write out the board in Forsythe-Edwards (FEN) notation.
   for (int i=1;i<=8;i++)
   {
      int j = 1;
      while (j <= 8)
      {
         int n = 0;
         Square sq;
         Piece p;
         do
         {
            sq = MakeSquare(j,i,Black);
            p = board.contents[sq];
            if (p != EmptyPiece)
               break;
            ++j; ++n;
         } while (j <= 8);
         if (n)
            o << (char)(n + '0');
         if (p != EmptyPiece)
         {
            char img = PieceImage(TypeOfPiece(p));
            if (PieceColor(p) == Black) img = tolower(img);
            o << img;
            j++;
         }
      }
      if (i != 8) o << '/';
   }
   if (board.sideToMove() == White)
      o << " w";
   else
      o << " b";

   // used in I/O of castling data:
   const bool kcastle[6] = { true, true, false, false, false, false};
   const bool qcastle[6] = { true, false, true, false, false, false};

   // note : unfortunately FEN doesn't allow recording if castling
   // has taken place, only whether or not it is possible.
   CastleType wcs = board.castleStatus(White);
   CastleType bcs = board.castleStatus(Black);
   o << ' ';
   if (!kcastle[(int)wcs] && !qcastle[(int)bcs])
      o << '-';
   else
   {
      if (kcastle[(int)wcs])
         o << 'K';
      if (qcastle[(int)wcs])
         o << 'Q';
      if (kcastle[(int)bcs])
         o << 'k';
      if (qcastle[(int)bcs])
         o << 'q';
   }
   o << ' ';
   Square epsq = board.enPassantSq();
   if (epsq == InvalidSquare) {
      o << '-';
   }
   else {
      // FEN stores the destination square for an en passant capture;
      // we store the location of the capturable pawn.
      Square target = (board.sideToMove() == White) ? epsq + 8 : epsq - 8;
      o << FileImage(target) << RankImage(target);
   }
   if (addMoveInfo)
   {
      // FEN is supposed to include the halfmove and fullmove numbers,
      // but these are attributes of the game - they are not stored in
      // the board.
      o << " 0 1";
   }
}
コード例 #9
0
ファイル: main.cpp プロジェクト: Haziba/GBA-Chess
void PlacePieces()
{
    for(int i = 0; i < 8; i++)
        for(int j = 0; j < 8; j++)
            if(PieceAt(i, j))
                DrawFourTilesAt((i * 2) + BOARD_OFFSET_X, (j * 2) + BOARD_OFFSET_Y, 29, _pieces[PieceColor(i, j)][PieceType(i, j)]);
}
コード例 #10
0
ファイル: main.cpp プロジェクト: Haziba/GBA-Chess
void AvailableMoves(int x, int y, int* moves, int* takingMoves)
{
    // Maximum number of moves available at one time is 28 (Queen at C3)
    int kPTC[8][2] = {{-2,-1},{-2,1},{-1,-2},{1,-2},{2,-1},{2,1},{1,2},{-1,2}};
    int kingPTC[8][2] = {{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}};
    for(int i = 0; i < 28; i++)
        moves[i] = -1;
    for(int i = 0; i < 16; i++)
        takingMoves[i] = -1;
    if(PieceAt(x, y))
    {
        int colour = PieceColor(x, y);
        int type = PieceType(x, y);
        int nextMoveSlot = 0;
        int nextTMoveSlot = 0;

        switch(type)
        {
        case KING:
            for(int i = 0; i < 8; i++)
            {
                int nx = x + kingPTC[i][0], ny = y + kingPTC[i][1];
                if(nx >= 0 && ny >= 0 && nx < 8 && ny < 8)
                {
                    if(!PieceAt(nx, ny))
                        moves[nextMoveSlot++] = ny * 8 + nx;
                    else if(PieceColor(nx, ny) != colour)
                        takingMoves[nextTMoveSlot++] = ny * 8 + nx;
                }
            }
            break;
        case QUEEN:
            HorizontalMovesFrom(x, y, moves, nextMoveSlot, takingMoves, nextTMoveSlot);
            DiagonalMovesFrom(x, y, moves, nextMoveSlot, takingMoves, nextTMoveSlot);
            break;
        case BISHOP:
            DiagonalMovesFrom(x, y, moves, nextMoveSlot, takingMoves, nextTMoveSlot);
            break;
        case ROOK:
            HorizontalMovesFrom(x, y, moves, nextMoveSlot, takingMoves, nextTMoveSlot);
            break;
        case KNIGHT:
            for(int i = 0; i < 8; i++)
            {
                int nx = x + kPTC[i][0], ny = y + kPTC[i][1];
                if(nx >= 0 && nx < 8 && ny >= 0 && ny < 8)
                {
                    if(!PieceAt(nx, ny))
                        moves[nextMoveSlot++] = ny * 8 + nx;
                    else if(PieceColor(nx, ny) != colour)
                        takingMoves[nextTMoveSlot++] = ny * 8 + nx;
                }
            }
            break;
        case PAWN:
            if(colour == WHITE)
            {
                for(int i = 0; i < (y == 6 ? 2 : 1); i++)
                    if(!PieceAt(x, y - 1 - i))
                        moves[nextMoveSlot++] = (y - 1 - i) * 8 + x;
                    else
                        break;
                if(x > 0)
                    if(PieceAt(x - 1, y - 1) && PieceColor(x - 1, y - 1) != colour)
                        takingMoves[nextTMoveSlot++] = (y - 1) * 8 + x - 1;
                if(x < 7)
                    if(PieceAt(x + 1, y - 1) && PieceColor(x + 1, y - 1) != colour)
                        takingMoves[nextTMoveSlot++] = (y - 1) * 8 + x + 1;
            }
            else
            {
                for(int i = 0; i < (y == 1 ? 2 : 1); i++)
                    if(!PieceAt(x, y + 1 + i))
                        moves[nextMoveSlot++] = (y + 1 + i) * 8 + x;
                    else
                        break;
                if(x > 0)
                    if(PieceAt(x - 1, y + 1) && PieceColor(x - 1, y + 1) != colour)
                        takingMoves[nextTMoveSlot++] = (y + 1) * 8 + x - 1;
                if(x < 7)
                    if(PieceAt(x + 1, y + 1) && PieceColor(x + 1, y + 1) != colour)
                        takingMoves[nextTMoveSlot++] = (y + 1) * 8 + x + 1;
            }
            break;
        }
    }
}
コード例 #11
0
ファイル: main.cpp プロジェクト: Haziba/GBA-Chess
void DiagonalMovesFrom(int x, int y, int* moves, int &nextMoveSlot, int* takingMoves, int &nextTMoveSlot)
{
    for(int i = 0; i < x && i < y; i++)
    {
        int nx = x - i - 1, ny = y - i - 1;
        if(!PieceAt(nx, ny))
            moves[nextMoveSlot++] = ny * 8 + nx;
        else if(PieceColor(nx, ny) != PieceColor(x, y))
        {
            takingMoves[nextTMoveSlot++] = ny * 8 + nx;
            break;
        }
        else
            break;
    }
    for(int i = 0; i < x && y + i < 8; i++)
    {
        int nx = x - i - 1, ny = y + i + 1;
        if(ny < 8)
        {
            if(!PieceAt(nx, ny))
                moves[nextMoveSlot++] = ny * 8 + nx;
            else if(PieceColor(nx, ny) != PieceColor(x, y))
            {
                takingMoves[nextTMoveSlot++] = ny * 8 + nx;
                break;
            }
            else
                break;
        }
    }
    for(int i = x + 1; i < 8; i++)
    {
        int nx = i, ny = y + (i - x);
        if(ny < 8)
        {
            if(!PieceAt(nx, ny))
                moves[nextMoveSlot++] = ny * 8 + nx;
            else if(PieceColor(nx, ny) != PieceColor(x, y))
            {
                takingMoves[nextTMoveSlot++] = ny * 8 + nx;
                break;
            }
            else
                break;
        }
    }
    for(int i = x + 1; i < 8; i++)
    {
        int nx = i, ny = y - (i - x);
        if(!PieceAt(nx, ny))
            moves[nextMoveSlot++] = ny * 8 + nx;
        else if(PieceColor(nx, ny) != PieceColor(x, y))
        {
            takingMoves[nextTMoveSlot++] = ny * 8 + nx;
            break;
        }
        else
            break;
    }
}
コード例 #12
0
ファイル: main.cpp プロジェクト: Haziba/GBA-Chess
int main()
{
    LoadAssets();
    ClearObjects();
    InitialiseStage();

    uint16_t oldKeys = REG_P1;

    Cursor cursor = Cursor(0);

    bool pieceSelected = false;
    int currentPiece = 0;
    int* moves = new int[28];
    int* takingMoves = new int[16];

    int currentTurnColor = WHITE;
    for(int i = 0; i < 2; i++)
        for(int j = 0; j < 16; j++)
            _lostPieces[i][j] = -1;


    while (true)
    {
        if(!(REG_P1 & KEY_RIGHT) && (oldKeys & KEY_RIGHT))
            cursor.Move(1,  0);
        if(!(REG_P1 & KEY_LEFT) && (oldKeys & KEY_LEFT))
            cursor.Move(-1, 0);
        if(!(REG_P1 & KEY_DOWN) && (oldKeys & KEY_DOWN))
            cursor.Move(0,  1);
        if(!(REG_P1 & KEY_UP) && (oldKeys & KEY_UP))
            cursor.Move(0, -1);

        if(!(REG_P1 & KEY_A) && (oldKeys & KEY_A))
        {
            if(PieceAt(cursor.X(), cursor.Y()))
            {
                pieceSelected = true;
                for(int i = 0; i < 16 && takingMoves[i] >= 0; i++)
                    if(takingMoves[i] % 8 == cursor.X() && takingMoves[i] / 8 == cursor.Y())
                    {
                        TakePiece(currentPiece % 8, currentPiece / 8, cursor.X(), cursor.Y());
                        currentTurnColor = (currentTurnColor == WHITE ? BLACK : WHITE);
                        pieceSelected = false;
                        ClearHighlights();
                        takingMoves[0] = -1;
                        break;
                    }

                if(pieceSelected && PieceColor(cursor.X(), cursor.Y()) == currentTurnColor)
                {
                    ClearHighlights();

                    AvailableMoves(cursor.X(), cursor.Y(), moves, takingMoves);

                    currentPiece = cursor.Y() * 8 + cursor.X();

                    for(int i = 0; i < 28 && moves[i] >= 0; i++)
                        Highlight(moves[i] % 8, moves[i] / 8, GREEN);

                    for(int i = 0; i < 16 && takingMoves[i] >= 0; i++)
                        Highlight(takingMoves[i] % 8, takingMoves[i] / 8, RED);
                }
            }
            else if(pieceSelected)
            {
                ClearHighlights();

                if(!PieceAt(cursor.X(), cursor.Y()))
                {
                    for(int i = 0; i < 28 && moves[i] >= 0; i++)
                        if(moves[i] % 8 == cursor.X() && moves[i] / 8 == cursor.Y())
                        {
                            MovePiece(currentPiece % 8, currentPiece / 8, cursor.X(), cursor.Y());
                            currentTurnColor = (currentTurnColor == WHITE ? BLACK : WHITE);
                            pieceSelected = false;
                            break;
                        }
                }
            }
        }

        oldKeys = REG_P1;

        if(currentTurnColor == WHITE)
            DrawString(20, 1, "WHITE", 5);
        else
            DrawString(20, 1, "BLACK", 5);

        WaitVSync();
        UpdateObjects();
    }

    return 0;
}
コード例 #13
0
ファイル: chesspiece.cpp プロジェクト: mishander/qmlchess
ChessPiece::ChessPiece(Piece _type, uint8_t index) :m_type(_type), m_position(index)
{
    m_color = PieceColor(_type > 6);
};
コード例 #14
0
ファイル: chesspiece.cpp プロジェクト: mishander/qmlchess
ChessPiece::ChessPiece(Piece _type) :m_type(_type)
{
    m_color = PieceColor(_type > 6);
};