Beispiel #1
0
void interrupt isr(void)
{
    
    //UART receiver interrupt
    if (PIR1bits.RCIF)
    {

        if (RCSTAbits.FERR)
        {
            RCSTAbits.SPEN = 0;
            RCSTAbits.SPEN = 1;
            return;
        }
        /*****************************
         *  Put action below
         * **************************/
        uart_putc(uart_getc());
        return;
        /*****************************
         *  Stop of action
         * **************************/
    }

    //Timer 1 interrupt
    if (TMR1IF)
    {
        /*char string [8];
        TMR1IF = 0;
        set_tick_period_timer1_us(1000);
        timer1_tick_nbr ++;
        if (timer1_tick_nbr== 1000){
            timer1_tick_nbr = 0;
            elapsed_time++;
            RC2 = 1- RC2;
            utoa (string, elapsed_time, 10);
            Lcd4_Set_Cursor(0,0);
            Lcd4_Write_String(string);
        }*/
        return;
    }

    //Prefer to use the timer 2 for a periodic time because we don't
    //have to reinitialize the counter every time it is done by hardware
    if (TMR2IF)
    {
        char string [9];

        TMR2IF = 0;
        timer2_tick_nbr ++;
        //The timer 2 ticks every 0.010 second => *100 = 1s
        //The time had to be adjusted.
        if (timer2_tick_nbr== 80){
            timer2_tick_nbr = 0;
            elapsed_time++;
            RC2 = 1- RC2;
            game_phase();
        }
        
        return;
    }

    if(RABIF != 0x00)
    {
        if (RA0 == 1)
        {
            switch_player();
            __delay_ms(500);
        }
        RABIF = 0x00;
        return;
    }

}
Beispiel #2
0
Entry* probe(const Position& pos, Table& entries, Endgames& endgames) {

  Key key = pos.material_key();
  Entry* e = entries[key];

  // If e->key matches the position's material hash key, it means that we
  // have analysed this material configuration before, and we can simply
  // return the information we found the last time instead of recomputing it.
  if (e->key == key)
      return e;

  std::memset(e, 0, sizeof(Entry));
  e->key = key;
  e->factor[WHITE] = e->factor[BLACK] = (uint8_t)SCALE_FACTOR_NORMAL;
  e->gamePhase = game_phase(pos);

  // Let's look if we have a specialized evaluation function for this particular
  // material configuration. Firstly we look for a fixed configuration one, then
  // for a generic one if the previous search failed.
  if (endgames.probe(key, e->evaluationFunction))
      return e;

  if (is_KXK<WHITE>(pos))
  {
      e->evaluationFunction = &EvaluateKXK[WHITE];
      return e;
  }

  if (is_KXK<BLACK>(pos))
  {
      e->evaluationFunction = &EvaluateKXK[BLACK];
      return e;
  }

  if (!pos.pieces(PAWN) && !pos.pieces(ROOK) && !pos.pieces(QUEEN))
  {
      // Minor piece endgame with at least one minor piece per side and
      // no pawns. Note that the case KmmK is already handled by KXK.
      assert((pos.pieces(WHITE, KNIGHT) | pos.pieces(WHITE, BISHOP)));
      assert((pos.pieces(BLACK, KNIGHT) | pos.pieces(BLACK, BISHOP)));

      if (   pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE) <= 2
          && pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK) <= 2)
      {
          e->evaluationFunction = &EvaluateKmmKm[pos.side_to_move()];
          return e;
      }
  }

  // OK, we didn't find any special evaluation function for the current
  // material configuration. Is there a suitable scaling function?
  //
  // We face problems when there are several conflicting applicable
  // scaling functions and we need to decide which one to use.
  EndgameBase<ScaleFactor>* sf;

  if (endgames.probe(key, sf))
  {
      e->scalingFunction[sf->color()] = sf;
      return e;
  }

  // Generic scaling functions that refer to more then one material
  // distribution. They should be probed after the specialized ones.
  // Note that these ones don't return after setting the function.
  if (is_KBPsKs<WHITE>(pos))
      e->scalingFunction[WHITE] = &ScaleKBPsK[WHITE];

  if (is_KBPsKs<BLACK>(pos))
      e->scalingFunction[BLACK] = &ScaleKBPsK[BLACK];

  if (is_KQKRPs<WHITE>(pos))
      e->scalingFunction[WHITE] = &ScaleKQKRPs[WHITE];

  else if (is_KQKRPs<BLACK>(pos))
      e->scalingFunction[BLACK] = &ScaleKQKRPs[BLACK];

  Value npm_w = pos.non_pawn_material(WHITE);
  Value npm_b = pos.non_pawn_material(BLACK);

  if (npm_w + npm_b == VALUE_ZERO)
  {
      if (!pos.count<PAWN>(BLACK))
      {
          assert(pos.count<PAWN>(WHITE) >= 2);
          e->scalingFunction[WHITE] = &ScaleKPsK[WHITE];
      }
      else if (!pos.count<PAWN>(WHITE))
      {
          assert(pos.count<PAWN>(BLACK) >= 2);
          e->scalingFunction[BLACK] = &ScaleKPsK[BLACK];
      }
      else if (pos.count<PAWN>(WHITE) == 1 && pos.count<PAWN>(BLACK) == 1)
      {
          // This is a special case because we set scaling functions
          // for both colors instead of only one.
          e->scalingFunction[WHITE] = &ScaleKPKP[WHITE];
          e->scalingFunction[BLACK] = &ScaleKPKP[BLACK];
      }
  }

  // No pawns makes it difficult to win, even with a material advantage. This
  // catches some trivial draws like KK, KBK and KNK
  if (!pos.count<PAWN>(WHITE) && npm_w - npm_b <= BishopValueMg)
  {
      e->factor[WHITE] = (uint8_t)
      (npm_w == npm_b || npm_w < RookValueMg ? 0 : NoPawnsSF[std::min(pos.count<BISHOP>(WHITE), 2)]);
  }

  if (!pos.count<PAWN>(BLACK) && npm_b - npm_w <= BishopValueMg)
  {
      e->factor[BLACK] = (uint8_t)
      (npm_w == npm_b || npm_b < RookValueMg ? 0 : NoPawnsSF[std::min(pos.count<BISHOP>(BLACK), 2)]);
  }

  // Compute the space weight
  if (npm_w + npm_b >= 2 * QueenValueMg + 4 * RookValueMg + 2 * KnightValueMg)
  {
      int minorPieceCount =  pos.count<KNIGHT>(WHITE) + pos.count<BISHOP>(WHITE)
                           + pos.count<KNIGHT>(BLACK) + pos.count<BISHOP>(BLACK);

      e->spaceWeight = make_score(minorPieceCount * minorPieceCount, 0);
  }

  // Evaluate the material imbalance. We use PIECE_TYPE_NONE as a place holder
  // for the bishop pair "extended piece", which allows us to be more flexible
  // in defining bishop pair bonuses.
  const int pieceCount[COLOR_NB][PIECE_TYPE_NB] = {
  { pos.count<BISHOP>(WHITE) > 1, pos.count<PAWN>(WHITE), pos.count<KNIGHT>(WHITE),
    pos.count<BISHOP>(WHITE)    , pos.count<ROOK>(WHITE), pos.count<QUEEN >(WHITE) },
  { pos.count<BISHOP>(BLACK) > 1, pos.count<PAWN>(BLACK), pos.count<KNIGHT>(BLACK),
    pos.count<BISHOP>(BLACK)    , pos.count<ROOK>(BLACK), pos.count<QUEEN >(BLACK) } };

  e->value = (int16_t)((imbalance<WHITE>(pieceCount) - imbalance<BLACK>(pieceCount)) / 16);

  // Having pawn(s) and ahead at least a piece (npm) ==> Exchange Pieces not Pawns !
  if (npm_w >= (npm_b + 3*PawnValueMg) && pos.count<PAWN>(WHITE) && pos.count<PAWN>(WHITE) > pos.count<PAWN>(BLACK) - 3)
    e->value += (int16_t)((imbalanceWinning<WHITE>(pieceCount) - imbalanceLoosing<BLACK>(pieceCount)) / 16);

  if (npm_b >= (npm_w + 3*PawnValueMg) && pos.count<PAWN>(BLACK) && pos.count<PAWN>(BLACK) > pos.count<PAWN>(WHITE) - 3)
    e->value += (int16_t)((imbalanceWinning<BLACK>(pieceCount) - imbalanceLoosing<WHITE>(pieceCount)) / 16);

  return e;
}
Beispiel #3
0
    // Material::probe () takes a position object as input,
    // looks up a MaterialEntry object, and returns a pointer to it.
    // If the material configuration is not already present in the table,
    // it is computed and stored there, so we don't have to recompute everything
    // when the same material configuration occurs again.
    Entry* probe     (const Position &pos, Table &table, Endgames &endgames)
    {
        Key key  = pos.matl_key ();
        Entry *e = table[key];

        // If e->_key matches the position's material hash key, it means that we
        // have analysed this material configuration before, and we can simply
        // return the information we found the last time instead of recomputing it.
        if (e->_key == key) return e;

        std::memset (e, 0, sizeof (Entry));
        e->_key           = key;
        e->_factor[WHITE] = e->_factor[BLACK] = SCALE_FACTOR_NORMAL;
        e->_game_phase    = game_phase (pos);

        // Let's look if we have a specialized evaluation function for this
        // particular material configuration. First we look for a fixed
        // configuration one, then a generic one if previous search failed.
        if (endgames.probe (key, e->evaluation_func))
        {
            return e;
        }

        if (is_KXK<WHITE> (pos))
        {
            e->evaluation_func = &EvaluateKXK[WHITE];
            return e;
        }
        if (is_KXK<BLACK> (pos))
        {
            e->evaluation_func = &EvaluateKXK[BLACK];
            return e;
        }

        // OK, we didn't find any special evaluation function for the current
        // material configuration. Is there a suitable scaling function?
        //
        // We face problems when there are several conflicting applicable
        // scaling functions and we need to decide which one to use.
        EndgameBase<ScaleFactor> *eg_sf;
        if (endgames.probe (key, eg_sf))
        {
            e->scaling_func[eg_sf->color ()] = eg_sf;
            return e;
        }

        // Generic scaling functions that refer to more then one material distribution.
        // Should be probed after the specialized ones.
        // Note that these ones don't return after setting the function.

        if (is_KBPsKs<WHITE> (pos))
        {
            e->scaling_func[WHITE] = &ScaleKBPsKs[WHITE];
        }
        if (is_KBPsKs<BLACK> (pos))
        {
            e->scaling_func[BLACK] = &ScaleKBPsKs[BLACK];
        }

        if      (is_KQKRPs<WHITE> (pos))
        {
            e->scaling_func[WHITE] = &ScaleKQKRPs[WHITE];
        }
        else if (is_KQKRPs<BLACK> (pos))
        {
            e->scaling_func[BLACK] = &ScaleKQKRPs[BLACK];
        }


        Value npm[CLR_NO] = 
        {
            pos.non_pawn_material (WHITE),
            pos.non_pawn_material (BLACK),
        };

        if (npm[WHITE] + npm[BLACK] == VALUE_ZERO)
        {
            if      (pos.count<PAWN> (BLACK) == 0
                &&   pos.count<PAWN> (WHITE) >= 2)
            {
                //ASSERT (pos.count<PAWN> (WHITE) >= 2);
                e->scaling_func[WHITE] = &ScaleKPsK[WHITE];
            }
            else if (pos.count<PAWN> (WHITE) == 0
                &&   pos.count<PAWN> (BLACK) >= 2)
            {
                //ASSERT (pos.count<PAWN> (BLACK) >= 2);
                e->scaling_func[BLACK] = &ScaleKPsK[BLACK];
            }
            else if (pos.count<PAWN> (WHITE) == 1
                &&   pos.count<PAWN> (BLACK) == 1)
            {
                // This is a special case because we set scaling functions for both colors instead of only one.
                e->scaling_func[WHITE] = &ScaleKPKP[WHITE];
                e->scaling_func[BLACK] = &ScaleKPKP[BLACK];
            }
        }

        // No pawns makes it difficult to win, even with a material advantage.
        // This catches some trivial draws like KK, KBK and KNK and gives a very drawish
        // scale factor for cases such as KRKBP and KmmKm (except for KBBKN).

        if (npm[WHITE] - npm[BLACK] <= VALUE_MG_BISHOP)
        {
            if      (pos.count<PAWN> (WHITE) == 0)
            {
                e->_factor[WHITE] = npm[WHITE] <= VALUE_MG_BISHOP ?
                    0 : !pos.count<NIHT> (WHITE) && !pos.bishops_pair (WHITE) ?
                    1 : npm[BLACK] <= VALUE_MG_BISHOP ? 
                    4 : 12;
            }
            else if (pos.count<PAWN> (WHITE) == 1)
            {
                e->_factor[WHITE] = (npm[WHITE] == npm[BLACK] || npm[WHITE] <= VALUE_MG_BISHOP) ?
                    4 : SCALE_FACTOR_ONEPAWN / (pos.count<PAWN> (BLACK) + 1);
            }
        }

        if (npm[BLACK] - npm[WHITE] <= VALUE_MG_BISHOP)
        {
            if      (pos.count<PAWN> (BLACK) == 0)
            {
                e->_factor[BLACK] = npm[BLACK] <= VALUE_MG_BISHOP ?
                    0 : !pos.count<NIHT> (BLACK) && !pos.bishops_pair (BLACK) ?
                    1 : npm[WHITE] <= VALUE_MG_BISHOP ? 
                    4 : 12;
            }
            else if (pos.count<PAWN> (BLACK) == 1)
            {
                e->_factor[BLACK] = (npm[BLACK] == npm[WHITE] || npm[BLACK] <= VALUE_MG_BISHOP) ?
                    4 : SCALE_FACTOR_ONEPAWN / (pos.count<PAWN> (WHITE) + 1);
            }
        }

        // Compute the space weight
        if (npm[WHITE] + npm[BLACK] >= 2 * VALUE_MG_QUEEN + 4 * VALUE_MG_ROOK + 2 * VALUE_MG_KNIGHT)
        {
            int32_t minor_piece_count = pos.count<NIHT> () + pos.count<BSHP> ();
            e->_space_weight = mk_score (minor_piece_count * minor_piece_count, 0);
        }

        // Evaluate the material imbalance.
        // We use KING as a place holder for the bishop pair "extended piece",
        // this allow us to be more flexible in defining bishop pair bonuses.
        const int32_t count[CLR_NO][NONE] =
        {
            {
                pos.count<PAWN> (WHITE), pos.count<NIHT> (WHITE), pos.count<BSHP> (WHITE),
                pos.count<ROOK> (WHITE), pos.count<QUEN> (WHITE), pos.bishops_pair (WHITE),
            },
            {
                pos.count<PAWN> (BLACK), pos.count<NIHT> (BLACK), pos.count<BSHP> (BLACK),
                pos.count<ROOK> (BLACK), pos.count<QUEN> (BLACK), pos.bishops_pair (BLACK),
            },
        };

        e->_value = int16_t ((imbalance<WHITE> (count) - imbalance<BLACK> (count)) / 16);
        return e;
    }