File indexing completed on 2024-11-24 03:43:17

0001 /*******************************************************************
0002  *
0003  * Copyright 2009  Pelladi Gabor <pelladigabor@gmail.com>
0004  *
0005  * Bovo is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation; either version 2, or (at your option)
0008  * any later version.
0009  *
0010  * Bovo is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU General Public License
0016  * along with Bovo; see the file COPYING.  If not, write to
0017  * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
0018  * Boston, MA 02110-1301, USA.
0019  *
0020  ********************************************************************/
0021 
0022 #include "node.h"
0023 #include "ai_impl.h"
0024 
0025 #include <cassert>
0026 
0027 Node::Node(Standing *_standing, AiImpl *ai)
0028     : standing(_standing)
0029     , parent(nullptr)
0030     , child(nullptr)
0031     , depth(0)
0032     , signum(_standing->current == 0 ? 1 : -1)
0033     , alpha(MinHeur - 1)
0034     , beta(MaxHeur + 1)
0035     , is_exact(false)
0036     , evaluated(false)
0037     , depth_limit(ai->depth_limit)
0038     , max_branch(ai->max_branch)
0039 {
0040     generateSteps();
0041 }
0042 
0043 Node::Node(Standing *_standing, Node *_parent)
0044     : standing(_standing)
0045     , parent(_parent)
0046     , child(nullptr)
0047     , depth(_parent->depth + 1)
0048     , signum(-(_parent->signum))
0049     , alpha(_parent->alpha)
0050     , beta(_parent->beta)
0051     , is_exact(false)
0052     , evaluated(false)
0053     , depth_limit(_parent->depth_limit)
0054     , max_branch(_parent->max_branch)
0055 {
0056     generateSteps();
0057 }
0058 
0059 Node::~Node()
0060 {
0061     delete child;
0062     delete standing;
0063     qDeleteAll(steps);
0064 }
0065 
0066 void Node::generateSteps()
0067 {
0068     steps.clear();
0069     if (depth >= depth_limit || standing->target) {
0070         heur_T hv = standing->hval;
0071         heur_T decay = depth_decay * depth;
0072         if (hv > 0)
0073             hv -= decay;
0074         else if (hv < 0)
0075             hv += decay;
0076         if (-decay <= hv && hv <= decay)
0077             hv = 0;
0078         alpha = beta = hv;
0079         evaluated = true;
0080         return;
0081     }
0082 
0083     suggestions_T suggestions;
0084     standing->getSuggestions(suggestions);
0085 
0086     for (suggestions_T::iterator s = suggestions.begin(); s != suggestions.end(); ++s) {
0087         pos_T x = s->x;
0088         pos_T y = s->y;
0089         assert(!standing->table[x][y]);
0090         auto p = new Standing(*this->standing);
0091         p->step(x, y);
0092 
0093         heur_T pv = p->hval * signum;
0094         steps_T::iterator i;
0095         for (i = steps.begin(); i != steps.end() && signum * (*i)->hval > pv; ++i)
0096             ;
0097         steps.insert(i, p);
0098 
0099         // we only keep the best looking positions
0100         if ((unsigned int)steps.size() > max_branch) {
0101             delete steps.back();
0102             steps.pop_back();
0103         }
0104     }
0105     assert(steps.size() > 0);
0106 }
0107 
0108 void Node::calcHash(hash_T *hash, NodeHashData *data)
0109 {
0110     data->remaining_depth = depth_limit - depth;
0111     assert(data->remaining_depth > 0);
0112 
0113     hash_T c_hash = 0;
0114     for (int i = 0; i < standing->table_size_x; i++) {
0115         for (int j = 0; j < standing->table_size_y; j++) {
0116             c_hash = c_hash * 3145 + standing->table[i][j];
0117         }
0118     }
0119     c_hash += standing->current;
0120     data->checksum = c_hash;
0121 
0122     c_hash = 0;
0123     for (int i = 0; i < standing->table_size_x; i++) {
0124         for (int j = 0; j < standing->table_size_y; j++) {
0125             c_hash = (c_hash * 5313 + standing->table[i][j]) % nodeHashSize;
0126         }
0127     }
0128     c_hash += standing->current;
0129     *hash = c_hash;
0130 }