File indexing completed on 2024-04-28 07:51:50
0001 /*************************************************************************** 0002 * Copyright (C) 2005, 2008 by Albert Astals Cid <aacid@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU General Public License as published by * 0006 * the Free Software Foundation; either version 2 of the License, or * 0007 * (at your option) any later version. * 0008 ***************************************************************************/ 0009 0010 #include "scores.h" 0011 0012 #include <QFont> 0013 #include <QPainter> 0014 #include <QPalette> 0015 0016 #include <KIconLoader> 0017 #include <KLocalizedString> 0018 0019 #include "settings.h" 0020 0021 scores::scores() 0022 { 0023 player p; 0024 for (int i = 1; i <= kirikiSettings::numberOfPlayers(); i++) 0025 { 0026 if (i == 1) 0027 { 0028 p.setName(kirikiSettings::player1Name()); 0029 p.setHuman(kirikiSettings::player1IsHuman()); 0030 } 0031 else if (i == 2) 0032 { 0033 p.setName(kirikiSettings::player2Name()); 0034 p.setHuman(kirikiSettings::player2IsHuman()); 0035 } 0036 else if (i == 3) 0037 { 0038 p.setName(kirikiSettings::player3Name()); 0039 p.setHuman(kirikiSettings::player3IsHuman()); 0040 } 0041 else if (i == 4) 0042 { 0043 p.setName(kirikiSettings::player4Name()); 0044 p.setHuman(kirikiSettings::player4IsHuman()); 0045 } 0046 else if (i == 5) 0047 { 0048 p.setName(kirikiSettings::player5Name()); 0049 p.setHuman(kirikiSettings::player5IsHuman()); 0050 } 0051 else if (i == 6) 0052 { 0053 p.setName(kirikiSettings::player6Name()); 0054 p.setHuman(kirikiSettings::player6IsHuman()); 0055 } 0056 0057 m_players.append(p); 0058 } 0059 0060 m_currentPlayer = 0; 0061 0062 m_rows.append(Row(Row::NamesRow)); 0063 m_rows.append(Row(Row::ScoreRow, i18n("1s"), 0)); 0064 m_rows.append(Row(Row::ScoreRow, i18n("2s"), 1)); 0065 m_rows.append(Row(Row::ScoreRow, i18n("3s"), 2)); 0066 m_rows.append(Row(Row::ScoreRow, i18n("4s"), 3)); 0067 m_rows.append(Row(Row::ScoreRow, i18n("5s"), 4)); 0068 m_rows.append(Row(Row::ScoreRow, i18n("6s"), 5)); 0069 m_rows.append(Row(Row::BonusRow, i18n("Bonus if > 62"), -1, Row::BoldFontFlag)); 0070 m_rows.append(Row(Row::UpperTotalRow, i18n("Upper total"), -1, Row::BoldFontFlag)); 0071 m_rows.append(Row(Row::EmptyRow)); 0072 m_rows.append(Row(Row::ScoreRow, i18n("3 of a Kind"), 6)); 0073 m_rows.append(Row(Row::ScoreRow, i18n("4 of a Kind"), 7)); 0074 m_rows.append(Row(Row::ScoreRow, i18n("Full House"), 8)); 0075 m_rows.append(Row(Row::ScoreRow, i18n("Small Straight"), 9)); 0076 m_rows.append(Row(Row::ScoreRow, i18n("Large Straight"), 10)); 0077 m_rows.append(Row(Row::ScoreRow, i18n("Kiriki"), 11)); 0078 m_rows.append(Row(Row::ScoreRow, i18n("Chance"), 12)); 0079 m_rows.append(Row(Row::LowerTotalRow, i18n("Lower Total"), -1, Row::BoldFontFlag)); 0080 m_rows.append(Row(Row::EmptyRow)); 0081 m_rows.append(Row(Row::GrandTotalRow, i18n("Grand Total"), -1, Row::BoldFontFlag | Row::BiggerFontFlag)); 0082 } 0083 0084 bool scores::allScores() const 0085 { 0086 bool all; 0087 all = true; 0088 for (int i = 0; i < m_players.count(); i++) all = all && m_players.at(i).allScores(); 0089 return all; 0090 } 0091 0092 void scores::nextPlayer() 0093 { 0094 m_currentPlayer++; 0095 m_currentPlayer = m_currentPlayer % m_players.count(); 0096 } 0097 0098 const player &scores::currentPlayer() const 0099 { 0100 return m_players.at(m_currentPlayer); 0101 } 0102 0103 int scores::currentPlayerNumber() const 0104 { 0105 return m_currentPlayer; 0106 } 0107 0108 const player &scores::winner() const 0109 { 0110 int best = 0; 0111 for (int i = 1; i < m_players.count(); i++) 0112 { 0113 if (m_players.at(best).grandTotal() < m_players.at(i).grandTotal()) best = i; 0114 } 0115 return m_players.at(best); 0116 } 0117 0118 Row scores::row(int row) const 0119 { 0120 return m_rows.at(row); 0121 } 0122 0123 int scores::rowForScoreRow(int scoreRow) const 0124 { 0125 for (int i = 0; i < m_rows.count(); ++i) 0126 { 0127 if (m_rows.at(i).scoreRow() == scoreRow) return i; 0128 } 0129 return -1; 0130 } 0131 0132 int scores::rowCount(const QModelIndex &/*index*/) const 0133 { 0134 return m_rows.count(); 0135 } 0136 0137 int scores::columnCount(const QModelIndex &/*index*/) const 0138 { 0139 return m_players.size() + 1; 0140 } 0141 0142 QVariant scores::data(const QModelIndex &index, int role) const 0143 { 0144 if (!index.isValid()) return QVariant(); 0145 0146 int column = index.column(); 0147 const Row row = m_rows.at(index.row()); 0148 0149 if (row.type() == Row::NamesRow) 0150 { 0151 if (column > 0) 0152 { 0153 const player &p = m_players.at(column - 1); 0154 if (role == Qt::DecorationRole) 0155 { 0156 QString icon; 0157 if (p.isHuman()) icon = QStringLiteral("user-identity"); 0158 else icon = QStringLiteral("cpu"); 0159 return KIconLoader::global()->loadIcon(icon, KIconLoader::NoGroup, KIconLoader::SizeMedium); 0160 } 0161 else if (role == Qt::DisplayRole) 0162 { 0163 return p.name(); 0164 } 0165 else if (role == Qt::BackgroundRole) 0166 { 0167 if (column - 1 == m_currentPlayer) 0168 { 0169 QPalette pal; 0170 return pal.alternateBase().color().darker(110); 0171 } 0172 } 0173 else if (role == Qt::FontRole) 0174 { 0175 QFont f; 0176 f.setPointSize(kirikiSettings::fontSize()); 0177 if (column - 1 == m_currentPlayer) 0178 { 0179 f.setBold(true); 0180 } 0181 return f; 0182 } 0183 } 0184 return QVariant(); 0185 } 0186 0187 if (role == Qt::FontRole) 0188 { 0189 QFont f; 0190 f.setPointSize(kirikiSettings::fontSize()); 0191 if (row.flags() & Row::BoldFontFlag) f.setBold(true); 0192 if (row.flags() & Row::BiggerFontFlag) f.setPointSize(f.pointSize() + 5); 0193 return f; 0194 } 0195 else if (role == Qt::BackgroundRole) 0196 { 0197 QPalette p; 0198 QColor c; 0199 if (column % 2 == 0) 0200 { 0201 c = p.alternateBase().color(); 0202 if (index.row() % 2) c = c.darker(105); 0203 } 0204 else 0205 { 0206 if (index.row() % 2 == 0) c = p.base().color(); 0207 else c = p.alternateBase().color(); 0208 } 0209 0210 if (row.type() == Row::GrandTotalRow) c = p.highlight().color().lighter(); 0211 0212 if (column - 1 == m_currentPlayer) c = c.darker(110); 0213 0214 return c; 0215 } 0216 else if (role == Qt::TextAlignmentRole) 0217 { 0218 if (column != 0) return Qt::AlignCenter; 0219 } 0220 0221 if (row.type() == Row::EmptyRow) return QVariant(); 0222 0223 if (role != Qt::DisplayRole) return QVariant(); 0224 0225 if (column == 0) return row.text(); 0226 0227 const player &p = m_players.at(column - 1); 0228 int score = -1; 0229 0230 if (row.type() == Row::ScoreRow) score = p.score(row.scoreRow()); 0231 else if (row.type() == Row::BonusRow) score = p.bonus(); 0232 else if (row.type() == Row::UpperTotalRow) score = p.upperTotalWithBonus(); 0233 else if (row.type() == Row::LowerTotalRow) score = p.lowerTotal(); 0234 else if (row.type() == Row::GrandTotalRow) score = p.grandTotal(); 0235 0236 if (score < 0) return QVariant(); 0237 else return QString::number(score); 0238 } 0239 0240 void scores::askForRedraw() 0241 { 0242 Q_EMIT dataChanged(index(0, 0), index(m_rows.count() - 1, m_players.count() - 1)); 0243 } 0244 0245 bool scores::setData(const QModelIndex &mi, const QVariant &value, int role) 0246 { 0247 if (role != Qt::EditRole) return false; 0248 0249 const Row row = m_rows.at(mi.row()); 0250 if (row.type() != Row::ScoreRow) return false; 0251 0252 if (row.scoreRow() == 11) 0253 { 0254 // Kiriki can be acumulated 0255 if (m_players[m_currentPlayer].score(11) > 0 && value.toInt() > 0) 0256 { 0257 m_players[m_currentPlayer].setScore(11, m_players[m_currentPlayer].score(11) + value.toInt()); 0258 } 0259 else if (m_players[m_currentPlayer].score(11) < 0) 0260 { 0261 m_players[m_currentPlayer].setScore(11, value.toInt()); 0262 } 0263 else return false; 0264 } 0265 else 0266 { 0267 if (m_players[m_currentPlayer].score(row.scoreRow()) >= 0) return false; 0268 m_players[m_currentPlayer].setScore(row.scoreRow(), value.toInt()); 0269 } 0270 0271 Q_EMIT dataChanged(mi, mi); 0272 0273 for (int i = 0; i < m_rows.count(); ++i) 0274 { 0275 const Row::Type t = m_rows.at(i).type(); 0276 if (t == Row::BonusRow || t == Row::UpperTotalRow || t == Row::LowerTotalRow || t == Row::GrandTotalRow) 0277 Q_EMIT dataChanged(index(m_currentPlayer + 1, i), index(m_currentPlayer + 1, i)); 0278 } 0279 0280 return true; 0281 } 0282 0283 void scores::print(QPainter &painter, double width, double height) const 0284 { 0285 QFont f; 0286 QFontMetrics fm(f); 0287 double margin = width * 0.1; 0288 double widthToUse = width - 2.0 * margin; 0289 double fontHeight; 0290 double heightToUse; 0291 bool continueFindingFont = true; 0292 while (continueFindingFont) 0293 { 0294 fontHeight = fm.height(); 0295 heightToUse = 40.0 * fontHeight; 0296 if ( heightToUse < height - 2.0 * margin ) 0297 { 0298 continueFindingFont = false; 0299 } 0300 else 0301 { 0302 f.setPointSize(f.pointSize() - 1); 0303 fm = QFontMetrics(f); 0304 } 0305 } 0306 0307 double cellWidth = widthToUse / (double)(m_players.count() + 1); 0308 double cellHeight = fontHeight * 2.0; 0309 0310 painter.drawRect( QRectF( margin, margin, widthToUse, heightToUse ) ); 0311 for (int i = 1; i <= 20; ++i) 0312 { 0313 painter.drawLine( QPointF(margin, margin + i * cellHeight), QPointF(margin + widthToUse, margin + i * cellHeight) ); 0314 } 0315 0316 for (int i = 1; i <= m_players.count() + 1; ++i) 0317 { 0318 painter.drawLine( QPointF(margin + i * cellWidth, margin), QPointF(margin + i * cellWidth, margin + heightToUse) ); 0319 } 0320 0321 // write the names 0322 for (int i = 1; i <= m_players.count(); ++i) 0323 { 0324 QRectF cell(margin + i * cellWidth, margin, cellWidth, cellHeight); 0325 painter.drawText( cell, Qt::AlignCenter, m_players[i-1].name() ); 0326 } 0327 0328 // write the plays 0329 for (int i = 1; i <= 20; ++i) 0330 { 0331 QRectF cell(margin, margin + i * cellHeight, cellWidth, cellHeight); 0332 painter.drawText( cell, Qt::AlignCenter, data( index(i, 0), Qt::DisplayRole ).toString() ); 0333 } 0334 0335 // write the scores 0336 for (int i = 1; i <= m_players.count(); ++i) 0337 { 0338 for (int j = 1; j <= 20; ++j) 0339 { 0340 QRectF cell(margin + i * cellWidth, margin + j * cellHeight, cellWidth, cellHeight); 0341 painter.drawText( cell, Qt::AlignCenter, data( index(j, i), Qt::DisplayRole ).toString() ); 0342 } 0343 } 0344 }