示例#1
0
Func repeat_edge(const Func &source,
                 const std::vector<std::pair<Expr, Expr>> &bounds) {
    std::vector<Var> args(source.args());
    user_assert(args.size() >= bounds.size()) <<
        "repeat_edge called with more bounds (" << bounds.size() <<
        ") than dimensions (" << args.size() << ") Func " <<
        source.name() << "has.\n";

    std::vector<Expr> actuals;
    for (size_t i = 0; i < bounds.size(); i++) {
        Var arg_var = args[i];
        Expr min = bounds[i].first;
        Expr extent = bounds[i].second;

        if (min.defined() && extent.defined()) {
            actuals.push_back(clamp(likely(arg_var), min, min + extent - 1));
        } else if (!min.defined() && !extent.defined()) {
            actuals.push_back(arg_var);
        } else {
            user_error << "Partially undefined bounds for dimension " << arg_var
                       << " of Func " << source.name() << "\n";
        }
    }

    // If there were fewer bounds than dimensions, regard the ones at the end as unbounded.
    actuals.insert(actuals.end(), args.begin() + actuals.size(), args.end());

    Func bounded("repeat_edge");
    bounded(args) = source(actuals);

    return bounded;
}
示例#2
0
/**
 * Set the minimum area based on the given size
 */
