From 12894e00e2d2be9ffff72b495770b676548deffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Teuli=C3=A8re?= Date: Sat, 5 Nov 2005 13:56:59 +0000 Subject: [PATCH] Take more advantage of the Coord class, and remove the useless accessors from Round (to force using the Coord object) --- game/board.cpp | 48 ++++++++++----------- game/board_search.cpp | 98 ++++++++++++++++++++++--------------------- game/coord.cpp | 63 +++++++++------------------- game/coord.h | 24 +++++++---- game/game.cpp | 64 +++++++--------------------- game/round.cpp | 4 +- game/round.h | 12 ++---- 7 files changed, 129 insertions(+), 184 deletions(-) diff --git a/game/board.cpp b/game/board.cpp index a454bf7..9e7ee80 100644 --- a/game/board.cpp +++ b/game/board.cpp @@ -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 &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 &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 &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++) { diff --git a/game/board_search.cpp b/game/board_search.cpp index 3170d32..ac71c1b 100644 --- a/game/board_search.cpp +++ b/game/board_search.cpp @@ -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 &iCrossMx, Matrix &iPointsMx, Matrix &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 &iCrossMx, Matrix &iPointsMx, Matrix &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, diff --git a/game/coord.cpp b/game/coord.cpp index 48e21c7..bc16431 100644 --- a/game/coord.cpp +++ b/game/coord.cpp @@ -26,54 +26,25 @@ #include #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; diff --git a/game/coord.h b/game/coord.h index cce588b..0ea503f 100644 --- a/game/coord.h +++ b/game/coord.h @@ -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; diff --git a/game/game.cpp b/game/game.cpp index 1ff418e..7e363bc 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -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 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) diff --git a/game/round.cpp b/game/round.cpp index 20fc09e..bfda3fd 100644 --- a/game/round.cpp +++ b/game/round.cpp @@ -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; diff --git a/game/round.h b/game/round.h index 34c238a..96fc3fc 100644 --- a/game/round.h +++ b/game/round.h @@ -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 m_word;