Lab_Colour ColourPickerConversions::toLab(RGB_Colour colour) { float X = toX(colour.r, colour.g, colour.b); float Y = toY(colour.r, colour.g, colour.b); float Z = toZ(colour.r, colour.g, colour.b); float L = toL(Y); float a = toA(X, Y); float b = toB(Y, Z); return Lab_Colour(L, a, b); }
// 基本思考ルーチン::depthMax手読み int AI::think(LightField &self, LightField &enemy, int depth, int timeLimit) { if (calls_count++ > 1000) { checkTime(); calls_count = 0; } // rootからの手数 int ply = depth_max_ - depth; #ifdef HASH TTEntry *tte; // 同一局面が発生するのは2手目以降しかありえない。 if (ply > 0) { bool tt_hit = TT.probe<true>(&self, nullptr, tte); // 局面が登録されていた if (tt_hit) { assert(tte->depth() >= 0); // 局面表に登録されている局面が、現在の局面の残り深さ以上 if (tte->depth() >= depth) { best_[depth] = tte->move(); // 局面表のスコアは信用できるのでそのまま返す return tte->score(); } } } #endif if (depth <= DEPTH_ZERO) return evalate(self, enemy, depth, timeLimit); else { int score; int max = -SCORE_INFINITE - 1; int movenum; int con_prev[3]; self.saveConnect(con_prev); Move move[22];// おける場所は最大で22種類なので // 置く場所なし == 負け if ((movenum = self.generateMoves(move)) == 0) return -SCORE_INFINITE; self.nextPlus(); #if defined(DEBUG) LightField f = self;// debug #endif for (int i = 0; i < movenum; i++) { // generateMovesでもとめた場所においてみる self.doMove<true>(move[i]); assert(self.key() == self.keyInit()); // 設置にかかる時間を計算 // 落下にかかる時間は、13 - 設置位置のyの小さいほう ちぎりなら、余計に時間がかかる int takeTime = (13 - std::min(toY(move[i].csq()), toY(move[i].psq()))) * FALLTIME + (move[i].isTigiri() ? TAKETIME_INCLUDETIGIRI : TAKETIME); if (self.flag(VANISH))// 消えるなら { score = evalVanish(self, enemy, depth, timeLimit) - takeTime; self.clearFlag(VANISH); } else// 消えないとき { if (timeLimit < takeTime) { // 致死量振るときに発火できなければ負け。 if (enemy.scoreMax() >= 30 * RATE || enemy.scoreMax() >= self.deadLine() * RATE) score = -SCORE_INFINITE; else score = think(self, enemy, depth - ONE_PLY, timeLimit - takeTime) - takeTime; } else score = think(self, enemy, depth - ONE_PLY, timeLimit - takeTime) - takeTime; } self.undoMove(move[i], con_prev); if (stop) return SCORE_ZERO; if (max < score) { max = score; best_[depth] = move[i];// もっとも評価の高い手を選ぶ } #if defined DEBUG assert(self == f); // debug::きちんともとの局面に戻せているか #endif } self.nextMinus(); #ifdef HASH if (ply > 0) { // この探索では後ろ二つの引数は使わない tte->save(self.key(), best_[depth].get(), max, depth, TT.generation(), BOUND_EXACT, 0, 0, 0); } #endif return max; } }
//----------------------------------------------------------------------------// float ColourPickerConversions::toY(unsigned char R, unsigned char G, unsigned char B) { return toY(R / 255.0f, G / 255.0f, B / 255.0f); }