/* This file is part of cardwords (c) 1998 1999 Tobias Peters see file COPYING for the copyright terms. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // cardwords_dicbot_cardtablecell.hh /* Classes containing _DicBot_ and files containing _dicbot_ indicate classes and files for dicbot. dicbot will be the dictionary and robot process started by the cardwords server. The server delegates the following tasks to dicbot: - Check if a move is valid. This means: . * Check if there is enough space on the card-table to actually lay the . cards. . * Check if all words created by that move are valid. This can be . disabled. - Calculate the score of a move. This contains a validity check as above. - Calculate the best possible move for a given set of cards. The best . possible move means the one that gets the most points. . This contains several score calculations as above. */ #ifndef CARDWORDS_DICBOT_CARDTABLECELL_HH #define CARDWORDS_DICBOT_CARDTABLECELL_HH // This file defines The class CardWords_DicBot_CardTableCell. // This class contains all information dicbot wants to have about a // special cell of the card-table. #include "cardwords_carddescription.hh" #include "cardwords_direction.hh" #include "cardwords_dicbot_cardtablemustnot.hh" #include "cardwords_exceptions.hh" #include "config.hh" class CardWords_DicBot_CardTableCell { public: // everything is modifyable through accessing functions CardWords_DicBot_CardTableCell (); // Each cell remembers if it is possible to start or end a word here, de- // pending on the direction. E.g. it is not possible to start a horizontal // word on a cell whose left neighbour carries already a card. bool is_startPossible (CardWords_Direction) const; bool is_endPossible (CardWords_Direction) const; // Because a cell has no clue what happens with its neighbours, this info // has to come from the outside: void set_startPossible (CardWords_Direction, bool = true); void unset_startPossible (CardWords_Direction); void set_endPossible (CardWords_Direction, bool = true); void unset_endPossible (CardWords_Direction); // if this cell carries a card: bool get_containsCard(void) const; // use remove_card and change_card instead of this: // void set_containsCard(bool); // return the CardDescription: const CardWords_CardDescription * get_card(void) const; // remove the card: void remove_card(void); // change the card, also used for adding: void change_card (const CardWords_CardDescription &); // get and set the letter and word factors: int get_letter_factor(void) const; int get_word_factor (void) const; int get_cell_points (void) const; bool is_cell_blocked (void) const; void set_letter_factor(int); void set_word_factor (int); void set_cell_points (int); void set_cell_blocked (bool); // Methods to modify the must_not information: // The direction parameter that every method takes is equivalent to the // direction of the words that must not contain these must_not characters. CardWords_DicBot_CardTableMustNot * get_must_not(CardWords_Direction); const CardWords_DicBot_CardTableMustNot * get_must_not(CardWords_Direction) const; // Check if the must_not allows char c, or if there is a card in this // cell, if that card's meaning is the same as c: inline bool test_allowed(CardWords_Char c, CardWords_Direction) const; // Add a forbidden char to the must nots: void add_must_not(CardWords_Char c, CardWords_Direction); // Clear all must nots because of a new card-table situation that has an // impact on this field: void clear_must_nots(CardWords_Direction); private: bool startPossible[2]; bool endPossible[2]; bool containsCard; CardWords_CardDescription card; int letter_factor; int word_factor; int cell_points; bool cell_blocked; CardWords_DicBot_CardTableMustNot * mustNot[2]; }; // everything is modifyable through accessing functions inline CardWords_DicBot_CardTableCell::CardWords_DicBot_CardTableCell() : card() { startPossible[0] = true; startPossible[1] = endPossible[0] = endPossible[1] = true; containsCard = false; letter_factor = DEFAULT_LETTER_FACTOR; word_factor = DEFAULT_WORD_FACTOR; cell_points = DEFAULT_CELL_POINTS; cell_blocked = false; mustNot[horizontal] = mustNot[vertikal] = 0; } // Each cell remembers if it is possible to start or end a word here, de- // pending on the direction. E.g. it is not possible to start a horizontal // word on a cell whose left neighbour carries already a card. inline bool CardWords_DicBot_CardTableCell:: is_startPossible(CardWords_Direction direction) const { return startPossible[int(direction)]; } inline bool CardWords_DicBot_CardTableCell:: is_endPossible(CardWords_Direction direction) const { return endPossible[int(direction)]; } // Because a cell has no clue what happens with its neighbours, this info // has to come from the outside: inline void CardWords_DicBot_CardTableCell:: set_startPossible(CardWords_Direction direction, bool b = true) { startPossible[int(direction)] = b; } inline void CardWords_DicBot_CardTableCell:: unset_startPossible(CardWords_Direction direction) { startPossible[int(direction)] = false; } inline void CardWords_DicBot_CardTableCell::set_endPossible(CardWords_Direction direction, bool b = true) { endPossible[int(direction)] = b; } inline void CardWords_DicBot_CardTableCell:: unset_endPossible(CardWords_Direction direction) { endPossible[int(direction)] = false; } // if this cell carries a card: inline bool CardWords_DicBot_CardTableCell::get_containsCard(void) const { return containsCard; } // return the CardDescription: inline const CardWords_CardDescription * CardWords_DicBot_CardTableCell::get_card(void) const { return containsCard ? (& card) : (const CardWords_CardDescription *) 0; } // remove the card: inline void CardWords_DicBot_CardTableCell::remove_card(void) { containsCard = false; } // change the card, also used for adding: inline void CardWords_DicBot_CardTableCell:: change_card(const CardWords_CardDescription & description) { containsCard = true; card = description; } // get and set the letter and word factors: inline int CardWords_DicBot_CardTableCell::get_letter_factor(void) const { return letter_factor; } inline int CardWords_DicBot_CardTableCell::get_word_factor(void) const { return word_factor; } inline int CardWords_DicBot_CardTableCell::get_cell_points (void) const { return cell_points; } inline bool CardWords_DicBot_CardTableCell::is_cell_blocked (void) const { return cell_blocked; } inline void CardWords_DicBot_CardTableCell::set_letter_factor(int v) { letter_factor = v; } inline void CardWords_DicBot_CardTableCell::set_word_factor(int v) { word_factor = v; } inline void CardWords_DicBot_CardTableCell::set_cell_points(int v) { cell_points = v; } inline void CardWords_DicBot_CardTableCell::set_cell_blocked (bool b) { cell_blocked = b; } // Methods to modify the must_not information: // The direction parameter that every method takes is equivalent to the // direction of the words that must not contain these must_not characters. inline CardWords_DicBot_CardTableMustNot * CardWords_DicBot_CardTableCell::get_must_not(CardWords_Direction dir) { return mustNot[dir]; } inline const CardWords_DicBot_CardTableMustNot * CardWords_DicBot_CardTableCell::get_must_not(CardWords_Direction dir) const { return mustNot[dir]; } // Check if the must_not allows char c, or if there is a card in this // cell, if that card's meaning is the same as c: inline bool CardWords_DicBot_CardTableCell:: test_allowed(CardWords_Char c, CardWords_Direction dir) const { if (get_containsCard() == true) { return c == get_card()->get_meaning(); } if (mustNot[dir] == 0) { return true; } return mustNot[dir]->test_allowed(c); } // Add a forbidden char to the must nots: inline void CardWords_DicBot_CardTableCell:: add_must_not(CardWords_Char c, CardWords_Direction dir) { assert (get_containsCard() == false); if (mustNot[dir] == 0) { mustNot[dir] = new CardWords_DicBot_CardTableMustNot(); if (mustNot[dir] == 0) { throw CardWords_XLowResources(gettext("In CardWords_DicBot_"\ "CardTableCell::"\ "add_must_not: "\ "Not enough memory "\ "for CardWords_DIcBot_"\ "TableMustNot")); } } mustNot[dir]->insert(c); } // Clear all must nots because of a new card-table situation that has an // impact on this field: inline void CardWords_DicBot_CardTableCell::clear_must_nots(CardWords_Direction dir) { if (mustNot[dir] != 0) { mustNot[dir]->clear(); } } #endif