Removed spaces from top-level directory names.

Spaces tend to cause annoyances in a Unix-style shell environment.
This change fixes that.
This commit is contained in:
Chris Reuter
2021-11-21 18:30:21 -05:00
parent df2e7426eb
commit d26dbf036a
1725 changed files with 0 additions and 0 deletions

3
16_Bug/java/README.md Normal file
View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Oracle Java](https://openjdk.java.net/)

253
16_Bug/java/src/Bug.java Normal file
View File

@@ -0,0 +1,253 @@
import java.util.ArrayList;
import java.util.Scanner;
/**
* Game of Bug
* <p>
* Based on the Basic game of Bug here
* https://github.com/coding-horror/basic-computer-games/blob/main/16%20Bug/bug.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 Bug {
// Dice roll
public static final int SIX = 6;
private enum GAME_STATE {
START,
PLAYER_TURN,
COMPUTER_TURN,
CHECK_FOR_WINNER,
GAME_OVER
}
// Used for keyboard input
private final Scanner kbScanner;
// Current game state
private GAME_STATE gameState;
private final Insect playersBug;
private final Insect computersBug;
// Used to show the result of dice roll.
private final String[] ROLLS = new String[]{"BODY", "NECK", "HEAD", "FEELERS", "TAIL", "LEGS"};
public Bug() {
playersBug = new PlayerBug();
computersBug = new ComputerBug();
gameState = GAME_STATE.START;
// 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.
// And optionally instructions.
case START:
intro();
if (!noEntered(displayTextAndGetInput("DO YOU WANT INSTRUCTIONS? "))) {
instructions();
}
gameState = GAME_STATE.PLAYER_TURN;
break;
case PLAYER_TURN:
int playersRoll = randomNumber();
System.out.println("YOU ROLLED A " + playersRoll + "=" + ROLLS[playersRoll - 1]);
switch (playersRoll) {
case 1:
System.out.println(playersBug.addBody());
break;
case 2:
System.out.println(playersBug.addNeck());
break;
case 3:
System.out.println(playersBug.addHead());
break;
case 4:
System.out.println(playersBug.addFeelers());
break;
case 5:
System.out.println(playersBug.addTail());
break;
case 6:
System.out.println(playersBug.addLeg());
break;
}
gameState = GAME_STATE.COMPUTER_TURN;
break;
case COMPUTER_TURN:
int computersRoll = randomNumber();
System.out.println("I ROLLED A " + computersRoll + "=" + ROLLS[computersRoll - 1]);
switch (computersRoll) {
case 1:
System.out.println(computersBug.addBody());
break;
case 2:
System.out.println(computersBug.addNeck());
break;
case 3:
System.out.println(computersBug.addHead());
break;
case 4:
System.out.println(computersBug.addFeelers());
break;
case 5:
System.out.println(computersBug.addTail());
break;
case 6:
System.out.println(computersBug.addLeg());
break;
}
gameState = GAME_STATE.CHECK_FOR_WINNER;
break;
case CHECK_FOR_WINNER:
boolean gameOver = false;
if (playersBug.complete()) {
System.out.println("YOUR BUG IS FINISHED.");
gameOver = true;
} else if (computersBug.complete()) {
System.out.println("MY BUG IS FINISHED.");
gameOver = true;
}
if (noEntered(displayTextAndGetInput("DO YOU WANT THE PICTURES? "))) {
gameState = GAME_STATE.PLAYER_TURN;
} else {
System.out.println("*****YOUR BUG*****");
System.out.println();
draw(playersBug);
System.out.println();
System.out.println("*****MY BUG*****");
System.out.println();
draw(computersBug);
gameState = GAME_STATE.PLAYER_TURN;
}
if (gameOver) {
System.out.println("I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!");
gameState = GAME_STATE.GAME_OVER;
}
}
} while (gameState != GAME_STATE.GAME_OVER);
}
/**
* Draw the bug (player or computer) based on what has
* already been added to it.
*
* @param bug The bug to be drawn.
*/
private void draw(Insect bug) {
ArrayList<String> insectOutput = bug.draw();
for (String s : insectOutput) {
System.out.println(s);
}
}
/**
* Display an intro
*/
private void intro() {
System.out.println("BUG");
System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println("THE GAME BUG");
System.out.println("I HOPE YOU ENJOY THIS GAME.");
}
private void instructions() {
System.out.println("THE OBJECT OF BUG IS TO FINISH YOUR BUG BEFORE I FINISH");
System.out.println("MINE. EACH NUMBER STANDS FOR A PART OF THE BUG BODY.");
System.out.println("I WILL ROLL THE DIE FOR YOU, TELL YOU WHAT I ROLLED FOR YOU");
System.out.println("WHAT THE NUMBER STANDS FOR, AND IF YOU CAN GET THE PART.");
System.out.println("IF YOU CAN GET THE PART I WILL GIVE IT TO YOU.");
System.out.println("THE SAME WILL HAPPEN ON MY TURN.");
System.out.println("IF THERE IS A CHANGE IN EITHER BUG I WILL GIVE YOU THE");
System.out.println("OPTION OF SEEING THE PICTURES OF THE BUGS.");
System.out.println("THE NUMBERS STAND FOR PARTS AS FOLLOWS:");
System.out.println("NUMBER\tPART\tNUMBER OF PART NEEDED");
System.out.println("1\tBODY\t1");
System.out.println("2\tNECK\t1");
System.out.println("3\tHEAD\t1");
System.out.println("4\tFEELERS\t2");
System.out.println("5\tTAIL\t1");
System.out.println("6\tLEGS\t6");
System.out.println();
}
/**
* Checks whether player entered N or NO to a question.
*
* @param text player string from kb
* @return true if N or NO was entered, otherwise false
*/
private boolean noEntered(String text) {
return stringIsAnyValue(text, "N", "NO");
}
/**
* Check whether a string equals one of a variable number of values
* Useful to check for Y or YES for example
* Comparison is case insensitive.
*
* @param text source string
* @param values a range of values to compare against the source string
* @return true if a comparison was found in one of the variable number of strings passed
*/
private boolean stringIsAnyValue(String text, String... values) {
// Cycle through the variable number of values and test each
for (String val : values) {
if (text.equalsIgnoreCase(val)) {
return true;
}
}
// no matches
return false;
}
/*
* 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();
}
/**
* Generate random number
*
* @return random number
*/
private int randomNumber() {
return (int) (Math.random()
* (SIX) + 1);
}
}

View File

@@ -0,0 +1,10 @@
public class BugGame {
public static void main(String[] args) {
Bug bug = new Bug();
bug.play();
}
}

View File

@@ -0,0 +1,15 @@
public class ComputerBug extends Insect {
// Create messages specific to the computer player.
public ComputerBug() {
// Call superclass constructor for initialization.
super();
addMessages(new String[]{"I GET A FEELER.", "I HAVE " + MAX_FEELERS + " FEELERS ALREADY.", "I DO NOT HAVE A HEAD."}, PARTS.FEELERS);
addMessages(new String[]{"I NEEDED A HEAD.", "I DO NOT NEED A HEAD.", "I DO NOT HAVE A NECK."}, PARTS.HEAD);
addMessages(new String[]{"I NOW HAVE A NECK.", "I DO NOT NEED A NECK.", "I DO NOT HAVE A BODY."}, PARTS.NECK);
addMessages(new String[]{"I NOW HAVE A BODY.", "I DO NOT NEED A BODY."}, PARTS.BODY);
addMessages(new String[]{"I NOW HAVE A TAIL.", "I DO NOT NEED A TAIL.", "I DO NOT HAVE A BODY."}, PARTS.TAIL);
addMessages(new String[]{"I NOW HAVE ^^^" + " LEG", "I HAVE " + MAX_LEGS + " FEET.", "I DO NOT HAVE A BODY."}, PARTS.LEGS);
}
}

363
16_Bug/java/src/Insect.java Normal file
View File

