remove old files add new sources
[mancala] / src / GameController.cpp
diff --git a/src/GameController.cpp b/src/GameController.cpp
new file mode 100644 (file)
index 0000000..5138c66
--- /dev/null
@@ -0,0 +1,975 @@
+/*
+Mancala - A Historical Board Game
+Copyright (C) 2009-2010 A.H.M.Mahfuzur Rahman 65mahfuz90@gmail.com
+Copyright (c) 2010 Reto Zingg g.d0b3rm4n@gmail.com
+
+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, see <http://www.gnu.org/licenses/>.
+*/
+
+// #include <KLocale>
+
+#include "GameController.h"
+
+#include <QTimer>
+#include <QStringList>
+#include <QList>
+
+// #include <kdebug.h>
+
+#include "Board.h"
+#include "Score.h"
+#include "Kalah.h"
+#include "MoveGenerator.h"
+
+
+GameController::GameController(GameInfo* gameInfo){
+    m_gameInfo = gameInfo;
+    m_humanScore = new Score();
+    m_computerScore = new Score();
+    initializeGameController();
+
+    connect(this,SIGNAL(signalSowMaker(int)),this,SLOT(sowMaker(int)));
+    connect(this,SIGNAL(signalAfterSow(int)),this,SLOT(afterSow(int)));
+    connect(this,SIGNAL(signalComputerMove()),this,SLOT(makeComputerMove()));
+
+}
+
+void GameController::initializeGameController(){
+
+    m_gameDifficulty = GameController::EASY;
+    m_moveGenerator = new MoveGenerator(m_gameDifficulty,m_gameInfo,this);
+    m_humanTurn = true;
+    m_cupIndexClicked = -1;
+    m_humanSide = GameController::LOWER;
+    m_humanKalah = Kalah::Right;
+    m_gamePaused = false;
+    m_gameOver = false;
+    m_physicalMoveAllowed = false;
+    m_captureInfo = m_gameInfo->captureInfo();
+
+    //If game is clockwise change human kalah
+    if(m_humanSide == GameController::LOWER && m_gameInfo->rotationType() == GameInfo::CLOCKWISE){
+        m_humanKalah = Kalah::Left;
+    }
+
+    m_humanScore->reset();
+    m_computerScore->reset();
+
+    emit signalMessage("");
+    emit signalShowTurn(m_humanTurn);
+    emit signalShowScore(m_humanScore->score(),true);
+    emit signalShowScore(m_computerScore->score(),false);
+
+    initializeBoard();
+    setHumanSideCups();
+
+}
+
+void GameController::initializeBoard(){
+
+    while(m_physicalBoard.count()){
+        m_physicalBoard.pop_back();
+        m_logicalBoard.pop_back();
+    }
+
+    //stoneInfo in cups (0 to 2*m_gameInfo->numCupsPerRow()-1)
+    for(int i = 0 ; i< 2*m_gameInfo->numCupsPerRow();i++){
+        m_physicalBoard.append(m_gameInfo->initialStonesPerCup());
+        m_logicalBoard.append(m_gameInfo->initialStonesPerCup());
+    }
+
+    //stoneInfo in kalah's
+    for(int i = 0 ; i < 2 ; i++){
+        m_physicalBoard.append(0);
+        m_logicalBoard.append(0);
+    }
+
+}
+
+void GameController::setHumanSideCups(){
+
+    while(m_humanSideCups.count())
+        m_humanSideCups.pop_back();
+
+    for(int i = 0 ; i < m_gameInfo->numCupsPerRow();i++)
+        m_humanSideCups.append(i);
+    if(m_humanSide == GameController::LOWER)
+        for(int i = 0 ; i < m_gameInfo->numCupsPerRow();i++){
+        m_humanSideCups[i] = 2*m_gameInfo->numCupsPerRow() - 1 - m_humanSideCups[i];
+
+    }
+
+}
+
+//It is called from the GraphcisScene to start the game
+void GameController::setBoardItem(Board *board){
+    m_board = board;
+
+    //If computer starts we will delay it by 1.5 seconds
+    if(!m_humanTurn){
+        emit signalShowTurn(false);
+        QTimer::singleShot(1500, this, SLOT(makeComputerMove()));
+    }
+
+}
+
+//-------------Is this valid cup(cupIndex) belongs to human ----------------
+bool GameController::isHumanCup(int cupIndex){
+
+    if(cupIndex >= m_gameInfo->numCupsPerRow())
+        return true;
+    return false;
+}
+
+//----------------Is the kalah(kalahIndex) belongs to human---------------------
+bool GameController::isHumanKalah(int kalahIndex){
+    kalahIndex -= 2*m_gameInfo->numCupsPerRow();
+
+    if(kalahIndex == m_humanKalah){
+        return true;
+    }
+    return false;
+}
+
+//-----------------------------Human Move-----------------------------------
+void GameController::makeHumanMove(int index){
+
+    if(isGameOver(m_physicalBoard) || !m_humanTurn) return;
+
+    m_physicalMoveAllowed = true;
+    // kDebug() << "Human Moving .................";
+    if(m_gameInfo->lapStyle() == GameInfo::MULTIPLE)
+        m_multipleLapDelay = false;
+    m_rotationInfo = m_gameInfo->rotationInfo(index);
+    sowMaker(index);
+
+}
+
+//----------------------------------Computer Move----------------------------
+void GameController::makeComputerMove(){
+
+    if(isGameOver(m_physicalBoard) || m_humanTurn) return;
+
+    // kDebug() << "Computer Moving ................";
+
+    m_physicalMoveAllowed = false;
+    int index = m_moveGenerator->bestMove(m_physicalBoard,false);
+    m_physicalMoveAllowed = true;
+    m_rotationInfo = m_gameInfo->rotationInfo(index);
+
+    if(index != -1){
+        // kDebug() << "Index: " << index << " Stones: " << m_physicalBoard[index];
+        sowMaker(index);
+    }
+
+    else
+        computerHasNoMove();
+}
+
+//slot sowMaker
+void GameController::sowMaker(int index){
+
+    if(isGameOver(m_physicalBoard)) return;
+    m_physicalMoveAllowed = true;
+
+    m_index = index;
+    //For human Turn, we want to response quick, unless it falls between multiple lap
+    if(m_humanTurn){
+        if(m_gameInfo->lapStyle() == GameInfo::MULTIPLE && m_multipleLapDelay)
+            QTimer::singleShot(1500,this,SLOT(sowController()));
+        else sowController();
+    }
+
+    else QTimer::singleShot(1500,this,SLOT(sowController()));
+}
+
+
+void GameController::sowController(){
+
+    if(m_gameOver) return;
+
+    int index = m_index;
+    index = singleSow(index);
+
+    if(m_gameInfo->lapStyle() == GameInfo::MULTIPLE && !isEndOfLap(index,m_physicalBoard)){
+        if(m_humanTurn) m_multipleLapDelay = true;
+        emit signalSowMaker(index);
+    }
+    else{
+        emit signalAfterSow(index);
+    }
+
+}
+
+//slot After Sow
+void GameController::afterSow(int index){
+
+    if(isGameOver(m_physicalBoard)) return;
+    if(m_gameInfo->isBonusTurn()){
+
+        if(index >= 2*m_gameInfo->numCupsPerRow()){   //is a kalah
+            // kDebug() << "A Bonus Turn:";
+            if(m_humanTurn && isHumanKalah(index)){
+                emit signalMessage( tr("You got a bonus turn") );
+                if(isHumanSideEmpty(m_physicalBoard)) humanHasNoMove();
+                return;
+
+            }
+            else if(!m_humanTurn && !isHumanKalah(index)){
+                emit signalMessage( tr("Computer got a bonus turn") );
+                if(isComputerSideEmpty(m_physicalBoard)) computerHasNoMove();
+                emit signalComputerMove();
+                return;
+            }
+
+        }
+    }
+
+
+    if(isGameOver(m_physicalBoard)) return;
+    handleCrossCapture(index,m_physicalBoard);
+    emit signalMessage("");
+
+    if(isGameOver(m_physicalBoard)) return;
+    int multiplier = handleCountNSeriesCapture(index,m_physicalBoard);
+
+    if(isGameOver(m_physicalBoard)) return;
+    changeTurn();
+
+    if(!m_humanTurn && !m_gameOver){
+        // kDebug() << "Next turn computer";
+        if(isComputerSideEmpty(m_physicalBoard)) computerHasNoMove();
+        else{
+            if(multiplier > 0)
+                QTimer::singleShot( multiplier * 1500, this, SLOT(makeComputerMove() ) );
+            else
+                QTimer::singleShot(1500, this, SLOT(makeComputerMove()));
+        }
+    }
+    else{
+        // kDebug() << "Next turn Human";
+        if(isHumanSideEmpty(m_physicalBoard) ) humanHasNoMove();
+    }
+
+}
+
+void GameController::changeTurn(){
+
+    m_humanTurn == true ? m_humanTurn = false : m_humanTurn = true;
+    emit signalShowTurn(m_humanTurn);
+}
+
+//---------------------------- is End Of Lap -----------------------------------
+bool GameController::isEndOfLap(int index,QList<int>& board){
+
+    //if last stone ends on a cup with desired no of stone
+    if(index < 2*m_gameInfo->numCupsPerRow() && board[index] == m_gameInfo->stonesToEndLap()){
+        return true;
+    }
+    //if last stone on a kalah
+    if(index >= 2*m_gameInfo->numCupsPerRow()){
+        return true;
+    }
+
+    return false;
+}
+
+//Will be true when each cup is empty
+bool GameController::isGameOver(QList<int>& board){
+
+    if(m_gameOver) return true;
+
+    for(int i = 0 ; i < 2*m_gameInfo->numCupsPerRow() ; i++)
+        if( board[i] > m_gameInfo->leftToCup() )
+            return false;
+    if(m_physicalMoveAllowed) emit signalGameOver();
+    m_gameOver = true;
+    return m_gameOver;
+}
+
+//--------------------------------single Lap sowing -------------------------------------
+int GameController::singleSow(int cupIndex){
+    //we first find out from which side the sowing started - easy, who is moving
+    Side side = m_humanSide;
+    if(!m_humanTurn) side = (Side)(1 - m_humanSide);
+
+    // if(m_physicalMoveAllowed) kDebug() << "We are here to sow";
+
+    QList<int> board;
+    if(m_physicalMoveAllowed) board = physicalBoard();
+    else board = logicalBoard();
+
+    //0-CLOCKWISE,1-ANTI_CLOCKWISE
+    int rotation = m_gameInfo->rotationInfo(cupIndex);
+    int i , kalahNo = Kalah::Left;
+    bool putKalahNow = false;
+    int returnValue = cupIndex;
+
+    //Initial Check where to put in the first stone
+    if( rotation == GameInfo::ANTICLOCKWISE){
+
+        i = cupIndex - 1;
+        if(cupIndex >= m_gameInfo->numCupsPerRow()){
+            kalahNo = Kalah::Right;
+        }
+
+        if( m_gameInfo->stonesToKalah() &&
+            ( (cupIndex == m_gameInfo->numCupsPerRow() && side == GameController::LOWER)
+            || ( cupIndex == 0 && side == GameController::UPPER ) ) )
+            putKalahNow = true;
+    }
+    //clockwise
+    else{
+        i = cupIndex + 1;
+        if(cupIndex < m_gameInfo->numCupsPerRow())
+            kalahNo = Kalah::Right;
+
+        if( m_gameInfo->stonesToKalah() &&
+            ( (cupIndex == (2 * m_gameInfo->numCupsPerRow()-1) && side == GameController::LOWER)
+               || ( cupIndex == (m_gameInfo->numCupsPerRow()-1) && side == GameController::UPPER) ) )
+            putKalahNow = true;
+    }
+
+
+    //Continuous check and update
+    int loop = board[cupIndex]- m_gameInfo->leftToCup();
+
+    for(int j = 0 ; j < loop ; j++){
+
+        if( rotation == GameInfo::CLOCKWISE)
+            i %= 2 * m_gameInfo->numCupsPerRow();
+        else
+            if( i < 0) i = 2 * m_gameInfo->numCupsPerRow() - 1;
+
+        //If it is need to be put in cup
+        if( !putKalahNow ){
+            board[i]++;
+
+            if(m_physicalMoveAllowed){
+                m_board->updateChildren(cupIndex,i,true);
+//                // kDebug() << "Putting to cup: " << i;
+            }
+            returnValue = i;
+
+            //check whether the next stone will put in kalah or not
+            if( rotation == GameInfo::ANTICLOCKWISE){
+                if( m_gameInfo->stonesToKalah() &&
+                    ( ( i == m_gameInfo->numCupsPerRow() && side == GameController::LOWER )
+                      ||( i == 0 && side == GameController::UPPER ) ) )
+                    putKalahNow = true;
+                i--;
+            }
+            else{
+                if( m_gameInfo->stonesToKalah() &&
+                    ( (i == (2 * m_gameInfo->numCupsPerRow()-1) && side == GameController::LOWER)
+                     || ( i == (m_gameInfo->numCupsPerRow()-1) &&  side == GameController::UPPER) ) )
+                    putKalahNow = true;
+                i++;
+            }
+
+        }
+        //going to put it in kalah
+        else{
+
+            if(kalahNo == Kalah::Right){
+
+                if(m_physicalMoveAllowed){
+//                    kDebug() << "Putting to Right Kalah";
+                    m_board->updateChildren(cupIndex,Kalah::Right,false);
+                }
+                returnValue = 2*m_gameInfo->numCupsPerRow() + Kalah::Right;
+                board[returnValue]++;
+            }
+
+            else{
+                if(m_physicalMoveAllowed){
+//                    kDebug() << "Putting to left kalah";
+                    m_board->updateChildren(cupIndex,Kalah::Left,false);
+                }
+
+                returnValue = 2*m_gameInfo->numCupsPerRow() + Kalah::Left;
+                board[returnValue]++;
+            }
+
+            if(m_physicalMoveAllowed){
+                if(m_humanTurn && kalahNo == m_humanKalah)
+                    changeScore(1,true);
+                else changeScore(1,false);
+            }
+
+            putKalahNow = false;
+        }
+
+        board[cupIndex]--;
+    }
+
+    if(m_physicalMoveAllowed) setPhysicalBoard(board);
+    else setLogicalBoard(board);
+
+    return returnValue;
+}
+
+
+void GameController::slotGameDifficulty(Difficulty difficulty){
+//    kDebug() << "GameDifficulty is: " << difficulty;
+    m_gameDifficulty = difficulty;
+    m_moveGenerator->changeDifficulty(m_gameDifficulty);
+}
+
+
+//******************************** slots ******************************************
+void GameController::slotMouseClicked(int index){
+
+    if(m_gameOver)
+        return;
+
+    if(m_humanTurn){
+        m_cupIndexClicked = index;
+
+        if(isHumanSideEmpty(m_physicalBoard)){
+            emit signalMessage( tr("Sorry, you have no move") );
+            humanHasNoMove();
+        }
+        else if(m_cupIndexClicked < 0){
+            emit signalMessage( tr("Click on a Cup") );
+        }
+
+        else if(!isHumanCup(index))
+            emit signalMessage( tr("Click on a cup in the lower row") );
+
+        else if(m_physicalBoard[index] <= m_gameInfo->leftToCup())
+            emit signalMessage( tr("Sorry, not enough stones to move") );
+
+        else{
+            makeHumanMove(m_cupIndexClicked);
+        }
+    }
+
+}
+
+void GameController::slotGameOverForNewGame(int identity){
+    m_gameOver = true;
+    emit signalMessage( tr("Loading game...") );
+
+    QTimer* timer = new QTimer(this);
+    signalMapper = new QSignalMapper(this);
+    connect(timer,SIGNAL(timeout()),signalMapper,SLOT(map()));
+    signalMapper->setMapping(timer,identity);
+    connect(signalMapper,SIGNAL(mapped(int)),this,SIGNAL(timeout(int)));
+
+    connect(this,SIGNAL(timeout(int)),this,SLOT(newGameEmitter(int)));
+    timer->setSingleShot(true);
+    timer->start(1500);
+}
+
+void GameController::newGameEmitter(int identity){
+    emit signalNewGame(identity);
+}
+
+void GameController::slotGameOverForRestartGame(){
+    m_gameOver = true;
+//    kDebug() << "GameOver is true";
+    emit signalMessage( tr("Loading game...") );
+    QTimer::singleShot(2000,this,SLOT(restartGameEmitter()));
+}
+
+void GameController::restartGameEmitter(){
+    emit signalRestartGame();
+}
+
+//******************************** slots *****************************
+
+bool GameController::isHumanSideEmpty(QList<int>& board){
+
+    for(int i = 0 ; i < m_gameInfo->numCupsPerRow() ; i++)
+        if(board[m_humanSideCups[i]] > m_gameInfo->leftToCup())
+            return false;
+    return true;
+}
+
+bool GameController::isComputerSideEmpty(QList<int>& board){
+
+    int maxIndex = 2*m_gameInfo->numCupsPerRow() - 1;
+
+    for(int i = 0 ; i < m_gameInfo->numCupsPerRow() ; i++)
+        if(board[maxIndex - m_humanSideCups[i]] > m_gameInfo->leftToCup())
+            return false;
+    return true;
+}
+
+//---------------------------------- capture handling-------------------------------------
+
+void GameController::handleCrossCapture(int index,QList<int>& board){
+
+    if(m_physicalMoveAllowed){ //kDebug() << "handle Cross capture -------";
+        if(isGameOver(m_physicalBoard)) return;
+    }
+    if(index >= 2*m_gameInfo->numCupsPerRow())
+        return;
+
+    //if CrossCapture allowed then 0th bit should be 1
+    int capture = m_gameInfo->captureType();
+    if(m_physicalMoveAllowed) // kDebug() << "Capture Info: " << capture;
+    if(!(capture & 1)){
+        if(m_physicalMoveAllowed) //kDebug() << "We will return";
+        return;
+    }
+
+    int opponentCupIndex;
+    int kalahIndex = -1;
+    //If it is a cup
+    if(index < 2*m_gameInfo->numCupsPerRow()){
+
+        opponentCupIndex = 2*m_gameInfo->numCupsPerRow() - 1 - index;
+        //if opponet cup is empty
+        if(board[opponentCupIndex] == 0)
+            return;
+        if(board[index] != 1)    //we are now taking that only 1 stone
+            return;
+
+        if(isHumanCup(index) && m_humanTurn)
+            kalahIndex = m_humanKalah;
+        else if(!m_humanTurn && !isHumanCup(index))
+            kalahIndex = 1 - m_humanKalah;
+
+        //Now do the capture;
+        if(kalahIndex != -1){
+           QString strIndex = QString("%1,%2").arg(index).arg(kalahIndex);
+
+           //Animation part
+           if(m_physicalMoveAllowed){
+               QTimer* timer = new QTimer(this);
+               signalMapper = new QSignalMapper(this);
+
+               connect(timer,SIGNAL(timeout()),signalMapper,SLOT(map()));
+               signalMapper->setMapping(timer,strIndex);
+               connect(signalMapper,SIGNAL(mapped(const QString&)),this,SIGNAL(timeout(const QString&)));
+
+               connect(this,SIGNAL(timeout(const QString&)),this,SLOT(crossCapture(const QString&)));
+               timer->setSingleShot(true);
+               timer->start(1500);
+           }
+           else crossCapture(strIndex);
+        }
+    }
+
+}
+
+//Cross Capture is done here
+void GameController::crossCapture(const QString& indexString){
+
+    if(isGameOver(m_physicalBoard)) return;
+
+    int capture = m_gameInfo->captureType();
+    if(! (capture & 1) ) return;
+
+    int loop,i;
+    QList<int> board;
+    QStringList list;
+    int index,kalahIndex,opponentCupIndex;
+
+    list = indexString.split(',');
+    index = list[0].toInt();
+    kalahIndex = list[1].toInt();
+    opponentCupIndex = 2*m_gameInfo->numCupsPerRow() - 1 - index;
+
+    if(m_physicalMoveAllowed) board = physicalBoard();
+    else board = logicalBoard();
+
+    loop = board[index];
+    for(i = 0 ; i < loop ; ++i){
+        //we want to remove from index and put to kalah(human)
+        if(m_physicalMoveAllowed) m_board->updateChildren(index,kalahIndex,false);
+        board[index]--;
+        board[kalahIndex + 2*m_gameInfo->numCupsPerRow()]++;
+
+        if(m_physicalMoveAllowed){
+            if(kalahIndex == m_humanKalah)
+                changeScore(1,true);
+            else changeScore(1,false);
+        }
+    }
+
+    loop = board[opponentCupIndex];
+    for(i = 0 ; i < loop ; ++i){
+        //we want to remove from index and put to kalah(human)
+        if(m_physicalMoveAllowed) m_board->updateChildren(opponentCupIndex,kalahIndex,false);
+        board[opponentCupIndex]--;
+        board[kalahIndex + 2*m_gameInfo->numCupsPerRow()]++;
+
+        if(m_physicalMoveAllowed){
+            if(kalahIndex == m_humanKalah)
+                changeScore(1,true);
+            else changeScore(1,false);
+        }
+
+    }
+
+    if(m_physicalMoveAllowed) setPhysicalBoard(board);
+    else setLogicalBoard(board);
+
+}
+
+int GameController::handleCountNSeriesCapture(int index,QList<int>& board){
+    if(m_physicalMoveAllowed){
+        // kDebug() << "count and series capture--------";
+        if(isGameOver(m_physicalBoard)) return 0;
+    }
+    //Do the capture
+    int capture = m_gameInfo->captureType(),i = 0,kalahIndex;
+    int countCaptureIndex = -1,seriesCaptureIndex = -1;
+    bool captureAllowed;
+    int timerCount;
+
+    if(capture & 1) i++;    //cross capture is at capture_info[0]
+    if(capture & 2) countCaptureIndex = i++;
+    if(capture & 4) seriesCaptureIndex = i++;
+
+    //If no count capture, then no series capture also
+    if(countCaptureIndex == -1){
+        return 0;
+    }
+    else{
+        //At this point we know count captue is allowed in this game
+        captureAllowed = false;
+
+        //we will check whether capture is allowed in this position. For example, game supports
+        //capture at the opponent, but current last stone is on own cup, so no capture
+        if( ( !( (m_humanTurn == false && isHumanCup(index) == false) || (m_humanTurn && isHumanCup(index) ) )
+            && ( m_captureInfo[countCaptureIndex].first == GameInfo::OPPONENT ||
+                 m_captureInfo[countCaptureIndex].first == GameInfo::BOTH ) )
+            ||
+                    ( ( ( m_humanTurn && isHumanCup(index) ) || (!m_humanTurn && !isHumanCup(index) ) )
+                      && (m_captureInfo[countCaptureIndex].first == GameInfo::OWN ||
+                          m_captureInfo[countCaptureIndex].first == GameInfo::BOTH ) ) )
+        {
+            captureAllowed = true;
+            timerCount = 0;
+        }
+
+        while(captureAllowed){
+
+            //if capture allowed and stone Number matched at the cup, then we will capture
+            if(stoneNumberMatched(index,countCaptureIndex,board)){
+                timerCount++;
+
+//                if(m_physicalMoveAllowed) kDebug() << "count capture allowed";
+                if(m_humanTurn) kalahIndex = m_humanKalah;
+                else kalahIndex = 1 - m_humanKalah;
+
+                QString strIndex = QString("%1,%2").arg(index).arg(kalahIndex);
+
+                //Animation part
+                if(m_physicalMoveAllowed){
+//                    kDebug() << "str: " << strIndex;
+
+                    QTimer* timer = new QTimer(this);
+                    signalMapper = new QSignalMapper(this);
+
+                    connect(timer,SIGNAL(timeout()),signalMapper,SLOT(map()));
+                    signalMapper->setMapping(timer,strIndex);
+                    connect(signalMapper,SIGNAL(mapped(const QString&)),this,SIGNAL(timeout(const QString&)));
+
+                    connect(this,SIGNAL(timeout(const QString&)),this,SLOT(countCapture(const QString&)));
+                    timer->setSingleShot(true);
+                    timer->start(timerCount * 1500);
+                }
+                else countCapture(strIndex);
+
+            }
+            else break;
+
+            //Get Index of the next cup
+            if(seriesCaptureIndex != -1){
+                index = nextIndex(index,seriesCaptureIndex);
+//                if(m_physicalMoveAllowed) kDebug() << "Next Cup Index: " << index;
+            }
+            else break;
+
+            //if at my own side but capture is only allowed at the opponent
+            if( ( ( ( m_humanTurn && isHumanCup(index)) || (!m_humanTurn && !isHumanCup(index) ) )
+                && m_captureInfo[countCaptureIndex].first == GameInfo::OPPONENT )
+                    ||
+            //Or at my opponent side, but capture is allowed only at my own side
+                    ( ( ( m_humanTurn && !isHumanCup(index) ) || ( !m_humanTurn && isHumanCup(index) ) )
+                && m_captureInfo[countCaptureIndex].first == GameInfo::OWN  ) )
+                    captureAllowed = false;
+        }
+
+    }
+    return timerCount;
+
+}
+
+//do the capture
+void GameController::countCapture(const QString& indexString){
+
+    if(isGameOver(m_physicalBoard)) return;
+
+    QList<int> board;
+    QStringList list;
+    int index,kalahIndex;
+
+    list = indexString.split(',');
+    index = list[0].toInt();
+    kalahIndex = list[1].toInt();
+
+    if(m_physicalMoveAllowed) board = physicalBoard();
+    else board = logicalBoard();
+
+    if(m_physicalMoveAllowed) m_board->updateChildren(index,kalahIndex,board[index]);
+    board[kalahIndex + 2*m_gameInfo->numCupsPerRow()] += board[index];
+
+    if(m_physicalMoveAllowed){
+        if(m_humanTurn) changeScore(board[index],true);
+        else changeScore(board[index],false);
+    }
+
+    board[index] = 0;
+
+    if(m_physicalMoveAllowed) setPhysicalBoard(board);
+    else setLogicalBoard(board);
+
+}
+
+bool GameController::stoneNumberMatched(int index,int countCaptureIndex,QList<int>& board){
+    //numbered
+    if( m_captureInfo[countCaptureIndex].second[0] == GameInfo::NUMBER){
+        //Check whether the cup has necessary stone to capture
+        for(int i = 1; i<m_captureInfo[countCaptureIndex].second.count();i++){
+            if(m_captureInfo[countCaptureIndex].second[i] == board[index]){
+//                if(m_physicalMoveAllowed) kDebug() << "Index: " << index << " Stone:" << board[index];
+                return true;
+            }
+        }
+//        if(m_physicalMoveAllowed) kDebug() << "Returning false";
+        return false;
+    }
+    //pattern
+    else{
+//        if(m_physicalMoveAllowed) kDebug() << "I am in pattern";
+        //Even Pattern
+        if(m_captureInfo[countCaptureIndex].second[1] == GameInfo::EVEN){
+            if( board[index] % 2 == 0 && board[index] != 0){
+//                if(m_physicalMoveAllowed) kDebug() << "Index: " << index << " Stone:" << board[index];
+                return true;
+            }
+        }
+        //Odd Pattern
+        else{
+            if(board[index] % 2)
+                return true;
+        }
+
+        return false;
+    }
+}
+
+
+int GameController::nextIndex(int index,int seriesCaptureIndex){
+    //We have to go back
+
+    if(m_captureInfo[seriesCaptureIndex].second[0] == GameInfo::FOLLOWING){
+
+        if(m_rotationInfo == GameInfo::CLOCKWISE){
+            if(index == 0){
+                index = 2 * m_gameInfo->numCupsPerRow() - 1;
+                return index;
+            }
+
+            else{
+                index = index-1;
+                return index;
+            }
+        }
+        else{
+            index = (index+1) % ( 2 * m_gameInfo->numCupsPerRow() );
+            return index;
+        }
+    }
+    //we will go forward
+    else{
+
+        if(m_rotationInfo == GameInfo::CLOCKWISE){
+            index = (index + 1) % ( 2 * m_gameInfo->numCupsPerRow() );
+            return index;
+        }
+
+        else{
+            if(index == 0){
+                index = 2 * m_gameInfo->numCupsPerRow() - 1;
+                return index;
+            }
+            else{
+                index = index - 1;
+                return index;
+            }
+        }
+    }
+}
+
+//-------------------------------------capture handling ends---------------------------
+
+void GameController::changeScore(int amount,bool human){
+    if(human){
+        m_humanScore->changeScore(amount);
+        emit signalShowScore(m_humanScore->score(),true);
+    }
+    else{
+        m_computerScore->changeScore(amount);
+        emit signalShowScore(m_computerScore->score(),false);
+    }
+}
+
+//Human Has no move, now what
+void GameController::humanHasNoMove(){
+
+    if(m_gameOver) return;
+    int check = m_gameInfo->specialFlag();
+    if(m_physicalMoveAllowed) emit signalMessage( tr("No Move human") );
+
+    if( check & 2){//turn passing
+        if(m_physicalMoveAllowed) changeTurn();
+        else m_humanTurn = !m_humanTurn;
+
+        if(m_physicalMoveAllowed) makeComputerMove();
+    }
+    else{
+        if(m_physicalMoveAllowed) finalCapture(m_physicalBoard);
+        else finalCapture(m_logicalBoard);
+    }
+}
+
+//computer has no move, now what
+void GameController::computerHasNoMove(){
+    // Special Flag - 0(empty Opponent),1(turn Passing),2(Compulsory Moves)
+    if(m_gameOver) return;
+    int check = m_gameInfo->specialFlag();
+    if(m_physicalMoveAllowed) emit signalMessage( tr("No Move Computer") );
+
+    if( check & 2){//turn passing
+        if(m_physicalMoveAllowed) changeTurn();
+        else m_humanTurn = !m_humanTurn;
+    }
+    else{
+        if(m_physicalMoveAllowed) finalCapture(m_physicalBoard);
+        else finalCapture(m_logicalBoard);
+    }
+}
+
+//when one has no move, this is called on condition
+void GameController::finalCapture(QList<int>& board){
+
+    int loop;
+
+    //capture from human side to humanKalah
+    for( int i = 0 ; i < m_humanSideCups.count() ; i++){
+        int index = m_humanSideCups[i];
+
+        //Going to Human Kalah
+        if(board[index]){
+            loop = board[index];
+            for(int i = 0 ; i < loop ; i++){
+                if(m_physicalMoveAllowed) m_board->updateChildren(index,m_humanKalah,false);
+                board[index]--;
+                board[m_humanKalah + 2*m_gameInfo->numCupsPerRow()]++;
+                if(m_physicalMoveAllowed) changeScore(1,true);
+            }
+        }
+        //Going to Computer kalah
+        if(board[2*m_gameInfo->numCupsPerRow() - 1 - index]){
+            loop = board[2*m_gameInfo->numCupsPerRow() - 1 - index];
+            for(int i = 0 ; i < loop ; i++){
+                if(m_physicalMoveAllowed)  m_board->updateChildren(2*m_gameInfo->numCupsPerRow() - 1 - index,1-m_humanKalah,false);
+                board[2*m_gameInfo->numCupsPerRow() - 1 - index]--;
+                board[1-m_humanKalah + 2*m_gameInfo->numCupsPerRow()]++;
+                if(m_physicalMoveAllowed) changeScore(1,false);
+            }
+        }
+
+    }
+
+    if(m_physicalMoveAllowed){
+        m_gameOver = true;
+        emit signalGameOver();
+    }
+}
+
+//----------------------------------------------------------------------------------------
+
+
+QPair< bool,QList<int> > GameController::logicalMoveController(QList<int>board,int index,bool turn){
+
+    bool tempTurn = m_humanTurn; //storing turn of physical board
+    m_physicalMoveAllowed = false; //setting physical move as invalid
+
+    bool humanTurn = !turn; //next turn should be other(if not bonus move)
+    m_humanTurn = turn;    //current board status, turn of parent node
+    setLogicalBoard(board);
+
+    //sowing
+    index = singleSow(index);
+
+    if(m_gameInfo->lapStyle() == GameInfo::MULTIPLE){
+        while(!isEndOfLap(index,m_logicalBoard)){
+            index = singleSow(index);
+        }
+    }
+
+
+    //If bonus turn do not change turn
+    if(m_gameInfo->isBonusTurn()){
+
+        if(index >= 2*m_gameInfo->numCupsPerRow()){   //is a kalah
+            //kDebug() << "A Bonus Turn:";
+            if(m_humanTurn && isHumanKalah(index)){
+                humanTurn = true;
+            }
+            else if(!m_humanTurn && !isHumanKalah(index)){
+                humanTurn = false;
+            }
+
+        }
+    }
+
+    handleCrossCapture(index,m_logicalBoard);
+    handleCountNSeriesCapture(index,m_logicalBoard);
+
+    if(isHumanSideEmpty(m_logicalBoard))
+        humanHasNoMove();
+    else if(isComputerSideEmpty(m_logicalBoard))
+        computerHasNoMove();
+
+    m_humanTurn = tempTurn; //restoring m_humanTurn
+    m_physicalMoveAllowed = true;
+    return qMakePair(humanTurn,m_logicalBoard);
+
+}
+
+void GameController::setPhysicalBoard(QList<int> board){
+    for(int i = 0 ; i < m_physicalBoard.count() ; i++)
+        m_physicalBoard[i] = board[i];
+}
+
+
+void GameController::setLogicalBoard(QList<int> board){
+    for(int i = 0 ; i < m_logicalBoard.count() ; i++)
+        m_logicalBoard[i] = board[i];
+}
+
+QList<int> GameController::logicalBoard(){ return m_logicalBoard;}
+QList<int> GameController::physicalBoard(){return m_physicalBoard;}
+
+//----------------------------------------------------------------------------------------
+#include "moc_GameController.cpp"