예제 #1
0
void AI::debug()
{
    Player human = (this->player == CROSS ? NOUGHT : CROSS);

    std::cout << std::endl << ":::::::DEBUG::::::" << std::endl;
    for (int i=0; i<BOARD_SIZE; i++)
    {
        for (int j=0; j<BOARD_SIZE; j++)
        {
            Position position = MakePosition(i, j);
            std::cout << "Position (" << i << "," << j << "):" << std::endl;

            std::cout << "\tAI:" << std::endl;
            std::map<Direction, int> & aiWeights = this->weightsAtPositionForPlayer(position, this->player);
            for (std::map<Direction, int>::iterator it=aiWeights.begin(); it!=aiWeights.end(); ++it)
            {
                std::cout << "\t\t" << DirectionName(it->first) << ": " << it->second << std::endl;
            }

            std::cout << "\tHuman:" << std::endl;
            std::map<Direction, int> & humanWeights = this->weightsAtPositionForPlayer(position, human);
            for (std::map<Direction, int>::iterator it=humanWeights.begin(); it!=humanWeights.end(); ++it)
            {
                std::cout << "\t\t" << DirectionName(it->first) << ": " << it->second << std::endl;
            }
        }
    }
    std::cout << std::endl;
}
예제 #2
0
bool Board::isFinished(Player &winner) const
{
	bool finished = false;
	int row = 0;
	while (row < BOARD_SIZE && !finished)
	{
		int column = 0;
		while (column < BOARD_SIZE && !finished)
		{
			Position pos = MakePosition(row, column);
			
			Box &box = this->boxAtPosition(pos);
			if (box.isOccupied())
			{
				const Player &player = box.getPlayer();
				
				int nDirections;
				Direction *directions = this->getDirectionsToCheckForPosition(pos, nDirections);
				int i = 0;
				while (i < nDirections && !finished)
				{
					Direction nextDirection = directions[i];
					
					bool samePlayer = true;
					Position nextPos = MovePosition(pos, nextDirection);
					while (this->positionIsValid(nextPos) && samePlayer)
					{
						Box &box = this->boxAtPosition(nextPos);
						samePlayer = (box.isOccupied() && box.getPlayer() == player);
						nextPos = MovePosition(nextPos, nextDirection);
					}
					
					finished = (samePlayer);
					if (finished)
					{
						winner = player;
					}
					++i;
				}
				
				delete [] directions;
			}
			
			++column;
		}
		++row;
	}
	
	return finished;
}
예제 #3
0
void AI::recalculateWeights()
{
    Player humanPlayer = (this->player == CROSS ? NOUGHT : CROSS);

    for (int i=0; i<BOARD_SIZE; i++)
    {
        for (int j=0; j<BOARD_SIZE; j++)
        {
            Position position = MakePosition(i, j);
            int nDirectionsToCheck;
            Direction *directionsToCheck = this->board->getDirectionsToCheckForPosition(position, nDirectionsToCheck);

            int nextDirectionIndex = 0;
            while (nextDirectionIndex < nDirectionsToCheck)
            {
                Direction nextDirection = directionsToCheck[nextDirectionIndex];

                std::map<Position, int> aiWeightsInCurrDirection = this->board->weightForBoxesFromPositionInDirectionForPlayer(position, nextDirection, this->player);
                this->applyWeightForBoxesFromPositionInDirectionAndPlayer(aiWeightsInCurrDirection, nextDirection, this->player);

                std::map<Position, int> humanWeightInCurrDirection = this->board->weightForBoxesFromPositionInDirectionForPlayer(position, nextDirection, humanPlayer);
                this->applyWeightForBoxesFromPositionInDirectionAndPlayer(humanWeightInCurrDirection, nextDirection, humanPlayer);

                ++nextDirectionIndex;
            }

            delete [] directionsToCheck;

        }
    }

    if (DEBUG > 1)
    {
        this->debug();
    }
}
예제 #4
0
void OvrSliderComponent::GetVerticalSliderParms( VRMenu & menu, 
		VRMenuId_t const parentId, VRMenuId_t const rootId, 
		imageInfo_t const & iconImage,
		imageInfo_t const & baseImage,
		imageInfo_t const & trackImage, 
		imageInfo_t const & trackFullImage,
		imageInfo_t const & scrubberImage,
		imageInfo_t const & bubbleImage,
		VRMenuId_t const scrubberId, VRMenuId_t const bubbleId, VRMenuId_t const fillId,
		float const sliderFrac, float const minValue, float const maxValue, 
		float const sensitivityScale, 
		Array< VRMenuObjectParms const* > & parms )
{
	Vector3f const fwd( 0.0f, 0.0f, -1.0f );
	Vector3f const right( 1.0f, 0.0f, 0.0f );
	Vector3f const up( 0.0f, 1.0f, 0.0f );

	float const BASE_FWD_OFFSET = 0.033f;
	float const FWD_INC = 0.01f;
	//float TRACK_UP_OFFSET = ( baseImage.h - trackImage.h - iconImage.h ) * 0.5f;	// offset track just above the button image
	float TRACK_UP_OFFSET = ( baseImage.h * 0.5f ) - ( trackImage.h * 0.5f  + iconImage.h );	// offset track just above the button image
	Vector3f const localSlideDelta( MakePosition( 0.0f, trackImage.h, 0.0f ) );

	bool const vertical = true;

	// add parms for the root object that holds all the slider components
	{
		Array< VRMenuComponent* > comps;
		comps.PushBack( new OvrSliderComponent( menu, sliderFrac, localSlideDelta, minValue, maxValue, sensitivityScale, rootId, scrubberId, VRMenuId_t(), bubbleId, fillId ) );
		Array< VRMenuSurfaceParms > surfParms;
		char const * text = "slider_root";
		Vector3f scale( 1.0f );
		Posef pose( MakePose( Quatf(), 0.0f, ( baseImage.h * 0.5f ) - ( iconImage.h * 0.5f ), 0.0f ) );
		Posef textPose( Quatf(), Vector3f( 0.0f ) );
		Vector3f textScale( 1.0f );
		VRMenuFontParms fontParms;
		VRMenuObjectFlags_t objectFlags( VRMENUOBJECT_RENDER_HIERARCHY_ORDER );
		VRMenuObjectInitFlags_t initFlags( VRMENUOBJECT_INIT_FORCE_POSITION );
		VRMenuObjectParms * itemParms = new VRMenuObjectParms( VRMENU_CONTAINER, comps,
				surfParms, text, pose, scale, textPose, textScale, fontParms, rootId, 
				objectFlags, initFlags );
		itemParms->ParentId = parentId;
		parms.PushBack( itemParms );
	}

	// add parms for the base image that underlays the whole slider
	{
		Array< VRMenuComponent* > comps;
		Array< VRMenuSurfaceParms > surfParms;
		VRMenuSurfaceParms baseParms( "base", GetSliderImage( baseImage, vertical ).ToCStr(), SURFACE_TEXTURE_DIFFUSE,
				NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX );
		surfParms.PushBack( baseParms );
		char const * text = "base";
		Vector3f scale( 1.0f );
		Posef pose( MakePose( Quatf(), BASE_FWD_OFFSET, 0.0f, 0.0f ) );
		Posef textPose( Quatf(), Vector3f( 0.0f ) );
		Vector3f textScale( 1.0f );
		VRMenuFontParms fontParms;
		VRMenuObjectFlags_t objectFlags( VRMENUOBJECT_DONT_RENDER_TEXT );
		objectFlags |= VRMENUOBJECT_FLAG_NO_DEPTH;
		VRMenuObjectInitFlags_t initFlags( VRMENUOBJECT_INIT_FORCE_POSITION );
		VRMenuObjectParms * itemParms = new VRMenuObjectParms( VRMENU_BUTTON, comps,
				surfParms, text, pose, scale, textPose, textScale, fontParms, VRMenuId_t(), 
				objectFlags, initFlags );
		itemParms->ParentId = rootId;
		parms.PushBack( itemParms );
	}

	// add parms for the track image
	{
		Array< VRMenuComponent* > comps;
		Array< VRMenuSurfaceParms > surfParms;
		VRMenuSurfaceParms baseParms( "track", GetSliderImage( trackImage, vertical ).ToCStr(), SURFACE_TEXTURE_DIFFUSE,
				NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX );
		surfParms.PushBack( baseParms );
		char const * text = "track";
		Vector3f scale( 1.0f );
		Posef pose( MakePose( Quatf(), BASE_FWD_OFFSET - FWD_INC * 1, -TRACK_UP_OFFSET, 0.0f ) );
		Posef textPose( Quatf(), Vector3f( 0.0f ) );
		Vector3f textScale( 1.0f );
		VRMenuFontParms fontParms;
		VRMenuObjectFlags_t objectFlags( VRMENUOBJECT_DONT_RENDER_TEXT );
		VRMenuObjectInitFlags_t initFlags( VRMENUOBJECT_INIT_FORCE_POSITION );
		VRMenuObjectParms * itemParms = new VRMenuObjectParms( VRMENU_BUTTON, comps,
				surfParms, text, pose, scale, textPose, textScale, fontParms, VRMenuId_t(), 
				objectFlags, initFlags );
		itemParms->ParentId = rootId;
		parms.PushBack( itemParms );
	}

	// add parms for the filled track image
	{
		Array< VRMenuComponent* > comps;
		Array< VRMenuSurfaceParms > surfParms;
		VRMenuSurfaceParms baseParms( "track_full", GetSliderImage( trackFullImage, vertical ).ToCStr(), SURFACE_TEXTURE_DIFFUSE,
				NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX );
		surfParms.PushBack( baseParms );
		char const * text = "track_full";
		Vector3f scale( 1.0f );
		Posef pose( MakePose( Quatf(), BASE_FWD_OFFSET - FWD_INC * 2, -TRACK_UP_OFFSET, 0.0f ) );
		Posef textPose( Quatf(), Vector3f( 0.0f ) );
		Vector3f textScale( 1.0f );
		VRMenuFontParms fontParms;
		VRMenuObjectFlags_t objectFlags( VRMENUOBJECT_DONT_RENDER_TEXT );
		VRMenuObjectInitFlags_t initFlags( VRMENUOBJECT_INIT_FORCE_POSITION );
		VRMenuObjectParms * itemParms = new VRMenuObjectParms( VRMENU_BUTTON, comps,
				surfParms, text, pose, scale, textPose, textScale, fontParms, fillId, 
				objectFlags, initFlags );
		itemParms->ParentId = rootId;
		parms.PushBack( itemParms );
	}

	// add parms for the scrubber
	{
		Array< VRMenuComponent* > comps;
		Array< VRMenuSurfaceParms > surfParms;
		VRMenuSurfaceParms baseParms( "scrubber", GetSliderImage( scrubberImage, vertical ).ToCStr(), SURFACE_TEXTURE_DIFFUSE,
				NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX );
		surfParms.PushBack( baseParms );
		char const * text = "scrubber";
		Vector3f scale( 1.0f );
		Posef pose( MakePose( Quatf(), BASE_FWD_OFFSET - FWD_INC * 3, -TRACK_UP_OFFSET, 0.0f ) );
		Posef textPose( Quatf(), Vector3f( 0.0f ) );
		Vector3f textScale( 1.0f );
		VRMenuFontParms fontParms;
		VRMenuObjectFlags_t objectFlags( VRMENUOBJECT_DONT_RENDER_TEXT );
		VRMenuObjectInitFlags_t initFlags( VRMENUOBJECT_INIT_FORCE_POSITION );
		VRMenuObjectParms * itemParms = new VRMenuObjectParms( VRMENU_BUTTON, comps,
				surfParms, text, pose, scale, textPose, textScale, fontParms, scrubberId, 
				objectFlags, initFlags );
		itemParms->ParentId = rootId;
		parms.PushBack( itemParms );
	}

	// add parms for the bubble
	{
		Array< VRMenuComponent* > comps;
		Array< VRMenuSurfaceParms > surfParms;
		VRMenuSurfaceParms baseParms( "bubble", GetSliderImage( bubbleImage, vertical ).ToCStr(), SURFACE_TEXTURE_DIFFUSE,
				NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX );
		surfParms.PushBack( baseParms );
		char const * text = NULL;
		Vector3f scale( 1.0f );
		//Posef pose( Quatf(), right * ( trackImage.w + SLIDER_BUBBLE_CENTER ) + fwd * ( BASE_FWD_OFFSET - ( FWD_INC * 4 ) ) );
		float const SLIDER_BUBBLE_CENTER = bubbleImage.w * 0.5f;
		Posef pose( MakePose( Quatf(), BASE_FWD_OFFSET - FWD_INC * 4, 0.0f , trackImage.w + bubbleImage.w * 0.5593f ) );
		const float bubbleTextScale = 0.66f;
		const float bubbleTextCenterOffset = SLIDER_BUBBLE_CENTER - ( bubbleImage.w * 0.5f );
		const Vector3f textPosition = right * bubbleTextCenterOffset;
		Posef textPose( Quatf(), textPosition );
		Vector3f textScale( 1.0f );
		VRMenuFontParms fontParms( HORIZONTAL_CENTER, VERTICAL_CENTER, false, false, true, bubbleTextScale );
		VRMenuObjectFlags_t objectFlags;
		VRMenuObjectInitFlags_t initFlags( VRMENUOBJECT_INIT_FORCE_POSITION );
		VRMenuObjectParms * itemParms = new VRMenuObjectParms( VRMENU_BUTTON, comps,
				surfParms, text, pose, scale, textPose, textScale, fontParms, bubbleId, 
				objectFlags, initFlags );
		itemParms->ParentId = scrubberId;
		parms.PushBack( itemParms );
	}
}
예제 #5
0
Posef MakePose( Quatf const & q, float const fwdDist, float const upDist, float const leftDist )
{
	return Posef( q, MakePosition( fwdDist, upDist, leftDist ) );
}
예제 #6
0
Position AI::nextMovement()
{
    int aiBestWeight = INT_MAX;
    Position aiBestWeightPosition = MakePosition(0, 0);
    float aiBestMedianWeight = FLT_MAX;
    Position aiBestMedianWeightPosition = MakePosition(0, 0);

    int humanBestWeight = INT_MAX;
    Position humanBestWeightPosition;
    float humanBestMedianWeight = FLT_MAX;
    Position humanBestMedianWeightPosition;

    Player humanPlayer = (this->player == CROSS ? NOUGHT : CROSS);

    for (int i=0; i<BOARD_SIZE; i++)
    {
        for (int j=0; j<BOARD_SIZE; j++)
        {
            Position position = MakePosition(i, j);

//			We have to decide if to attack or to defend.
//			Let's see what is the best box to check for the AI and what is its
//			weight but also which will be the best one for the user.
//			We will make one of those 2 movements: the one with the lowest
//			weight.

            //ATTACK
            int currAIBestWeight;
            float currAIBestMedianWeight;
            bool aiAnySolution = this->getAttackInfoToBoxAtPositionForPlayer(position, this->player, currAIBestWeight, currAIBestMedianWeight);
            if (aiAnySolution)
            {
                bool change = ((currAIBestWeight < aiBestWeight) || ((currAIBestWeight == aiBestWeight) && rand()%2));
                //let's add some random behaviour to make it harder to predict.
                if (change)
                {
                    aiBestWeight = currAIBestWeight;
                    aiBestWeightPosition = MakePosition(i, j);
                }
                change = ((currAIBestMedianWeight < aiBestMedianWeight) || ((fabsf(currAIBestMedianWeight - aiBestMedianWeight) < 0.01f) && rand()%2));
                if (change)
                {
                    aiBestMedianWeight = currAIBestMedianWeight;
                    aiBestMedianWeightPosition = MakePosition(i, j);
                }
            }

            //DEFFEND
            int currHumanBestWeight;
            float currHumanBestMedianWeight;
            bool humanAnySolution = this->getAttackInfoToBoxAtPositionForPlayer(position, humanPlayer, currHumanBestWeight, currHumanBestMedianWeight);
            if (humanAnySolution)
            {
                bool change = ((currHumanBestWeight < humanBestWeight) || ((currHumanBestWeight == humanBestWeight) && rand()%2));
                if (change)
                {
                    humanBestWeight = currHumanBestWeight;
                    humanBestWeightPosition = MakePosition(i, j);
                }
                change = ((currHumanBestMedianWeight < humanBestMedianWeight) || ((fabsf(currHumanBestMedianWeight-humanBestMedianWeight) < 0.0001f) && rand()%2));
                if (change)
                {
                    humanBestMedianWeight = currHumanBestMedianWeight;
                    humanBestMedianWeightPosition = MakePosition(i, j);
                }
            }
        }
    }

    bool shouldTakeMiddlePosition = (!this->board->positionIsOccupied(MakePosition(BOARD_SIZE/2, BOARD_SIZE/2)));
    if (shouldTakeMiddlePosition)
    {
        switch (this->aiLevel)
        {
        case EASY:
            break;
            shouldTakeMiddlePosition = (rand()%3 == 0);
        case NORMAL:
            shouldTakeMiddlePosition = (rand()%2 == 0);
            break;
        default:
            break;
        }
    }

    Position pos;
    if (aiBestWeight == 1)
    {
        if (DEBUG)
        {
            std::cout << "  1st --> Attacking at best weight" << std::endl;
        }
        pos = aiBestWeightPosition;
    } else if (humanBestWeight == 1)
    {
        if (DEBUG)
        {
            std::cout << "  2nd --> Defending at best weight" << std::endl;
        }
        pos = humanBestWeightPosition;
    } else if (!this->board->positionIsOccupied(MakePosition(BOARD_SIZE/2, BOARD_SIZE/2)))
    {
        if (DEBUG)
        {
            std::cout << "  3rd --> Taking the middle position" << std::endl;
        }
        pos = MakePosition(BOARD_SIZE/2, BOARD_SIZE/2);
    }
    else if (humanBestMedianWeight < aiBestMedianWeight)
    {
        if (DEBUG)
        {
            std::cout << "  4th --> Defending at best median" << std::endl;
        }
        pos = humanBestMedianWeightPosition;
    } else
    {
        if (DEBUG)
        {
            std::cout << "  5th --> Attacking at best median" << std::endl;
        }
        pos = aiBestMedianWeightPosition;
    }
    this->board->setPlayerAtPosition(this->player, pos);
    return pos;
}