//------------------------------------------------------------------------------ // public: //------------------------------------------------------------------------------ void Game::init() { HGE * hge( Engine::hge() ); b2World * b2d( Engine::b2d() ); hgeResourceManager * rm( Engine::rm() ); ViewPort * vp( Engine::vp() ); Engine::em()->init(); vp->offset().x = 0.0f; vp->offset().y = 0.0f; vp->centre().x = 0.0f; vp->centre().y = 0.0f; vp->bounds().x = 1280.0f; vp->bounds().y = 720.0f; vp->setAngle( 0.0f ); vp->setScale( 10.0f ); clearArena(); clearPiece(); m_index = 0; m_rotate = 0; m_col = 6; m_row = 1; m_num = 0; m_replaying = false; m_timer = 0.0f; }
void CChessGame :: initGame(const char *fenString, BOOL createChessmenList, PLAYER_TYPE white, PLAYER_TYPE black) { INT16 i, j, k, l; char FEN[FEN_STRING_LENGTH]; char *fenToken; strncpy(FEN, fenString, FEN_STRING_LENGTH); FEN[FEN_STRING_LENGTH-1] = '\0'; //cleanupLists(); fenToken = strtok(FEN, " /"); for(i = MAXY-1; i >= 0; i--) { for(j = 0, k = 0; j < MAXX; j++, k++) { if(fenToken[k] >= '1' && fenToken[k] <= '8') { for(l = 0; l < fenToken[k] - '0'; l++) { clearPiece(BOARD_POSITION(i, j + l)); } j += (fenToken[k] - '1'); continue; } if(isalpha(fenToken[k])) { insertPiece(BOARD_POSITION(i,j), strToPiece(fenToken[k])); } } fenToken = strtok(NULL, " /"); } gState.gameProgress = GP_IN_PROGRESS; if(createChessmenList == TRUE) { generateChessmenList(); } playerType[MT_WHITE] = white; playerType[MT_BLACK] = black; if(fenToken == NULL) { return; } if(fenToken[0] == 'w') gState.turn = MT_WHITE; else gState.turn = MT_BLACK; // castling and other info forbid castling by default gState.wKingMoved = TRUE; gState.bKingMoved = TRUE; gState.wRCastleMoved = TRUE; gState.wLCastleMoved = TRUE; gState.bRCastleMoved = TRUE; gState.bLCastleMoved = TRUE; fenToken = strtok(NULL, " "); if(fenToken == NULL) { return; } if(fenToken[0] == '-') { //all set } else { for(i = 0; i < (INT8)strlen(fenToken); i++) { if(fenToken[i] == 'K') { if(game.board[0][4] == W_KING && game.board[0][7] == W_CASTLE) { gState.wKingMoved = FALSE; gState.wRCastleMoved = FALSE; } } else if(fenToken[i] == 'Q') { if(game.board[0][4] == W_KING && game.board[0][0] == W_CASTLE) { gState.wKingMoved = FALSE; gState.wLCastleMoved = FALSE; } } else if(fenToken[i] == 'k') { if(game.board[7][4] == B_KING && game.board[7][7] == B_CASTLE) { gState.bKingMoved = FALSE; gState.bRCastleMoved = FALSE; } } else if(fenToken[i] == 'q') { if(game.board[7][4] == B_KING && game.board[7][0] == B_CASTLE) { gState.bKingMoved = FALSE; gState.bLCastleMoved = FALSE; } } } } //enp square fenToken = strtok(NULL, " "); if(fenToken == NULL) { return; } else { //if movelist is empty add the pawn move in the movelist so that enpassent capture can take place while(*fenToken == ' ') fenToken++; if(moveList.getTail() == NULL && fenToken[0] != '-') { INT8 beginning = (fenToken[1] - '1') > 3 ? 6 : 1; INT8 end = beginning == 6 ? 4 : 3; INT8 packPos; MOVELIST *mList; CZobrist zob; mList = newMoveListEntry(); mList->init = BOARD_POSITION(beginning, fenToken[0]-'a'); mList->dest = BOARD_POSITION(end, fenToken[0]-'a'); strncpy(mList->FEN, fenString, FEN_STRING_LENGTH); mList->FEN[FEN_STRING_LENGTH-1] = '\0'; mList->seqNum = 0; mList->status = MOVE_SUCCESS | MOVE_EN_PASSENT_ACTIVE; packPos = PACKPOS((fenToken[0]-'a'), (fenToken[1]-'1')); mList->status |= (packPos << 24); zob.updateBoardPosition(fenString); zob.calculateZobristHash(); mList->zobristHash = zob.getZobristHash(); moveList.insertAtTail((DLL_NODE *)mList); } } //half move count fenToken = strtok(NULL, " "); if(fenToken == NULL) { return; } gState.draw50HalfMoveCount = atoi(fenToken); return; }
STATUS CChessGame :: makeMove(BOARD_POSITION init, BOARD_POSITION dest, CHESSPIECE_GENERAL newCp, STATUS status) { MOVELIST *mList; CHESSMENLIST temp, *cList; CAPTUREDLIST *captList; CHESSPIECE oldPiece, userPiece, initPiece; INT8 moveDir = (dest.x > init.x) ? 1 : -1; UINT8 castleBase = (moveDir > 0) ? 7 : 0; UINT8 packPos = 0; BOOL castlingRightsChanged = FALSE; //printf("\n\nMaking Move.... "); if(!(status & MOVE_SUCCESS)) { //printf("Illegal move! \n\n"); return ERROR; } //printf("Success!! \n\n"); initPiece = getPiece(init); if(status & MOVE_EN_PASSENT) { oldPiece = getPiece(BOARD_POSITION(init.y, dest.x)); } else { oldPiece = getPiece(dest); } status |= (oldPiece << 16); if(status & MOVE_EN_PASSENT_ACTIVE) { packPos = PACKPOS(dest.x, ((init.y + dest.y)/2)); status |= (packPos << 24); } if(status & MOVE_PAWN_PROMOTED) { userPiece = CHESSPIECE(MAKE_CHESSMEN(getCurrentTurn(), newCp)); insertPiece(dest, userPiece); status |= (userPiece << 24); } else { insertPiece(dest, initPiece); } clearPiece(init); if(status & MOVE_CASTLING) { insertPiece(BOARD_POSITION(dest.y, dest.x - moveDir), getPiece(BOARD_POSITION(init.y, castleBase))); clearPiece(BOARD_POSITION(init.y, castleBase)); } if(status & MOVE_EN_PASSENT) { clearPiece(BOARD_POSITION(init.y, dest.x)); } /* Update the following figures for use for castling.. * Lets make things simple... dont even look for the pieces in the positions. * Just mark the pieces as moved if the init pos of a valid move matches them */ if(memcmp(&init, &wKingPos, sizeof(BOARD_POSITION)) == 0) { gState.wKingMoved = TRUE; if(gState.wKingMoved == FALSE) castlingRightsChanged = TRUE; if(status & MOVE_CASTLING) /* not useful... just for completeness sake */ { if(moveDir > 0) { gState.wRCastleMoved = TRUE; } else { gState.wLCastleMoved = TRUE; } } } else if(memcmp(&init, &bKingPos, sizeof(BOARD_POSITION)) == 0) { gState.bKingMoved = TRUE; if(gState.bKingMoved == FALSE) castlingRightsChanged = TRUE; if(status & MOVE_CASTLING) /* just 4 completeness */ { if(moveDir > 0) gState.bRCastleMoved = TRUE; else gState.wLCastleMoved = TRUE; } } else if(memcmp(&init, &wLCastlePos, sizeof(BOARD_POSITION)) == 0 || memcmp(&dest, &wLCastlePos, sizeof(BOARD_POSITION)) == 0) { if(gState.wLCastleMoved == FALSE) castlingRightsChanged = TRUE; gState.wLCastleMoved = TRUE; } else if(memcmp(&init, &wRCastlePos, sizeof(BOARD_POSITION)) == 0 || memcmp(&dest, &wRCastlePos, sizeof(BOARD_POSITION)) == 0) { if(gState.wRCastleMoved == FALSE) castlingRightsChanged = TRUE; gState.wRCastleMoved = TRUE; } else if(memcmp(&init, &bLCastlePos, sizeof(BOARD_POSITION)) == 0 || memcmp(&dest, &bLCastlePos, sizeof(BOARD_POSITION)) == 0) { if(gState.bLCastleMoved == FALSE) castlingRightsChanged = TRUE; gState.bLCastleMoved = TRUE; } else if(memcmp(&init, &bRCastlePos, sizeof(BOARD_POSITION)) == 0 || memcmp(&dest, &bRCastlePos, sizeof(BOARD_POSITION)) == 0) { if(gState.bRCastleMoved == FALSE) castlingRightsChanged = TRUE; gState.bRCastleMoved = TRUE; } if(CHESSPIECE_TYPE(initPiece) != PAWN && !(status & MOVE_CAPTURE_PIECE)) { gState.draw50HalfMoveCount++; } else { gState.draw50HalfMoveCount = 0; } if(status & MOVE_CAPTURE_PIECE) { if(status & MOVE_EN_PASSENT) { temp.data = BOARD_POSITION(init.y, dest.x); } else { temp.data = dest; } /* remove the captured piece from the chessmen list and add it to the captured pieces list */ cList = (CHESSMENLIST *)chessmenList[CHESSPIECE_COLOR(oldPiece)].removeNode((DLL_NODE *)&temp); deleteChessmenListEntry(cList); captList = newCapturedListEntry(); captList->piece = oldPiece; capturedPiecesList[CHESSPIECE_COLOR(oldPiece)].insertAtTail((DLL_NODE *)captList); } temp.data = init; cList = (CHESSMENLIST *)chessmenList[CHESSPIECE_COLOR(getPiece(dest))].findNode((DLL_NODE *)&temp); if(NULL != cList) { cList->data = dest; } if(status & MOVE_CASTLING) { temp.data = BOARD_POSITION(init.y, castleBase); cList = (CHESSMENLIST *)chessmenList[CHESSPIECE_COLOR(getPiece(dest))].findNode((DLL_NODE *)&temp); if(NULL != cList) { cList->data = BOARD_POSITION(dest.y, dest.x - moveDir); } } if(status & MOVE_CAPTURE_PIECE || CHESSPIECE_TYPE(initPiece) == PAWN || castlingRightsChanged == TRUE) { gState.seqNum = (gState.seqNum + 1) & 0xff; } mList = newMoveListEntry(); mList->init = init; mList->dest = dest; mList->status = status; mList->seqNum = gState.seqNum; mList->SAN[0] = '\0'; moveList.insertAtTail((DLL_NODE *)mList); return OK; }
//------------------------------------------------------------------------------ bool Game::update( float dt ) { const Controller & pad( Engine::instance()->getController() ); HGE * hge( Engine::hge() ); ViewPort * vp( Engine::vp() ); if ( Engine::instance()->isPaused() ) { return false; } if ( m_replaying ) { m_timer += dt; if ( m_timer < 0.2f ) { return false; } if ( m_row == 1 ) { if ( m_num == 0 ) { m_replaying = false; } else { --m_num; m_index = m_replay[m_num][0]; m_rotate = m_replay[m_num][1]; m_col = m_replay[m_num][3]; ++m_row; } } else { ++m_row; } } else if ( pad.isConnected() ) { if ( pad.buttonDown( XPAD_BUTTON_BUTTON_Y ) ) { m_replaying = true; m_row = 1; clearArena(); } if ( pad.buttonDown( XPAD_BUTTON_X ) ) { m_index = ( m_index + 6 ) % 7; } if ( pad.buttonDown( XPAD_BUTTON_B ) ) { m_index = ( m_index + 1 ) % 7; } if ( pad.buttonDown( XPAD_BUTTON_LEFT_SHOULDER ) ) { m_rotate = ( m_rotate + 3 ) % 4; } if ( pad.buttonDown( XPAD_BUTTON_RIGHT_SHOULDER ) ) { m_rotate = ( m_rotate + 1 ) % 4; } if ( pad.buttonDown( XPAD_BUTTON_DPAD_UP ) ) { m_row = ( m_row + 22 ) % 23; } if ( pad.buttonDown( XPAD_BUTTON_DPAD_DOWN ) ) { m_row = ( m_row + 1 ) % 23; } if ( pad.buttonDown( XPAD_BUTTON_DPAD_LEFT ) ) { m_col = ( m_col + 12 ) % 13; } if ( pad.buttonDown( XPAD_BUTTON_DPAD_RIGHT ) ) { m_col = ( m_col + 1 ) % 13; } } else { if ( Engine::hge()->Input_KeyDown( HGEK_R ) ) { m_replaying = true; m_row = 1; clearArena(); } if ( Engine::hge()->Input_KeyDown( HGEK_A ) ) { m_index = ( m_index + 6 ) % 7; } if ( Engine::hge()->Input_KeyDown( HGEK_D ) ) { m_index = ( m_index + 1 ) % 7; } if ( Engine::hge()->Input_KeyDown( HGEK_W ) ) { m_rotate = ( m_rotate + 3 ) % 4; } if ( Engine::hge()->Input_KeyDown( HGEK_S ) ) { m_rotate = ( m_rotate + 1 ) % 4; } if ( Engine::hge()->Input_KeyDown( HGEK_UP ) ) { m_row = ( m_row + 22 ) % 23; } if ( Engine::hge()->Input_KeyDown( HGEK_DOWN ) ) { m_row = ( m_row + 1 ) % 23; } if ( Engine::hge()->Input_KeyDown( HGEK_LEFT ) ) { m_col = ( m_col + 12 ) % 13; } if ( Engine::hge()->Input_KeyDown( HGEK_RIGHT ) ) { m_col = ( m_col + 1 ) % 13; } } clearPiece(); for ( int i = 0; i < 8; i += 2 ) { int x( PIECE[m_index][i] ), y( PIECE[m_index][i+1] + 1 ); for ( int j = 0; j < m_rotate; ++j ) { b2Swap( x, y ); y = 3 - y; } m_piece[x][y]= true; } for ( int x = 0; x < 10; ++x ) { for ( int y = 0; y < 20; ++y ) { m_buffer[x][y] = m_arena[x][y]; } } if ( m_replaying ) { if ( m_row == m_replay[m_num][2] ) { m_row = 1; for ( int y = 0; y < 4; ++y ) { for ( int x = 0; x < 4; ++x ) { if ( ! m_piece[x][y] ) { continue; } m_arena[m_col + x - 3][m_row + y - 3] = true; } } } return false; } checkBorders(); // If the piece has space beneath it, then fall down until we either hit the // bottom or there is something below us. while( ! checkBottom() && blankBelow() ) { m_row += 1; } // Add rows, starting at the bottom, to accomodate the piece addRows(); // If the user presses the button, check if the piece has nothing blocking // it above. If it doesn't, remove it. if ( pad.isConnected() ) { if ( pad.buttonDown( XPAD_BUTTON_A ) ) { removePiece(); } } else { if ( Engine::hge()->Input_KeyDown( HGEK_SPACE ) ) { removePiece(); } } return false; }