File indexing completed on 2022-11-23 10:43:24

0001 /*
0002     KBlackBox - A simple game inspired by an emacs module
0003 
0004     SPDX-FileCopyrightText: 1999-2000 Robert Cimrman <cimrman3@students.zcu.cz>
0005     SPDX-FileCopyrightText: 2007 Nicolas Roffet <nicolas-kde@roffet.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "kbbgamedoc.h"
0011 
0012 
0013 
0014 
0015 
0016 #include "kbbballsonboard.h"
0017 #include "kbbtutorial.h"
0018 
0019 
0020 
0021 //
0022 // Constructor / Destructor
0023 //
0024 
0025 KBBGameDoc::KBBGameDoc(KBBMainWindow *parent, KBBTutorial* tutorial)
0026     : QObject(parent)
0027     , m_random(QRandomGenerator::global()->generate())
0028 {
0029     setRunning(false);
0030     m_columns = 1;
0031     m_rows = 1;
0032     m_tutorial = tutorial;
0033     
0034     m_balls = new KBBBallsOnBoard(this, m_columns, m_rows);
0035     m_ballsPlaced = new KBBBallsOnBoard(this, m_columns, m_rows);
0036     connect(m_ballsPlaced, &KBBBallsOnBoard::changes, parent, &KBBMainWindow::updateStats);
0037 }
0038 
0039 
0040 
0041 //
0042 // Public
0043 //
0044 
0045 int KBBGameDoc::columns() const
0046 {
0047     return m_columns;
0048 }
0049 
0050 
0051 void KBBGameDoc::gameOver()
0052 {
0053     // Clear
0054     setRunning(false);
0055     
0056     // Compute final score
0057     if (m_ballsPlaced->numberOfBallsNotIn(m_balls)>0)
0058         setScore(SCORE_LOST);
0059 }
0060 
0061 
0062 bool KBBGameDoc::gameReallyStarted()
0063 {
0064     return m_gameReallyStarted;
0065 }
0066 
0067 
0068 bool KBBGameDoc::mayShootRay(const int incomingPosition) const
0069 {
0070     if (m_tutorial->isVisible() && !m_tutorial->mayShootRay(incomingPosition))
0071         return false;
0072     else
0073         return true;
0074 }
0075 
0076 
0077 void KBBGameDoc::newGame(int balls, int columns, int rows)
0078 {
0079     clean(columns, rows);
0080 
0081     // Puts the balls in the black box on random positions.
0082     int boxPos;
0083     for (int i = 0; i < balls; i++) {
0084         do {
0085             boxPos = m_random.bounded(m_columns * m_rows);
0086         } while (m_balls->contains(boxPos));
0087         m_balls->add(boxPos);
0088     }
0089 }
0090 
0091 
0092 int KBBGameDoc::numberOfBallsPlaced()
0093 {
0094     return m_ballsPlaced->count();
0095 }
0096 
0097 
0098 int KBBGameDoc::numberOfBallsToPlace()
0099 {
0100     return m_balls->count();
0101 }
0102 
0103 
0104 int KBBGameDoc::rows() const
0105 {
0106     return m_rows;
0107 }
0108 
0109 
0110 int KBBGameDoc::score()
0111 {
0112     return m_score;
0113 }
0114 
0115 
0116 int KBBGameDoc::shootRay( int borderPosition )
0117 {
0118     int outgoingBorderPosition = m_balls->oppositeBorderPosition(borderPosition);
0119     
0120     if ((outgoingBorderPosition == HIT_POSITION) || (borderPosition == outgoingBorderPosition))
0121         setScore(m_score + SCORE_ONE);
0122     else
0123         setScore(m_score + SCORE_TWO);
0124     
0125     if (!m_tutorial->isVisible())
0126         setRunning(true);
0127     Q_EMIT updateStats();
0128 
0129     return outgoingBorderPosition;
0130 }
0131 
0132 
0133 void KBBGameDoc::startTutorial()
0134 {
0135     clean(KBBTutorial::COLUMNS, KBBTutorial::ROWS);
0136     m_balls->add(16);
0137     m_balls->add(21);
0138     m_balls->add(33);
0139     m_tutorial->setStep(1);
0140     m_tutorial->start();
0141 }
0142 
0143 
0144 void KBBGameDoc::timeChanged()
0145 {
0146     setScore(m_score+1);
0147 }
0148 
0149 
0150 
0151 //
0152 // Private
0153 //
0154 
0155 void KBBGameDoc::clean(const int columns, const int rows)
0156 {
0157     m_columns = columns;
0158     m_rows = rows;
0159 
0160     // Clear
0161     setRunning(false);
0162     m_ballsPlaced->newBoard(m_columns, m_rows);
0163     setScore(-1); // -1 because a signal "timeChanged" will be send at the beginning and the score will be set to 0.
0164 
0165     m_balls->newBoard(m_columns, m_rows);
0166 }
0167 
0168 
0169 void KBBGameDoc::setRunning(const bool r)
0170 {
0171     m_gameReallyStarted = r;
0172     Q_EMIT isRunning(r);
0173 }
0174 
0175 
0176 void KBBGameDoc::setScore( int n )
0177 {
0178     if (n<1000)
0179         m_score = n;
0180     else
0181         m_score = 999;
0182     Q_EMIT updateStats();
0183 }
0184 
0185