void MythUIType::SetMinArea(const QSize &size)
{
    // If a minsize is not set, don't use MinArea
    if (m_MinSize.x() < 1)
        return;

    /**
     * The MinArea will have the same origin as the normal Area,
     * but can have a smaller size.
     */
    QSize minsize = QSize(m_MinSize.x(), m_MinSize.y());
    QSize bounded(size);

    bounded = bounded.expandedTo(minsize);
    bounded = bounded.boundedTo(m_Area.size());

    if (bounded == m_MinArea.size())
        return;

    m_MinArea.setSize(bounded);
    m_MinArea.setX(m_Area.x());
    m_MinArea.setY(m_Area.y());

    if (m_Parent)
        m_Parent->SetMinAreaSiblings(bounded,
                                     bounded.width()  - m_Area.width(),
                                     bounded.height() - m_Area.height());
}
示例#3
0
void ArchiveReader::read_everything(read_everything_co_t::push_type &sink){
	if (!this->version_manifest)
		this->read_manifest();
	auto ptr = this->get_stream();
	auto file_data_start = this->keypair ? 4096 / 8 : 0;
	ptr->seekg(file_data_start);

	boost::iostreams::stream<BoundedInputFilter> bounded(*ptr, this->base_objects_offset - file_data_start);
	std::istream *stream = &bounded;

	std::shared_ptr<std::istream> crypto;
	if (this->keypair){
		CryptoPP::SecByteBlock key, iv;
		zekvok_assert(this->get_key_iv(key, iv, KeyIndices::FileDataKey));
		crypto = CryptoInputFilter::create(default_crypto_algorithm, *stream, &key, &iv);
		stream = crypto.get();
	}
	boost::iostreams::stream<LzmaInputFilter> lzma(*stream);

	zekvok_assert(this->stream_ids.size() == this->stream_sizes.size());
	for (size_t i = 0; i < this->stream_ids.size(); i++){
		boost::iostreams::stream<BoundedInputFilter> bounded2(lzma, this->stream_sizes[i]);
		sink(std::make_pair(this->stream_ids[i], &bounded2));
		//Discard left over bytes.
		boost::iostreams::stream<NullOutputStream> null(0);
		null << bounded2.rdbuf();
	}
}
示例#4
0
bool BackupSystem::verify(version_number_t version) const{
	if (!this->version_exists(version))
		return false;
	fs::ifstream file(this->get_version_path(version), std::ios::binary);
	if (!file)
		return false;
	file.seekg(0, std::ios::end);
	std::uint64_t size = file.tellg();
	sha256_digest digest;
	file.seekg(-(int)digest.size(), std::ios::end);
	file.read((char *)digest.data(), digest.size());
	if (file.gcount() != digest.size())
		return false;
	file.seekg(0);
	sha256_digest new_digest;
	{
		boost::iostreams::stream<BoundedInputFilter> bounded(file, size - digest.size());
		boost::iostreams::stream<HashInputFilter> hash(bounded, new CryptoPP::SHA256);
		{
			boost::iostreams::stream<NullOutputStream> output(0);
			output << hash.rdbuf();
		}
		hash->get_result(new_digest.data(), new_digest.size());
	}
	return new_digest == digest;
}
示例#5
0
std::shared_ptr<VersionManifest> ArchiveReader::read_manifest(){
	auto stream = this->get_stream();
	if (this->manifest_offset < 0){
		const int uint64_length = sizeof(std::uint64_t);
		std::int64_t start = -uint64_length - sha256_digest_length;
		stream->seekg(start, std::ios::end);
		char temp[uint64_length];
		stream->read(temp, uint64_length);
		if (stream->gcount() != uint64_length)
			throw ArchiveReadException("Invalid data: File is too small to possibly be valid");
		deserialize_fixed_le_int(this->manifest_size, temp);
		start -= this->manifest_size;
		stream->seekg(start, std::ios::end);
		this->manifest_offset = stream->tellg();
	}else
		stream->seekg(this->manifest_offset);
	{
		boost::iostreams::stream<BoundedInputFilter> bounded(*stream, this->manifest_size);
		boost::iostreams::stream<LzmaInputFilter> lzma(bounded);

		ImplementedDeserializerStream ds(lzma);
		this->version_manifest.reset(ds.begin_deserialization<VersionManifest>(config::include_typehashes));
		if (!this->version_manifest)
			throw ArchiveReadException("Invalid data: Error during manifest deserialization");
	}

	this->base_objects_offset = this->manifest_offset - this->version_manifest->archive_metadata.entries_size_in_archive;
	this->stream_ids = this->version_manifest->archive_metadata.stream_ids;
	this->stream_sizes = this->version_manifest->archive_metadata.stream_sizes;

	return this->version_manifest;
}
示例#6
0
std::vector<std::shared_ptr<FileSystemObject>> ArchiveReader::read_base_objects(){
	if (!this->version_manifest)
		this->read_manifest();
	zekvok_assert(this->version_manifest);
	decltype(this->base_objects) ret;
	ret.reserve(this->version_manifest->archive_metadata.entry_sizes.size());
	auto stream = this->get_stream();
	stream->seekg(this->base_objects_offset);
	{
		boost::iostreams::stream<BoundedInputFilter> bounded(*stream, this->manifest_offset - this->base_objects_offset);
		std::istream *stream = &bounded;
		std::shared_ptr<std::istream> crypto;
		if (this->keypair){
			CryptoPP::SecByteBlock key, iv;
			zekvok_assert(this->get_key_iv(key, iv, KeyIndices::FileObjectDataKey));
			crypto = CryptoInputFilter::create(default_crypto_algorithm, *stream, &key, &iv);
			stream = crypto.get();
		}
		boost::iostreams::stream<LzmaInputFilter> lzma(*stream);

		for (const auto &s : this->version_manifest->archive_metadata.entry_sizes){
			boost::iostreams::stream<BoundedInputFilter> bounded2(lzma, s);
			ImplementedDeserializerStream ds(bounded2);
			std::shared_ptr<FileSystemObject> fso(ds.begin_deserialization<FileSystemObject>(config::include_typehashes));
			if (!fso)
				throw ArchiveReadException("Invalid data: Error during FSO deserialization");
			ret.push_back(fso);
		}
	}
	this->base_objects = std::move(ret);
	return this->base_objects;
}
示例#7
0
Func mirror_interior(const Func &source,
                     const std::vector<std::pair<Expr, Expr>> &bounds) {
    std::vector<Var> args(source.args());
    user_assert(args.size() >= bounds.size()) <<
        "mirror_interior called with more bounds (" << bounds.size() <<
        ") than dimensions (" << args.size() << ") Func " <<
        source.name() << "has.\n";

    std::vector<Expr> actuals;
    for (size_t i = 0; i < bounds.size(); i++) {
        Var arg_var = args[i];

        Expr min = bounds[i].first;
        Expr extent = bounds[i].second;

        if (min.defined() && extent.defined()) {
            Expr limit = extent - 1;
            Expr coord = arg_var - min;  // Enforce zero origin.
            coord = coord % (2 * limit); // Range is 0 to 2w-1
            coord = coord - limit;       // Range is -w, w
            coord = abs(coord);          // Range is 0, w
            coord = limit - coord;       // Range is 0, w
            coord = coord + min;         // Restore correct min

            // The boundary condition probably doesn't apply
            coord = select(arg_var < min || arg_var >= min + extent, coord,
                           clamp(likely(arg_var), min, min + extent - 1));

            actuals.push_back(coord);
        } else if (!min.defined() && !extent.defined()) {
            actuals.push_back(arg_var);
        } else {
            user_error << "Partially undefined bounds for dimension " << arg_var
                       << " of Func " << source.name() << "\n";
        }
    }

    // If there were fewer bounds than dimensions, regard the ones at the end as unbounded.
    actuals.insert(actuals.end(), args.begin() + actuals.size(), args.end());

    Func bounded("mirror_interior");
    bounded(args) = source(actuals);

    return bounded;
}
示例#8
0
/**
 * Adjust the size of a sibling.
 */
