/*
* Play the game of Concentration
*
* The runner creates a game board and shows the board. It gets a 2-tile selection from the user,
* checks if the cards at the 2 tile locations match, and then re-displays the board.
*/
public class GameRunner
{
public static void main(String[] args)
{
Game game = new Game();
game.play();
System.out.println(game.toString());
}
/*
* Activity 3.8.1
*/
public class TileTester
{
private static String[] tileValues =
{ "lion", "lion",
"penguin", "penguin",
"dolphin", "dolphin",
"fox", "fox",
"monkey", "monkey",
"turtle", "turtle" };
public static void main(String[] args)
{
int tileCount = 0;
int numRows = 3;
int numCols = 4;
Tile gameboard[][] = new Tile[numRows][numCols];
for(int i =0; i < numRows; i++){
for(int j=0; j < numCols; j++){
Tile newTile = new Tile(tileValues[tileCount]);
gameboard[i][j] = newTile;
tileCount++;
System.out.println(gameboard[i][j]);
}
}
System.out.println(java.util.Arrays.toString(gameboard[0]));
System.out.println(java.util.Arrays.toString(gameboard[1]));
System.out.println(java.util.Arrays.toString(gameboard[2]));
}
}
public class Board
{
private static String[] tileValues = {"lion", "lion",
"penguin", "penguin",
"dolphin", "dolphin",
"fox", "fox",
"monkey", "monkey",
"turtle", "turtle"};
int numRows = 3;
int numCols = 4;
private Tile[][] gameboard = new Tile[numRows][numCols];
/**
* Constructor for the game. Creates the 2D gameboard
* by populating it with card values
*
*/
public Board()
{
// steps 29 - 31
int tileCount = tileValues.length - 1;
for (int i = 0; i < gameboard.length; i++)
for (int j = 0; j < gameboard[0].length; j++)
{
int r = (int)(Math.random() * tileCount);
gameboard[i][j] = new Tile(tileValues[r]);
// call show method only for testing
// gameboard[i][j].show();
tileValues[r] = tileValues[tileCount];
tileCount--;
}
// Step 14: First implementation without randomization
/*
int tileCount = 0;
for (int i = 0; i < gameboard.length; i++)
for (int j = 0; j < gameboard[0].length; j++)
{
gameboard[i][j] = new Tile(tileValues[tileCount]);
tileCount++;
}
/* used for testing only
System.out.println(java.util.Arrays.toString(gameboard[0]));
System.out.println(java.util.Arrays.toString(gameboard[1]));
System.out.println(java.util.Arrays.toString(gameboard[2]));
*/
}
/**
* Returns a string representation of the board, getting the state of
* each tile. If the tile is showing, displays its value,
* otherwise displays it as hidden.
*
* Precondition: gameboard is populated with tiles
*
* @return a string represetation of the board
*/
public String toString() {
// step 15 - 18
String returnVal = "";
for (Tile[] row : gameboard) {
for (Tile tile : row) {
if (tile.isShowingValue())
returnVal += tile.getValue();
else
returnVal += tile.getHidden();
returnVal += "\t";
}
returnVal += "\n";
}
return returnVal;
}
/**
* Determines if the board is full of tiles that have all been matched,
* indicating the game is over.
*
* Precondition: gameboard is populated with tiles
*
* @return true if all tiles have been matched, false otherwse
*/
public boolean allTilesMatch()
{
// steps 19 - 20
for (Tile[] row : gameboard)
for (Tile tile : row)
if (!tile.matched())
return false;
return true;
}
/**
* Sets the tile to show its value (like a playing card face up)
*
* Preconditions:
* gameboard is populated with tiles,
* row values must be in the range of 0 to gameboard.length,
* column values must be in the range of 0 to gameboard[0].length
*
* @param row the row value of Tile
* @param column the column value of Tile
*/
public void showValue (int row, int column)
{
for(int i=0; i < gameboard.length; i++){
for(int j =0; j < gameboard[0].length; j++){
gameboard[row][column].show();
}
}
}
/**
* Checks if the Tiles in the two locations match.
*
* If Tiles match, show Tiles in matched state and return a "matched" message
* If Tiles do not match, re-hide Tiles (turn face down).
*
* Preconditions:
* gameboard is populated with Tiles,
* row values must be in the range of 0 to gameboard.length,
* column values must be in the range of 0 to gameboard[0].length
*
* @param row1 the row value of Tile 1
* @param col1 the column value of Tile 1
* @param row2 the row value of Tile 2
* @param col2 the column vlue of Tile 2
* @return a message indicating whether or not a match occured
*/
public String checkForMatch(int row1, int col1, int row2, int col2)
{
String msg = "no match";
for(int i=0; i < gameboard.length; i++){
for(int j =0; j < gameboard[0].length; j++){
if(gameboard[row1][col1].equals(gameboard[row2][col2])){
gameboard[row1][col1].foundMatch();
gameboard[row2][col2].foundMatch();
msg = "found match";
//System.out.println(msg); //test
}
gameboard[row1][col1].hide();
gameboard[row2][col2].hide();
}
}
return msg;
}
/**
* Checks the provided values fall within the range of the gameboard's dimension
* and that the tile has not been previously matched
*
* @param row the row value of Tile
* @param col the column value of Tile
* @return true if row and col fall on the board and the row,col tile is unmatched, false otherwise
*/
public boolean validateSelection(int row, int col)
{
// steps 26 - 28
if (row >= gameboard.length)
return false;
if(col >= gameboard[0].length)
return false;
if (gameboard[row][col].matched())
return false;
return true;
}
}
import java.util.Scanner;
/**
* A game class to play concentration
*/
public class Game
{
private Scanner in = new Scanner(System.in);
private Board board;
private int row1, col1;
private int row2, col2;
public void play()
{
// instructions
System.out.println("Welcome!");
System.out.println("Select the tile locations you want to match,");
System.out.println("or enter any non-integer character to quit.");
System.out.println("(You will need to know 2D arrays to play!)");
System.out.println("\nPress Enter to continue...");
in.nextLine();
board = new Board();
// play until all tiles are matched
while (!board.allTilesMatch())
{
// get player's first selection, if not an integer, quit
row1 = -1;
col1 = -1;
boolean validTile = false;
while (!validTile)
{
displayBoard();
System.out.print("First choice (row col): ");
validTile = getTile(true);
}
// display first tile
board.showValue(row1, col1);
// get player's second selection, if not an integer, quit
row2 = -1;
col2 = -1;
validTile = false;
while (!validTile)
{
displayBoard();
System.out.print("Second choice (row col): ");
validTile = getTile(false);
// check if user chosen same tile twice
if ((row1 == row2) && (col1 == col2))
{
System.out.println("You mush choose a different second tile");
wait(2);
validTile = false;
}
}
// display second tile
board.showValue(row2, col2);
displayBoard();
// determine if tiles match
String matched = board.checkForMatch(row1, col1, row2, col2);
System.out.println(matched);
// wait 2 seconds to start the next turn
wait(2);
}
displayBoard();
System.out.println("Game Over!");
}
/**
* Get tile choices from the user, validating that
* the choice falls within the range of rows and columns on the board.
*
* @param firstChoice if true, saves the user's first row/col choice, otherwise sets the user's second choice
* @return true if user has made a valid choice, false otherwise
*/
private boolean getTile(boolean firstChoice)
{
int num1 = 0;
int num2 = 0;
if (in.hasNextInt())
num1 = in.nextInt();
else
quitGame();
if (in.hasNextInt())
num2 = in.nextInt();
else
quitGame();
in.reset(); // ignore any extra input
if (!board.validateSelection(num1, num2))
{
System.out.print("Invalid input, please try again. ");
wait(2);
return false;
}
if (firstChoice)
{
row1 = num1;
col1 = num2;
}
else
{
row2 = num1;
col2 = num2;
}
return true;
}
/**
* Clear the console and show the game board
*/
public void displayBoard()
{
// scroll current board off screen
for (int x = 0; x < 50; x++) {
System.out.println();
}
System.out.println(board);
}
/**
* Wait n seconds before clearing the console
*/
private void wait(int n)
{
// a try is like an if statement, "throwing" an error if the body of the try fails
try
{
Thread.sleep(n * 1000);
} catch (InterruptedException e) { /* do nothing */ }
}
/**
* User quits game
*/
private void quitGame()
{
System.out.println("Quit game!");
System.exit(0);
}
}
/**
* A Tile class for a gameboard
*/
public class Tile
{
private boolean isMatched;
private boolean isShowing;
private String value;
private String hidden;
private String matched;
/**
* Construct a tile with a string value. The default state
* of a tile is hidden (face down) on the board and is unmatched.
*
* @param value the string value of the tile (face up value)
*/
public Tile(String value)
{
this.value = value; // face up value
isMatched = false;
isShowing = false;
hidden = "_____"; // face down value
matched = " * "; // a tile that is no longer in play
}
/**
* Get the value of this tile (face up value)
*
* @return the value of the tile
*/
public String getValue()
{
return value;
}
/**
* Get the hidden value of this tile (face down value)
*
* @return the hidden string
*/
public String getHidden()
{
return hidden;
}
/**
* Show this tile (turn it face up)
*/
public void show()
{
isShowing = true;
}
/**
* Hide this tile (turn it face down)
*/
public void hide()
{
isShowing = false;
}
/**
* Determine if the tile is currently showing its value (face up)
*
* @return true if the tile is showing a value, false otherwise
*/
public boolean isShowingValue()
{
return isShowing;
}
/**
* A matching tile to this tile has been found, set matched to true
* and change the way the tile is shown
*/
public void foundMatch()
{
isMatched = true;
value = matched;
hidden = matched;
}
/**
* Determine if this tile has been previously matched
*
* @return true of the tile was previously matched, false otherwise
*/
public boolean matched()
{
return isMatched;
}
/**
* Determines if two tiles have the same value
*
* @param tile the tile to compare this tile to
* @return true if their values are the same, false otherwise
*/
public boolean equals(Tile tile)
{
if (this.value.equals(tile.value))
return true;
return false;
}
/**
* Return the value of this tile
*/
public String toString()
{
return value;
}
}