openMidEndingEval.h
Go to the documentation of this file.
00001 /* openMidEndingEval.h
00002  */
00003 
00004 #ifndef EVAL_ML_OPENMIDENDINGEVAL_H
00005 #define EVAL_ML_OPENMIDENDINGEVAL_H
00006 
00007 #include "osl/eval/ml/weights.h"
00008 #include "osl/eval/ml/pieceEval.h"
00009 #include "osl/eval/ml/evalStagePair.h"
00010 #include "osl/eval/evalTraits.h"
00011 #include "osl/eval/pieceEval.h"
00012 #include "osl/state/numEffectState.h"
00013 #include "osl/progress/progress32.h"
00014 #include "osl/progress/effect5x3.h"
00015 #include "osl/progress/ml/newProgress.h"
00016 #include "osl/container/tripleInt.h"
00017 #include "osl/oslConfig.h"
00018 
00019 #define USE_TEST_PROGRESS
00020 // NewProgressが学習可能な場合に定義 (現在はosl側に変更はないので常に定義)
00021 #define LEARN_TEST_PROGRESS
00022 
00023 namespace osl
00024 {
00025   namespace eval
00026   {
00027     namespace ml
00028     {
00029       using namespace osl::progress::ml;
00030       class OpenMidEndingPtypeTable : public PtypeEvalTable
00031       {
00032       public:
00033         OpenMidEndingPtypeTable();
00034       };
00035 
00036       struct OpenMidEndingEvalDebugInfo
00037       {
00038         enum StageFeature
00039         {
00040           KING_PIECE_RELATIVE,
00041           PIECE_STAND,
00042           KING25_EFFECT_EACH,
00043           PTYPEX,
00044           PTYPEY,
00045           ROOK_MOBILITY,
00046           BISHOP_MOBILITY,
00047           LANCE_MOBILITY,
00048           ROOK_EFFECT,
00049           BISHOP_EFFECT,
00050           PIECE_STAND_COMBINATION,
00051           PIECE_STAND_TURN,
00052           ROOK_PAWN,
00053           PAWN_DROP,
00054           PIECE_STAND_Y,
00055           KNIGHT_CHECK,
00056           PAWN_ADVANCE,
00057           PAWN_PTYPEO,
00058           PROMOTED_MINOR_PIECE,
00059           KING_PIECE_RELATIVE_NOSUPPORT,
00060           NON_PAWN_ATTACKED,
00061           NON_PAWN_ATTACKED_PTYPE,
00062           PTYPE_YY,
00063           KING3PIECES,
00064           BISHOP_HEAD,
00065           KNIGHT_HEAD,
00066           ROOK_PROMOTE_DEFENSE,
00067           PTYPE_COUNT,
00068           LANCE_EFFECT_PIECE,
00069           PTYPE_Y_PAWN_Y,
00070           BISHOP_AND_KING,
00071           PIECE_FORK_TURN,
00072           ROOK_SILVER_KNIGHT,
00073           BISHOP_SILVER_KNIGHT,
00074           KING25_EFFECT_SUPPORTED,
00075           KING_ROOK_BISHOP,
00076           KING_X_BLOCKED3,
00077           GOLD_RETREAT,
00078           SILVER_RETREAT,
00079           ALL_GOLD,
00080           ALL_MAJOR,
00081           KING25_EFFECT_DEFENSE,
00082           ANAGUMA_EMPTY,
00083           NO_PAWN_ON_STAND,
00084           NON_PAWN_PIECE_STAND,
00085           PIN_PTYPE_ALL,
00086           KING_MOBILITY,
00087           GOLD_AND_SILVER_NEAR_KING,
00088           PTYPE_COMBINATION,
00089           KING25_BOTH_SIDE,
00090           KING25_MOBILITY,
00091           BISHOP_STAND_FILE5,
00092           MAJOR_CHECK_WITH_CAPTURE,
00093           SILVER_ADVANCE26,
00094           KING25_EFFECT3,
00095           BISHOP_BISHOP_PIECE,
00096           ROOK_ROOK,
00097           ROOK_ROOK_PIECE,
00098           KING25_EFFECT_COUNT_COMBINATION,
00099           NON_PAWN_ATTACKED_PTYPE_PAIR,
00100           ATTACK_MAJORS_IN_BASE,
00101           STAGE_FEATURE_LIMIT
00102         };
00103         enum ProgressIndependentFeature
00104         {
00105           PIECE,
00106           BISHOP_EXCHANGE_SILVER_KING, // recalculated_value
00107           ENTER_KING_DEFENSE,
00108           KING25_EFFECT_ATTACK, // end recalculated_value
00109           PIECE_PAIR,
00110           PIECE_PAIR_KING,
00111           PROGRESS_INDEPENDENT_FEATURE_LIMIT
00112         };
00113         int value;
00114         int progress;
00115         CArray<int, PROGRESS_INDEPENDENT_FEATURE_LIMIT> progress_independent_values;
00116         CArray<MultiInt, STAGE_FEATURE_LIMIT> stage_values;
00117 
00118         static const char *name(ProgressIndependentFeature);
00119         static const char *name(StageFeature);
00120       };
00121 
00122       class OpenMidEndingEval
00123       {
00124       private:
00125         enum { INVALID=EvalTraits<BLACK>::MAX_VALUE+1 };
00126         enum {
00128           ProgressIndependentValueLimit = 4000
00129         };
00130         enum LoadStatus { Zero=0, Loaded, Random };
00131         static volatile LoadStatus initialized_flag;
00132         static Weights piece_pair_weights;
00133 #ifdef USE_TEST_PROGRESS
00134         typedef osl::progress::ml::NewProgress progress_t;
00135 #else
00136         typedef osl::progress::Effect5x3 progress_t;
00137 #endif
00138         progress_t progress;
00139         MultiIntPair kingx_blocked, king25_effect_each;
00140         MultiIntPair king25_both_side,king_rook_bishop;
00141         MultiIntPair piece_stand_turn, non_pawn_attacked,
00142           non_pawn_attacked_ptype, piece_fork_turn;
00143         MultiInt ptypey, ptypex, king_table_value;
00144         MultiInt piece_stand_value, recalculated_stage_value, pawn_advance;
00145         MultiInt rook_mobility, bishop_mobility, lance_mobility;
00146         MultiInt knight_advance, pawn_drop, promoted_minor_piece, rook_pawn,
00147           rook_effect, bishop_effect, bishop_head, nosupport, ptype_yy, king3pieces;
00148         MultiInt rook_promote_defense;
00149         MultiInt piece_stand_combination, piece_stand_y, knight_check,
00150           knight_head, pawn_ptypeo, ptype_count_value, lance_effect_piece,
00151           ptype_y_pawn_y, bishop_and_king, rook_silver_knight, bishop_silver_knight;
00152         CArray<BoardMask, 2> knight_fork_squares;
00153         CArray<PieceMask, 2> effect25; // index: owner of king
00154         CArray<PieceMask, 2> effect25_supported; // index: owner of king
00155         CArray<PieceMask, 2> effected_mask;
00156         CArray<PieceMask, 2> effected_mask_for_attacked;
00157         CArray<PieceMask, 40> attacked_mask;
00158         CArray<int, 5>  black_vertical, white_vertical,
00159           black_king_vertical, white_king_vertical;
00160         // flat
00161         CArray<int,2> piece_pair_king_value;
00162         CArray<int, 2> non_pawn_stand_count;
00163         CArray2d<int, 2, 3> gs_near_king_count;
00164         CArray2d<int, 2, PTYPE_SIZE> ptype_count, ptype_board_count;
00165         CArray<std::pair<Square,int>, 2> knight_drop, silver_drop, bishop_drop, rook_drop;
00166         CArray2d<int, 2, 9> pawns;
00167         int progress_independent_value, // should be renamed to piece
00168           recalculated_value, piece_pair_value;
00169         int black_pawn_count;
00170         int black_major_count, black_gold_count;
00171         int black_attack_effect, black_attack_piece,
00172           white_attack_effect, white_attack_piece,
00173           black_attack_supported_piece, white_attack_supported_piece;
00174         int black_defense_effect, black_defense_piece,
00175           white_defense_effect, white_defense_piece;
00176         mutable int cache;
00177         Player turn;
00178         unsigned int ptypeo_mask;
00179         CArray<bool, 2> can_check; // king is defense
00180         bool use_progress_independent_value_limit;
00181         static const int ROUND_UP = 2;
00182         static int roundUp(int v)
00183         {
00184           return v & (~(ROUND_UP-1)); 
00185         }
00186         void updateGoldSilverNearKing(const NumEffectState &state)
00187         {
00188           const CArray<Square,2> kings = {{ 
00189               state.kingSquare(BLACK),
00190               state.kingSquare(WHITE),
00191             }};
00192           gs_near_king_count.fill(0);
00193           for (int i = PtypeTraits<GOLD>::indexMin;
00194                i < PtypeTraits<GOLD>::indexLimit; ++i)
00195           {
00196             const Piece p = state.pieceOf(i);
00197             if (p.isOnBoard())
00198             {
00199               const Square pos = p.square();
00200               const int y_diff = std::abs(pos.y() - kings[p.owner()].y());
00201               const int x_diff = std::abs(pos.x() - kings[p.owner()].x());
00202               if (y_diff <= 2 && x_diff <= 3)
00203               {
00204                 ++gs_near_king_count[p.owner()][std::max(x_diff, y_diff) - 1];
00205               }
00206             }
00207           }
00208           for (int i = PtypeTraits<SILVER>::indexMin;
00209                i < PtypeTraits<SILVER>::indexLimit; ++i)
00210           {
00211             const Piece p = state.pieceOf(i);
00212             if (p.isOnBoard())
00213             {
00214               const Square pos = p.square();
00215               const int y_diff = std::abs(pos.y() - kings[p.owner()].y());
00216               const int x_diff = std::abs(pos.x() - kings[p.owner()].x());
00217               if (y_diff <= 2 && x_diff <= 3)
00218               {
00219                 ++gs_near_king_count[p.owner()][std::max(x_diff, y_diff) - 1];
00220               }
00221             }
00222           }
00223         }
00224       public:
00225         explicit OpenMidEndingEval(const NumEffectState &state, bool limit_progress_independent_value=! OslConfig::hasByoyomi());
00226         void changeTurn() { }
00227         static bool initialized()
00228         {
00229           return initialized_flag;
00230         }
00231         static bool setUp(const char *filename);
00232         static bool setUp();
00233         static std::string defaultFilename();
00234         int progressIndependentValue() const 
00235         {
00236           return progress_independent_value + recalculated_value + piece_pair_value
00237             + piece_pair_king_value[BLACK] + piece_pair_king_value[WHITE];
00238         }
00239         void debug() const;
00240         MultiInt stageValue() const 
00241         {
00242           return king_table_value + piece_stand_value +
00243             king25_effect_each[BLACK] + king25_effect_each[WHITE] +
00244             ptypex + ptypey + rook_mobility + bishop_mobility + lance_mobility +
00245             rook_effect + bishop_effect +
00246             piece_stand_combination + piece_stand_turn[turn] +
00247             rook_pawn + pawn_drop + piece_stand_y + knight_check +
00248             pawn_advance + pawn_ptypeo + promoted_minor_piece +
00249             nosupport +
00250             non_pawn_attacked[turn] + non_pawn_attacked_ptype[turn] +
00251             ptype_yy + king3pieces + bishop_head + knight_head
00252             + rook_promote_defense +
00253             ptype_count_value + lance_effect_piece + ptype_y_pawn_y +
00254             bishop_and_king + piece_fork_turn[turn] + rook_silver_knight + bishop_silver_knight +
00255             recalculated_stage_value;
00256         }
00257         int openingValue() const 
00258         {
00259           return (king_table_value[0] +
00260                   piece_stand_value[0] +
00261                   king25_effect_each[BLACK][0] + king25_effect_each[WHITE][0] +
00262                   ptypex[0] +
00263                   ptypey[0] +
00264                   rook_mobility[0] +
00265                   bishop_mobility[0] +
00266                   lance_mobility[0] +
00267                   rook_effect[0] +
00268                   bishop_effect[0] +
00269                   piece_stand_combination[0] + 
00270                   piece_stand_turn[turn][0] +
00271                   rook_pawn[0] +
00272                   pawn_drop[0] +
00273                   piece_stand_y[0] +
00274                   knight_check[0] +
00275                   pawn_advance[0] +
00276                   pawn_ptypeo[0] +
00277                   promoted_minor_piece[0] +
00278                   nosupport[0] +
00279                   non_pawn_attacked[turn][0] +
00280                   non_pawn_attacked_ptype[turn][0] +
00281                   ptype_yy[0] +
00282                   king3pieces[0] +
00283                   bishop_head[0] +
00284                   knight_head[0] +
00285                   rook_promote_defense[0] +
00286                   ptype_count_value[0] +
00287                   lance_effect_piece[0] +
00288                   ptype_y_pawn_y[0] +
00289                   bishop_and_king[0] +
00290                   piece_fork_turn[turn][0] +
00291                   rook_silver_knight[0] +
00292                   bishop_silver_knight[0] +
00293                   recalculated_stage_value[0]);
00294         }
00295         int midgameValue() const 
00296         {
00297           return (king_table_value[1] +
00298                   piece_stand_value[1] +
00299                   king25_effect_each[BLACK][1] + king25_effect_each[WHITE][1] +
00300                   ptypex[1] +
00301                   ptypey[1] +
00302                   rook_mobility[1] +
00303                   bishop_mobility[1] +
00304                   lance_mobility[1] +
00305                   rook_effect[1] +
00306                   bishop_effect[1] +
00307                   piece_stand_combination[1] + 
00308                   piece_stand_turn[turn][1] +
00309                   rook_pawn[1] +
00310                   pawn_drop[1] +
00311                   piece_stand_y[1] +
00312                   knight_check[1] +
00313                   pawn_advance[1] +
00314                   pawn_ptypeo[1] +
00315                   promoted_minor_piece[1] +
00316                   nosupport[1] +
00317                   non_pawn_attacked[turn][1] +
00318                   non_pawn_attacked_ptype[turn][1] +
00319                   ptype_yy[1] +
00320                   king3pieces[1] +
00321                   bishop_head[1] +
00322                   knight_head[1] +
00323                   rook_promote_defense[1] +
00324                   ptype_count_value[1] +
00325                   lance_effect_piece[1] +
00326                   ptype_y_pawn_y[1] +
00327                   bishop_and_king[1] +
00328                   piece_fork_turn[turn][1] +
00329                   rook_silver_knight[1] +
00330                   bishop_silver_knight[1] +
00331                   recalculated_stage_value[1]);
00332         }
00333         int midgame2Value() const 
00334         {
00335           return (king_table_value[2] +
00336                   piece_stand_value[2] +
00337                   king25_effect_each[BLACK][2] + king25_effect_each[WHITE][2] +
00338                   ptypex[2] +
00339                   ptypey[2] +
00340                   rook_mobility[2] +
00341                   bishop_mobility[2] +
00342                   lance_mobility[2] +
00343                   rook_effect[2] +
00344                   bishop_effect[2] +
00345                   piece_stand_combination[2] + 
00346                   piece_stand_turn[turn][2] +
00347                   rook_pawn[2] +
00348                   pawn_drop[2] +
00349                   piece_stand_y[2] +
00350                   knight_check[2] +
00351                   pawn_advance[2] +
00352                   pawn_ptypeo[2] +
00353                   promoted_minor_piece[2] +
00354                   nosupport[2] +
00355                   non_pawn_attacked[turn][2] +
00356                   non_pawn_attacked_ptype[turn][2] +
00357                   ptype_yy[2] +
00358                   king3pieces[2] +
00359                   bishop_head[2] +
00360                   knight_head[2] +
00361                   rook_promote_defense[2] +
00362                   ptype_count_value[2] +
00363                   lance_effect_piece[2] +
00364                   ptype_y_pawn_y[2] +
00365                   bishop_and_king[2] +
00366                   piece_fork_turn[turn][2] +
00367                   rook_silver_knight[2] +
00368                   bishop_silver_knight[2] +
00369                   recalculated_stage_value[2]);
00370         }
00371         int endgameValue() const 
00372         {
00373           return (king_table_value[EndgameIndex] +
00374                   piece_stand_value[EndgameIndex] +
00375                   king25_effect_each[BLACK][EndgameIndex] + king25_effect_each[WHITE][EndgameIndex] +
00376                   ptypex[EndgameIndex] +
00377                   ptypey[EndgameIndex] +
00378                   rook_mobility[EndgameIndex] +
00379                   bishop_mobility[EndgameIndex] +
00380                   lance_mobility[EndgameIndex] +
00381                   rook_effect[EndgameIndex] +
00382                   bishop_effect[EndgameIndex] +
00383                   piece_stand_combination[EndgameIndex] + 
00384                   piece_stand_turn[turn][EndgameIndex] +
00385                   rook_pawn[EndgameIndex] +
00386                   pawn_drop[EndgameIndex] +
00387                   piece_stand_y[EndgameIndex] +
00388                   pawn_advance[EndgameIndex] +
00389                   knight_check[EndgameIndex] +
00390                   pawn_ptypeo[EndgameIndex] +
00391                   promoted_minor_piece[EndgameIndex] +
00392                   nosupport[EndgameIndex] +
00393                   non_pawn_attacked[turn][EndgameIndex] +
00394                   non_pawn_attacked_ptype[turn][EndgameIndex] +
00395                   ptype_yy[EndgameIndex] +
00396                   king3pieces[EndgameIndex] +
00397                   bishop_head[EndgameIndex] +
00398                   knight_head[EndgameIndex] +
00399                   rook_promote_defense[EndgameIndex] +
00400                   ptype_count_value[EndgameIndex] +
00401                   lance_effect_piece[EndgameIndex] +
00402                   ptype_y_pawn_y[EndgameIndex] +
00403                   bishop_and_king[EndgameIndex] +
00404                   piece_fork_turn[turn][EndgameIndex] +
00405                   rook_silver_knight[EndgameIndex] +
00406                   bishop_silver_knight[EndgameIndex] +
00407                   recalculated_stage_value[EndgameIndex]);
00408         }
00409         void invalidateCache() { cache=INVALID; }
00410         static int progressIndependentValueAdjusted(int value, int progress,
00411                                                     int progress_max)
00412         {
00413           if (value > ProgressIndependentValueLimit) {
00414             int diff = value - ProgressIndependentValueLimit;
00415             value = ProgressIndependentValueLimit
00416               + diff * progress/progress_max;
00417           }
00418           else if (value < -ProgressIndependentValueLimit) {
00419             int diff = value + ProgressIndependentValueLimit;
00420             value = -ProgressIndependentValueLimit
00421               + diff * progress/progress_max;
00422           }
00423           return value;
00424         }
00425         int composeOpenMidEndgame() const
00426         {
00427           const int progress_max = NewProgress::maxProgress(), c = progress_max/2;
00428           const int progress = this->progress.progress();
00429           int progress_independent = use_progress_independent_value_limit
00430             ? progressIndependentValueAdjusted
00431             (progressIndependentValue(), progress, progress_max)
00432             : progressIndependentValue();
00433           int sum = progress_independent * progress_max;
00434           if (progress < c) 
00435           {
00436             sum += openingValue() * 2*(c - progress);
00437             sum += midgameValue() * 2*progress;
00438           }
00439           else 
00440           {
00441             sum += midgameValue() * 2*(progress_max - progress);
00442             sum += endgameValue() * 2*(progress - c);
00443           }
00444           return sum;
00445         }
00446 #ifdef EVAL_QUAD
00447         int composeOpenMid2Endgame() const
00448         {
00449           const int progress_max = NewProgress::maxProgress();
00450           const int progress = this->progress.progress();
00451           const int c0 = progress_max/3, c1 = c0*2;
00452 #ifndef NDEBUG
00453           const int w2 = progress_max - c1;
00454 #endif
00455           assert(c0 == w2);
00456           int progress_independent = use_progress_independent_value_limit
00457             ? progressIndependentValueAdjusted
00458             (progressIndependentValue(), progress, progress_max)
00459             : progressIndependentValue();
00460           int sum = progress_independent * c0;
00461           const MultiInt stage_sum = stageValue();
00462           if (progress < c0) 
00463           {
00464             sum += stage_sum[0] * (c0 - progress);
00465             sum += stage_sum[1] * progress;
00466           }
00467           else if (progress < c1) 
00468           {
00469             sum += stage_sum[1] * (c1 - progress);
00470             sum += stage_sum[2] * (progress-c0);
00471           }
00472           else 
00473           {
00474             sum += stage_sum[2] * (progress_max - progress);
00475             sum += stage_sum[3] * (progress - c1);
00476           }
00477           return sum;
00478         }
00479 #endif
00480         int value() const
00481         {
00482           if (cache==INVALID) 
00483           {
00484 #ifdef USE_TEST_PROGRESS
00485 #  ifdef EVAL_QUAD
00486             cache = roundUp(composeOpenMid2Endgame());
00487 #  else
00488             cache = roundUp(composeOpenMidEndgame());
00489 #  endif
00490 #else
00491 #  ifdef EVAL_QUAD
00492 #    error "not supported"
00493 #  else
00494             cache = roundUp(progressIndependentValue() * 16 +
00495                             openingValue() * (16 - progress.progress16().value()) + 
00496                             endgameValue() * progress.progress16().value());
00497 #  endif
00498 #endif
00499           }
00500           return cache;
00501         }
00502         const Move suggestMove(const NumEffectState& state) const
00503         {
00504           assert(turn == state.turn());
00505           Move suggest;
00506           int best_value = 0;
00507           if (! rook_drop[turn].first.isPieceStand()) {
00508             assert(state.hasPieceOnStand(turn, ROOK));
00509             suggest = Move(rook_drop[turn].first, ROOK, turn);
00510             best_value = rook_drop[turn].second;
00511           }
00512           assert(best_value >= 0);
00513           if (bishop_drop[turn].second > best_value) {
00514             assert(! bishop_drop[turn].first.isPieceStand());
00515             assert(state.hasPieceOnStand(turn, BISHOP));
00516             suggest = Move(bishop_drop[turn].first, BISHOP, turn);
00517             best_value = bishop_drop[turn].second;
00518           }
00519           if (silver_drop[turn].second > best_value) {
00520             assert(! silver_drop[turn].first.isPieceStand());
00521             assert(state.hasPieceOnStand(turn, SILVER));
00522             suggest = Move(silver_drop[turn].first, SILVER, turn);
00523             best_value = silver_drop[turn].second;
00524           }
00525           if (knight_drop[turn].second > best_value
00526               && state.hasPieceOnStand(turn, KNIGHT)) {
00527             assert(! knight_drop[turn].first.isPieceStand());
00528             suggest = Move(knight_drop[turn].first, KNIGHT, turn);
00529             best_value = knight_drop[turn].second;
00530           }
00531           return suggest;
00532         }
00533         int expect(const NumEffectState &state, Move move) const;
00534         template<Player P>
00535         void updateSub(const NumEffectState &new_state, Move last_move);
00536         void update(const NumEffectState &new_state, Move last_move);
00537         const Progress32 progress32() const
00538         { 
00539           return Progress32(progress.progress16(BLACK).value()
00540                             + progress.progress16(WHITE).value()); 
00541         }
00542         const Progress16 progress16() const { return progress.progress16(); }
00543       public:
00544         static int infty()
00545         {
00546 #ifdef USE_TEST_PROGRESS
00547 #  ifdef EVAL_QUAD
00548           assert(NewProgress::maxProgress() % 3 == 0);
00549           return 57984 * (NewProgress::maxProgress()/3);
00550 #  else
00551           return 57984 * NewProgress::maxProgress();
00552 #  endif
00553 #else
00554           return 57984 * 16;
00555 #endif
00556         }
00557         static int captureValue(PtypeO ptypeO) {
00558           assert(isValidPtypeO(ptypeO));
00559           return roundUp((-PieceEval::value(ptypeO) +
00560                           PieceEval::value(captured(ptypeO))) * seeScale());
00561         }
00562         static int seeScale() {
00563 #ifdef USE_TEST_PROGRESS
00564 #  ifdef EVAL_QUAD
00565           assert(NewProgress::maxProgress() % 3 == 0);
00566           return (NewProgress::maxProgress()/3);
00567 #  else
00568           return NewProgress::maxProgress();
00569 #  endif
00570 #else
00571           return 16;
00572 #endif
00573         }
00574 
00575         OpenMidEndingEvalDebugInfo debugInfo(const NumEffectState &state);
00576         static void setRandom();
00577         static void resetWeights(const int *w, size_t length);
00578         static OpenMidEndingPtypeTable Piece_Value;
00579         bool progressIndependentValueLimit() const {
00580           return use_progress_independent_value_limit;
00581         }
00582       private:
00583         template <class Reader>
00584         static void doResetWeights(Reader& reader);
00585       };
00586     }
00587   }
00588 }
00589 
00590 #endif // EVAL_ML_OPENMIDENDINGEVAL_H
00591 // ;;; Local Variables:
00592 // ;;; mode:c++
00593 // ;;; c-basic-offset:2
00594 // ;;; coding:utf-8
00595 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines