mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-23 07:29:02 -08:00
Java version of Kinema
This commit is contained in:
176
52 Kinema/java/src/Kinema.java
Normal file
176
52 Kinema/java/src/Kinema.java
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game of Kinema
|
||||||
|
* <p>
|
||||||
|
* Based on the Basic game of Kinema here
|
||||||
|
* https://github.com/coding-horror/basic-computer-games/blob/main/52%20Kinema/kinema.bas
|
||||||
|
* <p>
|
||||||
|
* Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
|
||||||
|
* new features - no additional text, error checking, etc has been added.
|
||||||
|
*/
|
||||||
|
public class Kinema {
|
||||||
|
|
||||||
|
// Used for keyboard input
|
||||||
|
private final Scanner kbScanner;
|
||||||
|
|
||||||
|
private enum GAME_STATE {
|
||||||
|
STARTUP,
|
||||||
|
INIT,
|
||||||
|
HOW_HIGH,
|
||||||
|
SECONDS_TILL_IT_RETURNS,
|
||||||
|
ITS_VELOCITY,
|
||||||
|
RESULTS,
|
||||||
|
GAME_OVER
|
||||||
|
}
|
||||||
|
|
||||||
|
// Current game state
|
||||||
|
private GAME_STATE gameState;
|
||||||
|
|
||||||
|
private int numberAnswersCorrect;
|
||||||
|
|
||||||
|
// How many meters per second a ball is thrown
|
||||||
|
private int velocity;
|
||||||
|
|
||||||
|
public Kinema() {
|
||||||
|
kbScanner = new Scanner(System.in);
|
||||||
|
|
||||||
|
gameState = GAME_STATE.STARTUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main game loop
|
||||||
|
*/
|
||||||
|
public void play() {
|
||||||
|
|
||||||
|
double playerAnswer;
|
||||||
|
double correctAnswer;
|
||||||
|
do {
|
||||||
|
switch (gameState) {
|
||||||
|
|
||||||
|
case STARTUP:
|
||||||
|
intro();
|
||||||
|
gameState = GAME_STATE.INIT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INIT:
|
||||||
|
numberAnswersCorrect = 0;
|
||||||
|
|
||||||
|
// calculate a random velocity for the player to use in the calculations
|
||||||
|
velocity = 5 + (int) (35 * Math.random());
|
||||||
|
System.out.println("A BALL IS THROWN UPWARDS AT " + velocity + " METERS PER SECOND.");
|
||||||
|
gameState = GAME_STATE.HOW_HIGH;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HOW_HIGH:
|
||||||
|
|
||||||
|
playerAnswer = displayTextAndGetNumber("HOW HIGH WILL IT GO (IN METERS)? ");
|
||||||
|
|
||||||
|
// Calculate the correct answer to how high it will go
|
||||||
|
correctAnswer = 0.05 * Math.pow(velocity, 2);
|
||||||
|
if (calculate(playerAnswer, correctAnswer)) {
|
||||||
|
numberAnswersCorrect++;
|
||||||
|
}
|
||||||
|
gameState = GAME_STATE.ITS_VELOCITY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ITS_VELOCITY:
|
||||||
|
|
||||||
|
playerAnswer = displayTextAndGetNumber("HOW LONG UNTIL IT RETURNS (IN SECONDS)? ");
|
||||||
|
|
||||||
|
// Calculate current Answer for how long until it returns to the ground in seconds
|
||||||
|
correctAnswer = (double) velocity / 5;
|
||||||
|
if (calculate(playerAnswer, correctAnswer)) {
|
||||||
|
numberAnswersCorrect++;
|
||||||
|
}
|
||||||
|
gameState = GAME_STATE.SECONDS_TILL_IT_RETURNS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SECONDS_TILL_IT_RETURNS:
|
||||||
|
|
||||||
|
// Calculate random number of seconds for 3rd question
|
||||||
|
double seconds = 1 + (Math.random() * (2 * velocity)) / 10;
|
||||||
|
|
||||||
|
// Round to one decimal place.
|
||||||
|
double scale = Math.pow(10, 1);
|
||||||
|
seconds = Math.round(seconds * scale) / scale;
|
||||||
|
|
||||||
|
playerAnswer = displayTextAndGetNumber("WHAT WILL ITS VELOCITY BE AFTER " + seconds + " SECONDS? ");
|
||||||
|
|
||||||
|
// Calculate the velocity after the given number of seconds
|
||||||
|
correctAnswer = velocity - (10 * seconds);
|
||||||
|
if (calculate(playerAnswer, correctAnswer)) {
|
||||||
|
numberAnswersCorrect++;
|
||||||
|
}
|
||||||
|
gameState = GAME_STATE.RESULTS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RESULTS:
|
||||||
|
System.out.println(numberAnswersCorrect + " RIGHT OUT OF 3");
|
||||||
|
if (numberAnswersCorrect > 1) {
|
||||||
|
System.out.println(" NOT BAD.");
|
||||||
|
}
|
||||||
|
gameState = GAME_STATE.STARTUP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (gameState != GAME_STATE.GAME_OVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void intro() {
|
||||||
|
System.out.println(simulateTabs(33) + "KINEMA");
|
||||||
|
System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean calculate(double playerAnswer, double correctAnswer) {
|
||||||
|
|
||||||
|
boolean gotItRight = false;
|
||||||
|
|
||||||
|
if (Math.abs((playerAnswer - correctAnswer) / correctAnswer) < 0.15) {
|
||||||
|
System.out.println("CLOSE ENOUGH");
|
||||||
|
gotItRight = true;
|
||||||
|
} else {
|
||||||
|
System.out.println("NOT EVEN CLOSE");
|
||||||
|
}
|
||||||
|
System.out.println("CORRECT ANSWER IS " + correctAnswer);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
return gotItRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print a message on the screen, then accept input from Keyboard.
|
||||||
|
* Converts input to a Double
|
||||||
|
*
|
||||||
|
* @param text message to be displayed on screen.
|
||||||
|
* @return what was typed by the player.
|
||||||
|
*/
|
||||||
|
private double displayTextAndGetNumber(String text) {
|
||||||
|
return Double.parseDouble(displayTextAndGetInput(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulate the old basic tab(xx) command which indented text by xx spaces.
|
||||||
|
*
|
||||||
|
* @param spaces number of spaces required
|
||||||
|
* @return String with number of spaces
|
||||||
|
*/
|
||||||
|
private String simulateTabs(int spaces) {
|
||||||
|
char[] spacesTemp = new char[spaces];
|
||||||
|
Arrays.fill(spacesTemp, ' ');
|
||||||
|
return new String(spacesTemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
7
52 Kinema/java/src/KinemaGame.java
Normal file
7
52 Kinema/java/src/KinemaGame.java
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
public class KinemaGame {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Kinema kinema = new Kinema();
|
||||||
|
kinema.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user