Changeset 23 for trunk


Ignore:
Timestamp:
Dec 19, 2005, 1:26:09 PM (14 years ago)
Author:
jtv
Message:

Work on intelligence level 3... Not working yet though

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/gamelogic.cxx

    r22 r23  
    3131
    3232
     33#include<iostream>// DEBUG CODE
    3334namespace
    3435{
     
    183184  }
    184185};
     186
     187
     188bool are_neighbours(Coords a, Coords b)
     189{
     190  return abs(a.row-b.row) <= 1 && abs(a.col-b.col) <= 1;
     191}
     192
    185193
    186194/// Is Patch a candidate for "superset detection" based on newly revealed Patch?
     
    205213    m_rc(nr)
    206214  {
    207     assert(newly_revealed.revealed());
     215    assert(is_candidate(newly_revealed));
     216  }
     217
     218  /// Can this patch possibly qualify for subset/superset recognition?
     219  static bool is_candidate(const Patch &p) throw ()
     220  {
     221    return p.revealed() && p.near_unknown() && p.near_unknown() < 5;
    208222  }
    209223
    210224  void operator()(Coords c, const Patch &p)
    211225  {
    212     if (p.revealed())
     226    assert(are_neighbours(c,m_rc));
     227    if (is_candidate(p))
    213228    {
     229      assert(&p != &m_revealed);
    214230      const int areadiff = p.near_unknown() - m_revealed.near_unknown();
    215231      if (areadiff > 0)
     
    225241  Coords m_rc;
    226242
     243  /// How many neighbours do two neighbours a and b have in common?
     244  static int common_neighbours(Coords a, Coords b) throw ()
     245  {
     246    // Assuming that a and b are neighbours, there are only two cases: either
     247    // they lie on the same row or column, in which case they share 4 common
     248    // neighbours; or they touch diagonally, in which they have only two
     249    // neighbours in common.
     250    return (a.row==b.row||a.col==b.col) ? 4 : 2;
     251  }
     252
    227253  void consider(Coords subc, const Patch &subp,
    228254      Coords supc, const Patch &supp,
     
    230256  {
    231257    assert(areadiff > 0);
    232     if (supp.near_hiddenmines() == subp.near_hiddenmines() ||
    233     supp.near_hiddenmines() == areadiff)
     258    if (subp.near_unknown() <= common_neighbours(subc,supc) &&
     259    (supp.near_hiddenmines() == subp.near_hiddenmines() ||
     260     supp.near_hiddenmines() == areadiff))
    234261      m_worklist.insert(make_pair(subc,supc));
    235262  }
    236263};
    237264
     265
     266void common_neighbours(Coords a, Coords b, set<Coords> &output)
     267{
     268  assert(a < b || b < a);
     269  if (a.row == b.row)
     270  {
     271    assert(abs(a.col-b.col)==1);
     272    output.insert(Coords(a.row-1,a.col));
     273    output.insert(Coords(a.row-1,b.col));
     274    output.insert(Coords(a.row+1,a.col));
     275    output.insert(Coords(a.row+1,b.col));
     276  }
     277  else if (a.col == b.col)
     278  {
     279    assert(abs(a.row-b.row)==1);
     280    output.insert(Coords(a.row,a.col-1));
     281    output.insert(Coords(a.row,a.col+1));
     282    output.insert(Coords(b.row,a.col-1));
     283    output.insert(Coords(b.row,a.col+1));
     284  }
     285  else
     286  {
     287    assert(abs(a.row-b.row)==1);
     288    assert(abs(a.col-b.col)==1);
     289    output.insert(Coords(a.row,b.col));
     290    output.insert(Coords(b.row,a.col));
     291  }
     292}
     293
     294
     295/// Add unrevealed patches that are not neighbours of given patch to set
     296class NotNear
     297{
     298public:
     299  NotNear(Coords c, set<Coords> &work) : m_worklist(work), m_remote(c) {}
     300
     301  void operator()(Coords c, const Patch &p) const
     302  {
     303    if (!p.revealed() && !are_neighbours(c, m_remote)) m_worklist.insert(c);
     304  }
     305
     306private:
     307  set<Coords> &m_worklist;
     308  Coords m_remote;
     309};
    238310
    239311} // namespace
     
    507579      {
    508580    const Patch &p = at(i->row, i->col);
    509         if (p.revealed()) for_neighbours(i->row, i->col, SuperSet(cand,*i,p));
     581        if (SuperSet::is_candidate(p))
     582      for_neighbours(i->row, i->col, SuperSet(cand,*i,p));
    510583      }
    511584     
    512       // TODO: Iterate through candidates to find the *real* superset cases
     585      // Iterate through candidates to find the *real* superset cases
    513586      for (SuperSet::PairList::const_iterator i = cand.begin();
    514587       i != cand.end();
    515588       ++i)
    516589      {
     590    assert(are_neighbours(i->first,i->second));
     591
     592    set<Coords> overlap;
     593    common_neighbours(i->first,i->second, overlap);
     594    int subset_togo = at(i->first.row,i->first.col).near_unknown();
     595    // Verify that the number of unrevealed patches among the pair's set of
     596    // common neighbours accounts for all of the unrevealed neighbours of
     597    // the first ("subset") of the two
     598    for (set<Coords>::const_iterator j = overlap.begin();
     599         j != overlap.end();
     600         ++j)
     601    {
     602      assert(are_neighbours(i->first,*j));
     603      assert(are_neighbours(i->second,*j));
     604      subset_togo -= !at(j->row,j->col).revealed();
     605    }
     606    assert(subset_togo >= 0);
     607
     608    if (!subset_togo)
     609    {
     610      // All unrevealed neighbours accounted for!  All other unrevealed
     611      // neighbours of the second patch that are not neighbours of the first
     612      // can be revealed.
     613      for_neighbours(i->second.row, i->second.col, NotNear(i->first, next));
     614    }
    517615      }
    518616    }
  • trunk/ui_cli.cxx

    r22 r23  
    8585int main()
    8686{
    87   int rows=20, cols=30, mines=200;
     87  int rows=20, cols=30, mines=250;
    8888
    8989  srand(getpid()^time(NULL));
Note: See TracChangeset for help on using the changeset viewer.