Esempio n. 1
0
void GameSession::black_requestsTakeback()
{
   if(game_.position().moveNumber()>1)
   {
      ChessCoord prevCursorPos;
      unsigned nmoves = game_.moves().size();
      if(nmoves>=2)
         prevCursorPos = game_.moves()[nmoves-2].from;
      //
      bool accept = false;
      whitePlayer_->opponentRequestsTakeback(accept);
      //
      if(accept)
      {
         game_.takebackOneFullMove();
         updateSessionInfo();
         //
         g_localChessGui.dropLastFullMove();
         g_localChessGui.setInitialMoveCursorPos(prevCursorPos);
         g_localChessGui.updatePosition(game_.position(),
            game_.lastMove(), game_.possibleMoves());
         updateCapturedPieces();
         //updateClockDisplay();
      }
   }
   requestMove(blackPlayer_);
}
Esempio n. 2
0
void GameSession::black_moves(const ChessMove& move)
{
   if(game_.position().sideToMove()!=pcBlack)
   {
      assert(false);
      // report error: attempt to move out of turn
      return;
   }
   //
   if(!game_.applyMove(move))
   {
      blackPlayer_->illegalMove();
      g_localChessGui.showSessionMessage(g_msg("IllegalMove").arg(move.toString().c_str()));
      requestMove(blackPlayer_);
   }
   else
   {
      updateSessionInfo();
      //
      if(whiteDrawOfferActive_)
      {
         whitePlayer_->opponentRejectsDraw();
      }
      //
      if(game_.position().moveNumber()==2)
      {
         enableInGameCommands();
      }
      //
      blackDrawOfferActive_ = false;
      //
      blackClock_.remainingTime += blackClock_.moveIncrement;
      //
      outputLastMove();
      //updateClockDisplay();
      g_localChessGui.updatePosition(game_.position(), game_.lastMove(),
                                     game_.possibleMoves());
      updateCapturedPieces();
      //
      whitePlayer_->opponentMoves(move);
      if(game_.result()==resultNone && whiteClock_.remainingTime > 0)
      {
         requestMove(whitePlayer_);
      }
   }
}
Esempio n. 3
0
void Game::start()
{
    if (!white_ && !black_)
        throw NoPlayersSet();
    else if (!white_ || !black_)
        throw OnlyOnePlayerSet();
    currentPlayer_ = white_.get();
    gameState_->currentMove = 1;
    gameState_->currentPlayer = currentPlayer_->type();
    requestMove();
}
Esempio n. 4
0
void Game::prepareNextMoveRequest()
{
    switchCurrentPlayer();
    GameResult result;
    if (GameResult::ONGOING != (result = gameStateIndicator_->indicateGameEnd(
        gameState_->currentPlayer, gameState_->currentBoard)))
    {
        endGame(result);
        return;
    }
    requestMove();
}
Esempio n. 5
0
void GameSession::black_requestsAbort()
{
   bool accepted = true;
   if(game_.position().moveNumber()>1)
      whitePlayer_->opponentRequestsAbort(accepted);
   if(accepted)
   {
      endGame(reasonGameAborted, resultNone);
   }
   else
   {
      requestMove(blackPlayer_);
   }
}
Esempio n. 6
0
void Game::receiveMove(const Move& move)
{
    if (validator_->validate(move, currentPlayer_->type()))
    {
        currentPlayer_->responseAck(true);
        if (!applyMove(move))
            return;

        prepareNextMoveRequest();
    }
    else
    {
        currentPlayer_->responseAck(false);
        requestMove();
    }
}
Esempio n. 7
0
Controller::Controller(sf::Window &theWindow, sfg::Desktop &theDesktop, CallbackSystem &callbackSystem):
    desktop(theDesktop),
    boardWindow(sfg::Window::Create(sfg::Window::BACKGROUND)),
    settingsButton(sfg::Button::Create("Settings")),
    canvas(theWindow),
    m_whiteClock(Clock::Create()),
    m_blackClock(Clock::Create()),
    settingsWindow(desktop),
    premove({{0,0},{0,0}}), premoveOn(false),
    netWindow(m_currentEvent),
    player1(sfg::Label::Create()),
    player2(sfg::Label::Create())
{
    boardWindow->SetRequisition(static_cast<sf::Vector2f>(theWindow.getSize()));

    canvas.requestMove.connect(boost::bind(&Controller::requestMove, this,_1));
    settingsWindow.settingsDone.connect([this](const PieceToTexPos& pieceToTexPos){
        settingsWindow.enable(false);
        canvas.setPieceColors(pieceToTexPos);
    });
    messages.connect(Messages::ID::TextReady, [this](const Messages::Message& message){
        auto received = boost::polymorphic_downcast<const Messages::TextReady*>(&message);
        netWindow.addLine(received->text);
    });

    ButtonBox buttons;
    buttons.flip->GetSignal(sfg::Button::OnLeftClick).Connect(std::bind(&Canvas::flipBoard, &canvas));
    buttons.settings->GetSignal(sfg::Button::OnLeftClick).Connect([]{
        //settingsWindow.enable(true);
    });
    buttons.resign->GetSignal(sfg::Button::OnLeftClick).Connect([this]{
        messages.triggerEvent(Messages::TextToClient("resign"));
    });
    buttons.draw->GetSignal(sfg::Button::OnLeftClick).Connect([this]{
        messages.triggerEvent(Messages::TextToClient("draw"));
    });

    auto promotionLayout = sfg::Box::Create(sfg::Box::Orientation::VERTICAL);
    auto promotionGroup = sfg::RadioButtonGroup::Create();

    auto createPromotionButton = [this, promotionGroup, promotionLayout](const std::string& name, char letter){
        auto promotionButton = sfg::RadioButton::Create(name, promotionGroup);
        promotionLayout->Pack(promotionButton);
        promotionButton->GetSignal(sfg::ToggleButton::OnToggle).Connect([this, promotionButton, letter]{
            if (promotionButton->IsActive()){
                std::string promote("promote ");
                promote += letter;
                messages.triggerEvent(Messages::TextToClient(promote));
            }
        });
        return promotionButton;
    };

    auto promotionQueen = createPromotionButton("Queen", 'q');
    createPromotionButton("Bishop", 'b');
    createPromotionButton("Knight", 'n');
    createPromotionButton("Rook", 'r');

    auto promotionFrame = sfg::Frame::Create("Promotion");
    promotionFrame->Add(promotionLayout);

    auto sideLayout = sfg::Box::Create(sfg::Box::Orientation::VERTICAL);

    sideLayout->Pack(player1);
    sideLayout->Pack(m_whiteClock);
    sideLayout->Pack(player2);
    sideLayout->Pack(m_blackClock);
    sideLayout->Pack(status.getView());

    sfg::Table::Ptr mainLayout(sfg::Table::Create());
    mainLayout->SetRowSpacings(2.f);
    mainLayout->SetColumnSpacings(2.f);
    mainLayout->Attach(canvas.getBoardWidget(),{0, 0, 3, 2},sfg::Table::EXPAND, sfg::Table::EXPAND, sf::Vector2f( 10.f, 0.f ));
    mainLayout->Attach(promotionFrame, {0, 2, 1, 1});
    mainLayout->Attach(sideLayout, {3,0, 3, 1});
    mainLayout->Attach(moveList.getView(),{3, 1, 3, 3});
    mainLayout->Attach(buttons.layout,{0,4,6,1});

    desktop.Add(settingsWindow.getWidget());

    sfg::Notebook::Ptr notebook(sfg::Notebook::Create());
    notebook->AppendPage(mainLayout,sfg::Label::Create("Board"));
    notebook->AppendPage(netWindow.getWidget(),sfg::Label::Create("Server"));
    notebook->GetSignal(sfg::Notebook::OnTabChange).Connect([this]{
        netWindow.grabEntryFocus();
    });

    callbackSystem.connect(Action::Tab, [notebook](thor::ActionContext<Action> context){
        if (context.event->key.control){
            if (context.event->key.shift)
                notebook->PreviousPage();
            else
                notebook->NextPage();
        }
    });

    boardWindow->Add(notebook);

    desktop.Add(boardWindow);

    buttons.connect->GetSignal(sfg::Button::OnLeftClick).Connect([this, notebook]{
        client.connect();
        notebook->SetCurrentPage(1);
    });

    messages.connect(Messages::ID::GameState, [this](const Messages::Message& message){
        auto received = boost::polymorphic_downcast<const Messages::GameState*>(&message);
        m_whiteClock->setTimeLeft(received->white_time);
        m_blackClock->setTimeLeft(received->black_time);
        if (received->turnColor == Color::White){
            m_blackClock->stop();
            m_whiteClock->start();
        }else{
            assert(received->turnColor==Color::Black);
            m_whiteClock->stop();
            m_blackClock->start();
        }


        if (premoveOn)
        {
            premoveOn = false;
            canvas.clearArrows();
            requestMove(premove);
        }
    });

    messages.connect(Messages::ID::GameStart, [this, promotionQueen, notebook](const Messages::Message& message){
        auto received = boost::polymorphic_downcast<const Messages::GameStart*>(&message);
        player1->SetText(received->p1);
        player2->SetText(received->p2);
        premoveOn = false;
        promotionQueen->SetActive(true);
        updateClocks();
        notebook->SetCurrentPage(0);
    });

    messages.connect(Messages::ID::GameEnd, [this](const Messages::Message&){
        //auto received = boost::polymorphic_downcast<const EndGameMessage*>(&message);
        premoveOn = false;
        canvas.clearArrows();
        m_whiteClock->stop();
        m_blackClock->stop();
    });

    callbackSystem.connect(Action::Scroll, [this](thor::ActionContext<Action> context){
        int delta = context.event->mouseWheelScroll.delta;
        netWindow.scroll(delta);
    });
}
Esempio n. 8
0
void GameSession::startGame()
{
   whiteClock_ = sessionInfo_.profile.whiteClock;
   blackClock_ = sessionInfo_.profile.blackClock;
   //
   if(whiteClock_.untimed)
   {
      whiteClock_.initialTime = 10*60*1000;
      whiteClock_.remainingTime = whiteClock_.initialTime;
      whiteClock_.moveIncrement = 0;
   }
   //
   if(blackClock_.untimed)
   {
      blackClock_.initialTime = 10*60*1000;
      blackClock_.remainingTime = blackClock_.initialTime;
      blackClock_.moveIncrement = 0;
   }
   //
   g_localChessGui.beginGame(whitePlayer_->name(), blackPlayer_->name(),
                             sessionInfo_.profile, !sessionInfo_.moves.empty());
   //
   whitePlayer_->beginGame(pcWhite, blackPlayer_->name(), whiteClock_);
   blackPlayer_->beginGame(pcBlack, whitePlayer_->name(), blackClock_);
   //
   game_.start(sessionInfo_.initialPosition); // start from the given initial position
                                              // default position for standard chess
                                              // but may be different for chess960
   //
   whitePlayer_->setInitialPosition(game_.position());
   blackPlayer_->setInitialPosition(game_.position());
   //
   if(!sessionInfo_.moves.empty())
   {
      // replay moves one by one
      //
      std::vector<ChessMove>::const_iterator it = sessionInfo_.moves.begin(),
                                             itEnd = sessionInfo_.moves.end();
      for(;it!=itEnd;++it)
      {
         whitePlayer_->replayMove(*it);
         blackPlayer_->replayMove(*it);
         //
         bool moveOk = game_.applyMove(*it);
         //
         assert(moveOk);
      }
   }
   //
   if(game_.result()!=resultNone)
   {
      // a game end signal has come while replaying moves
      return;
   }
   //
   if(game_.position().moveNumber()>=2)
   {
      enableInGameCommands();
   }
   //
   if(!game_.moves().empty())
   {
      if(g_settings.useRussianNotation())
         g_localChessGui.appendToMoveList(game_.ruMoves());
      else
         g_localChessGui.appendToMoveList(game_.sanMoves());
   }
   //
   // finished setting up position, can actually start the game
   //
   g_localChessGui.updatePosition(game_.position(), game_.lastMove(), game_.possibleMoves());
   updateCapturedPieces();
   //updateClockDisplay();
   //
   counter_.restart();
   //
   clockUpdateTimer_.setInterval(cClockUpdateInterval);
   clockUpdateTimer_.setSingleShot(false);
   clockUpdateTimer_.start();
   //
   if(game_.position().sideToMove()==pcWhite)
      requestMove(whitePlayer_);
   else
      requestMove(blackPlayer_);
   //
}