[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Eliot-dev] eliot configure.in dic/Makefile.am dic/compdic.... [cppdic]
From: |
eliot-dev |
Subject: |
[Eliot-dev] eliot configure.in dic/Makefile.am dic/compdic.... [cppdic] |
Date: |
Tue, 27 Nov 2007 18:01:07 +0000 |
CVSROOT: /cvsroot/eliot
Module name: eliot
Branch: cppdic
Changes by: Olivier Teulière <ipkiss> 07/11/27 18:01:07
Modified files:
. : configure.in
dic : Makefile.am compdic.cpp dic.cpp dic.h
dic_search.cpp header.cpp header.h
game : Makefile.am bag.cpp bag.h board.cpp
board_cross.cpp board_search.cpp freegame.cpp
game.cpp history.cpp pldrack.cpp rack.cpp
rack.h
utils : eliottxt.cpp game_io.cpp
wxwin : auxframes.cc searchpanel.cc
Added files:
dic : tile.cpp tile.h
m4 : ax_boost_base.m4
Removed files:
game : tile.cpp tile.h
Log message:
- Removed wrappers in the DicSearch functions (except the regexp
ones): wide characters are now handled directly
- Added support for letter points, frequency, and for vowel/consonant
information in the dictionary header
- Moved the Tile class from game/ to dic/
- The tiles points, frequency, vowel/consonant info are not hard-coded
anymore but taken from the dictionary header
- Removed the Tile::m_dummy attribute, it was confusing and not really
useful
- The Tile::getAllTiles() method has been moved to the Dictionary class
- The Rack class has been changed not to use the internal letter codes
anymore
- There is a new dependency on Boost (checked by configure). In fact,
only Boost.Tokenizer is used at the moment (which only provides header files,
no library)
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/configure.in?cvsroot=eliot&only_with_tag=cppdic&r1=1.19.2.2&r2=1.19.2.3
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/Makefile.am?cvsroot=eliot&only_with_tag=cppdic&r1=1.14.4.5&r2=1.14.4.6
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/compdic.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.2.8&r2=1.1.2.9
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.2.6&r2=1.1.2.7
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.13.2.4&r2=1.13.2.5
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic_search.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.2.2&r2=1.1.2.3
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/header.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.2.7&r2=1.1.2.8
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/header.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.2.5&r2=1.1.2.6
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/tile.cpp?cvsroot=eliot&only_with_tag=cppdic&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/tile.h?cvsroot=eliot&only_with_tag=cppdic&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/game/Makefile.am?cvsroot=eliot&only_with_tag=cppdic&r1=1.13.2.1&r2=1.13.2.2
http://cvs.savannah.gnu.org/viewcvs/eliot/game/bag.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.7.2.1&r2=1.7.2.2
http://cvs.savannah.gnu.org/viewcvs/eliot/game/bag.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.8.2.1&r2=1.8.2.2
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.14.2.3&r2=1.14.2.4
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board_cross.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.6.2.3&r2=1.6.2.4
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board_search.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.11.2.3&r2=1.11.2.4
http://cvs.savannah.gnu.org/viewcvs/eliot/game/freegame.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.18&r2=1.18.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.31.2.3&r2=1.31.2.4
http://cvs.savannah.gnu.org/viewcvs/eliot/game/history.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.10.2.1&r2=1.10.2.2
http://cvs.savannah.gnu.org/viewcvs/eliot/game/pldrack.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.9&r2=1.9.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/game/rack.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.7&r2=1.7.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/game/rack.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.9&r2=1.9.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/game/tile.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/game/tile.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.8&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/m4/ax_boost_base.m4?cvsroot=eliot&only_with_tag=cppdic&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/eliottxt.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.16.2.6&r2=1.16.2.7
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/game_io.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.9.2.2&r2=1.9.2.3
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/auxframes.cc?cvsroot=eliot&only_with_tag=cppdic&r1=1.22.2.2&r2=1.22.2.3
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/searchpanel.cc?cvsroot=eliot&only_with_tag=cppdic&r1=1.15.2.1&r2=1.15.2.2
Patches:
Index: configure.in
===================================================================
RCS file: /cvsroot/eliot/eliot/configure.in,v
retrieving revision 1.19.2.2
retrieving revision 1.19.2.3
diff -u -b -r1.19.2.2 -r1.19.2.3
--- configure.in 11 Nov 2007 19:56:57 -0000 1.19.2.2
+++ configure.in 27 Nov 2007 18:01:04 -0000 1.19.2.3
@@ -86,12 +86,12 @@
AC_TYPE_SIZE_T
AC_C_BIGENDIAN
AC_C_INLINE
-AC_CHECK_SIZEOF(char, 1)
-AC_CHECK_SIZEOF(short, 2)
-AC_CHECK_SIZEOF(int *, 4)
-AC_CHECK_SIZEOF(int, 4)
-AC_CHECK_SIZEOF(long, 4)
-AC_CHECK_SIZEOF(long long, 0)
+dnl AC_CHECK_SIZEOF(char, 1)
+dnl AC_CHECK_SIZEOF(short, 2)
+dnl AC_CHECK_SIZEOF(int *, 4)
+dnl AC_CHECK_SIZEOF(int, 4)
+dnl AC_CHECK_SIZEOF(long, 4)
+dnl AC_CHECK_SIZEOF(long long, 0)
dnl --------------------------------------------------------------
dnl Checks for library functions.
@@ -102,6 +102,9 @@
dnl Checks for libraries.
dnl --------------------------------------------------------------
+dnl Check for the Boost libraries (in fact we only need the headers)
+AX_BOOST_BASE([1.33.1])
+
dnl Check for wxWidgets
AC_ARG_ENABLE([wxwidgets],AC_HELP_STRING([--enable-wxwidgets],[wxWidgets
interface support (default disabled)]))
if test "${enable_wxwidgets}" = "yes"
Index: dic/Makefile.am
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/Makefile.am,v
retrieving revision 1.14.4.5
retrieving revision 1.14.4.6
diff -u -b -r1.14.4.5 -r1.14.4.6
--- dic/Makefile.am 21 Nov 2007 16:25:43 -0000 1.14.4.5
+++ dic/Makefile.am 27 Nov 2007 18:01:04 -0000 1.14.4.6
@@ -29,11 +29,11 @@
dic_exception.cpp dic_exception.h \
header.cpp header.h \
dic_internals.h \
+ tile.cpp tile.h \
dic_search.cpp dic_search.h \
dic.cpp dic.h \
encoding.cpp encoding.h \
automaton.cpp automaton.h \
- hashtable.h hashtable.cpp \
regexp.cpp regexp.h
BUILT_SOURCES= \
@@ -62,7 +62,8 @@
listdic \
regexp
-compdic_SOURCES=compdic.cpp
+compdic_SOURCES=compdic.cpp \
+ hashtable.h hashtable.cpp
compdic_LDADD=libdic.a
listdic_SOURCES=listdic.cpp
Index: dic/compdic.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/Attic/compdic.cpp,v
retrieving revision 1.1.2.8
retrieving revision 1.1.2.9
diff -u -b -r1.1.2.8 -r1.1.2.9
--- dic/compdic.cpp 21 Nov 2007 16:25:44 -0000 1.1.2.8
+++ dic/compdic.cpp 27 Nov 2007 18:01:04 -0000 1.1.2.9
@@ -25,9 +25,11 @@
*/
#include <fstream>
+#include <sstream>
#include <iostream>
#include <vector>
#include <map>
+#include <boost/tokenizer.hpp>
#include <iconv.h>
#include <getopt.h>
#include <time.h>
@@ -54,14 +56,12 @@
wchar_t* load_uncompressed(const string &iFileName, unsigned int &ioDicSize)
{
- // TODO: we should throw exceptions everywhere instead of returning NULL
-
ifstream file(iFileName.c_str());
if (!file.is_open())
- return NULL;
+ throw DicException("Could not open file " + iFileName);
// Place the buffer in a vector to avoid worrying about memory handling
- std::vector<char> buffer(ioDicSize);
+ vector<char> buffer(ioDicSize);
// Load the file data, everything in one shot
file.read(&buffer.front(), ioDicSize);
file.close();
@@ -70,7 +70,7 @@
// wide characters
iconv_t handle = iconv_open("WCHAR_T", "UTF-8");
if (handle == (iconv_t)(-1))
- return NULL;
+ throw DicException("load_uncompressed: Error in iconv_open");
// Buffer for the wide characters (it will use at most as many characters
// as the utf-8 version)
@@ -85,7 +85,7 @@
iconv_close(handle);
// Problem during encoding conversion?
if (res == (size_t)(-1))
- return NULL;
+ throw DicException("load_uncompressed: Error while interpreting
UTF-8");
// Update ioDicSize with the actual length of the wchar_t array
ioDicSize -= outChars / sizeof(wchar_t);
@@ -94,7 +94,83 @@
}
-Header skip_init_header(ostream &outfile, Dict_header_info &ioHeaderInfo)
+void readLetters(const char *iFileName, DictHeaderInfo &ioHeaderInfo)
+{
+ ifstream in(iFileName);
+ if (!in.is_open())
+ throw DicException("Could not open file " + string(iFileName));
+
+ // Use a more friendly type name
+ typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
+
+ int lineNb = 1;
+ string line;
+ while (getline(in, line))
+ {
+ // Split the lines on space characters
+ vector<string> tokens;
+ boost::char_separator<char> sep(" ");
+ Tokenizer tok(line, sep);
+ Tokenizer::iterator it;
+ for (it = tok.begin(); it != tok.end(); ++it)
+ {
+ tokens.push_back(*it);
+ }
+
+ // Ignore empty lines
+ if (tokens.empty())
+ continue;
+
+ // We expect 5 fields on the line, and the first one is a letter, so
+ // it cannot exceed 4 bytes
+ if (tokens.size() != 5 || tokens[0].size() > 4)
+ {
+ ostringstream ss;
+ ss << "readLetters: Invalid line in " << iFileName;
+ ss << " (line " << lineNb;
+ throw DicException(ss.str());
+ }
+
+#define MAX_SIZE 4
+ wchar_t letter[MAX_SIZE];
+ char buff[MAX_SIZE];
+ strncpy(buff, tokens[0].c_str(), MAX_SIZE);
+
+ // The letter is supposed to be in utf-8, so convert it to
+ // wide characters
+ iconv_t handle = iconv_open("WCHAR_T", "UTF-8");
+ if (handle == (iconv_t)(-1))
+ throw DicException("readLetters: Error in iconv_open");
+ size_t inChars = tokens[0].size();
+ size_t outChars = sizeof(wchar_t) * MAX_SIZE;
+ char *in = buff;
+ char *out = (char*)letter;
+ size_t res = iconv(handle, &in, &inChars, &out, &outChars);
+ iconv_close(handle);
+ // Problem during encoding conversion?
+ if (res == (size_t)(-1))
+ throw DicException("readLetters: Error while interpreting UTF-8");
+ if (outChars != sizeof(wchar_t) * (MAX_SIZE - 1))
+ {
+ ostringstream ss;
+ ss << "readLetters: Invalid letter at line " << lineNb;
+ throw DicException(ss.str());
+ }
+#undef MAX_SIZE
+
+ ioHeaderInfo.letters += towupper(letter[0]);
+
+ ioHeaderInfo.points.push_back(atoi(tokens[1].c_str()));
+ ioHeaderInfo.frequency.push_back(atoi(tokens[2].c_str()));
+ ioHeaderInfo.vowels.push_back(atoi(tokens[3].c_str()));
+ ioHeaderInfo.consonants.push_back(atoi(tokens[4].c_str()));
+
+ ++lineNb;
+ }
+}
+
+
+Header skip_init_header(ostream &outfile, DictHeaderInfo &ioHeaderInfo)
{
ioHeaderInfo.root = 0;
ioHeaderInfo.nwords = 0;
@@ -109,7 +185,7 @@
}
-void fix_header(ostream &outfile, Dict_header_info &ioHeaderInfo)
+void fix_header(ostream &outfile, DictHeaderInfo &ioHeaderInfo)
{
ioHeaderInfo.root = ioHeaderInfo.edgesused;
// Go back to the beginning of the stream to overwrite the header
@@ -209,7 +285,7 @@
* the (wide) chars and their corresponding internal code
*/
unsigned int makenode(const wchar_t *iPrefix, ostream &outfile,
- Dict_header_info &ioHeaderInfo, const Header &iHeader)
+ DictHeaderInfo &ioHeaderInfo, const Header &iHeader)
{
#ifdef CHECK_RECURSION
IncDec inc(current_rec);
@@ -300,13 +376,26 @@
cout << "Usage: " << iBinaryName << " [options]" << endl
<< "Mandatory options:" << endl
<< " -d, --dicname <string> Set the dictionary name and version" <<
endl
- << " -l, --letters <string> Set the dictionary letters" << endl
- << " -i, --input <string> Name of the uncompressed dictionary
file" << endl
- << " -o, --output <string Name of the generated compressed
dictionary file" << endl
+ << " -l, --letters <string> Path to the file containing the letters
(see below)" << endl
+ << " -i, --input <string> Path to the uncompressed dictionary
file" << endl
+ << " -o, --output <string Path to the generated compressed
dictionary file" << endl
<< "Other options:" << endl
<< " -h, --help Print this help and exit" << endl
<< "Example:" << endl
- << " " << iBinaryName << " -d 'ODS 5.0' -l
ABCDEFGHIJKLMNOPQRSTUVWXYZ -i list -o ods5.dawg" << endl;
+ << " " << iBinaryName << " -d 'ODS 5.0' -l letters -i list -o
ods5.dawg" << endl
+ << endl
+ << "The file containing the letters (--letters switch) must be UTF-8
encoded." << endl
+ << "Each line corresponds to one letter, and must contains 5 fields
separated with " << endl
+ << "one or more space(s). " << endl
+ << " - 1st field: the letter itself" << endl
+ << " - 2nd field: the points of the letter" << endl
+ << " - 3rd field: the frequency of the letter (how many letters of
this kind in the game)" << endl
+ << " - 4th field: 1 if the letter is considered as a vowel in
Scrabble game, 0 otherwise" << endl
+ << " - 5th field: 1 if the letter is considered as a consonant in
Scrabble game, 0 otherwise" << endl
+ << "Example for french:" << endl
+ << "A 1 9 1 0" << endl
+ << "B 3 2 0 1" << endl
+ << "etc." << endl;
}
@@ -329,10 +418,9 @@
bool found_l = false;
bool found_i = false;
bool found_o = false;
- wstring dicName;
- wstring letters;
string inFileName;
string outFileName;
+ DictHeaderInfo headerInfo;
int res;
int option_index = 1;
@@ -346,14 +434,11 @@
exit(0);
case 'd':
found_d = true;
- dicName = convertToWc(optarg);
+ headerInfo.dicName = convertToWc(optarg);
break;
case 'l':
found_l = true;
- letters = convertToWc(optarg);
- // Ensure that the letters are uppercase
- for (unsigned int i = 0; i < letters.size(); ++i)
- letters[i] = towupper(letters[i]);
+ readLetters(optarg, headerInfo);
break;
case 'i':
found_i = true;
@@ -392,12 +477,8 @@
try
{
clock_t startLoadTime = clock();
+ // FIXME: not exception safe
wchar_t *uncompressed = load_uncompressed(inFileName, dicsize);
- if (uncompressed == NULL)
- {
- fprintf(stderr, "Cannot load uncompressed dictionary into
memory\n");
- exit(1);
- }
clock_t endLoadTime = clock();
global_input = uncompressed;
@@ -407,9 +488,6 @@
global_hashtable = new HashTable<vector<Dawg_edge>, unsigned int,
HashVector>((unsigned int)(dicsize * SCALE));
#undef SCALE
- Dict_header_info headerInfo;
- headerInfo.dicName = dicName;
- headerInfo.letters = letters;
headerInfo.dawg = true;
Header tempHeader = skip_init_header(outfile, headerInfo);
Index: dic/dic.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/Attic/dic.cpp,v
retrieving revision 1.1.2.6
retrieving revision 1.1.2.7
diff -u -b -r1.1.2.6 -r1.1.2.7
--- dic/dic.cpp 21 Nov 2007 16:25:44 -0000 1.1.2.6
+++ dic/dic.cpp 27 Nov 2007 18:01:04 -0000 1.1.2.7
@@ -20,7 +20,7 @@
/**
* \file dic.c
* \brief Dawg dictionary
- * \author Antoine Fraboulet
+ * \author Antoine Fraboulet & Olivier Teuliere
* \date 2002
*/
@@ -35,6 +35,7 @@
#include "header.h"
#include "dic_exception.h"
#include "dic_internals.h"
+#include "tile.h"
// FIXME: duplicated in header.cpp
@@ -89,6 +90,8 @@
}
convertDataToArch();
+
+ initializeTiles();
}
@@ -99,6 +102,23 @@
}
+void Dictionary::initializeTiles()
+{
+ // "Activate" the dictionary by giving the header to the Tile class
+ Tile::SetHeader(*m_header);
+
+ // XXX: temp
+ Tile::m_TheJoker = Tile(TILE_JOKER);
+
+ m_tilesVect.reserve(m_header->getLetters().size() + 1);
+ // Create a tile for each letter in the dictionary header
+ for (unsigned int i = 0; i < m_header->getLetters().size(); ++i)
+ m_tilesVect.push_back(Tile(m_header->getLetters()[i]));
+ // Another tile for the joker
+ m_tilesVect.push_back(Tile::Joker());
+}
+
+
const dic_elt_t Dictionary::getNext(const dic_elt_t &e) const
{
if (!isLast(e))
@@ -116,7 +136,6 @@
const dic_elt_t Dictionary::getRoot() const
{
return m_header->getRoot();
-
}
@@ -126,13 +145,9 @@
}
-char Dictionary::getChar(const dic_elt_t &e) const
+wchar_t Dictionary::getChar(const dic_elt_t &e) const
{
- char c = (m_dawg[e]).chr;
- if (c)
- return c + 'A' - 1;
- else
- return 0;
+ return m_header->getCharFromCode(m_dawg[e].chr);
}
@@ -175,7 +190,7 @@
return 0;
}
-unsigned int Dictionary::charLookup(const dic_elt_t &iRoot, const char *s)
const
+unsigned int Dictionary::charLookup(const dic_elt_t &iRoot, const wchar_t *s)
const
{
unsigned int p;
dic_elt_t rootCopy = iRoot;
Index: dic/dic.h
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/dic.h,v
retrieving revision 1.13.2.4
retrieving revision 1.13.2.5
diff -u -b -r1.13.2.4 -r1.13.2.5
--- dic/dic.h 21 Nov 2007 16:25:44 -0000 1.13.2.4
+++ dic/dic.h 27 Nov 2007 18:01:04 -0000 1.13.2.5
@@ -20,7 +20,7 @@
/**
* \file dic.h
* \brief Dawg dictionary
- * \author Antoine Fraboulet
+ * \author Antoine Fraboulet & Olivier Teuliere
* \date 2002
*/
@@ -28,6 +28,11 @@
#define _DIC_H_
#include <string>
+#include <vector>
+
+#include "tile.h"
+
+using namespace std;
/**
@@ -45,8 +50,6 @@
typedef unsigned int dic_elt_t;
typedef unsigned char dic_code_t;
-using namespace std;
-
class Dictionary
{
public:
@@ -62,6 +65,9 @@
/** Give access to the dictionary header */
const Header& getHeader() const { return *m_header; }
+ /** Return a vector containing one of each possible tile */
+ const vector<Tile>& getAllTiles() const { return m_tilesVect; }
+
/**
* Returns the character code associated with an element,
* codes may range from 0 to 31. 0 is the null character.
@@ -70,11 +76,10 @@
const dic_code_t getCode(const dic_elt_t &elt) const;
/**
- * Returns the character associated with an element
- * (in the range ['A'-'Z']), or the null character ('\0').
- * @returns ASCII code for the character
+ * Returns the wide character associated with an element.
+ * @returns wide character for the element
*/
- char getChar(const dic_elt_t &elt) const;
+ wchar_t getChar(const dic_elt_t &elt) const;
/**
* Returns a boolean to show if there is another available
@@ -132,7 +137,7 @@
* element that results from walking the dictionary according to the
* pattern
*/
- unsigned int charLookup(const dic_elt_t &iRoot, const char *iPattern)
const;
+ unsigned int charLookup(const dic_elt_t &iRoot, const wchar_t *iPattern)
const;
/// Getter for the dawg
const Dawg_edge *getDawg() const { return m_dawg; }
@@ -145,7 +150,11 @@
Header *m_header;
Dawg_edge *m_dawg;
+ /// Vector of available tiles
+ vector<Tile> m_tilesVect;
+
void convertDataToArch();
+ void initializeTiles();
};
#endif /* _DIC_H_ */
Index: dic/dic_search.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/Attic/dic_search.cpp,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -b -r1.1.2.2 -r1.1.2.3
--- dic/dic_search.cpp 11 Nov 2007 19:56:58 -0000 1.1.2.2
+++ dic/dic_search.cpp 27 Nov 2007 18:01:04 -0000 1.1.2.3
@@ -24,13 +24,14 @@
* \date 2002
*/
-#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
+#include <wctype.h>
#include "dic_internals.h"
#include "dic.h"
+#include "header.h"
#include "encoding.h"
#include "regexp.h"
#include "dic_search.h"
@@ -50,18 +51,18 @@
/**
* Dic_seel_edgeptr
* walk the dictionary until the end of the word
- * @param iDic : dictionnary
- * @param s : current pointer to letters
- * @param eptr : current edge in the dawg
+ * @param iDic: dictionnary
+ * @param s: current pointer to letters
+ * @param eptr: current edge in the dawg
*/
-static const Dawg_edge* Dic_seek_edgeptr(const Dictionary &iDic, const char*
s, const Dawg_edge *eptr)
+static const Dawg_edge* Dic_seek_edgeptr(const Dictionary &iDic, const
wchar_t* s, const Dawg_edge *eptr)
{
if (*s)
{
const Dawg_edge *p = iDic.getDawg() + eptr->ptr;
do
{
- if (p->chr == (unsigned)(*s & DIC_CHAR_MASK))
+ if (p->chr == iDic.getHeader().getCodeFromChar(*s))
return Dic_seek_edgeptr(iDic, s + 1, p);
} while (!(*p++).last);
return iDic.getDawg();
@@ -72,12 +73,12 @@
/**
- * Dic_search_word_inner : direct application of Dic_seek_edgeptr
- * @param iDic : dictionary
- * @param word : word to lookup
+ * searchWord: direct application of Dic_seek_edgeptr
+ * @param iDic: dictionary
+ * @param iWord: word to lookup
* @result 0 not a valid word, 1 ok
*/
-static int Dic_search_word_inner(const Dictionary &iDic, const string &iWord)
+int DicSearch::searchWord(const Dictionary &iDic, const wstring &iWord)
{
const Dawg_edge *e = Dic_seek_edgeptr(iDic, iWord.c_str(), iDic.getDawg()
+ iDic.getRoot());
return e->term;
@@ -85,17 +86,7 @@
/**
- * Wrapper around Dic_search_word_inner, until we have multibyte support in
- * the dictionary
- */
-int DicSearch::searchWord(const Dictionary &iDic, const wstring &iWord)
-{
- return Dic_search_word_inner(iDic, convertToMb(iWord));
-}
-
-
-/**
- * global variables for Dic_search_word_by_len :
+ * global variables for Dic_search_word_by_len:
*
* a pointer to the structure is passed as a parameter
* so that all the search_* variables appear to the functions
@@ -105,16 +96,16 @@
struct params_7plus1_t
{
- const Dictionary *search_dic;
- char added_char;
- map<char, list<string> > *results;
+ wchar_t added_char;
+ map<wchar_t, list<wstring> > *results;
int search_len;
- char search_wordtst[DIC_WORD_MAX];
- char search_letters[DIC_LETTERS];
+ wchar_t search_wordtst[DIC_WORD_MAX];
+ wchar_t search_letters[DIC_LETTERS];
};
static void
-Dic_search_word_by_len(struct params_7plus1_t *params, int i, const Dawg_edge
*edgeptr)
+Dic_search_word_by_len(const Dictionary &iDic, struct params_7plus1_t *params,
+ int i, const Dawg_edge *edgeptr)
{
/* depth first search in the dictionary */
do
@@ -125,7 +116,7 @@
/* is the letter available in search_letters */
if (params->search_letters[edgeptr->chr])
{
- params->search_wordtst[i] = edgeptr->chr + 'A' - 1;
+ params->search_wordtst[i] =
iDic.getHeader().getCharFromCode(edgeptr->chr);
params->search_letters[edgeptr->chr] --;
if (i == params->search_len)
{
@@ -136,16 +127,16 @@
}
else
{
- Dic_search_word_by_len(params, i + 1,
params->search_dic->getDawg() + edgeptr->ptr);
+ Dic_search_word_by_len(iDic, params, i + 1, iDic.getDawg()
+ edgeptr->ptr);
}
params->search_letters[edgeptr->chr] ++;
- params->search_wordtst[i] = '\0';
+ params->search_wordtst[i] = L'\0';
}
/* the letter is of course available if we have a joker available
*/
if (params->search_letters[0])
{
- params->search_wordtst[i] = edgeptr->chr + 'a' - 1;
+ params->search_wordtst[i] =
iDic.getHeader().getCharFromCode(edgeptr->chr);
params->search_letters[0] --;
if (i == params->search_len)
{
@@ -156,39 +147,45 @@
}
else
{
- Dic_search_word_by_len(params, i + 1,
params->search_dic->getDawg() + edgeptr->ptr);
+ Dic_search_word_by_len(iDic, params, i + 1, iDic.getDawg()
+ edgeptr->ptr);
}
params->search_letters[0] ++;
- params->search_wordtst[i] = '\0';
+ params->search_wordtst[i] = L'\0';
}
}
} while (! (*edgeptr++).last);
}
-static void
-Dic_search_7pl1_inner(const Dictionary &iDic, const string &iRack,
- map<char, list<string> > &oWordList,
+
+/**
+ * Wrapper around Dic_search_7pl1_inner, until we have multibyte support in
+ * the dictionary
+ */
+void DicSearch::search7pl1(const Dictionary &iDic, const wstring &iRack,
+ map<wchar_t, list<wstring> > &oWordList,
bool joker)
{
- int i, wordlen;
- const char* r = iRack.c_str();
+ if (iRack == L"" || iRack.size() > DIC_WORD_MAX)
+ return;
+
struct params_7plus1_t params;
- for (i = 0; i < DIC_LETTERS; i++)
+ for (int i = 0; i < DIC_LETTERS; i++)
params.search_letters[i] = 0;
/*
* the letters are verified and changed to the dic internal
- * representation (*r & DIC_CHAR_MASK)
+ * representation (using getCodeFromChar(*r))
*/
- for (wordlen=0; wordlen < DIC_WORD_MAX && *r; r++)
+ int wordlen = 0;
+ for (const wchar_t* r = iRack.c_str(); *r; r++)
{
- if (isalpha(*r))
+ if (iswalpha(*r))
{
- params.search_letters[(int)*r & DIC_CHAR_MASK]++;
+ params.search_letters[iDic.getHeader().getCodeFromChar(*r)]++;
wordlen++;
}
- else if (*r == '?')
+ else if (*r == L'?')
{
if (joker)
{
@@ -197,7 +194,7 @@
}
else
{
- oWordList[0].push_back("** joker **");
+ oWordList[0].push_back(L"** joker **");
return;
}
}
@@ -209,77 +206,49 @@
const Dawg_edge *root_edge =
iDic.getDawg() + (iDic.getDawg()[iDic.getRoot()].ptr);
- params.search_dic = &iDic;
params.results = &oWordList;
/* search for all the words that can be done with the letters */
- params.added_char = 0;
+ params.added_char = L'\0';
params.search_len = wordlen - 1;
- params.search_wordtst[wordlen]='\0';
- Dic_search_word_by_len(¶ms, 0, root_edge);
+ params.search_wordtst[wordlen] = L'\0';
+ Dic_search_word_by_len(iDic, ¶ms, 0, root_edge);
/* search for all the words that can be done with the letters +1 */
params.search_len = wordlen;
- params.search_wordtst[wordlen + 1]='\0';
- for (i = 'a'; i <= 'z'; i++)
+ params.search_wordtst[wordlen + 1] = L'\0';
+ const wstring &letters = iDic.getHeader().getLetters();
+ for (unsigned int i = 0; i <= letters.size(); i++)
{
- params.added_char = i & DIC_CHAR_MASK;
- params.search_letters[i & DIC_CHAR_MASK]++;
+ params.added_char = letters[i];
+ unsigned int code = iDic.getHeader().getCodeFromChar(letters[i]);
+ params.search_letters[code]++;
- Dic_search_word_by_len(¶ms, 0, root_edge);
+ Dic_search_word_by_len(iDic, ¶ms, 0, root_edge);
- params.search_letters[i & DIC_CHAR_MASK]--;
- }
-}
-
-
-/**
- * Wrapper around Dic_search_7pl1_inner, until we have multibyte support in
- * the dictionary
- */
-void DicSearch::search7pl1(const Dictionary &iDic, const wstring &iRack,
- map<wchar_t, list<wstring> > &oWordList,
- bool joker)
-{
- if (iRack == L"")
- return;
-
- map<char, list<string> > wordList;
- // Do the actual work
- Dic_search_7pl1_inner(iDic, convertToMb(iRack), wordList, joker);
-
- map<char, list<string> >::const_iterator it;
- for (it = wordList.begin(); it != wordList.end(); it++)
- {
- wchar_t letter = 0;
- if (it->first)
- {
- letter = convertToWc(string(1, it->first + 'A' - 1))[0];
- }
- list<string>::const_iterator itWord;
- for (itWord = it->second.begin(); itWord != it->second.end(); itWord++)
- {
- oWordList[letter].push_back(convertToWc(*itWord));
- }
+ params.search_letters[code]--;
}
}
/****************************************/
/****************************************/
-static void
-Dic_search_Racc_inner(const Dictionary &iDic, const string &iWord,
- list<string> &oWordList)
+void DicSearch::searchRacc(const Dictionary &iDic, const wstring &iWord,
+ list<wstring> &oWordList)
{
+ if (iWord == L"")
+ return;
+
/* search_racc will try to add a letter in front and at the end of a word
*/
/* let's try for the front */
- char wordtst[DIC_WORD_MAX];
- strcpy(wordtst+1, iWord.c_str());
- for (int i = 'a'; i <= 'z'; i++)
+ wchar_t wordtst[DIC_WORD_MAX];
+ wcscpy(wordtst + 1, iWord.c_str());
+ const wstring &letters = iDic.getHeader().getLetters();
+ for (unsigned int i = 0; i <= letters.size(); i++)
{
- wordtst[0] = i;
- if (Dic_search_word_inner(iDic, wordtst))
+ wordtst[0] = letters[i];
+ if (searchWord(iDic, wordtst))
oWordList.push_back(wordtst);
}
@@ -302,57 +271,37 @@
{
if (edge->term)
{
- wordtst[i] = edge->chr + 'a' - 1;
+ wordtst[i] = iDic.getHeader().getCharFromCode(edge->chr);
oWordList.push_back(wordtst);
}
} while (!(*edge++).last);
}
}
-/**
- * Wrapper around Dic_search_Racc_inner, until we have multibyte support in
- * the dictionary
- */
-void DicSearch::searchRacc(const Dictionary &iDic, const wstring &iWord,
+/****************************************/
+/****************************************/
+
+void DicSearch::searchBenj(const Dictionary &iDic, const wstring &iWord,
list<wstring> &oWordList)
{
if (iWord == L"")
return;
- list<string> tmpWordList;
- // Do the actual work
- Dic_search_Racc_inner(iDic, convertToMb(iWord), tmpWordList);
-
- list<string>::const_iterator it;
- for (it = tmpWordList.begin(); it != tmpWordList.end(); it++)
- {
- oWordList.push_back(convertToWc(*it));
- }
-}
-
-/****************************************/
-/****************************************/
-
-
-static void Dic_search_Benj_inner(const Dictionary &iDic,
- const string &iWord,
- list<string> &oWordList)
-{
- char wordtst[DIC_WORD_MAX];
- strcpy(wordtst + 3, iWord.c_str());
+ wchar_t wordtst[DIC_WORD_MAX];
+ wcscpy(wordtst + 3, iWord.c_str());
const Dawg_edge *edge0, *edge1, *edge2, *edgetst;
edge0 = iDic.getDawg() + (iDic.getDawg()[iDic.getRoot()].ptr);
do
{
- wordtst[0] = edge0->chr + 'a' - 1;
+ wordtst[0] = iDic.getHeader().getCharFromCode(edge0->chr);
edge1 = iDic.getDawg() + edge0->ptr;
do
{
- wordtst[1] = edge1->chr + 'a' - 1;
+ wordtst[1] = iDic.getHeader().getCharFromCode(edge1->chr);
edge2 = iDic.getDawg() + edge1->ptr;
do
{
- wordtst[2] = edge2->chr + 'a' - 1;
+ wordtst[2] = iDic.getHeader().getCharFromCode(edge2->chr);
edgetst = Dic_seek_edgeptr(iDic, iWord.c_str(), edge2);
if (edgetst->term)
oWordList.push_back(wordtst);
@@ -361,44 +310,23 @@
} while (!(*edge0++).last);
}
-/**
- * Wrapper around Dic_search_Benj_inner, until we have multibyte support in
- * the dictionary
- */
-void DicSearch::searchBenj(const Dictionary &iDic, const wstring &iWord,
- list<wstring> &oWordList)
-{
- if (iWord == L"")
- return;
-
- list<string> tmpWordList;
- // Do the actual work
- Dic_search_Benj_inner(iDic, convertToMb(iWord), tmpWordList);
-
- list<string>::const_iterator it;
- for (it = tmpWordList.begin(); it != tmpWordList.end(); it++)
- {
- oWordList.push_back(convertToWc(*it));
- }
-}
-
/****************************************/
/****************************************/
struct params_cross_t
{
- const Dictionary *dic;
int wordlen;
- char mask[DIC_WORD_MAX];
+ wchar_t mask[DIC_WORD_MAX];
};
-static void Dic_search_cross_rec(struct params_cross_t *params,
- list<string> &oWordList,
+static void Dic_search_cross_rec(const Dictionary &iDic,
+ struct params_cross_t *params,
+ list<wstring> &oWordList,
const Dawg_edge *edgeptr)
{
- const Dawg_edge *current = params->dic->getDawg() + edgeptr->ptr;
+ const Dawg_edge *current = iDic.getDawg() + edgeptr->ptr;
if (params->mask[params->wordlen] == '\0' && edgeptr->term)
{
@@ -408,9 +336,9 @@
{
do
{
- params->mask[params->wordlen] = current->chr + 'a' - 1;
+ params->mask[params->wordlen] =
iDic.getHeader().getCharFromCode(current->chr);
params->wordlen ++;
- Dic_search_cross_rec(params, oWordList, current);
+ Dic_search_cross_rec(iDic, params, oWordList, current);
params->wordlen --;
params->mask[params->wordlen] = '.';
}
@@ -420,10 +348,10 @@
{
do
{
- if (current->chr == (unsigned int)(params->mask[params->wordlen] &
DIC_CHAR_MASK))
+ if (current->chr ==
iDic.getHeader().getCodeFromChar(params->mask[params->wordlen]))
{
params->wordlen ++;
- Dic_search_cross_rec(params, oWordList, current);
+ Dic_search_cross_rec(iDic, params, oWordList, current);
params->wordlen --;
break;
}
@@ -433,46 +361,26 @@
}
-static void Dic_search_Cros_inner(const Dictionary &iDic, const string &iMask,
- list<string> &oWordList)
+void DicSearch::searchCros(const Dictionary &iDic, const wstring &iMask,
+ list<wstring> &oWordList)
{
+ if (iMask == L"")
+ return;
+
struct params_cross_t params;
int i;
for (i = 0; i < DIC_WORD_MAX && iMask[i]; i++)
{
- if (isalpha(iMask[i]))
- params.mask[i] = (iMask[i] & DIC_CHAR_MASK) + 'A' - 1;
+ if (iswalpha(iMask[i]))
+ params.mask[i] = towupper(iMask[i]);
else
params.mask[i] = '.';
}
params.mask[i] = '\0';
- params.dic = &iDic;
params.wordlen = 0;
- Dic_search_cross_rec(¶ms, oWordList, iDic.getDawg() + iDic.getRoot());
-}
-
-
-/**
- * Wrapper around Dic_search_Cros_inner, until we have multibyte support in
- * the dictionary
- */
-void DicSearch::searchCros(const Dictionary &iDic, const wstring &iMask,
- list<wstring> &oWordList)
-{
- if (iMask == L"")
- return;
-
- list<string> tmpWordList;
- // Do the actual work
- Dic_search_Cros_inner(iDic, convertToMb(iMask), tmpWordList);
-
- list<string>::const_iterator it;
- for (it = tmpWordList.begin(); it != tmpWordList.end(); it++)
- {
- oWordList.push_back(convertToWc(*it));
- }
+ Dic_search_cross_rec(iDic, ¶ms, oWordList, iDic.getDawg() +
iDic.getRoot());
}
/****************************************/
@@ -511,7 +419,7 @@
{
/* the current letter is current->chr */
next_state = params->automaton_field->getNextState(state,
current->chr);
- /* 1 : the letter appears in the automaton as is */
+ /* 1: the letter appears in the automaton as is */
if (next_state)
{
params->word[params->wordlen] = current->chr + 'a' - 1;
@@ -557,7 +465,7 @@
if (value)
{
#ifdef DEBUG_FLEX_IS_BROKEN
- fprintf(stderr, "parser error at pos %d - %d : %s\n",
+ fprintf(stderr, "parser error at pos %d - %d: %s\n",
report.pos1, report.pos2, report.msg);
#endif
regexp_delete_tree(root);
Index: dic/header.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/Attic/header.cpp,v
retrieving revision 1.1.2.7
retrieving revision 1.1.2.8
diff -u -b -r1.1.2.7 -r1.1.2.8
--- dic/header.cpp 21 Nov 2007 16:25:44 -0000 1.1.2.7
+++ dic/header.cpp 27 Nov 2007 18:01:04 -0000 1.1.2.8
@@ -78,6 +78,7 @@
// Do not change these values, as they impact the size of the structure
#define _USER_HOST_MAX_ 24
#define _MAX_DIC_NAME_SIZE_ 32
+#define _MAX_LETTERS_NB_ 63
#define _MAX_LETTERS_SIZE_ 80
/** Extension of the old format */
@@ -89,7 +90,7 @@
uint64_t compileDate;
// Compression algorithm (1 = DAWG, 2 = GADDAG)
- char algorithm;
+ uint8_t algorithm;
// Endianness (XXX: currently unused)
char bigEndian;
@@ -100,12 +101,22 @@
// Letters used in the dictionary
// We should have: nbLetters <= lettersSize <= _MAX_LETTERS_SIZE_
+ // and: nbLetters <= _MAX_LETTERS_NB_
// The letters themselves, in UTF-8
char letters[_MAX_LETTERS_SIZE_];
// Size taken by the letters
uint32_t lettersSize;
// Number of letters (XXX: in theory useless, but allows a sanity check)
uint32_t nbLetters;
+
+ // Points of the letters (indexed by their code)
+ uint8_t points[_MAX_LETTERS_NB_];
+ // Frequency of the letters (indexedy their code)
+ uint8_t frequency[_MAX_LETTERS_NB_];
+ // Bitfield indicating whether letters are vowels
+ uint64_t vowels;
+ // Bitfield indicating whether letters are consonants
+ uint64_t consonants;
//@}
};
@@ -122,11 +133,41 @@
}
-Header::Header(const Dict_header_info &iInfo)
+Header::Header(const DictHeaderInfo &iInfo)
{
// Use the latest serialization format
m_version = 1;
+ // Sanity checks
+ if (iInfo.letters.size() >= _MAX_LETTERS_NB_)
+ {
+ ostringstream ss;
+ ss << _MAX_LETTERS_NB_;
+ throw DicException("Header::Header: Too many different letters for "
+ "the current format; only " + ss.str() +
+ " are supported");
+ }
+ if (iInfo.points.size() != iInfo.letters.size())
+ {
+ throw DicException("Header::Header: Different sizes for "
+ "iInfo.points and iInfo.letters");
+ }
+ if (iInfo.frequency.size() != iInfo.letters.size())
+ {
+ throw DicException("Header::Header: Different sizes for "
+ "iInfo.frequency and iInfo.letters");
+ }
+ if (iInfo.vowels.size() != iInfo.letters.size())
+ {
+ throw DicException("Header::Header: Different sizes for "
+ "iInfo.vowels and iInfo.letters");
+ }
+ if (iInfo.consonants.size() != iInfo.letters.size())
+ {
+ throw DicException("Header::Header: Different sizes for "
+ "iInfo.consonants and iInfo.letters");
+ }
+
m_root = iInfo.root;
m_nbWords = iInfo.nwords;
m_nodesUsed = iInfo.nodesused;
@@ -135,13 +176,12 @@
m_edgesSaved = iInfo.edgessaved;
m_type = iInfo.dawg ? kDAWG : kGADDAG;
m_dicName = iInfo.dicName;
- // First protection, but it is not enough
- if (iInfo.letters.size() >= _MAX_LETTERS_SIZE_)
- {
- throw DicException("Header::Header: Too many different letters for "
- "the current format");
- }
m_letters = iInfo.letters;
+ m_points = iInfo.points;
+ m_frequency = iInfo.frequency;
+ m_vowels = iInfo.vowels;
+ m_consonants = iInfo.consonants;
+
buildMapCodeFromChar();
}
@@ -244,6 +284,21 @@
{
throw DicException("Header::read: inconsistent header");
}
+
+ // Letters points and frequency
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ m_points.push_back(aHeaderExt.points[i]);
+ m_frequency.push_back(aHeaderExt.frequency[i]);
+ }
+
+ // Vowels and consonants
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ m_vowels.push_back(aHeaderExt.vowels & (1 << i));
+ m_consonants.push_back(aHeaderExt.consonants & (1 << i));
+ }
+
}
}
@@ -284,6 +339,24 @@
_MAX_LETTERS_SIZE_, "dictionary letters");
aHeaderExt.nbLetters = (uint32_t)m_letters.size();
+ // Letters points and frequency
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ aHeaderExt.points[i] = m_points[i];
+ aHeaderExt.frequency[i] = m_frequency[i];
+ }
+
+ // Vowels and consonants
+ aHeaderExt.vowels = 0;
+ aHeaderExt.consonants = 0;
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ if (m_vowels[i])
+ aHeaderExt.vowels |= 1 << i;
+ if (m_consonants[i])
+ aHeaderExt.consonants |= 1 << i;
+ }
+
// Write the extension
oStream.write((char*)&aHeaderExt, sizeof(Dict_header_ext));
if (!oStream.good())
@@ -344,7 +417,6 @@
void Header::print() const
{
- printf("============================\n");
printf("dictionary name: %s\n", convertToMb(m_dicName).c_str());
printf("dictionary type: %s\n", m_type == kDAWG ? "DAWG" : "GADDAG");
printf("letters: %s\n", convertToMb(m_letters).c_str());
@@ -353,26 +425,16 @@
printf("header size: %u bytes\n", sizeof(Dict_header_old) +
m_version ? sizeof(Dict_header_ext) : 0);
printf("root: %d (edge)\n", m_root);
-// printf("root: %7u (byte)\n", m_root * sizeof(Dawg_edge));
printf("nodes: %d used + %d saved\n", m_nodesUsed, m_nodesSaved);
printf("edges: %d used + %d saved\n", m_edgesUsed, m_edgesSaved);
- printf("============================\n");
-
-#if 0
-#define OO(IDENT) (unsigned long)offsetof(Dict_header_old, IDENT)
-
- printf("Dictionary header information\n");
- printf("0x%02lx ident : %s\n", OO(ident) ,
_COMPIL_KEYWORD_);
- printf("0x%02lx unused 1 : %6d %06x\n", OO(unused_1) , header.unused_1
, header.unused_1);
- printf("0x%02lx unused 2 : %6d %06x\n", OO(unused_2) , header.unused_2
, header.unused_2);
- printf("0x%02lx root : %6d %06x\n", OO(root) , m_root ,
m_root);
- printf("0x%02lx words : %6d %06x\n", OO(nwords) , m_nbWords ,
m_nbWords);
- printf("0x%02lx edges used : %6d %06x\n", OO(edgesused) , m_edgesUsed ,
m_edgesUsed);
- printf("0x%02lx nodes used : %6d %06x\n", OO(nodesused) , m_nodesUsed ,
m_nodesUsed);
- printf("0x%02lx edges saved: %6d %06x\n", OO(edgessaved), m_edgesSaved,
m_edgesSaved);
- printf("0x%02lx nodes saved: %6d %06x\n", OO(nodessaved), m_nodesSaved,
m_nodesSaved);
- printf("\n");
- printf("sizeof(header) = 0x%lx (%lu)\n", sizeof(header), sizeof(header));
-#endif
+ printf("===============================================\n");
+ printf("letter | points | frequency | vowel | consonant\n");
+ printf("-------+--------+-----------+-------+----------\n");
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ printf(" %lc | %2d | %2d | %d | %d\n",
m_letters[i],
+ m_points[i], m_frequency[i], m_vowels[i], m_consonants[i]);
+ }
+ printf("===============================================\n");
}
Index: dic/header.h
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/Attic/header.h,v
retrieving revision 1.1.2.5
retrieving revision 1.1.2.6
diff -u -b -r1.1.2.5 -r1.1.2.6
--- dic/header.h 21 Nov 2007 16:25:44 -0000 1.1.2.5
+++ dic/header.h 27 Nov 2007 18:01:05 -0000 1.1.2.6
@@ -22,6 +22,7 @@
#include <iosfwd>
#include <map>
+#include <vector>
using namespace std;
@@ -31,24 +32,28 @@
* Note: this structure doesn't pretend to map the way the data is stored in a
* file. For (de)serialization, always use a Header object
*/
-struct Dict_header_info
+struct DictHeaderInfo
{
- int root;
- int nwords;
- unsigned int edgesused;
- unsigned int nodesused;
- unsigned int nodessaved;
- unsigned int edgessaved;
+ uint32_t root;
+ uint32_t nwords;
+ uint32_t edgesused;
+ uint32_t nodesused;
+ uint32_t nodessaved;
+ uint32_t edgessaved;
bool dawg;
- wstring letters;
wstring dicName;
+ wstring letters;
+ vector<uint8_t> points;
+ vector<uint8_t> frequency;
+ vector<bool> vowels;
+ vector<bool> consonants;
};
/**
* Dictionary header.
* There are 2 ways to create a Header object:
- * - fill a Dict_header_info structure and give it in the constructor of the
+ * - fill a DictHeaderInfo structure and give it in the constructor of the
* Header class (usually to call write() afterwards)
* - give it an input stream on a compiled dictionary
*
@@ -82,7 +87,7 @@
* Constructor from a filled structure
* @param iInfo: info needed to build the header
*/
- Header(const Dict_header_info &iInfo);
+ Header(const DictHeaderInfo &iInfo);
/// Getters
//@{
@@ -94,6 +99,10 @@
unsigned int getNbEdgesSaved() const { return m_edgesSaved; }
DictType getType() const { return m_type; }
wstring getLetters() const { return m_letters; }
+ uint8_t getPoints(unsigned int iCode) const { return m_points[iCode -
1]; }
+ uint8_t getFrequency(unsigned int iCode) const { return
m_frequency[iCode - 1]; }
+ bool isVowel(unsigned int iCode) const { return m_vowels[iCode -
1]; }
+ bool isConsonant(unsigned int iCode) const { return
m_consonants[iCode - 1]; }
//@}
/**
@@ -138,6 +147,18 @@
/// The letters constituting the words of the dictionary
wstring m_letters;
+ /// Points of the letters
+ vector<uint8_t> m_points;
+
+ /// Frequency of the letters
+ vector<uint8_t> m_frequency;
+
+ /// Vowels
+ vector<bool> m_vowels;
+
+ /// Consonants
+ vector<bool> m_consonants;
+
map<wchar_t, unsigned int> m_mapCodeFromChar;
/**
Index: game/Makefile.am
===================================================================
RCS file: /cvsroot/eliot/eliot/game/Makefile.am,v
retrieving revision 1.13.2.1
retrieving revision 1.13.2.2
diff -u -b -r1.13.2.1 -r1.13.2.2
--- game/Makefile.am 15 Oct 2006 11:07:55 -0000 1.13.2.1
+++ game/Makefile.am 27 Nov 2007 18:01:05 -0000 1.13.2.2
@@ -23,7 +23,6 @@
libgame_a_SOURCES= \
ai_percent.cpp ai_percent.h \
ai_player.h \
- tile.cpp tile.h \
bag.cpp bag.h \
coord.cpp coord.h \
cross.cpp cross.h \
Index: game/bag.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/bag.cpp,v
retrieving revision 1.7.2.1
retrieving revision 1.7.2.2
diff -u -b -r1.7.2.1 -r1.7.2.2
--- game/bag.cpp 23 Dec 2006 13:51:13 -0000 1.7.2.1
+++ game/bag.cpp 27 Nov 2007 18:01:05 -0000 1.7.2.2
@@ -20,22 +20,17 @@
#include <string>
-#include "tile.h"
+#include <dic.h>
#include "bag.h"
#include "debug.h"
-Bag::Bag()
-{
- init();
-}
-
-
-void Bag::init()
+Bag::Bag(const Dictionary &iDic)
+ : m_dic(iDic)
{
m_ntiles = 0;
- const list<Tile>& allTiles = Tile::getAllTiles();
- list<Tile>::const_iterator it;
+ const vector<Tile>& allTiles = m_dic.getAllTiles();
+ vector<Tile>::const_iterator it;
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
m_tilesMap[*it] = it->maxNumber();
@@ -115,7 +110,7 @@
n -= it->second;
}
ASSERT(false, "We should not come here");
- return Tile::dummy();
+ return Tile();
}
Index: game/bag.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/bag.h,v
retrieving revision 1.8.2.1
retrieving revision 1.8.2.2
diff -u -b -r1.8.2.1 -r1.8.2.2
--- game/bag.h 23 Dec 2006 16:48:33 -0000 1.8.2.1
+++ game/bag.h 27 Nov 2007 18:01:05 -0000 1.8.2.2
@@ -21,11 +21,13 @@
#ifndef _BAG_H_
#define _BAG_H_
-#include "tile.h"
#include <map>
+#include "tile.h"
using std::map;
+class Dictionary;
+
/**
* A bag stores the set of free tiles for the game.
@@ -33,9 +35,7 @@
class Bag
{
public:
- Bag();
- virtual ~Bag() {}
- void init();
+ Bag(const Dictionary &iDic);
/// Take a tile in the bag
void takeTile(const Tile &iTile);
@@ -66,8 +66,12 @@
void dumpAll() const;
private:
+ /// Dictionary
+ const Dictionary &m_dic;
+
/// Associate to each tile its number of occurrences in the bag
map<Tile, int> m_tilesMap;
+
/// Total number of tiles in the bag
int m_ntiles;
};
Index: game/board.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board.cpp,v
retrieving revision 1.14.2.3
retrieving revision 1.14.2.4
diff -u -b -r1.14.2.3 -r1.14.2.4
--- game/board.cpp 11 Nov 2007 19:56:59 -0000 1.14.2.3
+++ game/board.cpp 27 Nov 2007 18:01:05 -0000 1.14.2.4
@@ -82,8 +82,8 @@
Board::Board():
- m_tilesRow(BOARD_REALDIM, Tile::dummy()),
- m_tilesCol(BOARD_REALDIM, Tile::dummy()),
+ m_tilesRow(BOARD_REALDIM, Tile()),
+ m_tilesCol(BOARD_REALDIM, Tile()),
m_jokerRow(BOARD_REALDIM, false),
m_jokerCol(BOARD_REALDIM, false),
m_crossRow(BOARD_REALDIM, Cross()),
@@ -205,10 +205,10 @@
{
if (iRound.isPlayedFromRack(i))
{
- m_tilesRow[row][col + i] = Tile::dummy();
+ m_tilesRow[row][col + i] = Tile();
m_jokerRow[row][col + i] = false;
m_crossRow[row][col + i].setAny();
- m_tilesCol[col + i][row] = Tile::dummy();
+ m_tilesCol[col + i][row] = Tile();
m_jokerCol[col + i][row] = false;
m_crossCol[col + i][row].setAny();
}
@@ -220,10 +220,10 @@
{
if (iRound.isPlayedFromRack(i))
{
- m_tilesRow[row + i][col] = Tile::dummy();
+ m_tilesRow[row + i][col] = Tile();
m_jokerRow[row + i][col] = false;
m_crossRow[row + i][col].setAny();
- m_tilesCol[col][row + i] = Tile::dummy();
+ m_tilesCol[col][row + i] = Tile();
m_jokerCol[col][row + i] = false;
m_crossCol[col][row + i].setAny();
}
@@ -430,11 +430,11 @@
{
if (m_testsRow[row][col])
{
- m_tilesRow[row][col] = Tile::dummy();
+ m_tilesRow[row][col] = Tile();
m_testsRow[row][col] = 0;
m_jokerRow[row][col] = false;
- m_tilesCol[col][row] = Tile::dummy();
+ m_tilesCol[col][row] = Tile();
m_jokerCol[col][row] = false;
}
}
Index: game/board_cross.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board_cross.cpp,v
retrieving revision 1.6.2.3
retrieving revision 1.6.2.4
diff -u -b -r1.6.2.3 -r1.6.2.4
--- game/board_cross.cpp 23 Dec 2006 13:51:13 -0000 1.6.2.3
+++ game/board_cross.cpp 27 Nov 2007 18:01:05 -0000 1.6.2.4
@@ -25,11 +25,14 @@
* \date 2005
*/
+#include <wctype.h>
+
#include <dic.h>
#include "tile.h"
#include "board.h"
#include "debug.h"
+
static void Board_checkout_tile(const Dictionary &iDic,
vector<Tile>& iTiles,
vector<bool> & iJoker,
@@ -52,15 +55,15 @@
}
// FIXME: create temporary strings until the dictionary uses Tile objects
- char leftTiles [BOARD_DIM + 1];
- char rightTiles[BOARD_DIM + 1];
+ wchar_t leftTiles [BOARD_DIM + 1];
+ wchar_t rightTiles[BOARD_DIM + 1];
for (i = left; i < index; i++)
- leftTiles[i - left] = toupper(iTiles[i].toChar());
+ leftTiles[i - left] = towupper(iTiles[i].toChar());
leftTiles[index - left] = 0;
for (i = index + 1; !iTiles[i].isEmpty(); i++)
- rightTiles[i - index - 1] = toupper(iTiles[i].toChar());
+ rightTiles[i - index - 1] = towupper(iTiles[i].toChar());
rightTiles[i - index - 1] = 0;
/* Tiles that can be played */
@@ -80,8 +83,8 @@
}
/* Points on the right part */
- /* yes, it is REALLY [index+1] */
- while (!iTiles[index+1].isEmpty())
+ /* yes, it is REALLY [index + 1] */
+ while (!iTiles[index + 1].isEmpty())
{
index++;
if (!iJoker[index])
Index: game/board_search.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board_search.cpp,v
retrieving revision 1.11.2.3
retrieving revision 1.11.2.4
diff -u -b -r1.11.2.3 -r1.11.2.4
--- game/board_search.cpp 11 Nov 2007 19:56:59 -0000 1.11.2.3
+++ game/board_search.cpp 27 Nov 2007 18:01:05 -0000 1.11.2.4
@@ -146,7 +146,7 @@
l = iTilesMx[iRow][iCol];
for (succ = iDic.getSucc(iNode); succ ; succ = iDic.getNext(succ))
{
- if (iDic.getChar(succ) == toupper(l.toChar()))
+ if ((wint_t)iDic.getChar(succ) == towupper(l.toChar()))
{
ioPartialWord.addRightFromBoard(l);
ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
@@ -221,9 +221,9 @@
int row, col, lastanchor;
Round partialword;
- list<Tile> rackTiles;
+ vector<Tile> rackTiles;
iRack.getTiles(rackTiles);
- list<Tile>::const_iterator it;
+ vector<Tile>::const_iterator it;
bool match;
for (row = 1; row <= BOARD_DIM; row++)
Index: game/freegame.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/freegame.cpp,v
retrieving revision 1.18
retrieving revision 1.18.2.1
diff -u -b -r1.18 -r1.18.2.1
--- game/freegame.cpp 22 Jan 2006 12:23:53 -0000 1.18
+++ game/freegame.cpp 27 Nov 2007 18:01:06 -0000 1.18.2.1
@@ -222,7 +222,7 @@
// It is forbidden to change letters when the bag does not contain at
// least 7 letters (this is explicitely stated in the ODS).
- Bag bag;
+ Bag bag(*m_dic);
realBag(bag);
if (bag.nTiles() < 7)
{
Index: game/game.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game.cpp,v
retrieving revision 1.31.2.3
retrieving revision 1.31.2.4
diff -u -b -r1.31.2.3 -r1.31.2.4
--- game/game.cpp 11 Nov 2007 19:56:59 -0000 1.31.2.3
+++ game/game.cpp 27 Nov 2007 18:01:06 -0000 1.31.2.4
@@ -39,7 +39,7 @@
const int Game::BONUS_POINTS = 50;
Game::Game(const Dictionary &iDic):
- m_dic(&iDic)
+ m_dic(&iDic), m_bag(iDic)
{
m_variant = kNONE;
m_points = 0;
@@ -93,7 +93,7 @@
// Is the represented letter still available in the bag?
// FIXME: this way to get the represented letter sucks...
Tile t(towupper(iRound.getTile(i).toChar()));
- Bag bag;
+ Bag bag(*m_dic);
realBag(bag);
// FIXME: realBag() does not give us a real bag in this
// particular case! This is because Player::endTurn() is called
@@ -252,7 +252,7 @@
// Create a copy of the bag in which we can do everything we want,
// and take from it the tiles of the players rack so that "bag"
// contains the right number of tiles.
- Bag bag;
+ Bag bag(*m_dic);
realBag(bag);
if (mode == RACK_NEW && nold != 0)
@@ -403,8 +403,8 @@
*/
bool Game::rackInBag(const Rack &iRack, const Bag &iBag) const
{
- const list<Tile>& allTiles = Tile::getAllTiles();
- list<Tile>::const_iterator it;
+ const vector<Tile>& allTiles = m_dic->getAllTiles();
+ vector<Tile>::const_iterator it;
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
if (iRack.in(*it) > iBag.in(*it))
Index: game/history.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/history.cpp,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.2
diff -u -b -r1.10.2.1 -r1.10.2.2
--- game/history.cpp 13 Jan 2007 21:37:45 -0000 1.10.2.1
+++ game/history.cpp 27 Nov 2007 18:01:06 -0000 1.10.2.2
@@ -51,11 +51,7 @@
{
for (unsigned int i = 0; i < m_history.size(); i++)
{
- if (m_history[i] != NULL)
- {
delete m_history[i];
- m_history[i] = NULL;
- }
}
}
@@ -145,7 +141,7 @@
delete t;
}
- // now we have the previous played round in back()
+ // Now we have the previous played round in back()
Turn* t = m_history.back();
t->setNum(0);
t->setPlayer(0);
Index: game/pldrack.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/pldrack.cpp,v
retrieving revision 1.9
retrieving revision 1.9.2.1
diff -u -b -r1.9 -r1.9.2.1
--- game/pldrack.cpp 22 Jan 2006 12:23:53 -0000 1.9
+++ game/pldrack.cpp 27 Nov 2007 18:01:06 -0000 1.9.2.1
@@ -122,29 +122,17 @@
void PlayedRack::setOld(const Rack &iRack)
{
- list<Tile> l;
+ vector<Tile> l;
iRack.getTiles(l);
-
- m_oldTiles.clear();
- list<Tile>::const_iterator it;
- for (it = l.begin(); it != l.end(); it++)
- {
- addOld(*it);
- }
+ m_oldTiles = l;
}
void PlayedRack::setNew(const Rack &iRack)
{
- list<Tile> l;
+ vector<Tile> l;
iRack.getTiles(l);
-
- m_newTiles.clear();
- list<Tile>::const_iterator it;
- for (it = l.begin(); it != l.end(); it++)
- {
- addNew(*it);
- }
+ m_newTiles = l;
}
int PlayedRack::setManual(const wstring& iLetters)
@@ -152,7 +140,7 @@
unsigned int i;
reset();
- if (iLetters.size() == 0)
+ if (iLetters.empty())
{
return 0; /* empty is ok */
}
Index: game/rack.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/rack.cpp,v
retrieving revision 1.7
retrieving revision 1.7.2.1
diff -u -b -r1.7 -r1.7.2.1
--- game/rack.cpp 22 Jan 2006 12:23:53 -0000 1.7
+++ game/rack.cpp 27 Nov 2007 18:01:06 -0000 1.7.2.1
@@ -22,50 +22,53 @@
* \file rack.cpp
* \brief Rack class : multiset of tiles
* \author Antoine Fraboulet & Olivier Teuliere
- * \date 2002 - 2005
+ * \date 2002 - 2007
*/
#include "rack.h"
#include "encoding.h"
#include "debug.h"
-// FIXME: should not be here (duplicated from tile.cpp)
-#define TILES_NUMBER 28
-#define MIN_CODE 1
-
Rack::Rack()
- : m_tiles(TILES_NUMBER, 0), m_ntiles(0)
+ : m_ntiles(0)
+{
+}
+
+
+unsigned int Rack::in(const Tile &t) const
{
+ map<Tile, unsigned int>::const_iterator it = m_tiles.find(t);
+ if (it == m_tiles.end())
+ return 0;
+ return it->second;
}
+
void Rack::remove(const Tile &t)
{
ASSERT(in(t),
"The rack does not contain the letter " + convertToMb(t.toChar()));
- m_tiles[t.toCode()]--;
+ m_tiles[t]--;
m_ntiles--;
}
void Rack::clear()
{
- for (unsigned int i = 0; i < m_tiles.size(); i++)
- {
- m_tiles[i] = 0;
- }
+ m_tiles.clear();
m_ntiles = 0;
}
-void Rack::getTiles(list<Tile> &oTiles) const
+void Rack::getTiles(vector<Tile> &oTiles) const
{
- for (unsigned int i = MIN_CODE; i < m_tiles.size(); i++)
- {
- for (unsigned int j = 0; j < m_tiles[i]; j++)
+ oTiles.reserve(m_ntiles);
+ map<Tile, unsigned int>::const_iterator it;
+ for (it = m_tiles.begin(); it != m_tiles.end(); ++it)
{
- oTiles.push_back(Tile::GetTileFromCode(i));
- }
+ // Add it->second copies of the tile at the end of the vector
+ oTiles.insert(oTiles.end(), it->second, it->first);
}
}
@@ -73,12 +76,11 @@
wstring Rack::toString()
{
wstring rs;
- for (unsigned int i = MIN_CODE; i < m_tiles.size(); i++)
- {
- for (unsigned int j = 0; j < m_tiles[i]; j++)
+ map<Tile, unsigned int>::const_iterator it;
+ for (it = m_tiles.begin(); it != m_tiles.end(); ++it)
{
- rs += Tile::GetTileFromCode(i).toChar();
- }
+ // Append it->second copies of the char
+ rs.append(it->second, it->first.toChar());
}
return rs;
}
Index: game/rack.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/rack.h,v
retrieving revision 1.9
retrieving revision 1.9.2.1
diff -u -b -r1.9 -r1.9.2.1
--- game/rack.h 22 Jan 2006 12:23:53 -0000 1.9
+++ game/rack.h 27 Nov 2007 18:01:06 -0000 1.9.2.1
@@ -22,15 +22,15 @@
* \file rack.h
* \brief Rack class : multiset of tiles
* \author Antoine Fraboulet & Olivier Teuliere
- * \date 2002 - 2005
+ * \date 2002 - 2007
*/
#ifndef _RACK_H_
#define _RACK_H_
#include "tile.h"
-#include <set>
-#include <list>
+#include <map>
+#include <vector>
#include <string>
using namespace std;
@@ -49,17 +49,17 @@
int nTiles() const { return m_ntiles; }
bool isEmpty() const { return nTiles() == 0; }
- unsigned int in(const Tile &t) const { return m_tiles[t.toCode()]; }
- void add(const Tile &t) { m_tiles[t.toCode()]++; m_ntiles++; }
+ unsigned int in(const Tile &t) const;
+ void add(const Tile &t) { m_tiles[t]++; m_ntiles++; }
void remove(const Tile &t);
void clear();
- void getTiles(list<Tile> &oTiles) const;
+ void getTiles(vector<Tile> &oTiles) const;
wstring toString();
private:
- /// Vector indexed by tile codes, containing the number of tiles
- vector<unsigned int> m_tiles;
+ /// Map associating to tiles their number in the rack
+ map<Tile, unsigned int> m_tiles;
int m_ntiles;
};
Index: utils/eliottxt.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/eliottxt.cpp,v
retrieving revision 1.16.2.6
retrieving revision 1.16.2.7
diff -u -b -r1.16.2.6 -r1.16.2.7
--- utils/eliottxt.cpp 21 Nov 2007 16:25:45 -0000 1.16.2.6
+++ utils/eliottxt.cpp 27 Nov 2007 18:01:06 -0000 1.16.2.7
@@ -705,7 +705,8 @@
}
-void eliot_regexp_build_default_llist(struct search_RegE_list_t &llist)
+void eliot_regexp_build_default_llist(const Dictionary &iDic,
+ struct search_RegE_list_t &llist)
{
memset(&llist, 0, sizeof(llist));
@@ -729,8 +730,8 @@
memset(llist.letters[i], 0, sizeof(llist.letters[i]));
}
- const list<Tile>& allTiles = Tile::getAllTiles();
- list<Tile>::const_iterator it;
+ const vector<Tile>& allTiles = iDic.getAllTiles();
+ vector<Tile>::const_iterator it;
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
if (! it->isJoker() && ! it->isEmpty())
@@ -765,7 +766,7 @@
#define DIC_RE_MAX (3*DIC_WORD_MAX) // yes, it's 3
struct search_RegE_list_t llist;
- eliot_regexp_build_default_llist(llist);
+ eliot_regexp_build_default_llist(iDic, llist);
wchar_t *regexp = wcstok(NULL, delim, state);
wchar_t *cnres = wcstok(NULL, delim, state);
Index: utils/game_io.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/game_io.cpp,v
retrieving revision 1.9.2.2
retrieving revision 1.9.2.3
diff -u -b -r1.9.2.2 -r1.9.2.3
--- utils/game_io.cpp 11 Nov 2007 19:56:59 -0000 1.9.2.2
+++ utils/game_io.cpp 27 Nov 2007 18:01:07 -0000 1.9.2.3
@@ -20,8 +20,9 @@
#include <iomanip>
#include <string>
-#include "stdlib.h"
+#include <stdlib.h>
+#include <dic.h>
#include "game_io.h"
#include "game.h"
#include "training.h"
@@ -172,8 +173,8 @@
void GameIO::printNonPlayed(ostream &out, const Game &iGame)
{
- const list<Tile>& allTiles = Tile::getAllTiles();
- list<Tile>::const_iterator it;
+ const vector<Tile>& allTiles = iGame.getDic().getAllTiles();
+ vector<Tile>::const_iterator it;
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
Index: wxwin/auxframes.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/auxframes.cc,v
retrieving revision 1.22.2.2
retrieving revision 1.22.2.3
diff -u -b -r1.22.2.2 -r1.22.2.3
--- wxwin/auxframes.cc 11 Nov 2007 19:57:00 -0000 1.22.2.2
+++ wxwin/auxframes.cc 27 Nov 2007 18:01:07 -0000 1.22.2.3
@@ -182,8 +182,8 @@
tiles->ClearAll();
- std::list<Tile>::const_iterator it;
- const std::list<Tile>& allTiles = Tile::getAllTiles();
+ std::vector<Tile>::const_iterator it;
+ const std::vector<Tile>& allTiles = m_game.getDic().getAllTiles();
for (index = 0, it = allTiles.begin(); it != allTiles.end(); index++, it++)
{
n = m_game.getBag().in(*it);
Index: wxwin/searchpanel.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/searchpanel.cc,v
retrieving revision 1.15.2.1
retrieving revision 1.15.2.2
diff -u -b -r1.15.2.1 -r1.15.2.2
--- wxwin/searchpanel.cc 15 Oct 2006 11:07:55 -0000 1.15.2.1
+++ wxwin/searchpanel.cc 27 Nov 2007 18:01:07 -0000 1.15.2.2
@@ -273,8 +273,8 @@
memset(llist.letters[i],0,sizeof(llist.letters[i]));
}
- const std::list<Tile>& allTiles = Tile::getAllTiles();
- std::list<Tile>::const_iterator it;
+ const std::vector<Tile>& allTiles = dic->getAllTiles();
+ std::vector<Tile>::const_iterator it;
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
if (! it->isJoker() && ! it->isEmpty())
Index: dic/tile.cpp
===================================================================
RCS file: dic/tile.cpp
diff -N dic/tile.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/tile.cpp 27 Nov 2007 18:01:05 -0000 1.1.2.1
@@ -0,0 +1,156 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2007 Eliot
+ * Authors: Olivier Teuliere <ipkiss address@hidden gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *****************************************************************************/
+
+#include <sstream>
+#include <string>
+#include <wctype.h>
+#include "tile.h"
+#include "header.h"
+#include "encoding.h"
+#include "dic_exception.h"
+
+
+const Header * Tile::m_header = NULL;
+Tile Tile::m_TheJoker;
+
+
+Tile::Tile(wchar_t c)
+{
+ if (iswalpha(c))
+ {
+ m_joker = iswlower(c);
+ m_char = towupper(c);
+ m_code = m_header->getCodeFromChar(m_char);
+ }
+ else if (c == TILE_JOKER)
+ {
+ m_joker = true;
+ m_char = TILE_JOKER;
+ m_code = m_header->getLetters().size() + 1;
+ }
+ else if (c == TILE_DUMMY)
+ {
+ // The char and the code are chosen to be different from any possible
+ // real tile
+ m_joker = false;
+ m_char = TILE_DUMMY;
+ m_code = 0;
+ }
+ else
+ {
+ ostringstream ss;
+ ss << "Tile::Tile: Unknown character: " << convertToMb(c);
+ throw DicException(ss.str());
+ }
+}
+
+
+bool Tile::isVowel() const
+{
+ if (m_code == 0)
+ throw DicException("Tile::isVowel: Invalid tile");
+ if (m_joker)
+ return true;
+ return m_header->isVowel(m_code);
+}
+
+
+bool Tile::isConsonant() const
+{
+ if (m_code == 0)
+ throw DicException("Tile::isConsonant: Invalid tile");
+ if (m_joker)
+ return true;
+ return m_header->isConsonant(m_code);
+}
+
+
+unsigned int Tile::maxNumber() const
+{
+ if (m_code == 0)
+ throw DicException("Tile::maxNumber: Invalid tile");
+ if (m_joker)
+ return 2;
+ return m_header->getFrequency(m_code);
+}
+
+
+unsigned int Tile::getPoints() const
+{
+ if (m_code == 0)
+ throw DicException("Tile::getPoints: Invalid tile");
+ if (m_joker)
+ return 0;
+ return m_header->getPoints(m_code);
+}
+
+
+wchar_t Tile::toChar() const
+{
+ if (m_joker)
+ {
+ if (iswalpha(m_char))
+ return towlower(m_char);
+ else
+ return TILE_JOKER;
+ }
+ return m_char;
+}
+
+
+unsigned int Tile::toCode() const
+{
+ return m_code;
+}
+
+
+bool Tile::operator<(const Tile &iOther) const
+{
+ if (m_joker)
+ return false;
+ else if (iOther.m_joker)
+ return true;
+ else
+ return m_char < iOther.m_char;
+}
+
+
+bool Tile::operator==(const Tile &iOther) const
+{
+ if (m_joker || iOther.m_joker)
+ {
+ if (m_joker != iOther.m_joker)
+ return false;
+ return m_char == iOther.m_char;
+ }
+ return m_char == iOther.m_char;
+}
+
+
+bool Tile::operator!=(const Tile &iOther) const
+{
+ return !(*this == iOther);
+}
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: dic/tile.h
===================================================================
RCS file: dic/tile.h
diff -N dic/tile.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/tile.h 27 Nov 2007 18:01:05 -0000 1.1.2.1
@@ -0,0 +1,97 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2007 Eliot
+ * Authors: Olivier Teuliere <ipkiss address@hidden gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *****************************************************************************/
+
+#ifndef _TILE_H_
+#define _TILE_H_
+
+#include <list>
+#include <vector>
+
+using namespace std;
+
+class Header;
+
+
+/*************************
+ * A Tile is the internal representation
+ * used within the game library to
+ * handle letters
+ *************************/
+
+// XXX
+#define TILE_DUMMY L'%'
+#define TILE_JOKER L'?'
+
+
+class Tile
+{
+ friend class Dictionary;
+public:
+
+ // a lowercase character is always a joker
+ // - this permits to detect joker in already played games
+ // - we need to pay attention when inserting characters taken
+ // from user input
+
+ Tile(wchar_t c = TILE_DUMMY);
+ virtual ~Tile() {}
+
+ bool isEmpty() const { return m_char == TILE_DUMMY; }
+ bool isJoker() const { return m_joker; }
+ bool isVowel() const;
+ bool isConsonant() const;
+ unsigned int maxNumber() const;
+ unsigned int getPoints() const;
+ wchar_t toChar() const;
+ unsigned int toCode() const;
+
+ static const Tile &Joker() { return m_TheJoker; }
+
+ bool operator <(const Tile &iOther) const;
+ bool operator ==(const Tile &iOther) const;
+ bool operator !=(const Tile &iOther) const;
+
+private:
+ wchar_t m_char;
+ bool m_joker;
+
+ /**
+ * Internal code, used in the dictionary to represent the letter.
+ * It is mainly used by the Cross class.
+ */
+ int m_code;
+
+ // Special tiles are declared static
+ static Tile m_TheJoker;
+
+ /// Dictionary header
+ static const Header *m_header;
+
+ /// Update the dictionary header
+ static void SetHeader(const Header &iHeader) { m_header = &iHeader; }
+};
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: m4/ax_boost_base.m4
===================================================================
RCS file: m4/ax_boost_base.m4
diff -N m4/ax_boost_base.m4
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ m4/ax_boost_base.m4 27 Nov 2007 18:01:06 -0000 1.1.2.1
@@ -0,0 +1,198 @@
+##### http://autoconf-archive.cryp.to/ax_boost_base.html
+#
+# SYNOPSIS
+#
+# AX_BOOST_BASE([MINIMUM-VERSION])
+#
+# DESCRIPTION
+#
+# Test for the Boost C++ libraries of a particular version (or newer)
+#
+# If no path to the installed boost library is given the macro
+# searchs under /usr, /usr/local, and /opt, and evaluates the
+# $BOOST_ROOT environment variable. Further documentation is
+# available at <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
+#
+# And sets:
+#
+# HAVE_BOOST
+#
+# LAST MODIFICATION
+#
+# 2007-03-15
+#
+# COPYLEFT
+#
+# Copyright (c) 2007 Thomas Porschberg <address@hidden>
+#
+# Copying and distribution of this file, with or without
+# modification, are permitted in any medium without royalty provided
+# the copyright notice and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_BASE],
+[
+AC_ARG_WITH([boost],
+ AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes)
- it is possible to specify the root directory for boost (optional)]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ac_boost_path=""
+ else
+ want_boost="yes"
+ ac_boost_path="$withval"
+ fi
+ ],
+ [want_boost="yes"])
+
+if test "x$want_boost" = "xyes"; then
+ boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
+ boost_lib_version_req_shorten=`expr $boost_lib_version_req :
'\([[0-9]]*\.[[0-9]]*\)'`
+ boost_lib_version_req_major=`expr $boost_lib_version_req :
'\([[0-9]]*\)'`
+ boost_lib_version_req_minor=`expr $boost_lib_version_req :
'[[0-9]]*\.\([[0-9]]*\)'`
+ boost_lib_version_req_sub_minor=`expr $boost_lib_version_req :
'[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+ if test "x$boost_lib_version_req_sub_minor" = "x" ; then
+ boost_lib_version_req_sub_minor="0"
+ fi
+ WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+
$boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
+ AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
+ succeeded=no
+
+ dnl first we check the system location for boost libraries
+ dnl this location ist chosen if boost libraries are installed with the
--layout=system option
+ dnl or if you install boost with RPM
+ if test "$ac_boost_path" != ""; then
+ BOOST_LDFLAGS="-L$ac_boost_path/lib"
+ BOOST_CPPFLAGS="-I$ac_boost_path/include"
+ else
+ for ac_boost_path_tmp in /usr /usr/local /opt ; do
+ if test -d "$ac_boost_path_tmp/include/boost" && test
-r "$ac_boost_path_tmp/include/boost"; then
+ BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
+ BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
+ break;
+ fi
+ done
+ fi
+
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= $WANT_BOOST_VERSION
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+ found_system=yes
+ ],[
+ ])
+ AC_LANG_POP([C++])
+
+
+
+ dnl if we found no boost with system layout we search for boost
libraries
+ dnl built and installed without the --layout=system option or for a
staged(not installed) version
+ if test "x$succeeded" != "xyes"; then
+ _version=0
+ if test "$ac_boost_path" != ""; then
+ BOOST_LDFLAGS="-L$ac_boost_path/lib"
+ if test -d "$ac_boost_path" && test -r
"$ac_boost_path"; then
+ for i in `ls -d $ac_boost_path/include/boost-*
2>/dev/null`; do
+ _version_tmp=`echo $i | sed
"s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+ V_CHECK=`expr $_version_tmp \>
$_version`
+ if test "$V_CHECK" = "1" ; then
+ _version=$_version_tmp
+ fi
+ VERSION_UNDERSCORE=`echo $_version |
sed 's/\./_/'`
+
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
+ done
+ fi
+ else
+ for ac_boost_path in /usr /usr/local /opt ; do
+ if test -d "$ac_boost_path" && test -r
"$ac_boost_path"; then
+ for i in `ls -d
$ac_boost_path/include/boost-* 2>/dev/null`; do
+ _version_tmp=`echo $i | sed
"s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+ V_CHECK=`expr $_version_tmp \>
$_version`
+ if test "$V_CHECK" = "1" ; then
+ _version=$_version_tmp
+ best_path=$ac_boost_path
+ fi
+ done
+ fi
+ done
+
+ VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+
BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
+ BOOST_LDFLAGS="-L$best_path/lib"
+
+ if test "x$BOOST_ROOT" != "x"; then
+ if test -d "$BOOST_ROOT" && test -r
"$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r
"$BOOST_ROOT/stage/lib"; then
+ version_dir=`expr //$BOOST_ROOT :
'.*/\(.*\)'`
+ stage_version=`echo $version_dir | sed
's/boost_//' | sed 's/_/./g'`
+ stage_version_shorten=`expr
$stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
+ V_CHECK=`expr $stage_version_shorten
\>\= $_version`
+ if test "$V_CHECK" = "1" ; then
+ AC_MSG_NOTICE(We will use a
staged boost library from $BOOST_ROOT)
+ BOOST_CPPFLAGS="-I$BOOST_ROOT"
+
BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
+ fi
+ fi
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= $WANT_BOOST_VERSION
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+ found_system=yes
+ ],[
+ ])
+ AC_LANG_POP([C++])
+ fi
+
+ if test "$succeeded" != "yes" ; then
+ if test "$_version" = "0" ; then
+ AC_MSG_ERROR([[We could not detect the boost libraries
(version $boost_lib_version_req_shorten or higher). If you have a staged boost
library (still not installed) please specify \$BOOST_ROOT in your environment
and do not give a PATH to --with-boost option. If you are sure you have boost
installed, then check your version number looking in <boost/version.hpp>. See
http://randspringer.de/boost for more documentation.]])
+ else
+ AC_MSG_NOTICE([Your boost libraries seems to old
(version $_version).])
+ fi
+ else
+ AC_SUBST(BOOST_CPPFLAGS)
+ AC_SUBST(BOOST_LDFLAGS)
+ AC_DEFINE(HAVE_BOOST,,[define if the Boost library is
available])
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+fi
+
+])
Index: game/tile.cpp
===================================================================
RCS file: game/tile.cpp
diff -N game/tile.cpp
--- game/tile.cpp 22 Jan 2006 12:23:53 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,233 +0,0 @@
-/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *****************************************************************************/
-
-#include "tile.h"
-#include <wctype.h>
-
-
-/*************************
- * French tiles
- * Zero + 26 letters + joker
- * tiles ares supposed to be contiguous and joker is separated
- *************************/
-
-#define TILE_START 'A'
-#define TILE_END 'Z'
-#define TILE_JOKER '?'
-#define TILE_DUMMY '%'
-
-#define TILE_IDX_DUMMY 0
-#define TILE_IDX_START 1
-#define TILE_IDX_END 26
-#define TILE_IDX_JOKER 27
-
-#define TILES_NUMBER 28
-
-/* The jokers and the 'Y' can be considered both as vowels or consonants */
-const unsigned int Tiles_vowels[TILES_NUMBER] =
-{
-/* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ? */
- 0,1,0,0,0, 1,0,0,0,1,0, 0,0,0,0,1,0,0,0,0,0,1,0, 0, 0, 1, 0,1
-};
-
-const unsigned int Tiles_consonants[TILES_NUMBER] =
-{
-/* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ? */
- 0,0,1,1,1, 0,1,1,1,0,1, 1,1,1,1,0,1,1,1,1,1,0,1, 1, 1, 1, 1,1
-};
-
-const unsigned int Tiles_numbers[TILES_NUMBER] =
-{
-/* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ? */
- 0,9,2,2,3,15,2,2,2,8,1, 1,5,3,6,6,2,1,6,6,6,6,2, 1, 1, 1, 1,2
-};
-
-const unsigned int Tiles_points[TILES_NUMBER] =
-{
-/* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ? */
- 0,1,3,3,2, 1,4,2,4,1,8,10,1,2,1,1,3,8,1,1,1,1,4,10,10,10,10,0
-};
-
-/***************************
- ***************************/
-
-const Tile Tile::m_TheJoker(TILE_JOKER);
-const Tile Tile::m_TheDummy(0);
-list<Tile> Tile::m_tilesList;
-vector<Tile> Tile::m_tilesVect(TILES_NUMBER, Tile::dummy());
-bool Tile::m_vectInitialized(false);
-
-
-Tile::Tile(wchar_t c)
-{
- if (c == TILE_JOKER)
- {
- m_joker = true;
- m_dummy = false;
- m_char = TILE_JOKER;
- m_code = 27;
- }
- else if (isalpha(c))
- {
- m_joker = islower(c);
- m_dummy = false;
- m_char = towupper(c);
- m_code = m_char - 'A' + 1;
- }
- else
- {
- m_joker = false;
- m_dummy = true;
- m_char = 0;
- m_code = 0;
- }
-}
-
-
-bool Tile::isVowel() const
-{
- if (m_dummy)
- return false;
- if (m_joker)
- return Tiles_vowels[TILE_IDX_JOKER];
- return Tiles_vowels[TILE_IDX_START + m_char - TILE_START];
-}
-
-
-bool Tile::isConsonant() const
-{
- if (m_dummy)
- return false;
- if (m_joker)
- return Tiles_consonants[TILE_IDX_JOKER];
- return Tiles_consonants[TILE_IDX_START + m_char - TILE_START];
-}
-
-
-unsigned int Tile::maxNumber() const
-{
- if (m_dummy)
- return false;
- if (m_joker)
- return Tiles_numbers[TILE_IDX_JOKER];
- return Tiles_numbers[TILE_IDX_START + m_char - TILE_START];
-}
-
-
-unsigned int Tile::getPoints() const
-{
- if (m_dummy)
- return false;
- if (m_joker)
- return Tiles_points[TILE_IDX_JOKER];
- return Tiles_points[TILE_IDX_START + m_char - TILE_START];
-}
-
-
-const list<Tile>& Tile::getAllTiles()
-{
- if (Tile::m_tilesList.size() == 0)
- {
- // XXX: this should be filled from a "language file" instead
- for (char i = TILE_START; i <= TILE_END; i++)
- Tile::m_tilesList.push_back(Tile(i));
- m_tilesList.push_back(Tile(TILE_JOKER));
- }
- return Tile::m_tilesList;
-}
-
-
-const Tile& Tile::GetTileFromCode(unsigned int iCode)
-{
- if (!m_vectInitialized)
- {
- // XXX: this should be filled from a "language file" instead
- for (char i = TILE_IDX_START; i <= TILE_IDX_END; i++)
- Tile::m_tilesVect[i] = Tile(i + 'A' - TILE_IDX_START);
- m_tilesVect[TILE_IDX_JOKER] = Tile::Joker();
- m_vectInitialized = true;
- }
- return Tile::m_tilesVect[iCode];
-}
-
-
-wchar_t Tile::toChar() const
-{
- if (m_dummy)
- return TILE_DUMMY;
- if (m_joker)
- {
- if (iswalpha(m_char))
- return towlower(m_char);
- else
- return TILE_JOKER;
- }
- return m_char;
-}
-
-unsigned int Tile::toCode() const
-{
- return m_code;
-}
-
-bool Tile::operator <(const Tile &iOther) const
-{
- if (iOther.m_dummy)
- return false;
- else if (m_dummy)
- return true;
- else if (m_joker)
- return false;
- else if (iOther.m_joker)
- return true;
- else
- return m_char < iOther.m_char;
-}
-
-
-bool Tile::operator ==(const Tile &iOther) const
-{
- if (m_dummy || iOther.m_dummy)
- return m_dummy == iOther.m_dummy;
- if (m_joker || iOther.m_joker)
- {
- if (m_joker != iOther.m_joker)
- return false;
- return m_char == iOther.m_char;
- }
- return m_char == iOther.m_char;
-// return (m_joker && iOther.m_joker && m_char == iOther.m_char) ||
-// (m_dummy && iOther.m_dummy) ||
-// (!m_dummy && !iOther.m_dummy
-// && !m_joker && !iOther.m_joker
-// && m_char == iOther.m_char);
-}
-
-
-bool Tile::operator !=(const Tile &iOther) const
-{
- return !(*this == iOther);
-}
-
-/// Local Variables:
-/// mode: c++
-/// mode: hs-minor
-/// c-basic-offset: 4
-/// indent-tabs-mode: nil
-/// End:
Index: game/tile.h
===================================================================
RCS file: game/tile.h
diff -N game/tile.h
--- game/tile.h 22 Jan 2006 12:23:53 -0000 1.8
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,95 +0,0 @@
-/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *****************************************************************************/
-
-#ifndef _TILE_H_
-#define _TILE_H_
-
-#include <list>
-#include <vector>
-
-using namespace std;
-
-
-/*************************
- * A Tile is the internal representation
- * used within the game library to
- * handle letters
- *************************/
-
-class Tile
-{
-public:
-
- // a lowercase character always a joker
- // - this permits to detect joker in already played games
- // - we need to pay attention when inserting character taken
- // from user input
-
- Tile(wchar_t c = 0);
- virtual ~Tile() {}
-
- bool isEmpty() const { return m_dummy; }
- bool isJoker() const { return m_joker; }
- bool isVowel() const;
- bool isConsonant() const;
- unsigned int maxNumber() const;
- unsigned int getPoints() const;
- wchar_t toChar() const;
- unsigned int toCode() const;
-
- static const Tile &dummy() { return m_TheDummy; }
- static const Tile &Joker() { return m_TheJoker; }
- static const list<Tile>& getAllTiles();
- static const Tile &GetTileFromCode(unsigned int iCode);
-
- bool operator <(const Tile &iOther) const;
- bool operator ==(const Tile &iOther) const;
- bool operator !=(const Tile &iOther) const;
-
-private:
- wchar_t m_char;
- bool m_joker;
- bool m_dummy;
-
- /**
- * Internal code, used in the dictionary to represent the letter.
- * It is mainly used by the Cross class.
- */
- int m_code;
-
- // Special tiles are declared static
- static const Tile m_TheJoker;
- static const Tile m_TheDummy;
-
- /// List of available tiles
- static list<Tile> m_tilesList;
- /// Vector of tiles indexed by their code, for fast look-up
- static vector<Tile> m_tilesVect;
- /// True when m_tilesVect is correctly initialized
- static bool m_vectInitialized;
-};
-
-#endif
-
-/// Local Variables:
-/// mode: c++
-/// mode: hs-minor
-/// c-basic-offset: 4
-/// indent-tabs-mode: nil
-/// End:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Eliot-dev] eliot configure.in dic/Makefile.am dic/compdic.... [cppdic],
eliot-dev <=