void MythUIType::AdjustMinArea(int delta_x, int delta_y,
                               int delta_w, int delta_h)
{
    // If a minsize is not set, don't use MinArea
    if (!m_MinSize.isValid())
        return;

    // Delta's are negative values; knock down the area
    QRect bounded(m_Area.x() - delta_x,
                  m_Area.y() - delta_y,
                  m_Area.width() + delta_w,
                  m_Area.height() + delta_h);

    // Make sure we have not violated the min size
    if (!bounded.isNull() || !m_Vanish)
    {
        QPoint center = bounded.center();

        if (bounded.isNull())
            bounded.setSize(GetMinSize());
        else
            bounded.setSize(bounded.size().expandedTo(GetMinSize()));

        bounded.moveCenter(center);
    }

    if (bounded.x() + bounded.width() > m_Area.x() + m_Area.width())
        bounded.moveRight(m_Area.x() + m_Area.width());
    if (bounded.y() + bounded.height() > m_Area.y() + m_Area.height())
        bounded.moveBottom(m_Area.x() + m_Area.height());
    if (bounded.x() < m_Area.x())
    {
        bounded.moveLeft(m_Area.x());
        if (bounded.width() > m_Area.width())
            bounded.setWidth(m_Area.width());
    }
    if (bounded.y() < m_Area.y())
    {
        bounded.moveTop(m_Area.y());
        if (bounded.height() > m_Area.height())
            bounded.setHeight(m_Area.height());
    }

    m_MinArea = bounded;
    m_Vanished = false;

    QList<MythUIType *>::iterator it;

    for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
    {
        if (!(*it)->m_Initiator)
            (*it)->AdjustMinArea(delta_x, delta_y, delta_w, delta_h);
    }
}
示例#9
0
/**
 * Set the minimum area based on the given size
 */
void MythUIType::SetMinArea(const QSize &size)
{
    // If a minsize is not set, don't use MinArea
    if (!m_Initiator || !m_MinSize.isValid())
        return;

    m_MinArea.setWidth(0);

    if (m_Area.width() < m_NormalSize.width())
        m_Area.setWidth(m_NormalSize.width());

    if (m_Area.height() < m_NormalSize.height())
        m_Area.setHeight(m_NormalSize.height());

    /**
     * The MinArea will have the same origin as the normal Area,
     * but can have a smaller size.
     */
    QSize bounded(size);

    if (!bounded.isNull() || !m_Vanish)
    {
        if (bounded.isNull())
            bounded = GetMinSize();
        else
            bounded = bounded.expandedTo(GetMinSize());

        bounded = bounded.boundedTo(m_Area.size());
    }

    if (m_Vanish == m_Vanished && bounded == m_MinArea.size())
        return;

    m_MinArea.setWidth(bounded.width());
    m_MinArea.setHeight(bounded.height());
    m_Vanished = (m_Vanish && m_MinArea.size().isNull());

    if (m_Vanished)
    {
        m_MinArea.moveLeft(0);
        m_MinArea.moveTop(0);
    }
    else
    {
        m_MinArea.moveLeft(m_Area.x());
        m_MinArea.moveTop(m_Area.y());
    }

    if (m_Parent)
        m_Parent->SetMinAreaParent(m_MinArea, m_Area, this);
}
示例#10
0
Func constant_exterior(const Func &source, Tuple value,
                       const std::vector<std::pair<Expr, Expr>> &bounds) {
    std::vector<Var> args(source.args());
    user_assert(args.size() >= bounds.size()) <<
        "constant_exterior called with more bounds (" << bounds.size() <<
        ") than dimensions (" << source.args().size() << ") Func " <<
        source.name() << "has.\n";

    Expr out_of_bounds = cast<bool>(false);
    for (size_t i = 0; i < bounds.size(); i++) {
        Var arg_var = source.args()[i];
        Expr min = bounds[i].first;
        Expr extent = bounds[i].second;

        if (min.defined() && extent.defined()) {
            out_of_bounds = (out_of_bounds ||
                             arg_var < min ||
                             arg_var >= min + extent);
        } else if (min.defined() || extent.defined()) {
            user_error << "Partially undefined bounds for dimension " << arg_var
                       << " of Func " << source.name() << "\n";
        }
    }

    Func bounded("constant_exterior");
    if (value.as_vector().size() > 1) {
        std::vector<Expr> def;
        for (size_t i = 0; i < value.as_vector().size(); i++) {
            def.push_back(select(out_of_bounds, value[i], repeat_edge(source, bounds)(args)[i]));
        }
        bounded(args) = Tuple(def);
    } else {
        bounded(args) = select(out_of_bounds, value[0], repeat_edge(source, bounds)(args));
    }

    return bounded;
}
/*
 * runGame
 * 
 * sequence through each player taking turns, until there is a winner or 
 * players get "bored" (reach max turns)
 *
 */
