public int distanceToPartner(int p, Coordinates c) { // Given a person or house piece, and proposed coordinates for placing it, compute // the distance to its corresponding partner. Returns Integer.MAX_VALUE if the // partner is not found or the input is not a pure person/house piece. if (Pieces.isPerson(p)) { return(this.distance(this.locateHouse(Pieces.personNumber(p)), c)); } else if (Pieces.isHouse(p)) { return(this.distance(this.locatePerson(Pieces.houseNumber(p)), c)); } else { return(int.MaxValue); } }
public static int combinePieces(int p1, int p2) { // Combines a piece that is a person or house, with a regular piece. Order is unimportant. // Returns the failure piece if neither piece is a plain person or house. if (Pieces.isTile(p1)) { int t = p1; p1 = p2; p2 = t; } if (Pieces.isPerson(p1) && Pieces.isTile(p2)) { return(Pieces.setPersonNumber(p2, Pieces.personNumber(p1))); } if (Pieces.isHouse(p1) && Pieces.isTile(p2)) { return(Pieces.setHouseNumber(p2, Pieces.houseNumber(p1))); } return(Pieces.createFailurePiece()); }
public int playPieceDiscard(int p) { // Discards a piece. Of course you can't discard people or house pieces, and discarding // doesn't work if you started moving a person. // Returns the success or failure piece. if (this._movingPerson) { return(this.setFailure("You can't discard a person piece that you are moving.")); } if (Pieces.isHouse(p)) { return(this.setFailure("You can't discard a house piece.")); } if (Pieces.isPerson(p)) { return(this.setFailure("You can't discard a person piece.")); } this.setCurrentPiecePlayed(); // put the piece in the played pile return(Pieces.createSuccessPiece()); }
public bool rotateNextPiece() { // rotates a piece and sends a success or error message. Returns true on success. setFailureBoolean("You spent " + priceRotation() + " to rotate the piece."); if (priceRotation() == 0) { setFailureBoolean("You rotated the piece."); } if (this._movingPerson) { return(setFailureBoolean("You can't rotate a person who is moving.")); // no rotating people) } if (!this.piecesLeftThisTurn()) { return(setFailureBoolean("You have no pieces left to rotate.")); } int originalPiece = this.currentTurnPieces[0]; if (Pieces.isPerson(originalPiece)) { return(setFailureBoolean("You can't rotate a person.")); } if (Pieces.isHouse(originalPiece)) { return(setFailureBoolean("You can't rotate a house.")); } if (!spendCoins(priceRotation())) { return(setFailureBoolean("You can't afford to rotate. Rotation costs " + priceRotation() + " coins.")); } this.currentTurnPieces[0] = Pieces.rotatePiece(originalPiece); if (this.piecesToPlay[this.currentParticipant][0] == originalPiece) { this.piecesToPlay[this.currentParticipant][0] = Pieces.rotatePiece(originalPiece); } return(true); }
public static bool isTile(int p) { // true if the piece is any other piece but a plain person or house piece return((!Pieces.isHouse(p)) && (!Pieces.isPerson(p)) && (!Pieces.isPersonAndHouse(p))); }
public bool endTurn() { // call this when the turn is complete, right before serializing the data. // it saves the proposed turn into the actual current participant's board. // it also removes all the played pieces permanently from where they came from. // Returns true on success, false on error, and on error fills the last error message. if (!this._movingPerson && piecesLeftThisTurn()) { return(setFailureBoolean("You must play all pieces before clicking Play.")); } if (this._movingPerson) { this.setCurrentPiecePlayed(); // if we were moving a person, we didn't actually put the piece in the played pile till now. } bool housePersonPlayed = false; foreach (int thisPlayedPiece in this.currentTurnPlayedPieces) { if (Pieces.isPerson(thisPlayedPiece)) { removePiece(this.remainingPersons, thisPlayedPiece); housePersonPlayed = true; } else if (Pieces.isHouse(thisPlayedPiece)) { removePiece(this.remainingHouses, thisPlayedPiece); housePersonPlayed = true; } else { this.piecesToPlay[this.currentParticipant].Remove(thisPlayedPiece); } } //-- check if there is now a new minimum number of pieces if (this.piecesLeftInBag() < this.minPiecesLeft) { this.minPiecesLeft = this.piecesLeftInBag(); } //-- now check to see if anybody has pieces left! int participantsWithPieces = 0; foreach (String thisParticipantId in this.participantIds) { if (this.piecesToPlay[thisParticipantId].Count > 0) { participantsWithPieces++; } } if (participantsWithPieces == 0) { // nobody has pieces-- game is over! find and declare the winner. determineWinners(); } //--- now that we've removed played pieces, save the board. this.boards[this.currentParticipant].copyFrom(this.currentBoard); //-- if the user placed houses or people, they go on everybody's board the same way if (housePersonPlayed) { for (int i = 0; i < participantIds.Count; i++) { this.boards[participantIds[i]].copyFrom(this.currentBoard); } } return(true); }
public int playPieceAt(int p, int x, int y) { // Plays the valid piece P at (x,y) on the board. Returns the Success piece on regular success // (with the board updated), the Failure piece if the move is invalid, or, if a person has // begun moving, it returns a pure Person piece to indicate which person is moving. // If you get a failure piece, you can get an error message using getLastErrorMessage. Coordinates c = new Coordinates(x, y); // check if there are no moves left if (this._movingPerson && this.personMovesLeft <= 0) { return(this.setFailure("You have no moves left for your person.")); } if (!this.piecesLeftThisTurn()) { return(this.setFailure("You have no pieces left for this turn.")); } // check for valid coordinates, retrieve the current piece on the board. if (!this.currentBoard.isValidCoords(c)) { return(this.setFailure("Internal Error: invalid coordinates")); } int currentPiece = this.currentBoard.getCell(c); // check game rules and place piece based on which kind it is. if (Pieces.isPerson(p) && this._movingPerson) { // Playing a single step in moving a person. First, see if there is a path to move the person. // (The situation of having no moves left was already handled up top.) int sourcePiece = this.currentBoard.getCell(this.personCoordinates); int thisPersonPiece = Pieces.getPersonPieceFrom(sourcePiece); int thisPersonNumber = Pieces.personNumber(thisPersonPiece); int goalPiece = this.currentBoard.createGoalPiece(thisPersonNumber, 0, c); bool reachedGoal = (goalPiece == currentPiece); if (Pieces.personNumber(currentPiece) > 0) { return(this.setFailure("There can be only one person in a square at a time.")); } if (!Pieces.piecesConnect(this.currentBoard.getCell(this.personCoordinates), currentPiece, this.personCoordinates.x(), this.personCoordinates.y(), x, y)) { return(this.setFailure("There is no path for the person to get to that square. Make sure to move your person only one square at a time.")); } //-- it appears that we now have a valid move. //-- move the person sourcePiece = Pieces.setPersonNumber(sourcePiece, 0); currentPiece = Pieces.setPersonNumber(currentPiece, thisPersonNumber); this.currentBoard.setCell(this.personCoordinates, sourcePiece); this.personMovesLeft--; this.personCoordinates = c; //-- check for coins if (Pieces.gold(currentPiece) || Pieces.silver(currentPiece)) { if (Pieces.gold(currentPiece)) { this.incrementScore(this.pointsForGold()); } if (Pieces.silver(currentPiece)) { this.incrementScore(this.pointsForSilver()); } currentPiece = Pieces.setCoins(currentPiece, false, false); this.currentBoard.setCell(c, currentPiece); } //-- check for reaching goal if (reachedGoal) { int thisZeroBasedPersonNumber = thisPersonNumber - 1; this.incrementScore(this.personScores[thisZeroBasedPersonNumber]); // DEBUG: line where Nancy's game crashed 9/1 8:20pm: probably due to the zero-based/one-based thing, probably she got her purple person to the goal which caused the crash. this.personScores[thisZeroBasedPersonNumber]--; if (this.personScores[thisZeroBasedPersonNumber] < 0) { this.personScores[thisZeroBasedPersonNumber] = 0; } //-- check: have we won by finding all the goals? if (this.currentBoard.isWinningBoard()) { this.determineWinners(); } } //-- now our piece is ready to store and we can return. this.currentBoard.setCell(c, currentPiece); return(Pieces.createSuccessPiece()); } else if (Pieces.isPerson(p) || Pieces.isHouse(p)) { // Playing a person piece or house piece when you're not moving a person. if (!this.currentBoard.isOnEdge(c)) { return(this.setFailure("Person and house pieces can only be placed on the edges.")); // person piece has to be placed on edge } if (this.currentBoard.isOnCorner(c)) { return(this.setFailure("You can't place person and house pieces on the corners.")); } if (this.currentBoard.distanceToPartner(p, c) < 5) { return(this.setFailure("The person piece and the house piece of each color have to be at least 5 spaces apart.")); // person piece can't be too close to house piece } if (!Pieces.isGreenGrassPiece(currentPiece)) { return(this.setFailure("Person and house pieces can only be placed on green grass.")); // have to put house or person on green grass. } // combine the pieces and store the result. Also add a path for the person or house. int newPiece = Pieces.combinePieces(currentPiece, p); if (Pieces.isFailurePiece(newPiece)) { return(this.setFailure("There was an unexpected problem.")); } newPiece = this.currentBoard.setGoalDirections(newPiece, c); this.currentBoard.setCell(c, newPiece); this.setCurrentPiecePlayed(); return(Pieces.createSuccessPiece()); } else { // Playing a regular piece. If you play it against an existing piece with a person on it, // it starts person-moving mode. If you play it on a blank square, it places the piece. // Other moves are invalid. if (Pieces.personNumber(currentPiece) > 0) { // Begin person moving mode this._movingPerson = true; this.personCoordinates = c; this.personMovesLeft = Pieces.numberMoves(p); this.setCurrentPiecePlayed(); return(Pieces.createSuccessPiece()); } else if (this.currentBoard.isOnEdge(c)) //-- note: you CAN be on an edge if you're moving a person, see above. { return(this.setFailure("You can't play a path piece on the edge of the board.")); } else if (Pieces.isBlank(currentPiece)) { // Placing tile in blank space this.currentBoard.setCell(c, p); this.setCurrentPiecePlayed(); return(Pieces.createSuccessPiece()); } else { return(this.setFailure("You can't move there.")); } } // Shouldn't get here, and indeed, the compiler says you can't get here. }