@@ -0,0 +1,363 @@
import java.util.ArrayList;
import java.util.Arrays;
/**
* This tracks the insect (bug) and has methods to
* add body parts, create an array of output so it
* can be drawn and to determine if a bug is complete.
* N.B. This is a super class for ComputerBug and PlayerBug
*/
public class Insect {
public static final int MAX_FEELERS = 2;
public static final int MAX_LEGS = 6;
public static final int ADDED = 0;
public static final int NOT_ADDED = 1;
public static final int MISSING = 2;
// Various parts of the bug
public enum PARTS {
FEELERS,
HEAD,
NECK,
BODY,
TAIL,
LEGS
}
// Tracks what parts of the bug have been added
private boolean body;
private boolean neck;
private boolean head;
private int feelers;
private boolean tail;
private int legs;
// Messages about for various body parts
// These are set in the subclass ComputerBug or PlayerBug
private String[] bodyMessages;
private String[] neckMessages;
private String[] headMessages;
private String[] feelerMessages;
private String[] tailMessages;
private String[] legMessages;
public Insect() {
init();
}
/**
* Add a body to the bug if there is not one already added.
*
* @return return an appropriate message about the status of the operation.
*/
public String addBody() {
boolean currentState = false;
if (!body) {
body = true;
currentState = true;
}
return addBodyMessage(currentState);
}
/**
* Create output based on adding the body or it being already added previously
*
* @return contains the output message
*/
private String addBodyMessage(boolean wasAdded) {
// Return the appropriate message depending on whether the
// body was added or not.
if (wasAdded) {
return bodyMessages[ADDED];
} else {
return bodyMessages[NOT_ADDED];
}
}
/**
* Add a neck if a) a body has previously been added and
* b) a neck has not previously been added.
*
* @return text containing the status of the operation
*/
public String addNeck() {
int status = NOT_ADDED; // Default is not added
if (!body) {
// No body, cannot add a neck
status = MISSING;
} else if (!neck) {
neck = true;
status = ADDED;
}
return neckMessages[status];
}
/**
* Add a head to the bug if a) there already exists a neck and
* b) a head has not previously been added
*
* @return text outlining the success of the operation
*/
public String addHead() {
int status = NOT_ADDED; // Default is not added
if (!neck) {
// No neck, cannot add a head
status = MISSING;
} else if (!head) {
head = true;
status = ADDED;
}
return headMessages[status];
}
/**
* Add a feeler to the head if a) there has been a head added to
* the bug previously, and b) there are not already 2 (MAX_FEELERS)
* feelers previously added to the bug.
*
* @return text outlining the status of the operation
*/
public String addFeelers() {
int status = NOT_ADDED; // Default is not added
if (!head) {
// No head, cannot add a feeler
status = MISSING;
} else if (feelers < MAX_FEELERS) {
feelers++;
status = ADDED;
}
return feelerMessages[status];
}
/**
* Add a tail to the bug if a) there is already a body previously added
* to the bug and b) there is not already a tail added.
*
* @return text outlining the status of the operation.
*/
public String addTail() {
int status = NOT_ADDED; // Default is not added
if (!body) {
// No body, cannot add a tail
status = MISSING;
} else if (!tail) {
tail = true;
status = ADDED;
}
return tailMessages[status];
}
/**
* Add a leg to the bug if a) there is already a body previously added
* b) there are less than 6 (MAX_LEGS) previously added.
*
* @return text outlining status of the operation.
*/
public String addLeg() {
int status = NOT_ADDED; // Default is not added
if (!body) {
// No body, cannot add a leg
status = MISSING;
} else if (legs < MAX_LEGS) {
legs++;
status = ADDED;
}
String message = "";
// Create a string showing the result of the operation
switch(status) {
case ADDED:
// Replace # with number of legs
message = legMessages[status].replace("^^^", String.valueOf(legs));
// Add text S. if >1 leg, or just . if one leg.
if (legs > 1) {
message += "S.";
} else {
message += ".";
}
break;
case NOT_ADDED:
// Deliberate fall through to next case as its the
// same code to be executed
case MISSING:
message = legMessages[status];
break;
}
return message;
}
/**
* Initialise
*/
public void init() {
body = false;
neck = false;
head = false;
feelers = 0;
tail = false;
legs = 0;
}
/**
* Add unique messages depending on type of player
* A subclass of this class calls this method
* e.g. See ComputerBug or PlayerBug classes
*
* @param messages an array of messages
* @param bodyPart the bodypart the messages relate to.
*/
public void addMessages(String[] messages, PARTS bodyPart) {
switch (bodyPart) {
case FEELERS:
feelerMessages = messages;
break;
case HEAD:
headMessages = messages;
break;
case NECK:
neckMessages = messages;
break;
case BODY:
bodyMessages = messages;
break;
case TAIL:
tailMessages = messages;
break;
case LEGS:
legMessages = messages;
break;
}
}
/**
* Returns a string array containing
* the "bug" that can be output to console
*
* @return the bug ready to draw
*/
public ArrayList<String> draw() {
ArrayList<String> bug = new ArrayList<>();
StringBuilder lineOutput;
// Feelers
if (feelers > 0) {
for (int i = 0; i < 4; i++) {
lineOutput = new StringBuilder(addSpaces(10));
for (int j = 0; j < feelers; j++) {
lineOutput.append("A ");
}
bug.add(lineOutput.toString());
}
}
if (head) {
lineOutput = new StringBuilder(addSpaces(8) + "HHHHHHH");
bug.add(lineOutput.toString());
lineOutput = new StringBuilder(addSpaces(8) + "H" + addSpaces(5) + "H");
bug.add(lineOutput.toString());
lineOutput = new StringBuilder(addSpaces(8) + "H O O H");
bug.add(lineOutput.toString());
lineOutput = new StringBuilder(addSpaces(8) + "H" + addSpaces(5) + "H");
bug.add(lineOutput.toString());
lineOutput = new StringBuilder(addSpaces(8) + "H" + addSpaces(2) + "V" + addSpaces(2) + "H");
bug.add(lineOutput.toString());
lineOutput = new StringBuilder(addSpaces(8) + "HHHHHHH");
bug.add(lineOutput.toString());
}
if (neck) {
for (int i = 0; i < 2; i++) {
lineOutput = new StringBuilder(addSpaces(10) + "N N");
bug.add(lineOutput.toString());
}
}
if (body) {
lineOutput = new StringBuilder(addSpaces(5) + "BBBBBBBBBBBB");
bug.add(lineOutput.toString());
for (int i = 0; i < 2; i++) {
lineOutput = new StringBuilder(addSpaces(5) + "B" + addSpaces(10) + "B");
bug.add(lineOutput.toString());
}
if (tail) {
lineOutput = new StringBuilder("TTTTTB" + addSpaces(10) + "B");
bug.add(lineOutput.toString());
}
lineOutput = new StringBuilder(addSpaces(5) + "BBBBBBBBBBBB");
bug.add(lineOutput.toString());
}
if (legs > 0) {
for (int i = 0; i < 2; i++) {
lineOutput = new StringBuilder(addSpaces(5));
for (int j = 0; j < legs; j++) {
lineOutput.append(" L");
}
bug.add(lineOutput.toString());
}
}
return bug;
}
/**
* Check if the bug is complete i.e. it has
* 2 (MAX_FEELERS) feelers, a head, a neck, a body
* a tail and 6 (MAX_FEET) feet.
*
* @return true if complete.
*/
public boolean complete() {
return (feelers == MAX_FEELERS)
&& head
&& neck
&& body
&& tail
&& (legs == MAX_LEGS);
}
/**
* Simulate tabs be creating a string of X spaces.
*
* @param number contains number of spaces needed.
* @return a String containing the spaces
*/
private String addSpaces(int number) {
char[] spaces = new char[number];
Arrays.fill(spaces, ' ');
return new String(spaces);
}
}

