remove old files add new sources
[mancala] / src / Cup.cpp
1 /*
2 Mancala - A Historical Board Game
3 Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
4 Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of
9 the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "Cup.h"
21
22 #include <math.h>
23
24 #include <QFont>
25 #include <QSize>
26 #include <QPainter>
27 #include <QPointF>
28 #include <QGraphicsSceneMouseEvent>
29 #include <QTimer>
30
31 // #include <kdebug.h>
32
33 #include "Stone.h"
34 #include "Board.h"
35 #include "GameInfo.h"
36
37
38 Cup::Cup(GameInfo* info, int cupNumber, QGraphicsSvgItem *parent)
39     : QGraphicsSvgItem(parent)
40
41 {
42     m_index = cupNumber;
43     m_board = qgraphicsitem_cast<Board*>(parent);
44     m_gameInfo = info;
45     m_text = new QGraphicsSimpleTextItem(parent);
46
47     setSharedRenderer(m_board->renderer());
48     setElementId("cup");
49     setZValue(2);
50
51     drawInitially();
52     drawTextInitially(m_gameInfo->initialStonesPerCup());
53
54     //connect(this,SIGNAL(signalChangeText()),this,SLOT(slotChangeText()));
55 }
56
57 void Cup::drawInitially(){
58
59     qreal gapWidth = m_board->boundingRect().width() * ( 0.2 / ( m_gameInfo->numCupsPerRow() + m_gameInfo->numKalahs() + 1 ) );
60
61     m_size.setWidth( m_board->boundingRect().width() * 0.8 / ( m_gameInfo->numCupsPerRow() + m_gameInfo->numKalahs() ) );
62     m_size.setHeight( m_board->boundingRect().height() * 0.35 );
63
64     qreal posX,posY;
65
66     if(m_index < m_gameInfo->numCupsPerRow())
67         posX = m_board->boundingRect().x() + gapWidth * ( m_index % m_gameInfo->numCupsPerRow() +
68         m_gameInfo->numKalahs()) + ( m_index % m_gameInfo->numCupsPerRow() + 1) * m_size.width();
69
70     else{
71         posX = m_board->boundingRect().x() + gapWidth *
72         ((((2*m_gameInfo->numCupsPerRow()-1)-m_index) % m_gameInfo->numCupsPerRow()) + m_gameInfo->numKalahs() )
73         +(((2*m_gameInfo->numCupsPerRow()-1)-m_index) % m_gameInfo->numCupsPerRow() + 1) * m_size.width();
74     }
75     posY = m_board->boundingRect().y() + 0.1 * m_board->boundingRect().height();
76     if(m_index >= m_gameInfo->numCupsPerRow())
77         posY += 0.1 * m_board->boundingRect().height() + m_size.height();
78
79
80     m_pos.setX(posX);
81     m_pos.setY(posY);
82
83     qreal cupScaleX = m_size.width() / this->boundingRect().width();
84     qreal cupScaleY = m_size.height()/ this->boundingRect().height();
85
86     m_mid_point.setX( m_pos.x() + m_size.width() / 2 );
87     m_mid_point.setY( m_pos.y() + m_size.height() / 2 );
88
89     setPos(m_pos);
90     scale(cupScaleX,cupScaleY);
91
92 }
93
94
95 void Cup::drawTextInitially(int numStone){
96
97     QString str;
98     while(numStone != 0){
99             //qDebug() << "Number " << numStone % 10 << " Char " <<(QChar)(numStone % 10 + '0') ;
100             str.push_front( (QChar)(numStone % 10 + '0') );
101             numStone /= 10;
102         }
103
104     m_text->setText(str);
105     m_text->setFont( QFont("Comic Sans MS", 24, QFont::Bold) );
106     m_text->setPen(QPen(QColor("darkslateblue"), 1.5, Qt::SolidLine, Qt::RoundCap,
107                    Qt::RoundJoin));
108
109     QLinearGradient gradient(0, 0, 0, 100);
110     gradient.setColorAt(0.0, "mediumslateblue");
111     gradient.setColorAt(1.0, "cornsilk");
112     m_text->setBrush(gradient);
113
114     m_text->setVisible(false);
115
116     int textX = m_pos.x() + m_size.width();
117     textX -= m_text->boundingRect().size().width() + 15;
118
119     int textY =  m_pos.y() + m_size.height();
120     textY -= m_text->boundingRect().size().height() - 15;
121
122     m_text->scale(0.6,0.6);
123     m_text->setPos( textX,textY );
124     m_text->setZValue(4);
125     m_text->setVisible(true);
126
127 }
128
129 //add Stone to cup
130 void Cup::addStone(Stone* stone){
131
132     QPointF* stonePos;
133     qreal m_diameter_stone = qMin(m_size.width()/5, m_size.height()/5);
134
135     stone->setSize(QSize(m_diameter_stone,m_diameter_stone));
136     stonePos = calculateStonePosition(stone);
137
138     //kDebug() << "Stone Position: " << stonePos->x() << " " <<stonePos->y();
139
140     stone->setPosition(stonePos->x(),stonePos->y());
141
142     m_stone.append(stone);
143 }
144
145
146 //Add a stone to the stoneList
147 void Cup::updateStoneList(Stone* stoneItem){
148
149     QPointF *stonePos;
150     m_stone.append(stoneItem);
151
152     //calculate and update stone position
153     stonePos = calculateStonePosition(stoneItem);
154     stoneItem->animateStones(QPointF(stonePos->x(),stonePos->y()));
155     update();
156
157     QTimer::singleShot(500, this, SLOT(slotChangeText()));
158
159 }
160
161 //Remove a stone from the stoneList
162 Stone* Cup::updateStoneList(){
163
164     Stone* stone;
165
166     if(m_stone.count()){
167         stone = m_stone.front();
168         m_stone.pop_front();
169     }
170     else{
171         // kDebug() << "List is empty already";
172         return NULL;
173     }
174     slotChangeText();
175
176     return stone;
177
178 }
179
180 void Cup::slotChangeText(){
181
182     m_text->setVisible(false);
183     if( m_stone.count() ){
184         m_text->setText( QString("%1").arg( m_stone.count() ));
185         m_text->setVisible(true);
186         update();
187     }
188 }
189
190
191 QPointF* Cup::calculateStonePosition(Stone* stone){
192
193     QPointF *returnPoint = new QPointF();
194
195     qreal diameter = qMin( m_size.width(),m_size.height());
196
197     int initialLength = qrand() % (int) diameter / 3;
198     int angle = qrand() % 360;
199
200     qreal posX = middlePoint().x() + initialLength * cos(angle * M_PI / 180);
201     qreal posY = middlePoint().y() + initialLength * sin(angle * M_PI / 180);
202
203     if( ( posX + stone->size().width()) > ( position().x() + 0.7 * m_size.width() ) )
204         posX -= stone->size().width();
205     else if( posX < ( m_pos.x()+ 0.3 * m_size.width() ) )
206         posX += stone->size().width();
207
208     if( ( posY + stone->size().height() ) > ( m_pos.y() + 0.7 * m_size.height() ) )
209         posY -= stone->size().height();
210     else if( posY < (m_pos.y() + 0.3 < m_size.height() ) )
211         posY += stone->size().height();
212
213     returnPoint->setX(posX);
214     returnPoint->setY(posY);
215
216     return returnPoint;
217
218 }
219
220 //Reimplementing the shape item
221 QPainterPath Cup::shape() const
222  {
223      QPainterPath path;
224      path.addEllipse(boundingRect());
225      return path;
226  }