void testBufferConvertComplexComponents(const size_t inVlen, const size_t outVlen)
{
    const size_t numElems = 100 + (std::rand() % 100);
    Pothos::BufferChunk b0(Pothos::DType(typeid(InType), inVlen), numElems);
    const auto primElems = b0.length/b0.dtype.elemSize();

    //random fill primitive elements
    for (size_t i = 0; i < primElems; i++) randType(b0.as<InType *>()[i]);

    //convert
    const auto b1 = b0.convertComplex(Pothos::DType(typeid(OutType), outVlen), numElems);

    //check
    std::cout << "testBufferConvertComplexComponents: " << b0.dtype.toString() << " to " << b1.first.dtype.toString() << "...\t" << std::flush;
    for (size_t i = 0; i < primElems; i++)
    {
        const auto in = b0.as<const InType *>()[i];
        const auto outRe = b1.first.as<const OutType *>()[i];
        const auto outIm = b1.second.as<const OutType *>()[i];
        if (not checkEqual(in.real(), outRe) or not checkEqual(in.imag(), outIm))
        {
            std::cerr << "elem " << i << ": " << in << " != " << outRe << ", " << outIm << std::endl;
            POTHOS_TEST_TRUE(checkEqual(in.real(), outRe) and checkEqual(in.imag(), outIm));
        }
    }
    std::cout << "OK" << std::endl;
}
TetrisResult TetrisEmulator::emulate(int step_limit)
{
    step = 0;
    lastMaxHeight = 0;
    init_board(board);
    while (!fail())
    {
        TetrominoType type = randType();
        // For each rotation of the certain type.
        int bestRotation = -1;
        int bestX = T_WIDTH / 2;
        double bestValue = NEG_INF;
        for (int rotation = 0; rotation < TetrominoRotationCount[type]; ++rotation)
        {
            // for each possible drop position of the certain type and rotation.
            for (int x = TetrominoLeftBound[type][rotation];
                 x < T_WIDTH - TetrominoRightBound[type][rotation]; ++x)    // right bound is positive offset.
            {
                cloneBoard(board_temp, board); // TODO : potential efficiency enhancement point.
                if ((lastClearLines = drop(board_temp, type, rotation, x)) < 0)
                {
                    continue;
                }
                TetrisValue value = getValue(board_temp);
                if (value > bestValue)
                {
                    bestValue = value;
                    bestRotation = rotation;
                    bestX = x;
                }
            }
        }
        if (bestRotation == -1 || step >= step_limit)
        {
            break;
        }
		//if (_DEBUG) // debug-time only.
		//{
		//	printBoard(board);
		//	std::cout << getHoleDepth(board);
		//}
        drop(board, type, bestRotation, bestX);
        getValue(board);
        step++;
//		printBoard(board);
    }
    return step;
}