File indexing completed on 2024-04-21 04:02:38

0001 /*
0002     SPDX-FileCopyrightText: 2007 Dmitry Suzdalev <dimsuz@gmail.com>
0003     SPDX-FileCopyrightText: 2010 Brian Croom <brian.s.croom@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "cellitem.h"
0009 
0010 // own
0011 #include "settings.h"
0012 
0013 QHash<int, QString> CellItem::s_digitNames;
0014 QHash<KMinesState::CellState, QList<QString> > CellItem::s_stateNames;
0015 
0016 CellItem::CellItem(KGameRenderer* renderer, QGraphicsItem* parent)
0017     : KGameRenderedItem(renderer, QString(), parent)
0018 {
0019     if(s_digitNames.isEmpty())
0020         fillNameHashes();
0021     setShapeMode(BoundingRectShape);
0022     reset();
0023 }
0024 
0025 void CellItem::unflag()
0026 {
0027     m_state = KMinesState::Released;
0028     updatePixmap();
0029 }
0030 
0031 void CellItem::unexplode()
0032 {
0033     m_exploded = false;
0034 }
0035 
0036 bool CellItem::isRevealed() const
0037 {
0038     return ( m_state == KMinesState::Revealed || m_state == KMinesState::Error);
0039 }
0040 
0041 bool CellItem::isFlagged() const
0042 {
0043     return m_state == KMinesState::Flagged;
0044 }
0045 
0046 bool CellItem::isQuestioned() const
0047 {
0048     return m_state == KMinesState::Questioned;
0049 }
0050 
0051 bool CellItem::isExploded() const
0052 {
0053     return m_exploded;
0054 }
0055 
0056 
0057 void CellItem::reset()
0058 {
0059     m_state = KMinesState::Released;
0060     m_hasMine = false;
0061     m_exploded = false;
0062     m_digit = 0;
0063     updatePixmap();
0064 }
0065 
0066 void CellItem::updatePixmap()
0067 {
0068     QList<QGraphicsItem*> children = childItems();
0069     qDeleteAll(children);
0070 
0071     QList<QString> spriteKeys = s_stateNames[m_state];
0072     setSpriteKey(spriteKeys[0]);
0073     for(int i=1; i<spriteKeys.count(); i++)
0074         addOverlay(spriteKeys[i]);
0075     if(m_state == KMinesState::Revealed)
0076     {
0077         if(m_digit != 0)
0078             addOverlay(s_digitNames[m_digit]);
0079         else if(m_hasMine)
0080         {
0081             if(m_exploded)
0082                 addOverlay(QStringLiteral( "explosion" ));
0083             addOverlay(QStringLiteral( "mine" ));
0084         }
0085     }
0086 }
0087 
0088 void CellItem::setRenderSize(const QSize &renderSize)
0089 {
0090     KGameRenderedItem::setRenderSize(renderSize);
0091     const QList<QGraphicsItem*> children = childItems();
0092     for (QGraphicsItem* item : children) {
0093         ((KGameRenderedItem*)item)->setRenderSize(renderSize);
0094     }
0095 }
0096 
0097 void CellItem::setHasMine(bool hasMine)
0098 {
0099     m_hasMine = hasMine;
0100 }
0101 
0102 bool CellItem::hasMine() const
0103 {
0104     return m_hasMine;
0105 }
0106 
0107 void CellItem::setDigit(int digit)
0108 {
0109     m_digit = digit;
0110     updatePixmap();
0111 }
0112 
0113 int CellItem::digit() const
0114 {
0115     return m_digit;
0116 }
0117 
0118 void CellItem::press()
0119 {
0120     if(m_state == KMinesState::Released)
0121     {
0122         m_state = KMinesState::Pressed;
0123         updatePixmap();
0124     }
0125 }
0126 
0127 void CellItem::release(bool force)
0128 {
0129     // special case for mid-button magic
0130     if(force && (m_state == KMinesState::Flagged || m_state == KMinesState::Questioned))
0131         return;
0132 
0133     if(m_state == KMinesState::Pressed || force)
0134     {
0135         // if we hold mine, let's explode
0136         m_exploded = m_hasMine;
0137         reveal();
0138     }
0139 }
0140 
0141 void CellItem::mark()
0142 {
0143     // this will provide cycling through
0144     // Released -> "?"-mark -> "RedFlag"-mark -> Released
0145 
0146     bool useQuestion = Settings::useQuestionMarks();
0147 
0148     switch(m_state)
0149     {
0150         case KMinesState::Released:
0151             m_state = KMinesState::Flagged;
0152             break;
0153         case KMinesState::Flagged:
0154             m_state = useQuestion ? KMinesState::Questioned : KMinesState::Released;
0155             break;
0156         case KMinesState::Questioned:
0157             m_state = KMinesState::Released;
0158             break;
0159         default:
0160             // shouldn't be here
0161             break;
0162     } // end switch
0163     updatePixmap();
0164 }
0165 
0166 int CellItem::type() const
0167 {
0168     return Type;
0169 }
0170 
0171 void CellItem::reveal()
0172 {
0173     if(isRevealed())
0174         return; // already revealed
0175 
0176     if(m_state == KMinesState::Flagged && m_hasMine == false)
0177         m_state = KMinesState::Error;
0178     else
0179         m_state = KMinesState::Revealed;
0180     updatePixmap();
0181 }
0182 
0183 void CellItem::unreveal()
0184 {
0185     m_state = KMinesState::Released;
0186     updatePixmap();
0187 }
0188 
0189 void CellItem::undoPress()
0190 {
0191     if(m_state == KMinesState::Pressed)
0192     {
0193         m_state = KMinesState::Released;
0194         updatePixmap();
0195     }
0196 }
0197 
0198 void CellItem::fillNameHashes()
0199 {
0200     s_digitNames[1] = QStringLiteral( "arabicOne" );
0201     s_digitNames[2] = QStringLiteral( "arabicTwo" );
0202     s_digitNames[3] = QStringLiteral( "arabicThree" );
0203     s_digitNames[4] = QStringLiteral( "arabicFour" );
0204     s_digitNames[5] = QStringLiteral( "arabicFive" );
0205     s_digitNames[6] = QStringLiteral( "arabicSix" );
0206     s_digitNames[7] = QStringLiteral( "arabicSeven" );
0207     s_digitNames[8] = QStringLiteral( "arabicEight" );
0208 
0209     s_stateNames[KMinesState::Released].append(QStringLiteral( "cell_up" ));
0210     s_stateNames[KMinesState::Pressed].append(QStringLiteral( "cell_down" ));
0211     s_stateNames[KMinesState::Revealed].append(QStringLiteral( "cell_down" ));
0212     s_stateNames[KMinesState::Questioned].append(QStringLiteral( "cell_up" ));
0213     s_stateNames[KMinesState::Questioned].append(QStringLiteral( "question" ));
0214     s_stateNames[KMinesState::Flagged].append(QStringLiteral( "cell_up" ));
0215     s_stateNames[KMinesState::Flagged].append(QStringLiteral( "flag" ));
0216     s_stateNames[KMinesState::Error].append(QStringLiteral( "cell_down" ));
0217     s_stateNames[KMinesState::Error].append(QStringLiteral( "mine" ));
0218     s_stateNames[KMinesState::Error].append(QStringLiteral( "error" ));
0219     s_stateNames[KMinesState::Hint].append(QStringLiteral( "cell_up" ));
0220     s_stateNames[KMinesState::Hint].append(QStringLiteral( "hint" ));
0221 }
0222 
0223 void CellItem::addOverlay(const QString& spriteKey)
0224 {
0225     auto* overlay = new KGameRenderedItem(renderer(), spriteKey, this);
0226     overlay->setRenderSize(renderSize());
0227 }