Пример #1
0
int Player::gainOrLoseLife(int value)
{
    if (!value)
        return 0; //Don't do anything if there's no actual life change
    if (value>0 && (opponent()->game->battlefield->hasAbility(Constants::NOLIFEGAINOPPONENT)||game->battlefield->hasAbility(Constants::NOLIFEGAIN)))//nolifegain
        return 0;

    thatmuch = abs(value); //the value that much is a variable to be used with triggered abilities.
    //ie:when ever you gain life, draw that many cards. when used in a trigger draw:thatmuch, will return the value
    //that the triggered event stored in the card for "that much".
    if (!inPlay()->hasAbility(Constants::CANTCHANGELIFE))
        life+=value;
    if (value<0)
        lifeLostThisTurn += abs(value);
    else if (value > 0)
    {
        lifeGainedThisTurn += abs(value);
    }

    //Send life event to listeners
    WEvent * lifed = NEW WEventLife(this,value);
    observer->receiveEvent(lifed);

    return value;
}
Пример #2
0
void SuperBall::paddle_launch(Vector3D norm, Vector3D paddle_velocity)
{
	if (!inPlay())
	{
		_ball->launch(C_VELOCITY_REDUCE * (norm + paddle_velocity));
	}
}
Пример #3
0
int SuperBall::tick()
{
	if (!inPlay()) return 1;
	Point3D to = _ball->getPosition();
	m_transform = translation(Vector3D(to[0], to[1], to[2]));
	return 0;
}
Пример #4
0
void AI::generateMoves(fizGTableState state, set<shot>& moves, turn_T turn){
	//for each ball

	fizBall cueBall = state.getBall(CUE);

	//must have been a scratch, ball in hand...figure out what to do
	if(!inPlay(cueBall)) return;

	fizPoint cueBallPos = cueBall.getPos();


	BallType firstBall, lastBall;
	switch(turn){
		case stripes:
			firstBall = EIGHT;
			lastBall = FIFTEEN;
			break;
		case solids:
			firstBall = ONE;
			lastBall = EIGHT;
			break;
		case table_open:
			firstBall = ONE;
			lastBall = FIFTEEN;
			break;
	}

	for(BallType ballNum = firstBall; ballNum <= lastBall; ballNum = (BallType)(ballNum + 1)){

		if(ballNum == EIGHT && !isOnly8Left(state, (turn == solids))) continue;
		fizBall ball = state.getBall(ballNum);

		//if ball is not in play
		if(!inPlay(ball)) continue;

		fizPoint ballPos = ball.getPos();

		//for each pocket, generate a straight in shot
		int numOfPockets = 6;
		BoundaryId pockets[] = {SW_POCKET, W_POCKET, NW_POCKET, NE_POCKET, E_POCKET, SE_POCKET};

		for(int i = 0; i < numOfPockets; i++){
			//get ball position, cue ball position, and pocket position
			//calculate ghost ball position
			//calculate theta, a, b, phi, and minVelocity

			fizPoint pocketPos = theTable->getPocketCenter(pockets[i]);

			//make sure shot is possible
			//if(!shotPossible(cueBallPos, ballPos, pocketPos)) continue;


			//get ball-pocket line and cue-ghostball line
			double yDiff = fabs(pocketPos.y - ballPos.y);
			double xDiff = fabs(pocketPos.x - ballPos.x);
			double ballPocketAngle = atan( yDiff / xDiff);
			double deltaX = ballDiameter * cos(ballPocketAngle);
			double deltaY = ballDiameter * sin(ballPocketAngle);

			if(ballPos.x < pocketPos.x) deltaX = -deltaX;
			if(ballPos.y < pocketPos.y) deltaY = -deltaY;

			double ghostX = ballPos.x + deltaX;
			double ghostY = ballPos.y + deltaY;

			fizPoint ghostPos(ballPos.x + deltaX, ballPos.y + deltaY);

			//make sure no balls are in the way
			//this should also make sure that the shot is possible because
			//if it is not possible then the target ball will be in the way of the cue and ghost
			vec2 p1;
			p1.x = cueBallPos.x;
			p1.y = cueBallPos.y;
			vec2 p2;
			p2.x = ghostPos.x;
			p2.y = ghostPos.y;
			if(!isTrajectoryClear(p1, p2, state, -1)) continue;

			p1.x = ballPos.x;
			p1.y = ballPos.y;
			p2.x = pocketPos.x;
			p2.y = pocketPos.y;
			if(!isTrajectoryClear(p1, p2, state, -1)) continue;

			//ok create the shot
			//set a, b to zero
			//find minimum velocity
			//find cue angle and elevation angle

			shot theShot;
			theShot.a = 0; //positive is to right of center (mm)
			theShot.b = 0; //positive is up from center (mm)
			//theShot.v = 1; //have to calculate the minimum required velocity (m/s) max = 4.5

			xDiff = fabs(cueBallPos.x - ghostPos.x);
			yDiff = fabs(cueBallPos.y - ghostPos.y);
			theShot.phi = atan(yDiff / xDiff);

			//convert to degrees
			theShot.phi *= (180.0 / M_PI);

			//find true angle
			if(cueBallPos.x < ghostPos.x){
				if(cueBallPos.y > ghostPos.y){
					theShot.phi = -theShot.phi;
				}
				else{
					//have correct angle
				}
			}
			else{
				if(cueBallPos.y < ghostPos.y){
					theShot.phi = 180 - theShot.phi;//90 + theShot.phi;
				}
				else{
					theShot.phi = 180 + theShot.phi; //180 + theShot.phi;
				}
			}

			//distance from ball to pocket
			theShot.d1 = pointDistance(ballPos, pocketPos);

			//distance from cue to ghost
			theShot.d2 = pointDistance(cueBallPos, ghostPos);

			//slopes of lines, to determine angles
			yDiff = ballPos.y - pocketPos.y;
			xDiff = ballPos.x - pocketPos.x;
			double yDiff2 = cueBallPos.y - ghostPos.y;
			double xDiff2 = cueBallPos.x - ghostPos.x;

			theShot.cutAngle = angleBetweenLines(yDiff, xDiff, yDiff2, xDiff2);

			//determine the pocket angle
			bool isCorner = true;
			switch(pockets[i]){
			case W_POCKET:
			case E_POCKET:
				yDiff2 = 0;
				xDiff2 = 1;
				isCorner = false;
				break;

			case SW_POCKET:
				yDiff2 = 1;
				xDiff2 = 1;
				break;

			case NW_POCKET:
				yDiff2 = -1;
				xDiff2 = 1;
				break;

			case NE_POCKET:
				yDiff2 = -1;
				xDiff2 = -1;
				break;

			case SE_POCKET:
				yDiff2 = 1;
				xDiff2 = -1;
				break;
			}

			theShot.pocketAngle = angleBetweenLines(yDiff, xDiff, yDiff2, xDiff2);

			theShot.v = vTable.getMinVelocity(theShot.d2, theShot.d1, theShot.cutAngle) + .2;
			if(theShot.v < 0){
				
				continue;
			}

			ShotData shotCopy;
			shotCopy.a = theShot.a;
			shotCopy.b = theShot.b;
			shotCopy.v = theShot.v;
			shotCopy.theta = 2;
			shotCopy.phi = theShot.phi;

			theShot.theta = findMinTheta(*theTable, state, shotCopy); //elevation angle (degrees)

			theShot.ball = ballNum;
			theShot.pocket = pockets[i];

			theShot.probability = pTable.getProb(theShot.d1, theShot.d2, theShot.cutAngle, theShot.pocketAngle, isCorner);
			if(theShot.probability == 0) theShot.probability = .001;

			//add shot to the list
			moves.insert(theShot);
		}
	}
}