int main(int argc, char* argv[]){ displayMode = CONSOLE; if(argc>1){ if (str_equals(argv[1], "gui")){ displayMode = GUI; } } int initializationError = initialize(); if (initializationError == 1){ // allocation error occured allocationFailed(); } else if (initializationError == 2){ // SDL failed to initialize exit(0); } display(); while (1){ if (isEndGame()){ if (displayMode == CONSOLE){ break; } else{ gameEnded = 1; } } if (turn != player1 && gameMode == SINGLE_PLAYER_MODE && !gameEnded){ if (computerTurn()){ allocationFailed(); } } else{ short error = humanTurn(turn); if (error != 0 && error != 2){ //error occured or "start" command entered return error; } } } if (displayMode == CONSOLE){ printEndGameResults(); } return 0; }
STATUS CChessGame :: playMoveOnBoard(BOARD_POSITION init, BOARD_POSITION dest, CHESSPIECE_GENERAL newCp, MOVE_CLAIM mClaim = CLAIM_NONE) { STATUS status; CHECK_STATUS cStatus; MOVELIST *mList, *tempList; CZobrist zob; UINT64 currentHash; UINT8 count = 1, currentSeqNum; status = validateMove(init, dest, MVT_GENERAL); if((status & MOVE_PAWN_PROMOTED) && newCp == CHESSPIECE_TYPE(INVALID_CHESSPIECE)) { //pawn promotion should provide new piece also if(playerType[gState.turn] != PT_COMPUTER) { newCp = getNewPieceFromUser(); } else { status = MOVE_ILLEGAL; } } if(status & MOVE_SUCCESS) { (void)makeMove(init, dest, newCp, status); mList = (MOVELIST *)moveList.getTail(); if(mList != NULL) { //status must have got updated after makemove... status = mList->status; cStatus = scan4Check(init, dest, CHECK); if(isEndGame()) { if(cStatus == CHECK) { status |= MOVE_CHECKMATE; //printf("Checkmate\n"); } else { status |= MOVE_STALEMATE; //printf("Stalemate\n"); } } else if(cStatus == CHECK) { status |= MOVE_CHECK; //printf("Itz a check!!\n"); } /* Form the SAN notation for the MOVE */ mList->status = status; //This is needed for SAN (void)updateCANString(mList); (void)updateSANString(mList, TRUE); (void)updateFENString(mList->FEN); //check if 50 move repetition happened if(gState.draw50HalfMoveCount >= 50) { mList->status |= MOVE_DRAW_50MOVE_ACTIVE; } //check for insufficient material draw tempList = (MOVELIST *)moveList.getPrev((DLL_NODE *)mList); if((tempList != NULL && tempList->status & MOVE_DRAW_INSUFFICIENT_PIECES_ACTIVE) || insufficientMatingMaterial(getLastFENString()) == TRUE) { mList->status |= MOVE_DRAW_INSUFFICIENT_PIECES_ACTIVE; } // Update zobrist Hash zob.updateBoardPosition(getLastFENString()); zob.calculateZobristHash(); mList->zobristHash = zob.getZobristHash(); currentHash = mList->zobristHash; currentSeqNum = gState.seqNum; //check if 3 move repetition happened for(tempList = (MOVELIST *)moveList.getPrev((DLL_NODE *)mList); tempList != NULL; tempList = (MOVELIST *)moveList.getPrev((DLL_NODE *)tempList)) { if(tempList->seqNum != currentSeqNum) { break; } if(tempList->zobristHash == currentHash) { //add more detailed check using FEN string if required count++; } if(count == 3) { break; } } if(count == 3) { mList->status |= MOVE_DRAW_3MOVE_ACTIVE; } status = mList->status; } toggleTurn(); } return status; }
STATUS CChessGame :: makeGeneratedMove(MOVELIST move) { STATUS status; CHECK_STATUS cStatus; MOVELIST *mList, *tempList; UINT64 currentHash; UINT8 count = 1, currentSeqNum; CZobrist zob; CHESSPIECE_GENERAL newCp = CHESSPIECE_GENERAL(CHESSPIECE_TYPE((move.status >> 24))); status = makeMove(move.init, move.dest, newCp, move.status); mList = (MOVELIST *)moveList.getTail(); if(mList != NULL) { cStatus = scan4Check(move.init, move.dest, CHECK); if(isEndGame()) { if(cStatus == CHECK) { status |= MOVE_CHECKMATE; //printf("Checkmate\n"); } else { status |= MOVE_STALEMATE; //printf("Stalemate\n"); } } else if(cStatus == CHECK) { status |= MOVE_CHECK; //printf("Itz a check!!\n"); } /* Form the SAN notation for the MOVE */ mList->status = status; //This is needed for SAN (void)updateCANString(mList); (void)updateSANString(mList, TRUE); (void)updateFENString(mList->FEN); //check if 50 move repetition happened if(gState.draw50HalfMoveCount >= 50) { mList->status |= MOVE_DRAW_50MOVE_ACTIVE; } //check for insufficient material draw tempList = (MOVELIST *)moveList.getPrev((DLL_NODE *)mList); if((tempList != NULL && tempList->status & MOVE_DRAW_INSUFFICIENT_PIECES_ACTIVE) || insufficientMatingMaterial(getLastFENString()) == TRUE) { mList->status |= MOVE_DRAW_INSUFFICIENT_PIECES_ACTIVE; } // Update zobrist Hash zob.updateBoardPosition(getLastFENString()); zob.calculateZobristHash(); mList->zobristHash = zob.getZobristHash(); currentHash = mList->zobristHash; currentSeqNum = gState.seqNum; //check if 3 move repetition happened for(tempList = (MOVELIST *)moveList.getPrev((DLL_NODE *)mList); tempList != NULL; tempList = (MOVELIST *)moveList.getPrev((DLL_NODE *)tempList)) { if(tempList->seqNum != currentSeqNum) break; if(tempList->zobristHash == currentHash) { //add more detailed check using FEN string if required count++; } if(count == 3) { break; } } if(count == 3) { mList->status |= MOVE_DRAW_3MOVE_ACTIVE; } status = mList->status; } return status; }