From 5441007db10f907aa54359968c0f259d14b04e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Teuli=C3=A8re?= Date: Wed, 26 Dec 2012 14:14:44 +0100 Subject: [PATCH] New BoardLayout class to wrap the board layout (size and special squares). Until now there is no user-visible change, but it should make it much easier to add custom layouts. --- game/Makefile.am | 1 + game/board.cpp | 94 +++++-------------------- game/board.h | 15 ++-- game/board_layout.cpp | 158 ++++++++++++++++++++++++++++++++++++++++++ game/board_layout.h | 58 ++++++++++++++++ game/board_search.cpp | 8 ++- game/game_params.h | 6 ++ game/matrix.h | 28 ++++++-- qt/board_widget.cpp | 42 ++++++----- utils/game_io.cpp | 49 +++++++------ utils/ncurses.cpp | 6 +- 11 files changed, 328 insertions(+), 137 deletions(-) create mode 100644 game/board_layout.cpp create mode 100644 game/board_layout.h diff --git a/game/Makefile.am b/game/Makefile.am index 96c28db..6b0b5fd 100644 --- a/game/Makefile.am +++ b/game/Makefile.am @@ -41,6 +41,7 @@ libgame_a_SOURCES= \ ai_player.h \ ai_percent.cpp ai_percent.h \ game_params.h \ + board_layout.cpp board_layout.h \ board.cpp board.h \ board_cross.cpp \ matrix.h \ diff --git a/game/board.cpp b/game/board.cpp index ead37da..1176936 100644 --- a/game/board.cpp +++ b/game/board.cpp @@ -27,6 +27,7 @@ #include "board.h" #include "board_search.h" #include "game_params.h" +#include "board_layout.h" #include "tile.h" #include "round.h" #include "rack.h" @@ -34,63 +35,14 @@ #include "encoding.h" #include "debug.h" -#define oo 0 -#define __ 1 -#define T2 2 -#define T3 3 -#define W2 2 -#define W3 3 +#define BOARD_REALDIM (BOARD_DIM + 2) INIT_LOGGER(game, Board); -const int Board::m_tileMultipliers[BOARD_REALDIM][BOARD_REALDIM] = -{ - { oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo }, - { oo,__,__,__,T2,__,__,__,__,__,__,__,T2,__,__,__,oo }, - { oo,__,__,__,__,__,T3,__,__,__,T3,__,__,__,__,__,oo }, - { oo,__,__,__,__,__,__,T2,__,T2,__,__,__,__,__,__,oo }, - { oo,T2,__,__,__,__,__,__,T2,__,__,__,__,__,__,T2,oo }, - { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, - { oo,__,T3,__,__,__,T3,__,__,__,T3,__,__,__,T3,__,oo }, - { oo,__,__,T2,__,__,__,T2,__,T2,__,__,__,T2,__,__,oo }, - { oo,__,__,__,T2,__,__,__,__,__,__,__,T2,__,__,__,oo }, - { oo,__,__,T2,__,__,__,T2,__,T2,__,__,__,T2,__,__,oo }, - { oo,__,T3,__,__,__,T3,__,__,__,T3,__,__,__,T3,__,oo }, - { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, - { oo,T2,__,__,__,__,__,__,T2,__,__,__,__,__,__,T2,oo }, - { oo,__,__,__,__,__,__,T2,__,T2,__,__,__,__,__,__,oo }, - { oo,__,__,__,__,__,T3,__,__,__,T3,__,__,__,__,__,oo }, - { oo,__,__,__,T2,__,__,__,__,__,__,__,T2,__,__,__,oo }, - { oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo } -}; - - -const int Board::m_wordMultipliers[BOARD_REALDIM][BOARD_REALDIM] = -{ - { oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo }, - { oo,W3,__,__,__,__,__,__,W3,__,__,__,__,__,__,W3,oo }, - { oo,__,W2,__,__,__,__,__,__,__,__,__,__,__,W2,__,oo }, - { oo,__,__,W2,__,__,__,__,__,__,__,__,__,W2,__,__,oo }, - { oo,__,__,__,W2,__,__,__,__,__,__,__,W2,__,__,__,oo }, - { oo,__,__,__,__,W2,__,__,__,__,__,W2,__,__,__,__,oo }, - { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, - { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, - { oo,W3,__,__,__,__,__,__,W2,__,__,__,__,__,__,W3,oo }, - { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, - { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, - { oo,__,__,__,__,W2,__,__,__,__,__,W2,__,__,__,__,oo }, - { oo,__,__,__,W2,__,__,__,__,__,__,__,W2,__,__,__,oo }, - { oo,__,__,W2,__,__,__,__,__,__,__,__,__,W2,__,__,oo }, - { oo,__,W2,__,__,__,__,__,__,__,__,__,__,__,W2,__,oo }, - { oo,W3,__,__,__,__,__,__,W3,__,__,__,__,__,__,W3,oo }, - { oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo } -}; - - Board::Board(const GameParams &iParams): - m_params(iParams), + m_params(iParams), m_layout(iParams.getBoardLayout()), m_tilesRow(BOARD_REALDIM, Tile()), m_tilesCol(BOARD_REALDIM, Tile()), m_jokerRow(BOARD_REALDIM, false), @@ -142,8 +94,9 @@ bool Board::isJoker(int iRow, int iCol) const bool Board::isVacant(int iRow, int iCol) const { - ASSERT(iRow >= BOARD_MIN && iRow <= BOARD_MAX && - iCol >= BOARD_MIN && iCol <= BOARD_MAX, "Invalid coordinates"); + ASSERT(iRow >= 1 && (unsigned)iRow <= m_layout.getRowCount() && + iCol >= 1 && (unsigned)iCol <= m_layout.getColCount(), + "Invalid coordinates"); return m_tilesRow[iRow][iCol].isEmpty(); } @@ -154,7 +107,7 @@ void Board::addRound(const Dictionary &iDic, const Round &iRound) int col = iRound.getCoord().getCol(); if (iRound.getCoord().getDir() == Coord::HORIZONTAL) { - for (unsigned int i = 0; i < iRound.getWordLen(); i++) + for (unsigned i = 0; i < iRound.getWordLen(); i++) { const Tile &t = iRound.getTile(i); if (isVacant(row, col + i)) @@ -282,7 +235,7 @@ int Board::checkRoundAux(const Matrix &iTilesMx, int col = iRound.getCoord().getCol(); // Is the word going out of the board? - if (col + iRound.getWordLen() > BOARD_MAX + 1) + if (col + iRound.getWordLen() >= BOARD_REALDIM) return 8; // Is the word an extension of another word? @@ -323,16 +276,17 @@ int Board::checkRoundAux(const Matrix &iTilesMx, int l; if (!iRound.isJoker(i)) - l = t.getPoints() * m_tileMultipliers[row][col + i]; + l = t.getPoints() * getLayout().getLetterMultiplier(row, col + i); else l = 0; pts += l; - wordmul *= m_wordMultipliers[row][col + i]; + int wm = getLayout().getWordMultiplier(row, col + i); + wordmul *= wm; int p = iPointsMx[row][col + i]; if (p >= 0) { - ptscross += (p + l) * m_wordMultipliers[row][col + i]; + ptscross += (p + l) * wm; } ++fromrack; iRound.setFromRack(i); @@ -466,24 +420,6 @@ const Tile& Board::getTestTile(int iRow, int iCol) const } -int Board::GetWordMultiplier(int iRow, int iCol) -{ - if (iRow < BOARD_MIN || iRow > BOARD_MAX || - iCol < BOARD_MIN || iCol > BOARD_MAX) - return 0; - return m_wordMultipliers[iRow][iCol]; -} - - -int Board::GetLetterMultiplier(int iRow, int iCol) -{ - if (iRow < BOARD_MIN || iRow > BOARD_MAX || - iCol < BOARD_MIN || iCol > BOARD_MAX) - return 0; - return m_tileMultipliers[iRow][iCol]; -} - - // #define CELL_STRING_FORMAT "[%c:%s:%2d]" #define CELL_STRING_FORMAT "[%s:%2d]" @@ -511,9 +447,11 @@ string Board::getCellContent_col(int row, int col) const #ifdef DEBUG void Board::checkDouble() { - for (int row = BOARD_MIN; row <= BOARD_MAX; row++) + const unsigned nbRows = m_layout.getRowCount(); + const unsigned nbCols = m_layout.getColCount(); + for (unsigned row = 1; row <= nbRows; row++) { - for (int col = BOARD_MIN; col <= BOARD_MAX; col++) + for (unsigned col = 1; col <= nbCols; col++) { ASSERT(m_tilesRow[row][col] == m_tilesCol[col][row], "Tiles inconsistency at " << row << "x" << col); diff --git a/game/board.h b/game/board.h index ba18a2c..faa7649 100644 --- a/game/board.h +++ b/game/board.h @@ -30,6 +30,7 @@ #include "logging.h" class GameParams; +class BoardLayout; class Dictionary; class Rack; class Round; @@ -40,7 +41,6 @@ using namespace std; #define BOARD_MIN 1 #define BOARD_MAX 15 #define BOARD_DIM 15 -#define BOARD_REALDIM (BOARD_DIM + 2) /** @@ -55,6 +55,8 @@ class Board public: Board(const GameParams &iParams); + const BoardLayout & getLayout() const { return m_layout; } + bool isJoker(int iRow, int iCol) const; bool isVacant(int iRow, int iCol) const; @@ -76,12 +78,6 @@ public: void search(const Dictionary &iDic, const Rack &iRack, Results &oResults) const; void searchFirst(const Dictionary &iDic, const Rack &iRack, Results &oResults) const; - /** - * - */ - static int GetWordMultiplier(int iRow, int iCol); - static int GetLetterMultiplier(int iRow, int iCol); - /** * */ @@ -92,6 +88,8 @@ private: const GameParams &m_params; + const BoardLayout &m_layout; + Matrix m_tilesRow; Matrix m_tilesCol; @@ -109,9 +107,6 @@ private: /// Flag indicating if the board is empty or if it has letters bool m_isEmpty; - static const int m_tileMultipliers[BOARD_REALDIM][BOARD_REALDIM]; - static const int m_wordMultipliers[BOARD_REALDIM][BOARD_REALDIM]; - /** * board_cross.c */ diff --git a/game/board_layout.cpp b/game/board_layout.cpp new file mode 100644 index 0000000..37105ce --- /dev/null +++ b/game/board_layout.cpp @@ -0,0 +1,158 @@ +/***************************************************************************** + * Eliot + * Copyright (C) 2012 Olivier Teulière + * Authors: Olivier Teulière + * + * 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 "board_layout.h" + +#include "dic.h" +#include "debug.h" + +#define oo 0 +#define __ 1 +#define T2 2 +#define T3 3 +#define W2 2 +#define W3 3 + +#define BOARD_DIM 15 +#define BOARD_REALDIM (BOARD_DIM + 2) + + +INIT_LOGGER(game, BoardLayout); + + +static const int DefaultTileMultipliers[BOARD_REALDIM][BOARD_REALDIM] = +{ + { oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo }, + { oo,__,__,__,T2,__,__,__,__,__,__,__,T2,__,__,__,oo }, + { oo,__,__,__,__,__,T3,__,__,__,T3,__,__,__,__,__,oo }, + { oo,__,__,__,__,__,__,T2,__,T2,__,__,__,__,__,__,oo }, + { oo,T2,__,__,__,__,__,__,T2,__,__,__,__,__,__,T2,oo }, + { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, + { oo,__,T3,__,__,__,T3,__,__,__,T3,__,__,__,T3,__,oo }, + { oo,__,__,T2,__,__,__,T2,__,T2,__,__,__,T2,__,__,oo }, + { oo,__,__,__,T2,__,__,__,__,__,__,__,T2,__,__,__,oo }, + { oo,__,__,T2,__,__,__,T2,__,T2,__,__,__,T2,__,__,oo }, + { oo,__,T3,__,__,__,T3,__,__,__,T3,__,__,__,T3,__,oo }, + { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, + { oo,T2,__,__,__,__,__,__,T2,__,__,__,__,__,__,T2,oo }, + { oo,__,__,__,__,__,__,T2,__,T2,__,__,__,__,__,__,oo }, + { oo,__,__,__,__,__,T3,__,__,__,T3,__,__,__,__,__,oo }, + { oo,__,__,__,T2,__,__,__,__,__,__,__,T2,__,__,__,oo }, + { oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo } +}; + + +static const int DefaultWordMultipliers[BOARD_REALDIM][BOARD_REALDIM] = +{ + { oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo }, + { oo,W3,__,__,__,__,__,__,W3,__,__,__,__,__,__,W3,oo }, + { oo,__,W2,__,__,__,__,__,__,__,__,__,__,__,W2,__,oo }, + { oo,__,__,W2,__,__,__,__,__,__,__,__,__,W2,__,__,oo }, + { oo,__,__,__,W2,__,__,__,__,__,__,__,W2,__,__,__,oo }, + { oo,__,__,__,__,W2,__,__,__,__,__,W2,__,__,__,__,oo }, + { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, + { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, + { oo,W3,__,__,__,__,__,__,W2,__,__,__,__,__,__,W3,oo }, + { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, + { oo,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,oo }, + { oo,__,__,__,__,W2,__,__,__,__,__,W2,__,__,__,__,oo }, + { oo,__,__,__,W2,__,__,__,__,__,__,__,W2,__,__,__,oo }, + { oo,__,__,W2,__,__,__,__,__,__,__,__,__,W2,__,__,oo }, + { oo,__,W2,__,__,__,__,__,__,__,__,__,__,__,W2,__,oo }, + { oo,W3,__,__,__,__,__,__,W3,__,__,__,__,__,__,W3,oo }, + { oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo,oo } +}; + + +// Initialize the static member +BoardLayout BoardLayout::m_defaultLayout; + + +BoardLayout::BoardLayout() +{ + setDefaultLayout(); +} + + +unsigned BoardLayout::getRowCount() const +{ + ASSERT(m_wordMultipliers.size() > 2 && m_tileMultipliers.size() > 2, + "Invalid board size"); + return m_wordMultipliers.size() - 2; +} + + +unsigned BoardLayout::getColCount() const +{ + ASSERT(m_wordMultipliers.size() > 2 && m_tileMultipliers.size() > 2, + "Invalid board size"); + return m_wordMultipliers[0].size() - 2; +} + + +int BoardLayout::getWordMultiplier(unsigned iRow, unsigned iCol) const +{ + if (!isValidCoord(iRow, iCol)) + return 0; + return m_wordMultipliers[iRow][iCol]; +} + + +int BoardLayout::getLetterMultiplier(unsigned iRow, unsigned iCol) const +{ + if (!isValidCoord(iRow, iCol)) + return 0; + return m_tileMultipliers[iRow][iCol]; +} + + +bool BoardLayout::isValidCoord(unsigned iRow, unsigned iCol) const +{ + return (iRow >= 1 && iRow <= getRowCount() && + iCol >= 1 && iCol <= getColCount()); +} + + +static void InitMatrixFromArray(Matrix &oMatrix, const int iArray[BOARD_REALDIM][BOARD_REALDIM]) +{ + oMatrix.resize(BOARD_REALDIM, BOARD_REALDIM, 0); + for (unsigned i = 0; i < BOARD_REALDIM; ++i) + { + for (unsigned j = 0; j < BOARD_REALDIM; ++j) + { + oMatrix[i][j] = iArray[i][j]; + } + } +} + + + +void BoardLayout::setDefaultLayout() +{ + InitMatrixFromArray(m_wordMultipliers, DefaultWordMultipliers); + InitMatrixFromArray(m_tileMultipliers, DefaultTileMultipliers); +} + + +const BoardLayout & BoardLayout::GetDefault() +{ + return m_defaultLayout; +} + diff --git a/game/board_layout.h b/game/board_layout.h new file mode 100644 index 0000000..7632e4f --- /dev/null +++ b/game/board_layout.h @@ -0,0 +1,58 @@ +/***************************************************************************** + * Eliot + * Copyright (C) 2012 Olivier Teulière + * Authors: Olivier Teulière + * + * 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 BOARD_LAYOUT_H_ +#define BOARD_LAYOUT_H_ + +#include "matrix.h" +#include "logging.h" + + +/** + * Board layout (size and special squares) + */ +class BoardLayout +{ + DEFINE_LOGGER(); +public: + BoardLayout(); + + unsigned getRowCount() const; + unsigned getColCount() const; + int getWordMultiplier(unsigned iRow, unsigned iCol) const; + int getLetterMultiplier(unsigned iRow, unsigned iCol) const; + + static const BoardLayout & GetDefault(); + +private: + + static BoardLayout m_defaultLayout; + + Matrix m_wordMultipliers; + Matrix m_tileMultipliers; + + bool isValidCoord(unsigned iRow, unsigned iCol) const; + + void setDefaultLayout(); + +}; + +#endif + diff --git a/game/board_search.cpp b/game/board_search.cpp index ab6a3e5..5db0be3 100644 --- a/game/board_search.cpp +++ b/game/board_search.cpp @@ -246,6 +246,7 @@ void BoardSearch::evalMove(Results &oResults, Round &iWord) const int row = iWord.getCoord().getRow(); int col = iWord.getCoord().getCol(); + const BoardLayout & boardLayout = m_params.getBoardLayout(); for (unsigned int i = 0; i < len; i++) { if (!m_tilesMx[row][col+i].isEmpty()) @@ -258,15 +259,16 @@ void BoardSearch::evalMove(Results &oResults, Round &iWord) const int l; if (!iWord.isJoker(i)) l = iWord.getTile(i).getPoints() * - Board::GetLetterMultiplier(row, col + i); + boardLayout.getLetterMultiplier(row, col + i); else l = 0; pts += l; - wordmul *= Board::GetWordMultiplier(row, col + i); + int wm = boardLayout.getWordMultiplier(row, col + i); + wordmul *= wm; int t = m_pointsMx[row][col+i]; if (t >= 0) - ptscross += (t + l) * Board::GetWordMultiplier(row, col + i); + ptscross += (t + l) * wm; fromrack++; } } diff --git a/game/game_params.h b/game/game_params.h index 437cb58..b322482 100644 --- a/game/game_params.h +++ b/game/game_params.h @@ -22,6 +22,7 @@ #define GAME_PARAMS_H_ #include "game_exception.h" +#include "board_layout.h" class Dictionary; @@ -82,6 +83,8 @@ class GameParams m_rackSize = 8; } + void setBoardLayout(const BoardLayout &iLayout) { m_boardLayout = iLayout; } + // Getters const Dictionary & getDic() const { return m_dic; } GameMode getMode() const { return m_mode; } @@ -90,7 +93,10 @@ class GameParams int getLettersToPlay() const { return m_lettersToPlay; } int getBonusPoints() const { return m_bonusPoints; } + const BoardLayout & getBoardLayout() const { return m_boardLayout; } + private: + BoardLayout m_boardLayout; const Dictionary &m_dic; GameMode m_mode; unsigned int m_variants; diff --git a/game/matrix.h b/game/matrix.h index 20dba8c..e331530 100644 --- a/game/matrix.h +++ b/game/matrix.h @@ -31,16 +31,32 @@ template class Matrix: public vector > { public: - // Construct a matrix with an initial value + /// Construct a matrix with an initial value Matrix(int iSize1, int iSize2, const T &iValue) + { + resize(iSize1, iSize2, iValue); + } + + /// Construct a square matrix with an initial value + Matrix(int iSize, const T &iValue) + { + resize(iSize, iSize, iValue); + } + + Matrix() + { + } + + /** + * Resize the matrix to iSize1 rows and iSize2 cols. + * The contents may be erased. + */ + void resize(int iSize1, int iSize2, const T &iValue) { this->resize(iSize1, vector(iSize2, iValue)); } - // Construct a square matrix with an initial value - Matrix(int iSize, const T &iValue) - { - this->resize(iSize, vector(iSize, iValue)); - } + + using::vector >::resize; }; #endif diff --git a/qt/board_widget.cpp b/qt/board_widget.cpp index 6e1aeaf..7dd6c26 100644 --- a/qt/board_widget.cpp +++ b/qt/board_widget.cpp @@ -28,6 +28,7 @@ #include "qtcommon.h" #include "public_game.h" #include "tile.h" +#include "board_layout.h" #include "board.h" #include "play_model.h" #include "move.h" @@ -41,9 +42,14 @@ INIT_LOGGER(qt, BoardWidget); BoardWidget::BoardWidget(PlayModel &iPlayModel, QWidget *parent) : QFrame(parent), m_game(NULL), m_playModel(iPlayModel), m_showTemporarySigns(true), - m_showOnlyLastTurn(false), - m_widgetsMatrix(BOARD_MAX + 1, BOARD_MAX + 1, 0) + m_showOnlyLastTurn(false) { + const BoardLayout & boardLayout = BoardLayout::GetDefault(); + const unsigned nbRows = boardLayout.getRowCount(); + const unsigned nbCols = boardLayout.getColCount(); + + m_widgetsMatrix.resize(nbRows + 1, nbCols + 1, 0); + // Try to have a black background... FIXME: not working well! QPalette pal = palette(); for (int i = 0; i <= 19; ++i) @@ -52,37 +58,39 @@ BoardWidget::BoardWidget(PlayModel &iPlayModel, QWidget *parent) setForegroundRole(QPalette::Window); setBackgroundRole(QPalette::Window); - TileLayout *layout = new TileLayout(BOARD_MAX + 1, BOARD_MAX + 1); + TileLayout *layout = new TileLayout(nbRows + 1, nbCols + 1); layout->setSpacing(1); layout->setAlignment(Qt::AlignHCenter); + // Line full of coordinates TileWidget *cornerTile = new TileWidget; cornerTile->setCoordText(""); layout->addWidget(cornerTile); - for (unsigned int col = BOARD_MIN; col <= BOARD_MAX; ++col) + for (unsigned int col = 1; col <= nbCols; ++col) { TileWidget *coordTile = new TileWidget; coordTile->setCoordText(QString("%1").arg(col)); layout->addWidget(coordTile); } + // Rest of the board - for (unsigned int row = BOARD_MIN; row <= BOARD_MAX; ++row) + for (unsigned int row = 1; row <= nbRows; ++row) { // Add the coordinate TileWidget *coordTile = new TileWidget; - coordTile->setCoordText(QString(QChar('A' + row - BOARD_MIN))); + coordTile->setCoordText(QString(QChar('A' + row - 1))); layout->addWidget(coordTile); // Add the squares - for (unsigned int col = BOARD_MIN; col <= BOARD_MAX; ++col) + for (unsigned int col = 1; col <= nbCols; ++col) { TileWidget::Multiplier mult = TileWidget::NONE; - if (Board::GetWordMultiplier(row, col) == 3) + if (boardLayout.getWordMultiplier(row, col) == 3) mult = TileWidget::WORD_TRIPLE; - else if (Board::GetWordMultiplier(row, col) == 2) + else if (boardLayout.getWordMultiplier(row, col) == 2) mult = TileWidget::WORD_DOUBLE; - else if (Board::GetLetterMultiplier(row, col) == 3) + else if (boardLayout.getLetterMultiplier(row, col) == 3) mult = TileWidget::LETTER_TRIPLE; - else if (Board::GetLetterMultiplier(row, col) == 2) + else if (boardLayout.getLetterMultiplier(row, col) == 2) mult = TileWidget::LETTER_DOUBLE; TileWidget *t = new TileWidget(this, mult, row, col); m_widgetsMatrix[row][col] = t; @@ -159,9 +167,11 @@ void BoardWidget::refresh() // Note: the TileWidget class will redraw the tile only if something // has changed, to avoid useless repainting. const Board &board = m_game->getBoard(); - for (unsigned int row = BOARD_MIN; row <= BOARD_MAX; ++row) + const unsigned nbRows = board.getLayout().getRowCount(); + const unsigned nbCols = board.getLayout().getColCount(); + for (unsigned row = 1; row <= nbRows; ++row) { - for (unsigned int col = BOARD_MIN; col <= BOARD_MAX; ++col) + for (unsigned col = 1; col <= nbCols; ++col) { if (board.isTestChar(row, col) && m_showTemporarySigns) { @@ -191,9 +201,9 @@ void BoardWidget::refresh() else { // Clear the board - for (unsigned int row = BOARD_MIN; row <= BOARD_MAX; ++row) + for (unsigned row = 1; row < m_widgetsMatrix.size(); ++row) { - for (unsigned int col = BOARD_MIN; col <= BOARD_MAX; ++col) + for (unsigned col = 1; col < m_widgetsMatrix[1].size(); ++col) { m_widgetsMatrix[row][col]->tileChanged(TileWidget::BOARD_EMPTY); } @@ -222,7 +232,7 @@ void BoardWidget::paintEvent(QPaintEvent *) QLine vLine(0, 0, 0, rect.height() + 1); hLine.translate(rect.left() - 1, rect.top() - 1); vLine.translate(rect.left() - 1, rect.top() - 1); - for (int i = 0; i <= BOARD_MAX; ++i) + for (unsigned i = 0; i < m_widgetsMatrix.size(); ++i) { painter.drawLine(hLine); painter.drawLine(vLine); diff --git a/utils/game_io.cpp b/utils/game_io.cpp index b6c1012..34d0fb3 100644 --- a/utils/game_io.cpp +++ b/utils/game_io.cpp @@ -25,12 +25,13 @@ #include #include -#include #include "game_io.h" #include "game_params.h" +#include "dic.h" #include "public_game.h" #include "bag.h" #include "board.h" +#include "board_layout.h" #include "results.h" #include "player.h" #include "encoding.h" @@ -50,16 +51,17 @@ INIT_LOGGER(utils, GameIO); void GameIO::printBoard(ostream &out, const PublicGame &iGame) { - int row, col; + int nbRows = iGame.getBoard().getLayout().getRowCount(); + int nbCols = iGame.getBoard().getLayout().getColCount(); out << " "; - for (col = BOARD_MIN; col <= BOARD_MAX; col++) - out << setw(3) << col - BOARD_MIN + 1; + for (int col = 1; col <= nbCols; ++col) + out << setw(3) << col; out << endl; - for (row = BOARD_MIN; row <= BOARD_MAX; row++) + for (int row = 1; row <= nbRows; ++row) { - out << " " << (char)(row - BOARD_MIN + 'A') << " "; - for (col = BOARD_MIN; col <= BOARD_MAX; col++) + out << " " << (char)(row + 'A' - 1) << " "; + for (int col = 1; col <= nbCols; ++col) { if (iGame.getBoard().isVacant(row, col)) out << " - "; @@ -74,23 +76,24 @@ void GameIO::printBoard(ostream &out, const PublicGame &iGame) /* this mode is used for regression tests */ void GameIO::printBoardDebug(ostream &out, const PublicGame &iGame) { - int row, col; + int nbRows = iGame.getBoard().getLayout().getRowCount(); + int nbCols = iGame.getBoard().getLayout().getColCount(); /* first printf row cell contents */ - for (row = BOARD_MIN; row <= BOARD_MAX; row++) + for (int row = 1; row <= nbRows; ++row) { - out << " " << (char)(row - BOARD_MIN + 'A') << "r "; - for (col = BOARD_MIN; col <= BOARD_MAX; col++) + out << " " << (char)(row + 'A' - 1) << "r "; + for (int col = 1; col <= nbCols; ++col) { out << iGame.getBoard().getCellContent_row(row, col); } out << endl; } out << " -" << endl; - for (row = BOARD_MIN; row <= BOARD_MAX; row++) + for (int row = 1; row <= nbRows; ++row) { - out << " " << (char)(row - BOARD_MIN + 'A') << "c "; - for (col = BOARD_MIN; col <= BOARD_MAX; col++) + out << " " << (char)(row + 'A' - 1) << "c "; + for (int col = 1; col <= nbCols; ++col) { out << iGame.getBoard().getCellContent_col(row, col); } @@ -101,24 +104,26 @@ void GameIO::printBoardDebug(ostream &out, const PublicGame &iGame) void GameIO::printBoardMultipliers(ostream &out, const PublicGame &iGame) { - int row, col; + int nbRows = iGame.getBoard().getLayout().getRowCount(); + int nbCols = iGame.getBoard().getLayout().getColCount(); out << " "; - for (col = BOARD_MIN; col <= BOARD_MAX; col++) - out << setw(3) << col - BOARD_MIN + 1; + for (int col = 1; col <= nbCols; ++col) + out << setw(3) << col; out << endl; - for (row = BOARD_MIN; row <= BOARD_MAX; row++) + const BoardLayout & boardLayout = iGame.getBoard().getLayout(); + for (int row = 1; row <= nbRows; ++row) { - out << " " << (char)(row - BOARD_MIN + 'A') << " "; - for (col = BOARD_MIN; col <= BOARD_MAX; col++) + out << " " << (char)(row + 'A' - 1) << " "; + for (int col = 1; col <= nbCols; ++col) { if (!iGame.getBoard().isVacant(row, col)) out << padAndConvert(iGame.getBoard().getDisplayStr(row, col), 3); else { - int wm = iGame.getBoard().GetWordMultiplier(row, col); - int tm = iGame.getBoard().GetLetterMultiplier(row, col); + int wm = boardLayout.getWordMultiplier(row, col); + int tm = boardLayout.getLetterMultiplier(row, col); if (wm > 1) out << " " << ((wm == 3) ? '@' : '#'); diff --git a/utils/ncurses.cpp b/utils/ncurses.cpp index 2fcbbae..e360afd 100644 --- a/utils/ncurses.cpp +++ b/utils/ncurses.cpp @@ -42,6 +42,7 @@ #include "game_factory.h" #include "game_params.h" #include "board.h" +#include "board_layout.h" #include "bag.h" #include "public_game.h" #include "results.h" @@ -232,13 +233,14 @@ void CursesIntf::drawBoard(WINDOW *win, int y, int x) const } // The board itself + const BoardLayout & boardLayout = m_game->getBoard().getLayout(); for (int row = 1; row < 16; row++) { for (int col = 1; col < 16; col++) { // Handle colors - int wm = m_game->getBoard().GetWordMultiplier(row, col); - int lm = m_game->getBoard().GetLetterMultiplier(row, col); + int wm = boardLayout.getWordMultiplier(row, col); + int lm = boardLayout.getLetterMultiplier(row, col); if (wm == 3) wattron(win, COLOR_PAIR(COLOR_RED)); else if (wm == 2)