void GameRunner::runGame()
{
	int currentPlayerNum = selectStartingPlayer();				// starting player

	int turnCount = 0;
	while (!game.hasWinner() && (++turnCount < maxTurns))
	{
		turn(currentPlayerNum);									// sequence through next player's turn

		showProgress();
	
		int numPlayers = game.getPlayers().size();				// current num players in game
		currentPlayerNum = bounded(++currentPlayerNum, numPlayers); // advance to next player
	}	
}
示例#12
0
/**
 * Set the minimum area based on the given size
 */
void MythUIType::SetMinArea(const MythRect &rect)
{
    // If a minsize is not set, don't use MinArea
    if (!m_Initiator || !m_MinSize.isValid())
        return;

    QRect bounded(rect);
    bool  vanish = (m_Vanish && rect.isNull());

    if (vanish)
    {
        bounded.moveLeft(0);
        bounded.moveTop(0);
    }
    else
    {
        QPoint center = bounded.center();

        if (bounded.isNull())
            bounded.setSize(GetMinSize());
        else
            bounded.setSize(bounded.size().expandedTo(GetMinSize()));

        bounded.moveCenter(center);
        if (bounded.x() + bounded.width() > m_Area.x() + m_Area.width())
            bounded.moveRight(m_Area.x() + m_Area.width());
        if (bounded.y() + bounded.height() > m_Area.y() + m_Area.height())
            bounded.moveBottom(m_Area.x() + m_Area.height());
        if (bounded.x() < m_Area.x())
        {
            bounded.moveLeft(m_Area.x());
            if (bounded.width() > m_Area.width())
                bounded.setWidth(m_Area.width());
        }
        if (bounded.y() < m_Area.y())
        {
            bounded.moveTop(m_Area.y());
            if (bounded.height() > m_Area.height())
                bounded.setHeight(m_Area.height());
        }
    }

    m_MinArea = bounded;
    m_Vanished = vanish;

    if (m_Parent)
        m_Parent->SetMinAreaParent(m_MinArea, m_Area, this);
}
示例#13
0
static int shift_all(shifter_dd *dt, void **wdata, int what, void **where,
	multi_ext *mx)
{
	int i, j, rows = mx->nrows;

	/* Sanity check */
	if ((rows > NSHIFT) || (mx->ncols > 3) || (mx->mincols < 3) ||
		(mx->fractcol >= 0)) return (0); // Error

	for (i = 0; i < rows; i++)
	{
		int *row = mx->rows[i] + 1;
		for (j = 0; j < 3; j++)
			spins[i][j][0] = bounded(row[j], 0, spins[i][j][2]);
	}
	for (; i < NSHIFT; i++)
		spins[i][0][0] = spins[i][1][0] = spins[i][2][0] = 0;

	reset_frames(dt);

	return (1);
}
示例#14
0
void vmWishboneCar::simControl()
{
    // auto align steering angle
    if (manualYes)
        steerGain= 10;
    else
    {
        steerGain= 10;
        steer*= 0.98;
        speed*= 0.999;
    }


    dReal dsteer, realSpeed;
    //dsteer = bounded(steer,-40.0,40.0) - dJointGetHingeAngle(frWheel.joint);
    realSpeed = -bounded(speed, -14*M_PI, 30*M_PI);
    // steer
    /*dJointSetHingeParam(frWheel.joint, dParamVel, steerGain*dsteer+0.01*dsteer/0.01);
    dJointSetHingeParam(frWheel.joint, dParamFMax, 1000.0);
    dJointSetHingeParam (frWheel.joint,dParamLoStop,-40.0*M_PI/180.0);
    dJointSetHingeParam (frWheel.joint,dParamHiStop,40.0*M_PI/180.0);
    dJointSetHingeParam (frWheel.joint,dParamFudgeFactor,0.1);

    dJointSetHinge2Param(flWheel.joint, dParamVel, steerGain*dsteer+0.01*dsteer/0.01);
    dJointSetHinge2Param(flWheel.joint, dParamFMax, 1000.0);
    dJointSetHinge2Param (flWheel.joint,dParamLoStop,-40.0*M_PI/180.0);
    dJointSetHinge2Param (flWheel.joint,dParamHiStop,40.0*M_PI/180.0);
    dJointSetHinge2Param (flWheel.joint,dParamFudgeFactor,0.1);*/


    // speed
    if (brakeYes)
    {
        dReal factor= 0.1;
        dJointSetHingeParam(rrSuspension.jRotorMid, dParamVel
                            ,dJointGetHingeParam(rrSuspension.jRotorMid,dParamVel)*factor);
        dJointSetHingeParam(rrSuspension.jRotorMid, dParamFMax, 1000.0);
        dJointSetHingeParam(rlSuspension.jRotorMid, dParamVel
                            ,dJointGetHingeParam(rlSuspension.jRotorMid,dParamVel)*factor);
        dJointSetHingeParam(rlSuspension.jRotorMid, dParamFMax, 1000.0);

        dJointSetHingeParam(frSuspension.jRotorMid, dParamVel, realSpeed);//dJointGetHinge2Param(frWheel.joint,dParamVel2)*factor);
        dJointSetHingeParam(frSuspension.jRotorMid, dParamFMax, 1000.0);
        dJointSetHingeParam(flSuspension.jRotorMid, dParamVel, realSpeed);//dJointGetHinge2Param(flWheel.joint,dParamVel2)*factor);
        dJointSetHingeParam(flSuspension.jRotorMid, dParamFMax, 1000.0);
    }
    else
    {
        // turn off rear wheels
        dJointSetHingeParam(rrSuspension.jRotorMid, dParamFMax, 0.0);
        dJointSetHingeParam(rlSuspension.jRotorMid, dParamFMax, 0.0);
        // set up front wheels
        dJointSetHingeParam(frSuspension.jRotorMid, dParamVel, realSpeed);
        dJointSetHingeParam(frSuspension.jRotorMid, dParamFMax, 500.0);
        dJointSetHingeParam(flSuspension.jRotorMid, dParamVel, realSpeed);
        dJointSetHingeParam(flSuspension.jRotorMid, dParamFMax, 500.0);
        //printf("real speed: %f", realSpeed);
    }

    // reset manual mode flag
    manualYes= 0;

}
示例#15
0
/**Set a filter on the output to reduce sharp oscillations. <br>
 * 0.1 is likely a sane starting value. Larger values P and D oscillations, but force larger I values.
 * Uses an exponential rolling sum filter, according to a simple <br>
 * <pre>output*(1-strength)*sum(0..n){output*strength^n}</pre>
 * @param output valid between [0..1), meaning [current output only.. historical output only)
 */
