Take more advantage of the Coord class, and remove the useless accessors

from Round (to force using the Coord object)
This commit is contained in:
Olivier Teulière 2005-11-05 13:56:59 +00:00
parent 85a30f16a2
commit 12894e00e2
7 changed files with 129 additions and 184 deletions

View file

@ -153,9 +153,9 @@ void Board::addRound(const Dictionary &iDic, const Round &iRound)
Tile t;
int row, col;
row = iRound.getRow();
col = iRound.getCol();
if (iRound.getDir() == Coord::HORIZONTAL)
row = iRound.getCoord().getRow();
col = iRound.getCoord().getCol();
if (iRound.getCoord().getDir() == Coord::HORIZONTAL)
{
for (int i = 0; i < iRound.getWordLen(); i++)
{
@ -194,9 +194,9 @@ void Board::removeRound(const Dictionary &iDic, const Round &iRound)
{
int row, col;
row = iRound.getRow();
col = iRound.getCol();
if (iRound.getDir() == Coord::HORIZONTAL)
row = iRound.getCoord().getRow();
col = iRound.getCoord().getCol();
if (iRound.getCoord().getDir() == Coord::HORIZONTAL)
{
for (int i = 0; i < iRound.getWordLen(); i++)
{
@ -248,8 +248,8 @@ int Board::checkRoundAux(Matrix<Tile> &iTilesMx,
pts = 0;
ptscross = 0;
wordmul = 1;
row = iRound.getRow();
col = iRound.getCol();
row = iRound.getCoord().getRow();
col = iRound.getCoord().getCol();
/* Is the word an extension of another word? */
if (!iTilesMx[row][col - 1].isEmpty() ||
@ -314,7 +314,7 @@ int Board::checkRoundAux(Matrix<Tile> &iTilesMx,
if (isolated && !firstturn)
return 5;
/* The first word must be horizontal */
if (firstturn && iRound.getDir() == Coord::VERTICAL)
if (firstturn && iRound.getCoord().getDir() == Coord::VERTICAL)
return 6;
/* The first word must cover the H8 square */
if (firstturn
@ -334,28 +334,24 @@ int Board::checkRoundAux(Matrix<Tile> &iTilesMx,
int Board::checkRound(Round &iRound, bool firstturn)
{
if (iRound.getDir() == Coord::HORIZONTAL)
if (iRound.getCoord().getDir() == Coord::HORIZONTAL)
{
return checkRoundAux(m_tilesRow, m_crossRow,
m_pointRow, m_jokerRow,
iRound, firstturn);
}
else
{
int res, tmp;
// XXX: ugly!
/* Exchange the coordinates temporarily */
tmp = iRound.getRow();
iRound.setRow(iRound.getCol());
iRound.setCol(tmp);
// Exchange the coordinates temporarily
iRound.accessCoord().swap();
res = checkRoundAux(m_tilesCol, m_crossCol,
m_pointCol, m_jokerCol,
iRound, firstturn);
int res = checkRoundAux(m_tilesCol, m_crossCol,
m_pointCol, m_jokerCol,
iRound, firstturn);
/* Restore the coordinates */
tmp = iRound.getRow();
iRound.setRow(iRound.getCol());
iRound.setCol(tmp);
// Restore the coordinates
iRound.accessCoord().swap();
return res;
}
@ -367,9 +363,9 @@ void Board::testRound(const Round &iRound)
Tile t;
int row, col;
row = iRound.getRow();
col = iRound.getCol();
if (iRound.getDir() == Coord::HORIZONTAL)
row = iRound.getCoord().getRow();
col = iRound.getCoord().getCol();
if (iRound.getCoord().getDir() == Coord::HORIZONTAL)
{
for (int i = 0; i < iRound.getWordLen(); i++)
{

View file

@ -48,8 +48,8 @@ static void BoardSearchEvalMove(const Board &iBoard,
len = iWord.getWordLen();
row = iWord.getRow();
col = iWord.getCol();
row = iWord.getCoord().getRow();
col = iWord.getCoord().getCol();
for (i = 0; i < len; i++)
{
@ -78,16 +78,17 @@ static void BoardSearchEvalMove(const Board &iBoard,
iWord.setBonus(fromrack == 7);
iWord.setPoints(pts);
if (iWord.getDir() == Coord::VERTICAL)
// XXX: ugly!
if (iWord.getCoord().getDir() == Coord::VERTICAL)
{
iWord.setRow(col);
iWord.setCol(row);
// Exchange the coordinates temporarily
iWord.accessCoord().swap();
}
iResults.add(iWord);
if (iWord.getDir() == Coord::VERTICAL)
if (iWord.getCoord().getDir() == Coord::VERTICAL)
{
iWord.setRow(row);
iWord.setCol(col);
// Restore the coordinates
iWord.accessCoord().swap();
}
}
@ -98,18 +99,18 @@ static void ExtendRight(const Board &iBoard,
Matrix<Cross> &iCrossMx,
Matrix<int> &iPointsMx,
Matrix<bool> &iJokerMx,
Rack &iRack, Round &partialword,
Rack &iRack, Round &ioPartialWord,
Results &iResults, unsigned int iNode,
int iRow, int iCol, int anchor)
int iRow, int iCol, int iAnchor)
{
Tile l;
unsigned int succ;
if (iTilesMx[iRow][iCol].isEmpty())
{
if (Dic_word(iDic, iNode) && iCol > anchor)
if (Dic_word(iDic, iNode) && iCol > iAnchor)
BoardSearchEvalMove(iBoard, iTilesMx, iPointsMx, iJokerMx,
iResults, partialword);
iResults, ioPartialWord);
for (succ = Dic_succ(iDic, iNode); succ; succ = Dic_next(iDic, succ))
{
@ -119,21 +120,21 @@ static void ExtendRight(const Board &iBoard,
if (iRack.in(l))
{
iRack.remove(l);
partialword.addRightFromRack(l, 0);
ioPartialWord.addRightFromRack(l, 0);
ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, partialword, iResults,
succ, iRow, iCol + 1, anchor);
partialword.removeRightToRack(l, 0);
iJokerMx, iRack, ioPartialWord, iResults,
succ, iRow, iCol + 1, iAnchor);
ioPartialWord.removeRightToRack(l, 0);
iRack.add(l);
}
if (iRack.in(Tile::Joker()))
{
iRack.remove(Tile::Joker());
partialword.addRightFromRack(l, 1);
ioPartialWord.addRightFromRack(l, 1);
ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, partialword, iResults,
succ, iRow, iCol + 1, anchor);
partialword.removeRightToRack(l, 1);
iJokerMx, iRack, ioPartialWord, iResults,
succ, iRow, iCol + 1, iAnchor);
ioPartialWord.removeRightToRack(l, 1);
iRack.add(Tile::Joker());
}
}
@ -146,11 +147,11 @@ static void ExtendRight(const Board &iBoard,
{
if (Tile('A' - 1 + Dic_chr(iDic, succ)) == l)
{
partialword.addRightFromBoard(l);
ioPartialWord.addRightFromBoard(l);
ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, partialword,
iResults, succ, iRow, iCol + 1, anchor);
partialword.removeRightToBoard(l);
iJokerMx, iRack, ioPartialWord,
iResults, succ, iRow, iCol + 1, iAnchor);
ioPartialWord.removeRightToBoard(l);
}
}
}
@ -163,16 +164,17 @@ static void LeftPart(const Board &iBoard,
Matrix<Cross> &iCrossMx,
Matrix<int> &iPointsMx,
Matrix<bool> &iJokerMx,
Rack &iRack, Round &iPartialWord,
Results &iResults, int n, int iRow, int anchor, int limit)
Rack &iRack, Round &ioPartialWord,
Results &iResults, int n, int iRow,
int iAnchor, int iLimit)
{
Tile l;
int succ;
ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx, iJokerMx, iRack,
iPartialWord, iResults, n, iRow, anchor, anchor);
ioPartialWord, iResults, n, iRow, iAnchor, iAnchor);
if (limit > 0)
if (iLimit > 0)
{
for (succ = Dic_succ(iDic, n); succ; succ = Dic_next(iDic, succ))
{
@ -180,25 +182,25 @@ static void LeftPart(const Board &iBoard,
if (iRack.in(l))
{
iRack.remove(l);
iPartialWord.addRightFromRack(l, 0);
iPartialWord.setCol(iPartialWord.getCol() - 1);
ioPartialWord.addRightFromRack(l, 0);
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() - 1);
LeftPart(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, iPartialWord, iResults,
succ, iRow, anchor, limit - 1);
iPartialWord.setCol(iPartialWord.getCol() + 1);
iPartialWord.removeRightToRack(l, 0);
iJokerMx, iRack, ioPartialWord, iResults,
succ, iRow, iAnchor, iLimit - 1);
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() + 1);
ioPartialWord.removeRightToRack(l, 0);
iRack.add(l);
}
if (iRack.in(Tile::Joker()))
{
iRack.remove(Tile::Joker());
iPartialWord.addRightFromRack(l, 1);
iPartialWord.setCol(iPartialWord.getCol() - 1);
ioPartialWord.addRightFromRack(l, 1);
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() - 1);
LeftPart(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, iPartialWord, iResults,
succ, iRow, anchor, limit - 1);
iPartialWord.setCol(iPartialWord.getCol() + 1);
iPartialWord.removeRightToRack(l, 1);
iJokerMx, iRack, ioPartialWord, iResults,
succ, iRow, iAnchor, iLimit - 1);
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() + 1);
ioPartialWord.removeRightToRack(l, 1);
iRack.add(Tile::Joker());
}
}
@ -220,8 +222,8 @@ static void BoardSearchAux(const Board &iBoard,
for (row = 1; row <= BOARD_DIM; row++)
{
partialword.init();
partialword.setDir(iDir);
partialword.setRow(row);
partialword.accessCoord().setDir(iDir);
partialword.accessCoord().setRow(row);
lastanchor = 0;
for (col = 1; col <= BOARD_DIM; col++)
{
@ -233,14 +235,14 @@ static void BoardSearchAux(const Board &iBoard,
{
if (!iTilesMx[row][col - 1].isEmpty())
{
partialword.setCol(lastanchor + 1);
partialword.accessCoord().setCol(lastanchor + 1);
ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, partialword, iResults,
Dic_root(iDic), row, lastanchor + 1, col);
}
else
{
partialword.setCol(col);
partialword.accessCoord().setCol(col);
LeftPart(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, partialword, iResults,
Dic_root(iDic), row, col, col -
@ -275,15 +277,15 @@ void Board::searchFirst(const Dictionary &iDic,
const Rack &iRack,
Results &oResults)
{
Round partialword;
int row = 8, col = 8;
// Create a copy of the rack to avoid modifying the given one
Rack copyRack = iRack;
partialword.setRow(row);
partialword.setCol(col);
partialword.setDir(Coord::HORIZONTAL);
Round partialword;
partialword.accessCoord().setRow(row);
partialword.accessCoord().setCol(col);
partialword.accessCoord().setDir(Coord::HORIZONTAL);
LeftPart(*this, iDic, m_tilesRow, m_crossRow,
m_pointRow, m_jokerRow,
copyRack, partialword, oResults, Dic_root(iDic), row, col,

View file

@ -26,54 +26,25 @@
#include <string>
#include "coord.h"
#include "board.h" // for BOARD_MIN and BOARD_MAX (TODO: remove this include)
Coord::Coord()
Coord::Coord(int iRow, int iCol, Direction iDir)
{
m_row = 1;
m_col = 1;
m_dir = HORIZONTAL;
m_row = iRow;
m_col = iCol;
m_dir = iDir;
}
Coord::Coord(const string &iStr)
{
m_row = 1;
m_col = 1;
setFromString(iStr);
}
Coord::~Coord()
bool Coord::isValid() const
{
}
Coord::Direction Coord::getDir() const
{
return m_dir;
}
int Coord::getRow() const
{
return m_row;
}
int Coord::getCol() const
{
return m_col;
}
void Coord::setRow(int iRow)
{
m_row = iRow;
}
void Coord::setCol(int iCol)
{
m_col = iCol;
}
void Coord::setDir(Direction iDir)
{
m_dir = iDir;
return (m_row >= BOARD_MIN && m_row <= BOARD_MAX &&
m_col >= BOARD_MIN && m_col <= BOARD_MAX);
}
void Coord::operator=(const Coord &iOther)
@ -83,6 +54,13 @@ void Coord::operator=(const Coord &iOther)
m_col = iOther.m_col;
}
void Coord::swap()
{
int tmp = m_col;
m_col = m_row;
m_row = tmp;
}
void Coord::setFromString(const string &iStr)
{
char l[4];
@ -98,8 +76,8 @@ void Coord::setFromString(const string &iStr)
}
else
{
col = 1;
l[0] = 'A';
col = -1;
l[0] = 'A' - 1;
}
int row = toupper(*l) - 'A' + 1;
setCol(col);
@ -109,16 +87,15 @@ void Coord::setFromString(const string &iStr)
string Coord::toString() const
{
string rs;
char s[5];
sprintf(s, "%d", m_col);
if (getDir() == HORIZONTAL)
{
char s[5];
sprintf(s, "%d", m_col);
rs = string(1, m_row + 'A' - 1) + s;
}
else
{
char s[5];
sprintf(s, "%d", m_col);
rs = s + string(1, m_row + 'A' - 1);
}
return rs;

View file

@ -35,19 +35,25 @@ public:
enum Direction {VERTICAL, HORIZONTAL};
Coord();
// Construction, destruction
Coord(int iRow = -1, int iCol = -1, Direction iDir = HORIZONTAL);
Coord(const string &iStr);
virtual ~Coord();
virtual ~Coord() {}
void setRow(int iRow);
void setCol(int iCol);
void setDir(Direction iDir);
Direction getDir() const;
int getRow() const;
int getCol() const;
// Accessors
void setRow(int iRow) { m_row = iRow; }
void setCol(int iCol) { m_col = iCol; }
void setDir(Direction iDir) { m_dir = iDir; }
int getRow() const { return m_row; }
int getCol() const { return m_col; }
Direction getDir() const { return m_dir; }
bool isValid() const;
void operator=(const Coord &iOther);
// Swap the coordinates (without changing the direction)
void swap();
void setFromString(const string &iStr);
string toString() const;

View file

@ -209,22 +209,22 @@ Game * Game::load(FILE *fin, const Dictionary &iDic)
// Build a round
Round round;
round.accessCoord().setFromString(ref);
if (!round.getCoord().isValid())
continue;
round.setPoints(pts);
if (bonus == '*')
round.setBonus(1);
if (isalpha(ref[0]))
for (unsigned int i = 0; i < strlen(word); i++)
{
// Horizontal word
round.setDir(Coord::HORIZONTAL);
round.setRow(ref[0] - 'A' + 1);
round.setCol(atoi(ref + 1));
tile = Tile(word[i]);
for (unsigned int i = 0; i < strlen(word); i++)
if (round.getCoord().getDir() == Coord::HORIZONTAL)
{
tile = Tile(word[i]);
if (!pGame->m_board.getTile(round.getRow(), round.getCol() + i).isEmpty())
if (!pGame->m_board.getTile(round.getCoord().getRow(),
round.getCoord().getCol() + i).isEmpty())
{
round.addRightFromBoard(tile);
}
@ -234,19 +234,10 @@ Game * Game::load(FILE *fin, const Dictionary &iDic)
pGame->m_bag.takeTile((islower(word[i])) ? Tile::Joker() : tile);
}
}
}
else
{
// Vertical word
round.setDir(Coord::VERTICAL);
round.setRow(ref[strlen(ref) - 1] - 'A' + 1);
round.setCol(atoi(ref));
for (unsigned int i = 0; i < strlen(word); i++)
else
{
tile = Tile(word[i]);
if (!pGame->m_board.getTile(round.getRow() + i, round.getCol()).isEmpty())
if (!pGame->m_board.getTile(round.getCoord().getRow() + i,
round.getCoord().getCol()).isEmpty())
{
round.addRightFromBoard(tile);
}
@ -717,18 +708,8 @@ int Game::helperSetRackManual(int p, bool iCheck, const string &iLetters)
string Game::formatCoords(const Round &iRound) const
{
if (iRound.getDir() == Coord::HORIZONTAL)
{
char s[5];
sprintf(s, "%d", iRound.getCol());
return string(1, iRound.getRow() + 'A' - 1) + s;
}
else
{
char s[5];
sprintf(s, "%d", iRound.getCol());
return s + string(1, iRound.getRow() + 'A' - 1);
}
ASSERT(iRound.getCoord().isValid(), "Invalid coordinates");
return iRound.getCoord().toString();
}
@ -888,28 +869,15 @@ int Game::checkPlayedWord(const string &iCoord,
{
ASSERT(getNPlayers() != 0, "Expected at least one player");
char l[4];
int col, row;
int res;
vector<Tile> tiles;
Tile t;
/* Init the round with the given coordinates */
oRound.init();
if (sscanf(iCoord.c_str(), "%1[a-oA-O]%2d", l, &col) == 2)
oRound.setDir(Coord::HORIZONTAL);
else if (sscanf(iCoord.c_str(), "%2d%1[a-oA-O]", &col, l) == 2)
oRound.setDir(Coord::VERTICAL);
else
oRound.accessCoord().setFromString(iCoord);
if (!oRound.getCoord().isValid())
return 2;
row = toupper(*l) - 'A' + 1;
if (col < BOARD_MIN || col > BOARD_MAX ||
row < BOARD_MIN || row > BOARD_MAX)
{
return 2;
}
oRound.setCol(col);
oRound.setRow(row);
/* Check the existence of the word */
if (Dic_search_word(*m_dic, iWord.c_str()) == 0)

View file

@ -37,8 +37,8 @@ void Round::init()
{
m_word.clear();
m_tileOrigin.clear();
m_coord.setRow(1);
m_coord.setCol(1);
m_coord.setRow(-1);
m_coord.setCol(-1);
m_coord.setDir(Coord::HORIZONTAL);
m_points = 0;
m_bonus = 0;

View file

@ -71,18 +71,14 @@ public:
bool isPlayedFromRack(int iIndex) const;
const Tile& getTile (int iIndex) const;
int getWordLen() const;
int getPoints() const { return m_points; }
int getBonus() const { return m_bonus; }
int getPoints() const { return m_points; }
int getBonus() const { return m_bonus; }
/*************************
* Coordinates
*************************/
int getRow() const { return m_coord.getRow(); }
int getCol() const { return m_coord.getCol(); }
Coord::Direction getDir() const { return m_coord.getDir(); }
void setRow(int iRow) { m_coord.setRow(iRow); }
void setCol(int iCol) { m_coord.setCol(iCol); }
void setDir(Coord::Direction iDir) { m_coord.setDir(iDir); }
const Coord& getCoord() const { return m_coord; }
Coord& accessCoord() { return m_coord; }
private:
vector<Tile> m_word;