View File

@@ -0,0 +1,18 @@
public class PlayerBug extends Insect {
// Create messages specific to the player.
public PlayerBug() {
// Call superclass constructor for initialization.
super();
addMessages(new String[]{"I NOW GIVE YOU A FEELER.", "YOU HAVE " + MAX_FEELERS + " FEELERS ALREADY.", "YOU DO NOT HAVE A HEAD."}, PARTS.FEELERS);
addMessages(new String[]{"YOU NEEDED A HEAD.", "YOU HAVE A HEAD.", "YOU DO NOT HAVE A NECK."}, PARTS.HEAD);
addMessages(new String[]{"YOU NOW HAVE A NECK.", "YOU DO NOT NEED A NECK.", "YOU DO NOT HAVE A BODY."}, PARTS.NECK);
addMessages(new String[]{"YOU NOW HAVE A BODY.", "YOU DO NOT NEED A BODY."}, PARTS.BODY);
addMessages(new String[]{"I NOW GIVE YOU A TAIL.", "YOU ALREADY HAVE A TAIL.", "YOU DO NOT HAVE A BODY."}, PARTS.TAIL);
addMessages(new String[]{"YOU NOW HAVE ^^^ LEG", "YOU HAVE " + MAX_LEGS + " FEET ALREADY.", "YOU DO NOT HAVE A BODY."}, PARTS.LEGS);
}
}