void MiniPID::setOutputFilter(double strength){
	if(strength==0 || bounded(strength,0,1)){
		outputFilter=strength;
	}
}
示例#16
0
/** Calculate the PID value needed to hit the target setpoint. 
* Automatically re-calculates the output at each call. 
* @param actual The monitored value
* @param target The target value
* @return calculated output value for driving the actual to the target 
*/
double MiniPID::getOutput(double actual, double setpoint){
	double output;
	double Poutput;
	double Ioutput;
	double Doutput;
	double Foutput;

	this->setpoint=setpoint;

	//Ramp the setpoint used for calculations if user has opted to do so
	if(setpointRange!=0){
		setpoint=clamp(setpoint,actual-setpointRange,actual+setpointRange);
	}

	//Do the simple parts of the calculations
	double error=setpoint-actual;

	//Calculate F output. Notice, this->depends only on the setpoint, and not the error. 
	Foutput=F*setpoint;

	//Calculate P term
	Poutput=P*error;	 

	//If this->is our first time running this-> we don't actually _have_ a previous input or output. 
	//For sensor, sanely assume it was exactly where it is now.
	//For last output, we can assume it's the current time-independent outputs. 
	if(firstRun){
		lastActual=actual;
		lastOutput=Poutput+Foutput;
		firstRun=false;
	}


	//Calculate D Term
	//Note, this->is negative. this->actually "slows" the system if it's doing
	//the correct thing, and small values helps prevent output spikes and overshoot 

	Doutput= -D*(actual-lastActual);
	lastActual=actual;



	//The Iterm is more complex. There's several things to factor in to make it easier to deal with.
	// 1. maxIoutput restricts the amount of output contributed by the Iterm.
	// 2. prevent windup by not increasing errorSum if we're already running against our max Ioutput
	// 3. prevent windup by not increasing errorSum if output is output=maxOutput	
	Ioutput=I*errorSum;
	if(maxIOutput!=0){
		Ioutput=clamp(Ioutput,-maxIOutput,maxIOutput); 
	}	

	//And, finally, we can just add the terms up
	output=Foutput + Poutput + Ioutput + Doutput;

	//Figure out what we're doing with the error.
	if(minOutput!=maxOutput && !bounded(output, minOutput,maxOutput) ){
		errorSum=error; 
		// reset the error sum to a sane level
		// Setting to current error ensures a smooth transition when the P term 
		// decreases enough for the I term to start acting upon the controller
		// From that point the I term will build up as would be expected
	}
	else if(outputRampRate!=0 && !bounded(output, lastOutput-outputRampRate,lastOutput+outputRampRate) ){
		errorSum=error; 
	}
	else if(maxIOutput!=0){
		errorSum=clamp(errorSum+error,-maxError,maxError);
		// In addition to output limiting directly, we also want to prevent I term 
		// buildup, so restrict the error directly
	}
	else{
		errorSum+=error;
	}

	//Restrict output to our specified output and ramp limits
	if(outputRampRate!=0){
		output=clamp(output, lastOutput-outputRampRate,lastOutput+outputRampRate);
	}
	if(minOutput!=maxOutput){ 
		output=clamp(output, minOutput,maxOutput);
		}
	if(outputFilter!=0){
		output=lastOutput*outputFilter+output*(1-outputFilter);
	}

	lastOutput=output;
	return output;
}
示例#17
0
 */

