eliot-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Eliot-dev] eliot/game board_search.cpp cross.cpp cross.h [cppdic]


From: eliot-dev
Subject: [Eliot-dev] eliot/game board_search.cpp cross.cpp cross.h [cppdic]
Date: Fri, 14 Dec 2007 12:35:38 +0000

CVSROOT:        /cvsroot/eliot
Module name:    eliot
Branch:         cppdic
Changes by:     Olivier Teulière <ipkiss>      07/12/14 12:35:38

Modified files:
        game           : board_search.cpp cross.cpp cross.h 

Log message:
        Several search optimizations (which could have been done a long time 
ago...).
        The number of calls to some functions (like Dictionary::getCode()) 
drops by almost 20% on my test case!

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board_search.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.11.2.4&r2=1.11.2.5
http://cvs.savannah.gnu.org/viewcvs/eliot/game/cross.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.6.2.1&r2=1.6.2.2
http://cvs.savannah.gnu.org/viewcvs/eliot/game/cross.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.7.2.2&r2=1.7.2.3

Patches:
Index: board_search.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board_search.cpp,v
retrieving revision 1.11.2.4
retrieving revision 1.11.2.5
diff -u -b -r1.11.2.4 -r1.11.2.5
--- board_search.cpp    27 Nov 2007 18:01:05 -0000      1.11.2.4
+++ board_search.cpp    14 Dec 2007 12:35:37 -0000      1.11.2.5
@@ -110,9 +110,16 @@
     if (iTilesMx[iRow][iCol].isEmpty())
     {
         if (iDic.isEndOfWord(iNode) && iCol > iAnchor)
+        {
             BoardSearchEvalMove(iBoard, iTilesMx, iPointsMx, iJokerMx,
                                 iResults, ioPartialWord);
+        }
+
+        // Optimization: avoid entering the for loop if no tile can match
+        if (iCrossMx[iRow][iCol].isNone())
+            return;
 
+        bool hasJokerInRack = iRack.in(Tile::Joker());
         for (succ = iDic.getSucc(iNode); succ; succ = iDic.getNext(succ))
         {
             l = Tile(iDic.getChar(succ));
@@ -121,21 +128,21 @@
                 if (iRack.in(l))
                 {
                     iRack.remove(l);
-                    ioPartialWord.addRightFromRack(l, 0);
+                    ioPartialWord.addRightFromRack(l, false);
                     ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
                                 iJokerMx, iRack, ioPartialWord, iResults,
                                 succ, iRow, iCol + 1, iAnchor);
-                    ioPartialWord.removeRightToRack(l, 0);
+                    ioPartialWord.removeRightToRack(l, false);
                     iRack.add(l);
                 }
-                if (iRack.in(Tile::Joker()))
+                if (hasJokerInRack)
                 {
                     iRack.remove(Tile::Joker());
-                    ioPartialWord.addRightFromRack(l, 1);
+                    ioPartialWord.addRightFromRack(l, true);
                     ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
                                 iJokerMx, iRack, ioPartialWord, iResults,
                                 succ, iRow, iCol + 1, iAnchor);
-                    ioPartialWord.removeRightToRack(l, 1);
+                    ioPartialWord.removeRightToRack(l, true);
                     iRack.add(Tile::Joker());
                 }
             }
@@ -144,15 +151,19 @@
     else
     {
         l = iTilesMx[iRow][iCol];
+        wint_t upperChar = towupper(l.toChar());
         for (succ = iDic.getSucc(iNode); succ ; succ = iDic.getNext(succ))
         {
-            if ((wint_t)iDic.getChar(succ) == towupper(l.toChar()))
+            if ((wint_t)iDic.getChar(succ) == upperChar)
             {
                 ioPartialWord.addRightFromBoard(l);
                 ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
                             iJokerMx, iRack, ioPartialWord,
                             iResults, succ, iRow, iCol + 1, iAnchor);
                 ioPartialWord.removeRightToBoard(l);
+                // The letter will be present only once in the dictionary,
+                // so we can stop looping
+                break;
             }
         }
     }
