mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-23 07:29:02 -08:00
248
18 Bullseye/java/src/Bullseye.java
Normal file
248
18 Bullseye/java/src/Bullseye.java
Normal file
@@ -0,0 +1,248 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Bullseye {
|
||||
|
||||
public static final int FIRST_IDENT = 10;
|
||||
public static final int SECOND_IDENT = 30;
|
||||
public static final int THIRD_INDENT = 30;
|
||||
|
||||
public static final double[] SHOT_ONE = new double[] { .65, .55, .5, .5};
|
||||
public static final double[] SHOT_TWO = new double[] { .99, .77, .43,.01};
|
||||
public static final double[] SHOT_THREE = new double[] { .95, .75, .45, .05 };
|
||||
|
||||
private enum GAME_STATE {
|
||||
STARTING,
|
||||
START_GAME,
|
||||
PLAYING,
|
||||
GAME_OVER
|
||||
}
|
||||
|
||||
private GAME_STATE gameState;
|
||||
|
||||
private ArrayList<Player> players;
|
||||
|
||||
private Shot[] shots;
|
||||
|
||||
// Used for keyboard input
|
||||
private Scanner kbScanner;
|
||||
|
||||
private int numberOfPlayers;
|
||||
|
||||
private int round;
|
||||
|
||||
public Bullseye() {
|
||||
|
||||
gameState = GAME_STATE.STARTING;
|
||||
players = new ArrayList<>();
|
||||
|
||||
// Save the random chances of points based on shot type
|
||||
|
||||
shots = new Shot[3];
|
||||
shots[0] = new Shot(SHOT_ONE);
|
||||
shots[1] = new Shot(SHOT_TWO);
|
||||
shots[2] = new Shot(SHOT_THREE);
|
||||
|
||||
// Initialise kb scanner
|
||||
kbScanner = new Scanner(System.in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main game loop
|
||||
*
|
||||
*/
|
||||
public void play() {
|
||||
|
||||
do {
|
||||
switch (gameState) {
|
||||
|
||||
// Show an introduction the first time the game is played.
|
||||
case STARTING:
|
||||
intro();
|
||||
gameState = GAME_STATE.START_GAME;
|
||||
break;
|
||||
|
||||
// Start the game, set the number of players, names and round
|
||||
case START_GAME:
|
||||
|
||||
this.numberOfPlayers = chooseNumberOfPlayers();
|
||||
|
||||
for(int i=0; i<this.numberOfPlayers; i++) {
|
||||
String name = displayTextAndGetInput("NAME OF PLAYER #" + (i+1) + "? ");
|
||||
Player player = new Player(name);
|
||||
this.players.add(player);
|
||||
}
|
||||
|
||||
this.round = 1;
|
||||
|
||||
gameState = GAME_STATE.PLAYING;
|
||||
break;
|
||||
|
||||
// Playing round by round until we have a winner
|
||||
case PLAYING:
|
||||
System.out.println();
|
||||
System.out.println("ROUND " + this.round);
|
||||
System.out.println("=======");
|
||||
|
||||
// Each player takes their turn
|
||||
for(int i=0; i<players.size(); i++) {
|
||||
Player player = players.get(i);
|
||||
int playerThrow = getPlayersThrow(player);
|
||||
int points = calculatePlayerPoints(playerThrow);
|
||||
player.addScore(points);
|
||||
System.out.println("TOTAL SCORE = " + player.getScore());
|
||||
}
|
||||
|
||||
boolean foundWinner = false;
|
||||
|
||||
// Check if any player won
|
||||
for(int i=0; i<players.size(); i++) {
|
||||
Player thePlayer = players.get(i);
|
||||
int score = thePlayer.getScore();
|
||||
if(score >=200) {
|
||||
if(!foundWinner) {
|
||||
System.out.println("WE HAVE A WINNER!!");
|
||||
System.out.println();
|
||||
foundWinner = true;
|
||||
}
|
||||
System.out.println(thePlayer.getName() + " SCORED "
|
||||
+ thePlayer.getScore() + " POINTS");
|
||||
}
|
||||
}
|
||||
|
||||
if(foundWinner) {
|
||||
System.out.println("THANKS FOR THE GAME.");
|
||||
gameState = GAME_STATE.GAME_OVER;
|
||||
} else {
|
||||
// No winner found, continue on with the next round
|
||||
this.round++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} while(gameState != GAME_STATE.GAME_OVER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display info about the game
|
||||
*
|
||||
*/
|
||||
private void intro() {
|
||||
System.out.println("BULLSEYE");
|
||||
System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
|
||||
System.out.println();
|
||||
System.out.println("IN THIS GAME, UP TO 20 PLAYERS THROW DARTS AT A TARGET");
|
||||
System.out.println("WITH 10, 20, 30, AND 40 POINT ZONES. THE OBJECTIVE IS");
|
||||
System.out.println("TO GET 200 POINTS.");
|
||||
System.out.println();
|
||||
System.out.println(paddedString("THROW", "DESCRIPTION", "PROBABLE SCORE"));
|
||||
System.out.println(paddedString("1", "FAST OVERARM","BULLSEYE OR COMPLETE MISS"));
|
||||
System.out.println(paddedString("2", "CONTROLLED OVERARM", "10, 20 OR 30 POINTS"));
|
||||
System.out.println(paddedString("3", "UNDERARM", "ANYTHING"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the players score
|
||||
* Score is based on the type of shot plus a random factor
|
||||
*
|
||||
* @param playerThrow 1,2, or 3 indicating the type of shot
|
||||
* @return player score
|
||||
*/
|
||||
private int calculatePlayerPoints(int playerThrow) {
|
||||
|
||||
// -1 is because of 0 base Java array
|
||||
double p1 = this.shots[playerThrow-1].getShot(0);
|
||||
double p2 = this.shots[playerThrow-1].getShot(1);
|
||||
double p3 = this.shots[playerThrow-1].getShot(2);
|
||||
double p4 = this.shots[playerThrow-1].getShot(3);
|
||||
|
||||
double random = Math.random();
|
||||
|
||||
int points;
|
||||
|
||||
if(random >= p1) {
|
||||
System.out.println("BULLSEYE!! 40 POINTS!");
|
||||
points = 40;
|
||||
// If the throw was 1 (bullseye or missed, then make it missed
|
||||
// N.B. This is a fix for the basic code which for shot type 1
|
||||
// allowed a bullseye but did not make the score zero if a bullseye
|
||||
// was not made (which it should have done).
|
||||
} else if (playerThrow == 1) {
|
||||
System.out.println("MISSED THE TARGET! TOO BAD.");
|
||||
points = 0;
|
||||
} else if(random >= p2) {
|
||||
System.out.println("30-POINT ZONE!");
|
||||
points = 30;
|
||||
} else if(random >= p3) {
|
||||
System.out.println("20-POINT ZONE");
|
||||
points = 20;
|
||||
} else if(random >= p4) {
|
||||
System.out.println("WHEW! 10 POINTS.");
|
||||
points = 10;
|
||||
} else {
|
||||
System.out.println("MISSED THE TARGET! TOO BAD.");
|
||||
points = 0;
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get players shot 1,2, or 3 - ask again if invalid input
|
||||
*
|
||||
* @param player
|
||||
* @return 1,2, or 3 indicating the players shot
|
||||
*/
|
||||
private int getPlayersThrow(Player player) {
|
||||
boolean inputCorrect = false;
|
||||
String theThrow;
|
||||
do {
|
||||
theThrow = displayTextAndGetInput(player.getName() + "'S THROW ");
|
||||
if(theThrow.equals("1") || theThrow.equals("2") || theThrow.equals("3")) {
|
||||
inputCorrect = true;
|
||||
} else {
|
||||
System.out.println("INPUT 1, 2, OR 3!");
|
||||
}
|
||||
|
||||
} while(!inputCorrect);
|
||||
|
||||
return Integer.valueOf(theThrow);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get players guess from kb
|
||||
*
|
||||
* @return players guess as an int
|
||||
*/
|
||||
private int chooseNumberOfPlayers() {
|
||||
|
||||
return Integer.valueOf((displayTextAndGetInput("HOW MANY PLAYERS? ")));
|
||||
}
|
||||
/*
|
||||
* Print a message on the screen, then accept input from Keyboard.
|
||||
*
|
||||
* @param text message to be displayed on screen.
|
||||
* @return what was typed by the player.
|
||||
*/
|
||||
private String displayTextAndGetInput(String text) {
|
||||
System.out.print(text);
|
||||
return kbScanner.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format three strings to a given number of spaces
|
||||
* Replacing the original basic code which used tabs
|
||||
*
|
||||
* @param first String to print in pos 1
|
||||
* @param second String to print in pos 2
|
||||
* @param third String to print in pos 3
|
||||
* @return formatted string
|
||||
*/
|
||||
private String paddedString(String first, String second, String third) {
|
||||
String output = String.format("%1$" + FIRST_IDENT + "s", first);
|
||||
output += String.format("%1$" + SECOND_IDENT + "s", second);
|
||||
output += String.format("%1$" + THIRD_INDENT + "s", third);
|
||||
return output;
|
||||
}
|
||||
}
|
||||
8
18 Bullseye/java/src/BullseyeGame.java
Normal file
8
18 Bullseye/java/src/BullseyeGame.java
Normal file
@@ -0,0 +1,8 @@
|
||||
public class BullseyeGame {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Bullseye bullseye = new Bullseye();
|
||||
bullseye.play();
|
||||
}
|
||||
}
|
||||
26
18 Bullseye/java/src/Player.java
Normal file
26
18 Bullseye/java/src/Player.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* A Player in the game - consists of name and score
|
||||
*
|
||||
*/
|
||||
public class Player {
|
||||
|
||||
private String name;
|
||||
private int score;
|
||||
|
||||
Player(String name) {
|
||||
this.name = name;
|
||||
this.score = 0;
|
||||
}
|
||||
|
||||
public void addScore(int score) {
|
||||
this.score += score;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
}
|
||||
21
18 Bullseye/java/src/Shot.java
Normal file
21
18 Bullseye/java/src/Shot.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* This class records the percentage chance of a given type of shot
|
||||
* scoring specific points
|
||||
* see Bullseye class points calculation method where its used
|
||||
*/
|
||||
public class Shot {
|
||||
|
||||
double[] chances;
|
||||
|
||||
// Array of doubles are passed for a specific type of shot
|
||||
Shot(double[] shots) {
|
||||
chances = new double[shots.length];
|
||||
for(int i=0; i<shots.length; i++) {
|
||||
chances[i] = shots[i];
|
||||
}
|
||||
}
|
||||
|
||||
public double getShot(int index) {
|
||||
return chances[index];
|
||||
}
|
||||
}
|
||||
186
51 Hurkle/java/src/Hurkle.java
Normal file
186
51 Hurkle/java/src/Hurkle.java
Normal file
@@ -0,0 +1,186 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Hurkle {
|
||||
|
||||
public static final int GRID_SIZE = 10;
|
||||
public static final int MAX_GUESSES = 5;
|
||||
|
||||
private enum GAME_STATE {
|
||||
STARTING,
|
||||
START_GAME,
|
||||
GUESSING,
|
||||
PLAY_AGAIN,
|
||||
GAME_OVER
|
||||
}
|
||||
|
||||
private GAME_STATE gameState;
|
||||
|
||||
// Used for keyboard input
|
||||
private Scanner kbScanner;
|
||||
|
||||
private int guesses;
|
||||
|
||||
// hurkle position
|
||||
private int hurkleXPos;
|
||||
private int hurkleYPos;
|
||||
|
||||
// player guess
|
||||
private int playerGuessXPos;
|
||||
private int playerGuessYPos;
|
||||
|
||||
public Hurkle() {
|
||||
|
||||
gameState = GAME_STATE.STARTING;
|
||||
|
||||
// Initialise kb scanner
|
||||
kbScanner = new Scanner(System.in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main game loop
|
||||
*/
|
||||
public void play() {
|
||||
|
||||
do {
|
||||
switch (gameState) {
|
||||
|
||||
// Show an introduction the first time the game is played.
|
||||
case STARTING:
|
||||
intro();
|
||||
gameState = GAME_STATE.START_GAME;
|
||||
break;
|
||||
|
||||
// Start the game, set the number of players, names and round
|
||||
case START_GAME:
|
||||
|
||||
this.hurkleXPos = randomNumber();
|
||||
this.hurkleYPos = randomNumber();
|
||||
System.out.println("HURKLE AT : " + this.hurkleXPos + "," + this.hurkleYPos);
|
||||
|
||||
this.guesses = 1;
|
||||
gameState = GAME_STATE.GUESSING;
|
||||
|
||||
break;
|
||||
|
||||
// Guess an x,y position of the hurkle
|
||||
case GUESSING:
|
||||
String guess = displayTextAndGetInput("GUESS #" + this.guesses + "? ");
|
||||
this.playerGuessXPos = getDelimitedValue(guess, 0);
|
||||
this.playerGuessYPos = getDelimitedValue(guess, 1);
|
||||
if (foundHurkle()) {
|
||||
this.gameState = GAME_STATE.PLAY_AGAIN;
|
||||
} else {
|
||||
showDirectionOfHurkle();
|
||||
this.guesses++;
|
||||
if(this.guesses > MAX_GUESSES) {
|
||||
System.out.println("SORRY, THAT'S "
|
||||
+ MAX_GUESSES + " GUESSES.");
|
||||
System.out.println("THE HURKLE IS AT "
|
||||
+ this.hurkleXPos + "," + this.hurkleYPos);
|
||||
System.out.println();
|
||||
this.gameState = GAME_STATE.PLAY_AGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PLAY_AGAIN:
|
||||
System.out.println("LET'S PLAY AGAIN, HURKLE IS HIDING.");
|
||||
System.out.println();
|
||||
this.gameState = GAME_STATE.START_GAME;
|
||||
break;
|
||||
}
|
||||
// Effectively an endless loop because the game never quits as per
|
||||
// the original basic code.
|
||||
} while (gameState != GAME_STATE.GAME_OVER);
|
||||
}
|
||||
|
||||
private void showDirectionOfHurkle() {
|
||||
System.out.print("GO ");
|
||||
if(this.playerGuessYPos == this.hurkleYPos) {
|
||||
// don't print North or South because the player has chosen the
|
||||
// same y grid pos as the hurkle
|
||||
} else if (this.playerGuessYPos < this.hurkleYPos) {
|
||||
System.out.print("NORTH");
|
||||
} else if(this.playerGuessYPos > this.hurkleYPos) {
|
||||
System.out.print("SOUTH");
|
||||
}
|
||||
|
||||
if(this.playerGuessXPos == this.hurkleXPos) {
|
||||
// don't print East or West because the player has chosen the
|
||||
// same x grid pos as the hurkle
|
||||
} else if(this.playerGuessXPos < this.hurkleXPos) {
|
||||
System.out.print("EAST");
|
||||
} else if(this.playerGuessXPos > this.hurkleXPos) {
|
||||
System.out.print("WEST");
|
||||
}
|
||||
System.out.println();
|
||||
return;
|
||||
}
|
||||
|
||||
private boolean foundHurkle() {
|
||||
if ((this.playerGuessXPos - this.hurkleXPos)
|
||||
- (this.playerGuessYPos - this.hurkleYPos) == 0) {
|
||||
System.out.println("YOU FOUND HIM IN " + this.guesses + " GUESSES.");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display info about the game
|
||||
*/
|
||||
private void intro() {
|
||||
System.out.println("HURKLE");
|
||||
System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
|
||||
System.out.println();
|
||||
System.out.println("A HURKLE IS HIDING ON A " + GRID_SIZE + " BY "
|
||||
+ GRID_SIZE + " GRID. HOMEBASE");
|
||||
System.out.println("ON THE GRID IS POINT 0,0 IN THE SOUTHWEST CORNER,");
|
||||
System.out.println("AND ANY POINT ON THE GRID IS DESIGNATED BY A");
|
||||
System.out.println("PAIR OF WHOLE NUMBERS SEPERATED BY A COMMA. THE FIRST");
|
||||
System.out.println("NUMBER IS THE HORIZONTAL POSITION AND THE SECOND NUMBER");
|
||||
System.out.println("IS THE VERTICAL POSITION. YOU MUST TRY TO");
|
||||
System.out.println("GUESS THE HURKLE'S GRIDPOINT. YOU GET "
|
||||
+ MAX_GUESSES + " TRIES.");
|
||||
System.out.println("AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE");
|
||||
System.out.println("DIRECTION TO GO TO LOOK FOR THE HURKLE.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate random number
|
||||
* Used to create one part of an x,y grid position
|
||||
*
|
||||
* @return random number
|
||||
*/
|
||||
private int randomNumber() {
|
||||
return (int) (Math.random()
|
||||
* (GRID_SIZE) + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a message on the screen, then accept input from Keyboard.
|
||||
*
|
||||
* @param text message to be displayed on screen.
|
||||
* @return what was typed by the player.
|
||||
*/
|
||||
private String displayTextAndGetInput(String text) {
|
||||
System.out.print(text);
|
||||
return kbScanner.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a string delimited by comma's and returns the pos'th delimited
|
||||
* value (starting at count 0).
|
||||
*
|
||||
* @param text - text with values separated by comma's
|
||||
* @param pos - which position to return a value for
|
||||
* @return the int representation of the value
|
||||
*/
|
||||
private int getDelimitedValue(String text, int pos) {
|
||||
String[] tokens = text.split(",");
|
||||
return Integer.parseInt(tokens[pos]);
|
||||
}
|
||||
}
|
||||
7
51 Hurkle/java/src/HurkleGame.java
Normal file
7
51 Hurkle/java/src/HurkleGame.java
Normal file
@@ -0,0 +1,7 @@
|
||||
public class HurkleGame {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Hurkle hurkle = new Hurkle();
|
||||
hurkle.play();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user