#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>

#include "defs.h"
#include "compress.h"

__RCSID("$MirOS: contrib/hosted/fwcf/c_zlib.c,v 1.4 2006/09/23 23:46:35 tg Exp $");

static void c_zlib_load(void) __attribute__((constructor));
static int c_init(void);
static int c_compress(char **, char *, size_t)
    __attribute__((bounded (string, 2, 3)));
static int c_decompress(char *, size_t, char *, size_t)
    __attribute__((bounded (string, 1, 2)))
    __attribute__((bounded (string, 3, 4)));

static fwcf_compressor c_zlib = {
	c_init,			/* init */
	c_compress,		/* compress */
	c_decompress,		/* decompress */
	"zlib",			/* name */
	0x01			/* code */
};

static void
c_zlib_load(void)
{
示例#18
0
/**
 * Return a random point in a generic shape.
 * @param object an IObject within which the point is generated
 * @param rng a random number generator
 * @param maxAttempts maximum number of random numbers to use before giving up
 * @return a point
 */
boost::optional<Kernel::V3D>
inGenericShape(const IObject &object, Kernel::PseudoRandomNumberGenerator &rng,
               size_t maxAttempts) {
  return bounded(object, rng, object.getBoundingBox(), maxAttempts);
}
/*
 * selectStartingPlayer
 *
 * who rolls first (random)
 *
 */
int GameRunner::selectStartingPlayer()
{
	// best roll wins - but this is simply by chance => just use the chance from a single roll!
	return bounded(game.getDice().roll(), game.getPlayers().size());
}
示例#20
0
int goSomewhere(struct state *s, char **a, int penalty){
    int i,j, is, js, k, wx=0, wy=0, stage=-1;
	unsigned int change = 0, end = 0;
    struct state *ns;
	char * answer;
	char move='U';
	unsigned int *c = malloc( ((s-> world_w+1) * s->world_h+1) * sizeof( unsigned int ));
	
	if (c == NULL ){}
	for(i=0; i<((s-> world_w+1) * s->world_h+1); i++){
		c[i]=UINT_MAX;  
	}
	
	c[point_to_index(s, s->robot_x, s->robot_y)]=0;	
	
	put(s, 1, 1, O_EMPTY);
	move_robot(s, 1, 1);
	ns = copy(s);
	
	do{
	    free(s);
	    s = copy(ns);
		update_world(ns, s);
		change++;
		stage++;
		end = 0;
		for(i=1; i <= s->world_w; i++){
			for(j=1; j <= s->world_h; j++){
				if(c[point_to_index(s,i,j)]==stage){
					if(get(s, i, j) == O_LIFT_OPEN || get(s, i, j) == O_LAMBDA){
						wx=i;
						wy=j;
						end=stage;
						break;
					}
					//consider four cells - (-1, 0), (1, 0), (0, -1), (0, 1)
					for(k = 1; k<=4; k++){
						if(k==1) {is= 0 ; js=-1;}
						if(k==2) {is= 0 ; js= 1;}
						if(k==3) {is=-1 ; js= 0;}
						if(k==4) {is= 1 ; js= 0;}						
						if(bounded(s,i+is,j+js)	&& c[point_to_index(s, i+is, j+js)]==UINT_MAX){
							//can we go there?
							if(	!bounded(s, i+is, j+js+1) || (get(s, i+is, j+js+1) != O_EMPTY || get(ns, i+is, j+js+1) != O_ROCK)){	
								if(get(s, i+is, j+js)==O_LIFT_OPEN 
								|| get(s, i+is, j+js)==O_LAMBDA 
								|| get(s, i+is, j+js)==O_EARTH 
								|| get(s, i+is, j+js)==O_EMPTY){
									if((bounded(s, i+is, j+js+1) && get(s, i+is, j+js+1)==O_ROCK)
										|| (bounded(s, i+is+1, j+js+1) && get(s, i+is+1, j+js)==O_ROCK && get(s, i+is+1, j+js+1)==O_ROCK)
										|| (bounded(s, i+is-1, j+js+1) && get(s, i+is-1, j+js)==O_ROCK && get(s, i+is-1, j+js+1)==O_ROCK)){
										c[point_to_index(s, i+is, j+js)]=stage+penalty;
									}else{
										c[point_to_index(s, i+is, j+js)]=stage+1;
									}
									change = 0;
							    }
							}
						}
					}
				}
			}
		}
	}while(change <= penalty && end == 0);
	
	//debug
	//dump(s);
	
	if(0){
		for(j=s->world_h; j>0; j--){
			for(i=1; i<=s->world_w; i++){
				if(c[point_to_index(s, i, j)]==UINT_MAX){
					printf("X");
				}else{
					printf("%u", c[point_to_index(s, i, j)]);
				}
			}
			printf("\n");
		}
		printf("\n");
	}
	
	i=0;
	if(end>0){
		answer = malloc( (end+2)*sizeof( char ));
		if (answer == NULL ){}
		
		while(end>0){
			for(k=1; k<=4;k++){
				if(k==1) {is=-1; js= 0;move='R';}
				if(k==2) {is= 1; js= 0;move='L';}						
				if(k==3) {is= 0; js=-1;move='U';}
				if(k==4) {is= 0; js= 1;move='D';}
				if( bounded(s, wx+is, wy+js) && c[point_to_index(s, wx+is, wy+js)] < end) {
					end = c[point_to_index(s, wx+is, wy+js)];
					answer[i++]=move;
					wx = wx+is;
					wy = wy+js;
					break;
				}
			}
		}
		answer[i]='\0';
		reverse(answer,0,strlen(answer)-1);
	}else{
		answer = malloc(1*sizeof( char ));
		if (answer == NULL ){}
		answer[0]='\0';
     	*a=answer;
		free(c);
		return 1;
	}
	*a=answer;
	free(c);
	return 0;
}