@@ -177,31 +188,32 @@
 
     if (iLimit > 0)
     {
+        bool hasJokerInRack = iRack.in(Tile::Joker());
         for (succ = iDic.getSucc(n); succ; succ = iDic.getNext(succ))
         {
             l = Tile(iDic.getChar(succ));
             if (iRack.in(l))
             {
                 iRack.remove(l);
-                ioPartialWord.addRightFromRack(l, 0);
+                ioPartialWord.addRightFromRack(l, false);
                 
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() - 1);
                 LeftPart(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
                          iJokerMx, iRack, ioPartialWord, iResults,
                          succ, iRow, iAnchor, iLimit - 1);
                 
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() + 1);
-                ioPartialWord.removeRightToRack(l, 0);
+                ioPartialWord.removeRightToRack(l, false);
                 iRack.add(l);
             }
-            if (iRack.in(Tile::Joker()))
+            if (hasJokerInRack)
             {
                 iRack.remove(Tile::Joker());
-                ioPartialWord.addRightFromRack(l, 1);
+                ioPartialWord.addRightFromRack(l, true);
                 
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() - 1);
                 LeftPart(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
                          iJokerMx, iRack, ioPartialWord, iResults,
                          succ, iRow, iAnchor, iLimit - 1);
                 
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() + 1);
-                ioPartialWord.removeRightToRack(l, 1);
+                ioPartialWord.removeRightToRack(l, true);
                 iRack.add(Tile::Joker());
             }
         }
@@ -224,7 +236,7 @@
     vector<Tile> rackTiles;
     iRack.getTiles(rackTiles);
     vector<Tile>::const_iterator it;
-    bool match;
+    vector<Tile>::const_iterator itEnd;
 
     for (row = 1; row <= BOARD_DIM; row++)
     {
@@ -261,13 +273,13 @@
                 // Optimization compared to the original Appel & Jacobson
                 // algorithm: skip Leftpart if none of the tiles of the rack
                 // matches the cross mask for the current anchor
-                match = false;
-                for (it = rackTiles.begin();
-                     !match && it != rackTiles.end(); it++)
+                bool match = false;
+                for (it = rackTiles.begin(); it != rackTiles.end(); it++)
                 {
                     if (iCrossMx[row][col].check(*it))
                     {
                         match = true;
+                        break;
                     }
                 }
                 if (match)

Index: cross.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/cross.cpp,v
retrieving revision 1.6.2.1
retrieving revision 1.6.2.2
diff -u -b -r1.6.2.1 -r1.6.2.2
--- cross.cpp   5 Nov 2006 17:27:03 -0000       1.6.2.1
+++ cross.cpp   14 Dec 2007 12:35:38 -0000      1.6.2.2
@@ -22,26 +22,25 @@
 
 #define CROSS_MASK 0xFFFFFFFF
 
+
 Cross::Cross()
 {
     // The default behaviour is to match everything
     setAny();
 }
 
+
 void Cross::setAny()                   
 { 
     m_mask = CROSS_MASK;
 }
 
+
 bool Cross::isAny() const
 { 
     return m_mask == CROSS_MASK; 
 }
 
-void Cross::setNone()
-{
-    m_mask = 0;
-}
 
 string Cross::getHexContent() const
 {
@@ -51,22 +50,21 @@
     return s;
 }
 
+
 bool Cross::check(const Tile& iTile) const
 {
     return (iTile.isJoker() && m_mask != 0) || (m_mask & (1 << 
iTile.toCode()));
 }
 
+
 void Cross::insert(const Tile& iTile)
 { 
     m_mask |= (1 << iTile.toCode());
 }
 
+
 bool Cross::operator==(const Cross &iOther) const
 {
-    /* 
-     *  if (isAny() || iOther.isAny())
-     *    return isAny() && iOther.isAny();
-     */
     return m_mask == iOther.m_mask;
 }
 

Index: cross.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/cross.h,v
retrieving revision 1.7.2.2
retrieving revision 1.7.2.3
diff -u -b -r1.7.2.2 -r1.7.2.3
--- cross.h     13 Dec 2007 12:11:07 -0000      1.7.2.2
+++ cross.h     14 Dec 2007 12:35:38 -0000      1.7.2.3
@@ -36,10 +36,10 @@
     Cross();
 
     void setAny();
-    void setNone();
+    void setNone() { m_mask = 0; }
 
     bool isAny() const;
-    bool isNone() const;
+    bool isNone() const { return m_mask == 0; }
 
     bool check(const Tile& iTile) const;
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]