Merge branch 'main' into 84-super-star-trek-csharp

This commit is contained in:
Andrew Cooper
2021-02-27 17:43:17 +11:00
committed by GitHub
146 changed files with 10419 additions and 386 deletions

5
.gitignore vendored
View File

@@ -1,7 +1,3 @@
################################################################################
# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
################################################################################
/01 Acey Ducey/csharp/obj
/47 Hi-Lo/csharp/obj
/.vs
@@ -13,3 +9,4 @@
*/csharp/bin
*/csharp/obj

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -1,15 +1,12 @@
package aceyducey;
import java.util.Scanner;
/**
* Game of AceyDucey
*
* <p>
* Based on the Basic game of AceyDucey here
* https://github.com/coding-horror/basic-computer-games/blob/main/01%20Acey%20Ducey/aceyducey.bas
* Note: The idea was to create a version of this 1970's Basic game in Java, without introducing
* new features - no additional text, error checking, etc has been added.
*
* 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 AceyDucey {
@@ -32,10 +29,10 @@ public class AceyDucey {
private boolean gameOver = false;
// Used for keyboard input
private Scanner kbScanner;
private final Scanner kbScanner;
// Constant value for cards from a deck - 2 lowest, 14 (Ace) highest
public static final int LOW_CARD_RANGE =2;
public static final int LOW_CARD_RANGE = 2;
public static final int HIGH_CARD_RANGE = 14;
public AceyDucey() {
@@ -58,7 +55,7 @@ public class AceyDucey {
String playAgain = kbScanner.next().toUpperCase();
System.out.println();
System.out.println();
if(playAgain.equals("YES")) {
if (playAgain.equals("YES")) {
return true;
} else {
System.out.println("O.K., HOPE YOU HAD FUN!");
@@ -71,9 +68,8 @@ public class AceyDucey {
public void play() {
// Keep playing hands until player runs out of cash
// which sets gameover to true
do {
if(firstTimePlaying) {
if (firstTimePlaying) {
intro();
firstTimePlaying = false;
}
@@ -81,17 +77,17 @@ public class AceyDucey {
drawCards();
displayCards();
int betAmount = getBet();
this.playersCard = randomCard();
playersCard = randomCard();
displayPlayerCard();
if(playerWon()) {
if (playerWon()) {
System.out.println("YOU WIN!!");
this.playerAmount += betAmount;
playerAmount += betAmount;
} else {
System.out.println("SORRY, YOU LOSE");
this.playerAmount -= betAmount;
playerAmount -= betAmount;
// Player run out of money?
if(this.playerAmount <=0) {
this.gameOver = true;
if (playerAmount <= 0) {
gameOver = true;
}
}
@@ -102,18 +98,14 @@ public class AceyDucey {
// to win a players card has to be in the range of the first and second dealer
// drawn cards inclusive of first and second cards.
private boolean playerWon() {
if((this.playersCard.getValue() >= this.firstCard.getValue())
&& this.playersCard.getValue() <= this.secondCard.getValue()) {
// winner
return true;
}
return false;
// winner
return (playersCard.getValue() >= firstCard.getValue())
&& playersCard.getValue() <= secondCard.getValue();
}
private void displayPlayerCard() {
System.out.println(this.playersCard.getName());
System.out.println(playersCard.getName());
}
// Get the players bet, and return the amount
@@ -121,16 +113,16 @@ public class AceyDucey {
// method will loop until a valid bet is entered.
private int getBet() {
boolean validBet = false;
int amount = 0;
int amount;
do {
System.out.print("WHAT IS YOUR BET ");
amount = kbScanner.nextInt();
if(amount == 0) {
if (amount == 0) {
System.out.println("CHICKEN!!");
validBet = true;
} else if(amount > this.playerAmount) {
} else if (amount > playerAmount) {
System.out.println("SORRY, MY FRIEND, BUT YOU BET TOO MUCH.");
System.out.println("YOU HAVE ONLY " + this.playerAmount + " DOLLARS TO BET.");
System.out.println("YOU HAVE ONLY " + playerAmount + " DOLLARS TO BET.");
} else {
validBet = true;
}
@@ -140,13 +132,13 @@ public class AceyDucey {
}
private void displayBalance() {
System.out.println("YOU NOW HAVE " + this.playerAmount + " DOLLARS.");
System.out.println("YOU NOW HAVE " + playerAmount + " DOLLARS.");
}
private void displayCards() {
System.out.println("HERE ARE YOUR NEXT TWO CARDS: ");
System.out.println(this.firstCard.getName());
System.out.println(this.secondCard.getName());
System.out.println(firstCard.getName());
System.out.println(secondCard.getName());
}
// Draw two dealer cards, and save them for later use.
@@ -154,9 +146,9 @@ public class AceyDucey {
private void drawCards() {
do {
this.firstCard = randomCard();
this.secondCard = randomCard();
} while(this.firstCard.getValue() >= this.secondCard.getValue());
firstCard = randomCard();
secondCard = randomCard();
} while (firstCard.getValue() >= secondCard.getValue());
}
// Creates a random card

View File

@@ -1,20 +1,16 @@
package aceyducey;
/**
* This class is used to invoke the game.
*
*/
public class Game {
private static AceyDucey game;
public class AceyDuceyGame {
public static void main(String[] args) {
boolean keepPlaying = true;
boolean keepPlaying;
AceyDucey game = new AceyDucey();
// Keep playing game until infinity or the player loses
do {
game = new AceyDucey();
game.play();
System.out.println();
System.out.println();

View File

@@ -1,5 +1,3 @@
package aceyducey;
/**
* A card from a deck - the value is between 2-14 to cover
* cards with a face value of 2-9 and then a Jack, Queen, King, and Ace
@@ -14,7 +12,7 @@ public class Card {
private void init(int value) {
this.value = value;
if(value <11) {
if (value < 11) {
this.name = String.valueOf(value);
} else {
switch (value) {

View File

@@ -0,0 +1,121 @@
import random
# Python translation by Frank Palazzolo - 2/2021
print(' '*28+'AMAZING PROGRAM')
print(' '*15+'CREATIVE COMPUTING MORRISTOWN, NEW JERSEY')
print()
print()
print()
while True:
width, length = input('What are your width and length?').split(',')
width = int(width)
length = int(length)
if width != 1 and length != 1:
break
print('Meaningless dimensions. Try again.')
# Build two 2D arrays
#
# used:
# Initially set to zero, unprocessed cells
# Filled in with consecutive non-zero numbers as cells are processed
#
# walls:
# Initially set to zero, (all paths blocked)
# Remains 0 if there is no exit down or right
# Set to 1 if there is an exit down
# Set to 2 if there is an exit right
# Set to 3 if there are exits down and right
used = []
walls = []
for i in range(length):
used.append([0]*width)
walls.append([0]*width)
# Use direction variables with nice names
GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN=[0,1,2,3]
# Give Exit directions nice names
EXIT_DOWN = 1
EXIT_RIGHT = 2
# Pick a random entrance, mark as used
enter_col=random.randint(0,width-1)
row,col=0,enter_col
count=1
used[row][col]=count
count=count+1
while count!=width*length+1:
# remove possible directions that are blocked or
# hit cells that we have already processed
possible_dirs = [GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN]
if col==0 or used[row][col-1]!=0:
possible_dirs.remove(GO_LEFT)
if row==0 or used[row-1][col]!=0:
possible_dirs.remove(GO_UP)
if col==width-1 or used[row][col+1]!=0:
possible_dirs.remove(GO_RIGHT)
if row==length-1 or used[row+1][col]!=0:
possible_dirs.remove(GO_DOWN)
# If we can move in a direction, move and make opening
if len(possible_dirs)!=0:
direction=random.choice(possible_dirs)
if direction==GO_LEFT:
col=col-1
walls[row][col]=EXIT_RIGHT
elif direction==GO_UP:
row=row-1
walls[row][col]=EXIT_DOWN
elif direction==GO_RIGHT:
walls[row][col]=walls[row][col]+EXIT_RIGHT
col=col+1
elif direction==GO_DOWN:
walls[row][col]=walls[row][col]+EXIT_DOWN
row=row+1
used[row][col]=count
count=count+1
# otherwise, move to the next used cell, and try again
else:
while True:
if col!=width-1:
col=col+1
elif row!=length-1:
row,col=row+1,0
else:
row,col=0,0
if used[row][col]!=0:
break
# Add a random exit
col=random.randint(0,width-1)
row=length-1
walls[row][col]=walls[row][col]+1
# Print the maze
for col in range(width):
if col==enter_col:
print('. ',end='')
else:
print('.--',end='')
print('.')
for row in range(length):
print('I',end='')
for col in range(width):
if walls[row][col]<2:
print(' I',end='')
else:
print(' ',end='')
print()
for col in range(width):
if walls[row][col]==0 or walls[row][col]==2:
print(':--',end='')
else:
print(': ',end='')
print('.')

95
03 Animal/ruby/animal.rb Normal file
View File

@@ -0,0 +1,95 @@
require 'set'
def intro
puts " ANIMAL
CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
PLAY 'GUESS THE ANIMAL'
THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT.
"
end
def ask(question)
print "#{question} "
(gets || '').chomp.upcase
end
Feature = Struct.new(:question, :yes_guess, :no_guess)
def add_guess(animals, guess)
guess.is_a?(Struct) ? get_all_animals(guess, animals) : animals.add(guess)
end
def get_all_animals(feature, animals = Set.new)
add_guess(animals, feature.yes_guess)
add_guess(animals, feature.no_guess)
animals
end
def create_feature(current_animal)
new_animal = ask('THE ANIMAL YOU WERE THINKING OF WAS A ?')
puts "PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A #{new_animal} FROM A #{current_animal}"
question = ask('?')
loop do
yes_no = ask("FOR A #{new_animal} THE ANSWER WOULD BE ?")
next unless ['Y', 'N'].include?(yes_no[0])
guesses = yes_no[0] == 'Y' ? [new_animal, current_animal] : [current_animal, new_animal]
return Feature.new(question, *guesses)
end
end
def guess_loop(feature)
loop do
answer = ask(feature.question)
next unless ['Y', 'N'].include?(answer[0])
answer_is_yes = answer[0] == 'Y'
name = answer_is_yes ? feature.yes_guess : feature.no_guess
if name.is_a?(Struct)
feature = name
next
end
guess = ask("IS IT A #{name}?")
correct_guess = guess[0] == 'Y'
if correct_guess
puts "WHY NOT TRY ANOTHER ANIMAL?"
break
end
if answer_is_yes
feature.yes_guess = create_feature(name)
else
feature.no_guess = create_feature(name)
end
break
end
end
def main
intro
feature = Feature.new('DOES IT SWIM?', 'FISH', 'BIRD')
while true do
option = ask("ARE YOU THINKING OF AN ANIMAL?")
if option == 'LIST'
puts
puts "ANIMALS I ALREADY KNOW ARE:"
puts get_all_animals(feature).to_a.join(" " * 15)
puts
elsif option[0] == 'Y'
guess_loop(feature)
elsif option == ''
puts
end
end
end
trap "SIGINT" do puts; exit 130 end
main

View File

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace BasicComputerGames.Bagels
{
public enum BagelValidation
{
Valid,
WrongLength,
NotUnique,
NonDigit
};
public class BagelNumber
{
private static readonly Random Rnd = new Random();
private readonly int[] _digits;
public override string ToString()
{
return String.Join('-', _digits);
}
public static BagelNumber CreateSecretNumber(int numDigits)
{
if (numDigits < 3 || numDigits > 9)
throw new ArgumentOutOfRangeException(nameof(numDigits),
"Number of digits must be between 3 and 9, inclusive");
var digits = GetDigits(numDigits);
return new BagelNumber(digits);
}
public static BagelValidation IsValid(string number, int length)
{
if (number.Length != length)
return BagelValidation.WrongLength;
if (!number.All(Char.IsDigit))
return BagelValidation.NonDigit;
if (new HashSet<char>(number).Count != length)
return BagelValidation.NotUnique;
return BagelValidation.Valid;
}
public BagelNumber(string number)
{
if (number.Any(d => !Char.IsDigit(d)))
throw new ArgumentException("Number must be all unique digits", nameof(number));
_digits = number.Select(d => d - '0').ToArray();
}
//public BagelNumber(long number)
//{
// var digits = new List<int>();
// if (number >= 1E10)
// throw new ArgumentOutOfRangeException(nameof(number), "Number can be no more than 9 digits");
// while (number > 0)
// {
// long num = number / 10;
// int digit = (int)(number - (num * 10));
// number = num;
// digits.Add(digit);
// }
// _digits = digits.ToArray();
//}
public BagelNumber(int[] digits)
{
_digits = digits;
}
private static int[] GetDigits(int numDigits)
{
int[] digits = {1, 2, 3, 4, 5, 6, 7, 8, 9};
Shuffle(digits);
return digits.Take(numDigits).ToArray();
}
private static void Shuffle(int[] digits)
{
for (int i = digits.Length - 1; i > 0; --i)
{
int pos = Rnd.Next(i);
var t = digits[i];
digits[i] = digits[pos];
digits[pos] = t;
}
}
public (int pico, int fermi) CompareTo(BagelNumber other)
{
int pico = 0;
int fermi = 0;
for (int i = 0; i < _digits.Length; i++)
{
for (int j = 0; j < other._digits.Length; j++)
{
if (_digits[i] == other._digits[j])
{
if (i == j)
++fermi;
else
++pico;
}
}
}
return (pico, fermi);
}
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>BasicComputerGames.Bagels</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Remove="TextUtil.cs" />
</ItemGroup>
</Project>

124
05 Bagels/csharp/Game.cs Normal file
View File

@@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace BasicComputerGames.Bagels
{
public class Game : GameBase
{
public void GameLoop()
{
DisplayIntroText();
int points = 0;
do
{
var result =PlayRound();
if (result)
++points;
} while (TryAgain());
Console.WriteLine();
Console.WriteLine($"A {points} point Bagels buff!!");
Console.WriteLine("Hope you had fun. Bye.");
}
private const int Length = 3;
private const int MaxGuesses = 20;
private bool PlayRound()
{
var secret = BagelNumber.CreateSecretNumber(Length);
Console.WriteLine("O.K. I have a number in mind.");
for (int guessNo = 1; guessNo <= MaxGuesses; ++guessNo)
{
string strGuess;
BagelValidation isValid;
do
{
Console.WriteLine($"Guess #{guessNo}");
strGuess = Console.ReadLine();
isValid = BagelNumber.IsValid(strGuess, Length);
PrintError(isValid);
} while (isValid != BagelValidation.Valid);
var guess = new BagelNumber(strGuess);
var fermi = 0;
var pico = 0;
(pico, fermi) = secret.CompareTo(guess);
if(pico + fermi == 0)
Console.Write("BAGELS!");
else if (fermi == Length)
{
Console.WriteLine("You got it!");
return true;
}
else
{
PrintList("Pico ", pico);
PrintList("Fermi ", fermi);
}
Console.WriteLine();
}
Console.WriteLine("Oh, well.");
Console.WriteLine($"That's {MaxGuesses} guesses. My Number was {secret}");
return false;
}
private void PrintError(BagelValidation isValid)
{
switch (isValid)
{
case BagelValidation.NonDigit:
Console.WriteLine("What?");
break;
case BagelValidation.NotUnique:
Console.WriteLine("Oh, I forgot to tell you that the number I have in mind has no two digits the same.");
break;
case BagelValidation.WrongLength:
Console.WriteLine($"Try guessing a {Length}-digit number.");
break;
case BagelValidation.Valid:
break;
}
}
private void PrintList(string msg, int repeat)
{
for(int i=0; i<repeat; ++i)
Console.Write(msg);
}
private void DisplayIntroText()
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Bagels");
Console.WriteLine("Creating Computing, Morristown, New Jersey.");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine(
"Original code author unknow but suspected to be from Lawrence Hall of Science, U.C. Berkley");
Console.WriteLine("Originally published in 1978 in the book 'Basic Computer Games' by David Ahl.");
Console.WriteLine("Modernized and converted to C# in 2021 by James Curran (noveltheory.com).");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("I am thinking of a three-digit number. Try to guess");
Console.WriteLine("my number and I will give you clues as follows:");
Console.WriteLine(" pico - One digit correct but in the wrong position");
Console.WriteLine(" fermi - One digit correct and in the right position");
Console.WriteLine(" bagels - No digits correct");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Press any key start the game.");
Console.ReadKey(true);
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
namespace BasicComputerGames.Bagels
{
public class GameBase
{
protected Random Rnd { get; } = new Random();
/// <summary>
/// Prompt the player to try again, and wait for them to press Y or N.
/// </summary>
/// <returns>Returns true if the player wants to try again, false if they have finished playing.</returns>
protected bool TryAgain()
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Would you like to try again? (Press 'Y' for yes or 'N' for no)");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("> ");
char pressedKey;
// Keep looping until we get a recognised input
do
{
// Read a key, don't display it on screen
ConsoleKeyInfo key = Console.ReadKey(true);
// Convert to upper-case so we don't need to care about capitalisation
pressedKey = Char.ToUpper(key.KeyChar);
// Is this a key we recognise? If not, keep looping
} while (pressedKey != 'Y' && pressedKey != 'N');
// Display the result on the screen
Console.WriteLine(pressedKey);
// Return true if the player pressed 'Y', false for anything else.
return (pressedKey == 'Y');
}
}
}

View File

@@ -0,0 +1,14 @@
namespace BasicComputerGames.Bagels
{
public class Program
{
public static void Main(string[] args)
{
// Create an instance of our main Game class
var game = new Game();
// Call its GameLoop function. This will play the game endlessly in a loop until the player chooses to quit.
game.GameLoop();
}
}
}

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>BASKETBALL</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="basketball.js"></script>
</body>
</html>

View File

@@ -0,0 +1,384 @@
// BASKETBALL
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
var s = [0, 0];
var z;
var d;
var p;
var your_turn;
var game_restart;
function two_minutes()
{
print("\n");
print(" *** TWO MINUTES LEFT IN THE GAME ***\n");
print("\n");
}
function show_scores()
{
print("SCORE: " + s[1] + " TO " + s[0] + "\n");
}
function score_computer()
{
s[0] = s[0] + 2;
show_scores();
}
function score_player()
{
s[1] = s[1] + 2;
show_scores();
}
function half_time()
{
print("\n");
print(" ***** END OF FIRST HALF *****\n");
print("SCORE: DARMOUTH: " + s[1] + " " + os + ": " + s[0] + "\n");
print("\n");
print("\n");
}
function foul()
{
if (Math.random() <= 0.49) {
print("SHOOTER MAKES BOTH SHOTS.\n");
s[1 - p] = s[1 - p] + 2;
show_scores();
} else if (Math.random() <= 0.75) {
print("SHOOTER MAKES ONE SHOT AND MISSES ONE.\n");
s[1 - p] = s[1 - p] + 1;
show_scores();
} else {
print("BOTH SHOTS MISSED.\n");
show_scores();
}
}
function player_play()
{
if (z == 1 || z == 2) {
t++;
if (t == 50) {
half_time();
game_restart = 1;
return;
}
if (t == 92)
two_minutes();
print("JUMP SHOT\n");
if (Math.random() <= 0.341 * d / 8) {
print("SHOT IS GOOD.\n");
score_player();
return;
}
if (Math.random() <= 0.682 * d / 8) {
print("SHOT IS OFF TARGET.\n");
if (d / 6 * Math.random() >= 0.45) {
print("REBOUND TO " + os + "\n");
return;
}
print("DARTMOUTH CONTROLS THE REBOUND.\n");
if (Math.random() > 0.4) {
if (d == 6) {
if (Math.random() > 0.6) {
print("PASS STOLEN BY " + os + " EASY LAYUP.\n");
score_computer();
return;
}
}
print("BALL PASSED BACK TO YOU. ");
your_turn = 1;
return;
}
} else if (Math.random() <= 0.782 * d / 8) {
print("SHOT IS BLOCKED. BALL CONTROLLED BY ");
if (Math.random() <= 0.5) {
print("DARTMOUTH.\n");
your_turn = 1;
return;
}
print(os + ".\n");
return;
} else if (Math.random() <= 0.843 * d / 8) {
print("SHOOTER IS FOULED. TWO SHOTS.\n");
foul();
return;
// In original code but lines 1180-1195 aren't used (maybe replicate from computer's play)
// } else if (Math.random() <= 0.9 * d / 8) {
// print("PLAYER FOULED, TWO SHOTS.\n");
// foul();
// return;
} else {
print("CHARGING FOUL. DARTMOUTH LOSES BALL.\n");
return;
}
}
while (1) {
if (++t == 50) {
half_time();
game_restart = 1;
return;
}
if (t == 92)
two_minutes();
if (z == 0) {
your_turn = 2;
return;
}
if (z <= 3)
print("LAY UP.\n");
else
print("SET SHOT.\n");
if (7 / d * Math.random() <= 0.4) {
print("SHOT IS GOOD. TWO POINTS.\n");
score_player();
return;
}
if (7 / d * Math.random() <= 0.7) {
print("SHOT IS OFF THE RIM.\n");
if (Math.random() <= 2.0 / 3.0) {
print(os + " CONTROLS THE REBOUND.\n");
return;
}
print("DARMOUTH CONTROLS THE REBOUND.\n");
if (Math.random() <= 0.4)
continue;
print("BALL PASSED BACK TO YOU.\n");
your_turn = 1;
return;
}
if (7 /d * Math.random() <= 0.875) {
print("SHOOTER FOULED. TWO SHOTS.\n");
foul();
return;
}
if (7 /d * Math.random() <= 0.925) {
print("SHOT BLOCKED. " + os + "'S BALL.\n");
return;
}
print("CHARGING FOUL. DARTHMOUTH LOSES THE BALL.\n");
return;
}
}
function computer_play()
{
rebound = 0;
while (1) {
p = 1;
if (++t == 50) {
half_time();
game_restart = 1;
return;
}
print("\n");
z1 = 10 / 4 * Math.random() + 1;
if (z1 <= 2) {
print("JUMP SHOT.\n");
if (8 / d * Math.random() <= 0.35) {
print("SHOT IS GOOD.\n");
score_computer();
return;
}
if (8 / d * Math.random() <= 0.75) {
print("SHOT IS OFF RIM.\n");
if (d / 6 * Math.random() <= 0.5) {
print("DARMOUTH CONTROLS THE REBOUND.\n");
return;
}
print(os + " CONTROLS THE REBOUND.\n");
if (d == 6) {
if (Math.random() <= 0.75) {
print("BALL STOLEN. EASY LAP UP FOR DARTMOUTH.\n");
score_player();
continue;
}
if (Math.random() > 0.6) {
print("PASS STOLEN BY " + os + " EASY LAYUP.\n");
score_computer();
return;
}
print("BALL PASSED BACK TO YOU. ");
return;
}
if (Math.random() <= 0.5) {
print("PASS BACK TO " + os + " GUARD.\n");
continue;
}
} else if (8 / d * Math.random() <= 0.90) {
print("PLAYER FOULED. TWO SHOTS.\n");
foul();
return;
} else {
print("OFFENSIVE FOUL. DARTMOUTH'S BALL.\n");
return;
}
}
while (1) {
if (z1 > 3) {
print("SET SHOT.\n");
} else {
print("LAY UP.\n");
}
if (7 / d * Math.random() <= 0.413) {
print("SHOT IS GOOD.\n");
score_computer();
return;
}
print("SHOT IS MISSED.\n");
// Spaguetti jump, better to replicate code
if (d / 6 * Math.random() <= 0.5) {
print("DARMOUTH CONTROLS THE REBOUND.\n");
return;
}
print(os + " CONTROLS THE REBOUND.\n");
if (d == 6) {
if (Math.random() <= 0.75) {
print("BALL STOLEN. EASY LAP UP FOR DARTMOUTH.\n");
score_player();
break;
}
if (Math.random() > 0.6) {
print("PASS STOLEN BY " + os + " EASY LAYUP.\n");
score_computer();
return;
}
print("BALL PASSED BACK TO YOU. ");
return;
}
if (Math.random() <= 0.5) {
print("PASS BACK TO " + os + " GUARD.\n");
break;
}
}
}
}
// Main program
async function main()
{
print(tab(31) + "BASKETBALL\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
print("THIS IS DARTMOUTH COLLEGE BASKETBALL. YOU WILL BE DARTMOUTH\n");
print(" CAPTAIN AND PLAYMAKER. CALL SHOTS AS FOLLOWS: 1. LONG\n");
print(" (30 FT.) JUMP SHOT; 2. SHORT (15 FT.) JUMP SHOT; 3. LAY\n");
print(" UP; 4. SET SHOT.\n");
print("BOTH TEAMS WILL USE THE SAME DEFENSE. CALL DEFENSE AS\n");
print("FOLLOWS: 6. PRESS; 6.5 MAN-TO MAN; 7. ZONE; 7.5 NONE.\n");
print("TO CHANGE DEFENSE, JUST TYPE 0 AS YOUR NEXT SHOT.\n");
print("YOUR STARTING DEFENSE WILL BE");
t = 0;
p = 0;
d = parseFloat(await input());
if (d < 6) {
your_turn = 2;
} else {
print("\n");
print("CHOOSE YOUR OPPONENT");
os = await input();
game_restart = 1;
}
while (1) {
if (game_restart) {
game_restart = 0;
print("CENTER JUMP\n");
if (Math.random() > 3.0 / 5.0) {
print("DARMOUTH CONTROLS THE TAP.\n");
} else {
print(os + " CONTROLS THE TAP.\n");
computer_play();
}
}
if (your_turn == 2) {
print("YOUR NEW DEFENSIVE ALLIGNMENT IS");
d = parseFloat(await input());
}
print("\n");
while (1) {
print("YOUR SHOT");
z = parseInt(await input());
p = 0;
if (z != Math.floor(z) || z < 0 || z > 4)
print("INCORRECT ANSWER. RETYPE IT. ");
else
break;
}
if (Math.random() < 0.5 || t < 100) {
game_restart = 0;
your_turn = 0;
player_play();
if (game_restart == 0 && your_turn == 0)
computer_play();
} else {
print("\n");
if (s[1] == s[0]) {
print("\n");
print(" ***** END OF SECOND HALF *****\n");
print("\n");
print("SCORE AT END OF REGULATION TIME:\n");
print(" DARTMOUTH: " + s[1] + " " + os + ": " + s[0] + "\n");
print("\n");
print("BEGIN TWO MINUTE OVERTIME PERIOD\n");
t = 93;
print("CENTER JUMP\n");
if (Math.random() > 3.0 / 5.0)
print("DARMOUTH CONTROLS THE TAP.\n");
else
print(os + " CONTROLS THE TAP.\n");
} else {
print(" ***** END OF GAME *****\n");
print("FINAL SCORE: DARMOUTH: " + s[1] + " " + os + ": " + s[0] + "\n");
break;
}
}
}
}
main();

View File

@@ -0,0 +1,292 @@
import java.util.Arrays;
import java.util.Scanner;
/**
* Game of BatNum
* <p>
* Based on the Basic game of BatNum here
* https://github.com/coding-horror/basic-computer-games/blob/main/08%20Batnum/batnum.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 BatNum {
private enum GAME_STATE {
STARTING,
START_GAME,
CHOOSE_PILE_SIZE,
SELECT_WIN_OPTION,
CHOOSE_MIN_AND_MAX,
SELECT_WHO_STARTS_FIRST,
PLAYERS_TURN,
COMPUTERS_TURN,
ANNOUNCE_WINNER,
GAME_OVER
}
// Used for keyboard input
private final Scanner kbScanner;
// Current game state
private GAME_STATE gameState;
private int pileSize;
// How to win the game options
enum WIN_OPTION {
TAKE_LAST,
AVOID_LAST
}
// Tracking the winner
enum WINNER {
COMPUTER,
PLAYER
}
private WINNER winner;
private WIN_OPTION winOption;
private int minSelection;
private int maxSelection;
// Used by computer for optimal move
private int rangeOfRemovals;
public BatNum() {
gameState = GAME_STATE.STARTING;
// Initialise kb scanner
kbScanner = new Scanner(System.in);
}
/**
* Main game loop
*/
public void play() {
do {
switch (gameState) {
// Show an introduction and optional instructions the first time the game is played.
case STARTING:
intro();
gameState = GAME_STATE.START_GAME;
break;
// Start new game
case START_GAME:
gameState = GAME_STATE.CHOOSE_PILE_SIZE;
break;
case CHOOSE_PILE_SIZE:
System.out.println();
System.out.println();
pileSize = displayTextAndGetNumber("ENTER PILE SIZE ");
if (pileSize >= 1) {
gameState = GAME_STATE.SELECT_WIN_OPTION;
}
break;
case SELECT_WIN_OPTION:
int winChoice = displayTextAndGetNumber("ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: ");
if (winChoice == 1) {
winOption = WIN_OPTION.TAKE_LAST;
gameState = GAME_STATE.CHOOSE_MIN_AND_MAX;
} else if (winChoice == 2) {
winOption = WIN_OPTION.AVOID_LAST;
gameState = GAME_STATE.CHOOSE_MIN_AND_MAX;
}
break;
case CHOOSE_MIN_AND_MAX:
String range = displayTextAndGetInput("ENTER MIN AND MAX ");
minSelection = getDelimitedValue(range, 0);
maxSelection = getDelimitedValue(range, 1);
if (maxSelection > minSelection && minSelection >= 1) {
gameState = GAME_STATE.SELECT_WHO_STARTS_FIRST;
}
// Used by computer in its turn
rangeOfRemovals = minSelection + maxSelection;
break;
case SELECT_WHO_STARTS_FIRST:
int playFirstChoice = displayTextAndGetNumber("ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST ");
if (playFirstChoice == 1) {
gameState = GAME_STATE.COMPUTERS_TURN;
} else if (playFirstChoice == 2) {
gameState = GAME_STATE.PLAYERS_TURN;
}
break;
case PLAYERS_TURN:
int playersMove = displayTextAndGetNumber("YOUR MOVE ");
if (playersMove == 0) {
System.out.println("I TOLD YOU NOT TO USE ZERO! COMPUTER WINS BY FORFEIT.");
winner = WINNER.COMPUTER;
gameState = GAME_STATE.ANNOUNCE_WINNER;
break;
}
if (playersMove == pileSize && winOption == WIN_OPTION.AVOID_LAST) {
winner = WINNER.COMPUTER;
gameState = GAME_STATE.ANNOUNCE_WINNER;
break;
}
// Check if players move is with the min and max possible
if (playersMove >= minSelection && playersMove <= maxSelection) {
// Valid so reduce pileSize by amount player entered
pileSize -= playersMove;
// Did this move result in there being no more objects on pile?
if (pileSize == 0) {
// Was the game setup so the winner was whoever took the last object
if (winOption == WIN_OPTION.TAKE_LAST) {
// Player won
winner = WINNER.PLAYER;
} else {
// Computer one
winner = WINNER.COMPUTER;
}
gameState = GAME_STATE.ANNOUNCE_WINNER;
} else {
// There are still items left.
gameState = GAME_STATE.COMPUTERS_TURN;
}
} else {
// Invalid move
System.out.println("ILLEGAL MOVE, REENTER IT ");
}
break;
case COMPUTERS_TURN:
int pileSizeLeft = pileSize;
if (winOption == WIN_OPTION.TAKE_LAST) {
if (pileSize > maxSelection) {
int objectsToRemove = calculateComputersTurn(pileSizeLeft);
pileSize -= objectsToRemove;
System.out.println("COMPUTER TAKES " + objectsToRemove + " AND LEAVES " + pileSize);
gameState = GAME_STATE.PLAYERS_TURN;
} else {
System.out.println("COMPUTER TAKES " + pileSize + " AND WINS.");
winner = WINNER.COMPUTER;
gameState = GAME_STATE.ANNOUNCE_WINNER;
}
} else {
pileSizeLeft--;
if (pileSize > minSelection) {
int objectsToRemove = calculateComputersTurn(pileSizeLeft);
pileSize -= objectsToRemove;
System.out.println("COMPUTER TAKES " + objectsToRemove + " AND LEAVES " + pileSize);
gameState = GAME_STATE.PLAYERS_TURN;
} else {
System.out.println("COMPUTER TAKES " + pileSize + " AND LOSES.");
winner = WINNER.PLAYER;
gameState = GAME_STATE.ANNOUNCE_WINNER;
}
}
break;
case ANNOUNCE_WINNER:
switch (winner) {
case PLAYER:
System.out.println("CONGRATULATIONS, YOU WIN.");
break;
case COMPUTER:
System.out.println("TOUGH LUCK, YOU LOSE.");
break;
}
gameState = GAME_STATE.START_GAME;
break;
}
} while (gameState != GAME_STATE.GAME_OVER);
}
/**
* Figure out the computers turn - i.e. how many objects to remove
*
* @param pileSizeLeft current size
* @return the number of objects to remove.
*/
private int calculateComputersTurn(int pileSizeLeft) {
int computersNumberToRemove = pileSizeLeft - rangeOfRemovals * (pileSizeLeft / rangeOfRemovals);
if (computersNumberToRemove < minSelection) {
computersNumberToRemove = minSelection;
}
if (computersNumberToRemove > maxSelection) {
computersNumberToRemove = maxSelection;
}
return computersNumberToRemove;
}
private void intro() {
System.out.println(simulateTabs(33) + "BATNUM");
System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println("THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE");
System.out.println("COMPUTER IS YOUR OPPONENT.");
System.out.println();
System.out.println("THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU");
System.out.println("AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.");
System.out.println("WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR");
System.out.println("NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS.");
System.out.println("DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME.");
System.out.println("ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING.");
}
/*
* Print a message on the screen, then accept input from Keyboard.
* Converts input to Integer
*
* @param text message to be displayed on screen.
* @return what was typed by the player.
*/
private int displayTextAndGetNumber(String text) {
return Integer.parseInt(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);
}
/**
* Accepts a string delimited by comma's and returns the nth 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]);
}
}

View File

@@ -0,0 +1,8 @@
public class BatNumGame {
public static void main(String[] args) {
BatNum batNum = new BatNum();
batNum.play();
}
}

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>BATNUM</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="batnum.js"></script>
</body>
</html>

View File

@@ -0,0 +1,161 @@
// BATNUM
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
// Main program
async function main()
{
print(tab(33) + "BATNUM\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
print("THIS PROGRAM IS A 'BATTLE OF NUMBERS' GAME, WHERE THE\n");
print("COMPUTER IS YOUR OPPONENT.\n");
print("\n");
print("THE GAME STARTS WITH AN ASSUMED PILE OF OBJECTS. YOU\n");
print("AND YOUR OPPONENT ALTERNATELY REMOVE OBJECTS FROM THE PILE.\n");
print("WINNING IS DEFINED IN ADVANCE AS TAKING THE LAST OBJECT OR\n");
print("NOT. YOU CAN ALSO SPECIFY SOME OTHER BEGINNING CONDITIONS.\n");
print("DON'T USE ZERO, HOWEVER, IN PLAYING THE GAME.\n");
print("ENTER A NEGATIVE NUMBER FOR NEW PILE SIZE TO STOP PLAYING.\n");
print("\n");
first_time = 1;
while (1) {
while (1) {
if (first_time == 1) {
first_time = 0;
} else {
for (i = 1; i <= 10; i++)
print("\n");
}
print("ENTER PILE SIZE");
n = parseInt(await input());
if (n >= 1)
break;
}
while (1) {
print("ENTER WIN OPTION - 1 TO TAKE LAST, 2 TO AVOID LAST: ");
m = parseInt(await input());
if (m == 1 || m == 2)
break;
}
while (1) {
print("ENTER MIN AND MAX ");
str = await input();
a = parseInt(str);
b = parseInt(str.substr(str.indexOf(",") + 1));
if (a <= b && a >= 1)
break;
}
while (1) {
print("ENTER START OPTION - 1 COMPUTER FIRST, 2 YOU FIRST ");
s = parseInt(await input());
print("\n");
print("\n");
if (s == 1 || s == 2)
break;
}
w = 0;
c = a + b;
while (1) {
if (s == 1) {
// Computer's turn
q = n;
if (m != 1)
q--;
if (m != 1 && n <= a) {
w = 1;
print("COMPUTER TAKES " + n + " AND LOSES.\n");
} else if (m == 1 && n <= b) {
w = 1;
print("COMPUTER TAKES " + n + " AND WINS.\n");
} else {
p = q - c * Math.floor(q / c);
if (p < a)
p = a;
if (p > b)
p = b;
n -= p;
print("COMPUTER TAKES " + p + " AND LEAVES " + n + "\n");
w = 0;
}
s = 2;
}
if (w)
break;
if (s == 2) {
while (1) {
print("\n");
print("YOUR MOVE ");
p = parseInt(await input());
if (p == 0) {
print("I TOLD YOU NOT TO USE ZERO! COMPUTER WINS BY FORFEIT.\n");
w = 1;
break;
} else if (p >= a && p <= b && n - p >= 0) {
break;
}
}
if (p != 0) {
n -= p;
if (n == 0) {
if (m != 1) {
print("TOUGH LUCK, YOU LOSE.\n");
} else {
print("CONGRATULATIONS, YOU WIN.\n");
}
w = 1;
} else {
w = 0;
}
}
s = 1;
}
if (w)
break;
}
}
}
main();

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>Blackjack</RootNamespace>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,32 @@
namespace Blackjack
{
public class Card
{
private static readonly string[] _names = new[] {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
public Card(int index)
{
Index = index;
}
public int Index { get; private set; }
public string Name => _names[Index];
public string IndefiniteArticle => (Index == 0 || Index == 7) ? "an" : "a";
public bool IsAce => Index == 0;
public int Value
{
get
{
if (IsAce)
return 11;
if (Index > 8)
return 10;
return Index + 1;
}
}
}
}

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
namespace Blackjack
{
public class Deck
{
private static readonly Random _random = new Random();
private readonly List<Card> _cards = new List<Card>(52);
private readonly List<Card> _discards = new List<Card>(52);
public Deck()
{
for (var index = 0; index < 12; index++)
{
for (var suit = 0; suit < 4; suit++)
{
_discards.Add(new Card(index));
}
}
Reshuffle();
}
private void Reshuffle()
{
Console.WriteLine("Reshuffling");
_cards.AddRange(_discards);
_discards.Clear();
for (var index1 = _cards.Count - 1; index1 > 0; index1--)
{
var index2 = _random.Next(0, index1);
var swapCard = _cards[index1];
_cards[index1] = _cards[index2];
_cards[index2] = swapCard;
}
}
public Card DrawCard()
{
if (_cards.Count < 2)
Reshuffle();
var card = _cards[_cards.Count - 1];
_cards.RemoveAt(_cards.Count - 1);
return card;
}
public void Discard(IEnumerable<Card> cards)
{
_discards.AddRange(cards);
}
}
}

232
10 Blackjack/csharp/Game.cs Normal file
View File

@@ -0,0 +1,232 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Blackjack
{
public class Game
{
private readonly Deck _deck = new Deck();
private readonly int _numberOfPlayers;
private readonly Player[] _players;
private readonly Hand _dealerHand;
public Game(int numberOfPlayers)
{
_numberOfPlayers = numberOfPlayers;
_players = new Player[_numberOfPlayers];
for (var playerIndex = 0; playerIndex < _numberOfPlayers; playerIndex++)
_players[playerIndex] = new Player(playerIndex);
_dealerHand = new Hand();
}
public void PlayGame()
{
while (true)
{
PlayRound();
TallyResults();
ResetRoundState();
Console.WriteLine();
}
}
public void PlayRound()
{
GetPlayerBets();
DealHands();
// Test for insurance
var dealerIsShowingAce = _dealerHand.Cards[0].IsAce;
if (dealerIsShowingAce && Prompt.ForYesNo("Any insurance?"))
{
Console.WriteLine("Insurance bets");
var insuranceBets = new int[_numberOfPlayers];
foreach (var player in _players)
insuranceBets[player.Index] = Prompt.ForInteger($"# {player.Index + 1} ?", 0, player.RoundBet / 2);
var insuranceEffectMultiplier = _dealerHand.IsBlackjack ? 2 : -1;
foreach (var player in _players)
player.RoundWinnings += insuranceBets[player.Index] * insuranceEffectMultiplier;
}
// Test for dealer blackjack
var concealedCard = _dealerHand.Cards[0];
if (_dealerHand.IsBlackjack)
{
Console.WriteLine();
Console.WriteLine("Dealer has {0} {1} in the hole for blackjack.", concealedCard.IndefiniteArticle, concealedCard.Name);
return;
}
else if (dealerIsShowingAce)
{
Console.WriteLine();
Console.WriteLine("No dealer blackjack.");
}
foreach (var player in _players)
PlayHand(player);
// Dealer hand
var allPlayersBusted = _players.All(p => p.Hand.IsBusted && (!p.SecondHand.Exists || p.SecondHand.IsBusted));
if (allPlayersBusted)
Console.WriteLine("Dealer had {0} {1} concealed.", concealedCard.IndefiniteArticle, concealedCard.Name);
else
{
Console.WriteLine("Dealer has {0} {1} concealed for a total of {2}", concealedCard.IndefiniteArticle, concealedCard.Name, _dealerHand.Total);
if (_dealerHand.Total < 17)
{
Console.Write("Draws");
while (_dealerHand.Total < 17)
{
var card = _dealerHand.AddCard(_deck.DrawCard());
Console.Write(" {0}", card.Name);
}
if (_dealerHand.IsBusted)
Console.WriteLine(" ...Busted");
else
Console.WriteLine(" ---Total is {0}", _dealerHand.Total);
}
}
}
private void GetPlayerBets()
{
Console.WriteLine("Bets:");
foreach (var player in _players)
player.RoundBet = Prompt.ForInteger($"# {player.Name} ?", 1, 500);
}
private void DealHands()
{
Console.Write("Player ");
foreach (var player in _players)
Console.Write("{0} ", player.Name);
Console.WriteLine("Dealer");
for (var cardIndex = 0; cardIndex < 2; cardIndex++)
{
Console.Write(" ");
foreach (var player in _players)
Console.Write(" {0,-4}", player.Hand.AddCard(_deck.DrawCard()).Name);
var dealerCard = _dealerHand.AddCard(_deck.DrawCard());
Console.Write(" {0,-4}", (cardIndex == 0) ? "XX" : dealerCard.Name);
Console.WriteLine();
}
}
private void PlayHand(Player player)
{
var hand = player.Hand;
Console.Write("Player {0} ", player.Name);
var playerCanSplit = hand.Cards[0].Value == hand.Cards[1].Value;
var command = Prompt.ForCommandCharacter("?", playerCanSplit ? "HSD/" : "HSD");
switch (command)
{
case "D":
player.RoundBet *= 2;
goto case "H";
case "H":
while (TakeHit(hand) && PromptForAnotherHit())
{ }
if (!hand.IsBusted)
Console.WriteLine("Total is {0}", hand.Total);
break;
case "S":
if (hand.IsBlackjack)
{
Console.WriteLine("Blackjack!");
player.RoundWinnings = (int)(1.5 * player.RoundBet + 0.5);
player.RoundBet = 0;
}
else
Console.WriteLine("Total is {0}", hand.Total);
break;
case "/":
hand.SplitHand(player.SecondHand);
var card = hand.AddCard(_deck.DrawCard());
Console.WriteLine("First hand receives {0} {1}", card.IndefiniteArticle, card.Name);
card = player.SecondHand.AddCard(_deck.DrawCard());
Console.WriteLine("Second hand receives {0} {1}", card.IndefiniteArticle, card.Name);
for (int handNumber = 1; handNumber <= 2; handNumber++)
{
hand = (handNumber == 1) ? player.Hand : player.SecondHand;
Console.Write("Hand {0}", handNumber);
while (PromptForAnotherHit() && TakeHit(hand))
{ }
if (!hand.IsBusted)
Console.WriteLine("Total is {0}", hand.Total);
}
break;
}
}
private bool TakeHit(Hand hand)
{
var card = hand.AddCard(_deck.DrawCard());
Console.Write("Received {0,-6}", $"{card.IndefiniteArticle} {card.Name}");
if (hand.IsBusted)
{
Console.WriteLine("...Busted");
return false;
}
return true;
}
private bool PromptForAnotherHit()
{
return String.Equals(Prompt.ForCommandCharacter(" Hit?", "HS"), "H");
}
private void TallyResults()
{
Console.WriteLine();
foreach (var player in _players)
{
player.RoundWinnings += CalculateWinnings(player, player.Hand);
if (player.SecondHand.Exists)
player.RoundWinnings += CalculateWinnings(player, player.SecondHand);
player.TotalWinnings += player.RoundWinnings;
Console.WriteLine("Player {0} {1,-6} {2,3} Total= {3,5}",
player.Name,
(player.RoundWinnings > 0) ? "wins" : (player.RoundWinnings) < 0 ? "loses" : "pushes",
(player.RoundWinnings != 0) ? Math.Abs(player.RoundWinnings).ToString() : "",
player.TotalWinnings);
}
Console.WriteLine("Dealer's total= {0}", -_players.Sum(p => p.TotalWinnings));
}
private int CalculateWinnings(Player player, Hand hand)
{
if (hand.IsBusted)
return -player.RoundBet;
if (hand.Total == _dealerHand.Total)
return 0;
if (_dealerHand.IsBusted || hand.Total > _dealerHand.Total)
return player.RoundBet;
return -player.RoundBet;
}
private void ResetRoundState()
{
foreach (var player in _players)
{
player.RoundWinnings = 0;
player.RoundBet = 0;
player.Hand.Discard(_deck);
player.SecondHand.Discard(_deck);
}
_dealerHand.Discard(_deck);
}
}
}

View File

@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
namespace Blackjack
{
public class Hand
{
private readonly List<Card> _cards = new List<Card>(12);
private int _cachedTotal = 0;
public Card AddCard(Card card)
{
_cards.Add(card);
_cachedTotal = 0;
return card;
}
public void Discard(Deck deck)
{
deck.Discard(_cards);
_cards.Clear();
_cachedTotal = 0;
}
public void SplitHand(Hand secondHand)
{
if (Count != 2 || secondHand.Count != 0)
throw new InvalidOperationException();
secondHand.AddCard(_cards[1]);
_cards.RemoveAt(1);
_cachedTotal = 0;
}
public IReadOnlyList<Card> Cards => _cards;
public int Count => _cards.Count;
public bool Exists => _cards.Count > 0;
public int Total
{
get
{
if (_cachedTotal == 0)
{
var aceCount = 0;
foreach (var card in _cards)
{
_cachedTotal += card.Value;
if (card.IsAce)
aceCount++;
}
while (_cachedTotal > 21 && aceCount > 0)
{
_cachedTotal -= 10;
aceCount--;
}
}
return _cachedTotal;
}
}
public bool IsBlackjack => Total == 21 && Count == 2;
public bool IsBusted => Total > 21;
}
}

View File

@@ -0,0 +1,27 @@
namespace Blackjack
{
public class Player
{
public Player(int index)
{
Index = index;
Name = (index + 1).ToString();
Hand = new Hand();
SecondHand = new Hand();
}
public int Index { get; private set; }
public string Name { get; private set; }
public Hand Hand { get; private set; }
public Hand SecondHand { get; private set;}
public int RoundBet { get; set; }
public int RoundWinnings { get; set; }
public int TotalWinnings { get; set; }
}
}

View File

@@ -0,0 +1,41 @@
using System;
namespace Blackjack
{
static class Program
{
static void Main(string[] args)
{
Console.WriteLine("{0}BLACK JACK", new string(' ', 31));
Console.WriteLine("{0}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY", new string(' ', 15));
Console.WriteLine();
Console.WriteLine();
Console.WriteLine();
OfferInstructions();
var numberOfPlayers = Prompt.ForInteger("Number of players?", 1, 6);
var game = new Game(numberOfPlayers);
game.PlayGame();
}
private static void OfferInstructions()
{
if (!Prompt.ForYesNo("Do you want instructions?"))
return;
Console.WriteLine("This is the game of 21. As many as 7 players may play the");
Console.WriteLine("game. On each deal, bets will be asked for, and the");
Console.WriteLine("players' bets should be typed in. The cards will then be");
Console.WriteLine("dealt, and each player in turn plays his hand. The");
Console.WriteLine("first response should be either 'D', indicating that the");
Console.WriteLine("player is doubling down, 'S', indicating that he is");
Console.WriteLine("standing, 'H', indicating he wants another card, or '/',");
Console.WriteLine("indicating that he wants to split his cards. After the");
Console.WriteLine("initial response, all further responses should be 's' or");
Console.WriteLine("'H', unless the cards were split, in which case doubling");
Console.WriteLine("down is again permitted. In order to collect for");
Console.WriteLine("Blackjack, the initial response should be 'S'.");
}
}
}

View File

@@ -0,0 +1,58 @@
using System;
namespace Blackjack
{
public static class Prompt
{
public static bool ForYesNo(string prompt)
{
while(true)
{
Console.Write("{0} ", prompt);
var input = Console.ReadLine();
if (input.StartsWith("y", StringComparison.InvariantCultureIgnoreCase))
return true;
if (input.StartsWith("n", StringComparison.InvariantCultureIgnoreCase))
return false;
WriteNotUnderstood();
}
}
public static int ForInteger(string prompt, int minimum = 1, int maximum = int.MaxValue)
{
while (true)
{
Console.Write("{0} ", prompt);
if (!int.TryParse(Console.ReadLine(), out var number))
WriteNotUnderstood();
else if (number < minimum || number > maximum)
Console.WriteLine("Sorry, I need a number between {0} and {1}.", minimum, maximum);
else
return number;
}
}
public static string ForCommandCharacter(string prompt, string allowedCharacters)
{
while (true)
{
Console.Write("{0} ", prompt);
var input = Console.ReadLine();
if (input.Length > 0)
{
var character = input.Substring(0, 1);
var characterIndex = allowedCharacters.IndexOf(character, StringComparison.InvariantCultureIgnoreCase);
if (characterIndex != -1)
return allowedCharacters.Substring(characterIndex, 1);
}
Console.WriteLine("Type one of {0} please", String.Join(", ", allowedCharacters.ToCharArray()));
}
}
private static void WriteNotUnderstood()
{
Console.WriteLine("Sorry, I didn't understand.");
}
}
}

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -3,12 +3,12 @@ import java.util.Scanner;
/**
* Game of Bombardment
*
* <p>
* Based on the Basic game of Bombardment here
* https://github.com/coding-horror/basic-computer-games/blob/main/11%20Bombardment/bombardment.bas
*
* Note: The idea was to create a version of this 1970's Basic game in Java, without introducing
* new features - no additional text, error checking, etc has been added.
* <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 Bombardment {
@@ -28,11 +28,11 @@ public class Bombardment {
private GAME_STATE gameState;
public static final String[] PLAYER_HIT_MESSAGES = { "ONE DOWN, THREE TO GO.",
"TWO DOWN, TWO TO GO.", "THREE DOWN, ONE TO GO." };
public static final String[] PLAYER_HIT_MESSAGES = {"ONE DOWN, THREE TO GO.",
"TWO DOWN, TWO TO GO.", "THREE DOWN, ONE TO GO."};
public static final String[] COMPUTER_HIT_MESSAGES = {"YOU HAVE ONLY THREE OUTPOSTS LEFT.",
"YOU HAVE ONLY TWO OUTPOSTS LEFT.", "YOU HAVE ONLY ONE OUTPOST LEFT." };
"YOU HAVE ONLY TWO OUTPOSTS LEFT.", "YOU HAVE ONLY ONE OUTPOST LEFT."};
private HashSet<Integer> computersPlatoons;
private HashSet<Integer> playersPlatoons;
@@ -44,7 +44,7 @@ public class Bombardment {
public Bombardment() {
this.gameState = GAME_STATE.STARTING;
gameState = GAME_STATE.STARTING;
// Initialise kb scanner
kbScanner = new Scanner(System.in);
@@ -56,19 +56,19 @@ public class Bombardment {
public void play() {
do {
switch (this.gameState) {
switch (gameState) {
// Show an introduction the first time the game is played.
case STARTING:
init();
intro();
this.gameState = GAME_STATE.DRAW_BATTLEFIELD;
gameState = GAME_STATE.DRAW_BATTLEFIELD;
break;
// Enter the players name
case DRAW_BATTLEFIELD:
drawBattlefield();
this.gameState = GAME_STATE.GET_PLAYER_CHOICES;
gameState = GAME_STATE.GET_PLAYER_CHOICES;
break;
// Get the players 4 locations for their platoons
@@ -76,35 +76,35 @@ public class Bombardment {
String playerChoices = displayTextAndGetInput("WHAT ARE YOUR FOUR POSITIONS? ");
// Store the 4 player choices that were entered separated with commas
for(int i=0; i<PLATOONS; i++) {
playersPlatoons.add(getDelimitedValue(playerChoices,i));
for (int i = 0; i < PLATOONS; i++) {
playersPlatoons.add(getDelimitedValue(playerChoices, i));
}
this.gameState = GAME_STATE.PLAYERS_TURN;
gameState = GAME_STATE.PLAYERS_TURN;
break;
// Players turn to pick a location
case PLAYERS_TURN:
int firePosition = getDelimitedValue(
displayTextAndGetInput("WHERE DO YOU WISH TO FIRE YOUR MISSILE? "),0);
displayTextAndGetInput("WHERE DO YOU WISH TO FIRE YOUR MISSILE? "), 0);
if(didPlayerHitComputerPlatoon(firePosition)) {
if (didPlayerHitComputerPlatoon(firePosition)) {
// Player hit a player platoon
int hits = updatePlayerHits(firePosition);
// How many hits has the player made?
if(hits != PLATOONS) {
if (hits != PLATOONS) {
showPlayerProgress(hits);
this.gameState = GAME_STATE.COMPUTER_TURN;
gameState = GAME_STATE.COMPUTER_TURN;
} else {
// Player has obtained 4 hits, they win
this.gameState = GAME_STATE.PLAYER_WON;
gameState = GAME_STATE.PLAYER_WON;
}
} else {
// Player missed
System.out.println("HA, HA YOU MISSED. MY TURN NOW:");
System.out.println();
this.gameState = GAME_STATE.COMPUTER_TURN;
gameState = GAME_STATE.COMPUTER_TURN;
}
break;
@@ -114,25 +114,25 @@ public class Bombardment {
// Computer takes a guess of a location
int computerFirePosition = uniqueComputerGuess();
if(didComputerHitPlayerPlatoon(computerFirePosition)) {
if (didComputerHitPlayerPlatoon(computerFirePosition)) {
// Computer hit a player platoon
int hits = updateComputerHits(computerFirePosition);
// How many hits has the computer made?
if(hits != PLATOONS) {
if (hits != PLATOONS) {
showComputerProgress(hits, computerFirePosition);
this.gameState = GAME_STATE.PLAYERS_TURN;
gameState = GAME_STATE.PLAYERS_TURN;
} else {
// Computer has obtained 4 hits, they win
System.out.println("YOU'RE DEAD. YOUR LAST OUTPOST WAS AT " + computerFirePosition
+ ". HA, HA, HA.");
this.gameState = GAME_STATE.PLAYER_LOST;
gameState = GAME_STATE.PLAYER_LOST;
}
} else {
// Computer missed
System.out.println("I MISSED YOU, YOU DIRTY RAT. I PICKED " + computerFirePosition
+ ". YOUR TURN:");
System.out.println();
this.gameState = GAME_STATE.PLAYERS_TURN;
gameState = GAME_STATE.PLAYERS_TURN;
}
break;
@@ -141,37 +141,36 @@ public class Bombardment {
case PLAYER_WON:
System.out.println("YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN");
System.out.println("MY TRANSISTO&S RECUP%RA*E!");
this.gameState = GAME_STATE.GAME_OVER;
gameState = GAME_STATE.GAME_OVER;
break;
case PLAYER_LOST:
System.out.println("BETTER LUCK NEXT TIME.");
this.gameState = GAME_STATE.GAME_OVER;
gameState = GAME_STATE.GAME_OVER;
break;
// GAME_OVER State does not specifically have a case
}
} while (this.gameState != GAME_STATE.GAME_OVER);
} while (gameState != GAME_STATE.GAME_OVER);
}
/**
* Calculate computer guess. Make that the computer does not guess the same
* location twice
*
* @return location of the computers guess that has not been guessed previously
* @return location of the computers guess that has not been guessed previously
*/
private int uniqueComputerGuess() {
boolean validGuess = false;
int computerGuess;
do
{
do {
computerGuess = randomNumber();
if(!computersGuesses.contains(computerGuess)) {
if (!computersGuesses.contains(computerGuess)) {
validGuess = true;
}
} while(!validGuess);
} while (!validGuess);
computersGuesses.add(computerGuess);
@@ -185,7 +184,6 @@ public class Bombardment {
* until all four are in the hashset
*
* @return 4 locations of computers platoons
*
*/
private HashSet<Integer> computersChosenPlatoons() {
@@ -198,19 +196,20 @@ public class Bombardment {
tempPlatoons.add(randomNumber());
// All four created?
if(tempPlatoons.size() == PLATOONS) {
if (tempPlatoons.size() == PLATOONS) {
// Exit when we have created four
allPlatoonsAdded = true;
}
} while(!allPlatoonsAdded);
} while (!allPlatoonsAdded);
return tempPlatoons;
}
/**
* Shows a different message for each number of hits
*
* @param hits total number of hits by player on computer
* @param hits total number of hits by player on computer
*/
private void showPlayerProgress(int hits) {
@@ -221,7 +220,7 @@ public class Bombardment {
/**
* Shows a different message for each number of hits
*
* @param hits total number of hits by computer on player
* @param hits total number of hits by computer on player
*/
private void showComputerProgress(int hits, int lastGuess) {
@@ -231,42 +230,42 @@ public class Bombardment {
/**
* Prints a message from the passed array based on the value of hits
* @param hits - number of hits the player or computer has made
*
* @param hits - number of hits the player or computer has made
* @param messages - an array of string with messages
*/
private void showProgress(int hits, String[] messages) {
System.out.println(messages[hits-1]);
System.out.println(messages[hits - 1]);
}
/**
*
* Update a player hit - adds a hit the player made on the computers platoon.
*
* @param fireLocation - computer location that got hit
* @return number of hits the player has inflicted on the computer in total
*/
private int updatePlayerHits(int fireLocation) {
// N.B. only removes if present, so its redundant to check if it exists first
this.computersPlatoons.remove(fireLocation);
computersPlatoons.remove(fireLocation);
// return number of hits in total
return PLATOONS - this.computersPlatoons.size();
return PLATOONS - computersPlatoons.size();
}
/**
*
* Update a computer hit - adds a hit the computer made on the players platoon.
*
* @param fireLocation - player location that got hit
* @return number of hits the player has inflicted on the computer in total
*/
private int updateComputerHits(int fireLocation) {
// N.B. only removes if present, so its redundant to check if it exists first
this.playersPlatoons.remove(fireLocation);
playersPlatoons.remove(fireLocation);
// return number of hits in total
return PLATOONS - this.playersPlatoons.size();
return PLATOONS - playersPlatoons.size();
}
/**
@@ -276,7 +275,7 @@ public class Bombardment {
* @return true if a computer platoon was at that position
*/
private boolean didPlayerHitComputerPlatoon(int fireLocation) {
return this.computersPlatoons.contains(fireLocation);
return computersPlatoons.contains(fireLocation);
}
/**
@@ -286,22 +285,20 @@ public class Bombardment {
* @return true if a players platoon was at that position
*/
private boolean didComputerHitPlayerPlatoon(int fireLocation) {
return this.playersPlatoons.contains(fireLocation);
return playersPlatoons.contains(fireLocation);
}
/**
* Draw the battlefield grid
*
*/
private void drawBattlefield() {
for(int i=1; i<MAX_GRID_SIZE+1; i+= 5) {
System.out.printf("%-2s %-2s %-2s %-2s %-2s %n", i, i+1, i+2, i+3, i+4);
for (int i = 1; i < MAX_GRID_SIZE + 1; i += 5) {
System.out.printf("%-2s %-2s %-2s %-2s %-2s %n", i, i + 1, i + 2, i + 3, i + 4);
}
}
/**
* Basic information about the game
*
*/
private void intro() {
System.out.println("BOMBARDMENT");
@@ -327,12 +324,12 @@ public class Bombardment {
private void init() {
// Create four locations for the computers platoons.
this.computersPlatoons = computersChosenPlatoons();
computersPlatoons = computersChosenPlatoons();
// Players platoons.
this.playersPlatoons = new HashSet<>();
playersPlatoons = new HashSet<>();
this.computersGuesses = new HashSet<>();
computersGuesses = new HashSet<>();
}
/**

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>BOMBARDMENT</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="bombardment.js"></script>
</body>
</html>

View File

@@ -0,0 +1,167 @@
// BOMBARDMENT
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
// Main program
async function main()
{
print(tab(33) + "BOMBARDMENT\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
print("YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU\n");
print("HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.\n");
print("YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST.\n");
print("THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS.\n");
print("\n");
print("THE OBJECT OF THE GAME IS TO FIRE MISSILES AT THE\n");
print("OUTPOSTS OF THE COMPUTER. IT WILL DO THE SAME TO YOU.\n");
print("THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS\n");
print("FIRST IS THE WINNER.\n");
print("\n");
print("GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!\n");
print("\n");
// "TEAR OFF" because it supposed this to be printed on a teletype
print("TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.\n");
for (r = 1; r <= 5; r++)
print("\n");
ma = [];
for (r = 1; r <= 100; r++)
ma[r] = 0;
p = 0;
q = 0;
z = 0;
for (r = 1; r <= 5; r++) {
i = (r - 1) * 5 + 1;
print(i + "\t" + (i + 1) + "\t" + (i + 2) + "\t" + (i + 3) + "\t" + (i + 4) + "\n");
}
for (r = 1; r <= 10; r++)
print("\n");
c = Math.floor(Math.random() * 25) + 1;
do {
d = Math.floor(Math.random() * 25) + 1;
e = Math.floor(Math.random() * 25) + 1;
f = Math.floor(Math.random() * 25) + 1;
} while (c == d || c == e || c == f || d == e || d == f || e == f) ;
print("WHAT ARE YOUR FOUR POSITIONS");
str = await input();
g = parseInt(str);
str = str.substr(str.indexOf(",") + 1);
h = parseInt(str);
str = str.substr(str.indexOf(",") + 1);
k = parseInt(str);
str = str.substr(str.indexOf(",") + 1);
l = parseInt(str);
print("\n");
// Another "bug" your outpost can be in the same position as a computer outpost
// Let us suppose both live in a different matrix.
while (1) {
// The original game didn't limited the input to 1-25
do {
print("WHERE DO YOU WISH TO FIRE YOUR MISSLE");
y = parseInt(await input());
} while (y < 0 || y > 25) ;
if (y == c || y == d || y == e || y == f) {
// The original game has a bug. You can shoot the same outpost
// several times. This solves it.
if (y == c)
c = 0;
if (y == d)
d = 0;
if (y == e)
e = 0;
if (y == f)
f = 0;
q++;
if (q == 1) {
print("ONE DOWN. THREE TO GO.\n");
} else if (q == 2) {
print("TWO DOWN. TWO TO GO.\n");
} else if (q == 3) {
print("THREE DOWN. ONE TO GO.\n");
} else {
print("YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN\n");
print("MY TRANSISTO&S RECUP%RA*E!\n");
break;
}
} else {
print("HA, HA YOU MISSED. MY TURN NOW:\n");
}
print("\n");
print("\n");
do {
m = Math.floor(Math.random() * 25 + 1);
p++;
n = p - 1;
for (t = 1; t <= n; t++) {
if (m == ma[t])
break;
}
} while (t <= n) ;
x = m;
ma[p] = m;
if (x == g || x == h || x == l || x == k) {
z++;
if (z < 4)
print("I GOT YOU. IT WON'T BE LONG NOW. POST " + x + " WAS HIT.\n");
if (z == 1) {
print("YOU HAVE ONLY THREE OUTPOSTS LEFT.\n");
} else if (z == 2) {
print("YOU HAVE ONLY TWO OUTPOSTS LEFT.\n");
} else if (z == 3) {
print("YOU HAVE ONLY ONE OUTPOST LEFT.\n");
} else {
print("YOU'RE DEAD. YOUR LAST OUTPOST WAS AT " + x + ". HA, HA, HA.\n");
print("BETTER LUCK NEXT TIME.\n");
}
} else {
print("I MISSED YOU, YOU DIRTY RAT. I PICKED " + m + ". YOUR TURN:\n");
}
print("\n");
print("\n");
}
}
main();

View File

@@ -0,0 +1,151 @@
#!/usr/bin/env python3
import random
from functools import partial
def display_intro():
print("" * 33 + "BOMBARDMENT")
print("" * 15 + " CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print("\n\n")
print("YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU")
print("HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.")
print("YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST.")
print("THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS.")
print()
print("THE OBJECT OF THE GAME IS TO FIRE MISSLES AT THE")
print("OUTPOSTS OF THE COMPUTER. IT WILL DO THE SAME TO YOU.")
print("THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS")
print("FIRST IS THE WINNER.")
print()
print("GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!")
print()
print("TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.")
print("\n" * 4)
def display_field():
for row in range(5):
initial = row * 5 + 1
print('\t'.join([str(initial + column) for column in range(5)]))
print("\n" * 9)
def positions_list():
return list(range(1, 26, 1))
def generate_enemy_positions():
""" Randomly choose 4 'positions' out of a range of 1 to 25 """
positions = positions_list()
random.shuffle(positions)
return set(positions[:4])
def is_valid_position(pos):
return pos in positions_list()
def prompt_for_player_positions():
while True:
raw_positions = input("WHAT ARE YOUR FOUR POSITIONS? ")
positions = set(int(pos) for pos in raw_positions.split())
# Verify user inputs (for example, if the player gives a
# a position for 26, the enemy can never hit it)
if (len(positions) != 4):
print("PLEASE ENTER 4 UNIQUE POSITIONS\n")
continue
elif (any(not is_valid_position(pos) for pos in positions)):
print("ALL POSITIONS MUST RANGE (1-25)\n")
continue
else:
return positions
def prompt_player_for_target():
while True:
target = int(input("WHERE DO YOU WISH TO FIRE YOUR MISSLE? "))
if not is_valid_position(target):
print("POSITIONS MUST RANGE (1-25)\n")
continue
return target
def attack(target, positions, hit_message, miss_message, progress_messages):
""" Performs attack procedure returning True if we are to continue. """
if target in positions:
print(hit_message.format(target))
positions.remove(target)
print(progress_messages[len(positions)].format(target))
else:
print(miss_message.format(target))
return len(positions) > 0
def init_enemy():
""" Returns a closure analogous to prompt_player_for_target. Will
choose from a unique sequence of positions to avoid picking the
same position twice. """
position_sequence = positions_list()
random.shuffle(position_sequence)
position = iter(position_sequence)
def choose():
return next(position)
return choose
# Messages correspond to outposts remaining (3, 2, 1, 0)
PLAYER_PROGRESS_MESSAGES = (
"YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN\n"
"MY TRANSISTO&S RECUP%RA*E!",
"THREE DOWN, ONE TO GO.\n\n",
"TWO DOWN, TWO TO GO.\n\n",
"ONE DOWN, THREE TO GO.\n\n"
)
ENEMY_PROGRESS_MESSAGES = (
"YOU'RE DEAD. YOUR LAST OUTPOST WAS AT {}. HA, HA, HA.\n"
"BETTER LUCK NEXT TIME.",
"YOU HAVE ONLY ONE OUTPOST LEFT.\n\n",
"YOU HAVE ONLY TWO OUTPOSTS LEFT.\n\n",
"YOU HAVE ONLY THREE OUTPOSTS LEFT.\n\n",
)
def play():
display_intro()
display_field()
enemy_positions = generate_enemy_positions()
player_positions = prompt_for_player_positions()
# Build partial functions only requiring the target as input
player_attacks = partial(attack,
positions=enemy_positions,
hit_message="YOU GOT ONE OF MY OUTPOSTS!",
miss_message="HA, HA YOU MISSED. MY TURN NOW:\n\n",
progress_messages=PLAYER_PROGRESS_MESSAGES)
enemy_attacks = partial(attack,
positions=player_positions,
hit_message="I GOT YOU. IT WON'T BE LONG NOW. POST {} WAS HIT.",
miss_message="I MISSED YOU, YOU DIRTY RAT. I PICKED {}. YOUR TURN:\n\n",
progress_messages=ENEMY_PROGRESS_MESSAGES)
enemy_position_choice = init_enemy()
# Play as long as both player_attacks and enemy_attacks allow to continue
while player_attacks(prompt_player_for_target()) and enemy_attacks(enemy_position_choice()):
pass
if __name__ == "__main__":
play()

View File

@@ -0,0 +1,505 @@
import java.util.Scanner;
/**
* Game of Bombs Away
*
* Based on the Basic game of Bombs Away here
* https://github.com/coding-horror/basic-computer-games/blob/main/12%20Bombs%20Away/bombsaway.bas
*
* 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 BombsAway {
public static final int MAX_PILOT_MISSIONS = 160;
public static final int MAX_CASUALTIES = 100;
public static final int MISSED_TARGET_CONST_1 = 2;
public static final int MISSED_TARGET_CONST_2 = 30;
public static final int CHANCE_OF_BEING_SHOT_DOWN_BASE = 100;
public static final double SIXTY_FIVE_PERCENT = .65;
private enum GAME_STATE {
START,
CHOOSE_SIDE,
CHOOSE_PLANE,
CHOOSE_TARGET,
CHOOSE_MISSIONS,
CHOOSE_ENEMY_DEFENCES,
FLY_MISSION,
DIRECT_HIT,
MISSED_TARGET,
PROCESS_FLAK,
SHOT_DOWN,
MADE_IT_THROUGH_FLAK,
PLAY_AGAIN,
GAME_OVER
}
public enum SIDE {
ITALY(1),
ALLIES(2),
JAPAN(3),
GERMANY(4);
private final int value;
SIDE(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
public enum TARGET {
ALBANIA(1),
GREECE(2),
NORTH_AFRICA(3),
RUSSIA(4),
ENGLAND(5),
FRANCE(6);
private final int value;
TARGET(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
public enum ENEMY_DEFENCES {
GUNS(1),
MISSILES(2),
BOTH(3);
private final int value;
ENEMY_DEFENCES(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
public enum AIRCRAFT {
LIBERATOR(1),
B29(2),
B17(3),
LANCASTER(4);
private final int value;
AIRCRAFT(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
// Used for keyboard input
private final Scanner kbScanner;
// Current game state
private GAME_STATE gameState;
private SIDE side;
private int missions;
private int chanceToHit;
private int percentageHitRateOfGunners;
public BombsAway() {
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.
case START:
intro();
chanceToHit = 0;
percentageHitRateOfGunners = 0;
gameState = GAME_STATE.CHOOSE_SIDE;
break;
case CHOOSE_SIDE:
side = getSide("WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4) ? ");
if (side == null) {
System.out.println("TRY AGAIN...");
} else {
// Different game paths depending on which side was chosen
switch (side) {
case ITALY:
case GERMANY:
gameState = GAME_STATE.CHOOSE_TARGET;
break;
case ALLIES:
case JAPAN:
gameState = GAME_STATE.CHOOSE_PLANE;
break;
}
}
break;
case CHOOSE_TARGET:
String prompt;
if (side == SIDE.ITALY) {
prompt = "YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3) ? ";
} else {
// Germany
System.out.println("A NAZI, EH? OH WELL. ARE YOU GOING FOR RUSSIA(1),");
prompt = "ENGLAND(2), OR FRANCE(3) ? ";
}
TARGET target = getTarget(prompt);
if (target == null) {
System.out.println("TRY AGAIN...");
} else {
displayTargetMessage(target);
gameState = GAME_STATE.CHOOSE_MISSIONS;
}
case CHOOSE_MISSIONS:
missions = getNumberFromKeyboard("HOW MANY MISSIONS HAVE YOU FLOWN? ");
if(missions <25) {
System.out.println("FRESH OUT OF TRAINING, EH?");
gameState = GAME_STATE.FLY_MISSION;
} else if(missions < 100) {
System.out.println("THAT'S PUSHING THE ODDS!");
gameState = GAME_STATE.FLY_MISSION;
} else if(missions >=160) {
System.out.println("MISSIONS, NOT MILES...");
System.out.println("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS.");
System.out.println("NOW THEN, ");
} else {
// No specific message if missions is 100-159, but still valid
gameState = GAME_STATE.FLY_MISSION;
}
break;
case CHOOSE_PLANE:
switch(side) {
case ALLIES:
AIRCRAFT plane = getPlane("AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4)? ");
if(plane == null) {
System.out.println("TRY AGAIN...");
} else {
switch(plane) {
case LIBERATOR:
System.out.println("YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI.");
break;
case B29:
System.out.println("YOU'RE DUMPING THE A-BOMB ON HIROSHIMA.");
break;
case B17:
System.out.println("YOU'RE CHASING THE BISMARK IN THE NORTH SEA.");
break;
case LANCASTER:
System.out.println("YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR.");
break;
}
gameState = GAME_STATE.CHOOSE_MISSIONS;
}
break;
case JAPAN:
System.out.println("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.");
if(yesEntered(displayTextAndGetInput("YOUR FIRST KAMIKAZE MISSION(Y OR N) ? "))) {
if(randomNumber(1) > SIXTY_FIVE_PERCENT) {
gameState = GAME_STATE.DIRECT_HIT;
} else {
// It's a miss
gameState = GAME_STATE.MISSED_TARGET;
}
} else {
gameState = GAME_STATE.PROCESS_FLAK;
}
break;
}
break;
case FLY_MISSION:
double missionResult = (MAX_PILOT_MISSIONS * randomNumber(1));
if(missions > missionResult) {
gameState = GAME_STATE.DIRECT_HIT;
} else {
gameState = GAME_STATE.MISSED_TARGET;
}
break;
case DIRECT_HIT:
System.out.println("DIRECT HIT!!!! " + (int) Math.round(randomNumber(MAX_CASUALTIES)) + " KILLED.");
System.out.println("MISSION SUCCESSFUL.");
gameState = GAME_STATE.PLAY_AGAIN;
break;
case MISSED_TARGET:
System.out.println("MISSED TARGET BY " + (int) Math.round(MISSED_TARGET_CONST_1 + MISSED_TARGET_CONST_2 * (randomNumber(1))) + " MILES!");
System.out.println("NOW YOU'RE REALLY IN FOR IT !!");
System.out.println();
gameState = GAME_STATE.CHOOSE_ENEMY_DEFENCES;
break;
case CHOOSE_ENEMY_DEFENCES:
boolean bothWeapons = true;
ENEMY_DEFENCES enemyDefences = getEnemyDefences("DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3) ? ");
if(enemyDefences == null) {
System.out.println("TRY AGAIN...");
} else {
switch(enemyDefences) {
case MISSILES:
case GUNS:
bothWeapons = false;
// fall through on purpose to BOTH since its pretty much identical code other than the chance to hit
// increasing if both weapons are part of the defence.
case BOTH:
percentageHitRateOfGunners = getNumberFromKeyboard("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? ");
if(percentageHitRateOfGunners < 10) {
System.out.println("YOU LIE, BUT YOU'LL PAY...");
}
if(bothWeapons) {
chanceToHit = 35;
}
break;
}
}
gameState = GAME_STATE.PROCESS_FLAK;
// Determine if the players airplan makes it through the Flak.
case PROCESS_FLAK:
double calc = (CHANCE_OF_BEING_SHOT_DOWN_BASE * randomNumber(1));
if ((chanceToHit + percentageHitRateOfGunners) > calc) {
gameState = GAME_STATE.SHOT_DOWN;
} else {
gameState = GAME_STATE.MADE_IT_THROUGH_FLAK;
}
break;
case SHOT_DOWN:
System.out.println("* * * * BOOM * * * *");
System.out.println("YOU HAVE BEEN SHOT DOWN.....");
System.out.println("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR");
System.out.println("LAST TRIBUTE...");
gameState = GAME_STATE.PLAY_AGAIN;
break;
case MADE_IT_THROUGH_FLAK:
System.out.println("YOU MADE IT THROUGH TREMENDOUS FLAK!!");
gameState = GAME_STATE.PLAY_AGAIN;
break;
case PLAY_AGAIN:
if(yesEntered(displayTextAndGetInput("ANOTHER MISSION (Y OR N) ? "))) {
gameState = GAME_STATE.START;
} else {
System.out.println("CHICKEN !!!");
gameState = GAME_STATE.GAME_OVER;
}
break;
}
} while (gameState != GAME_STATE.GAME_OVER) ;
}
/**
* Display a (brief) intro
*/
public void intro() {
System.out.println("YOU ARE A PILOT IN A WORLD WAR II BOMBER.");
}
/**
* Determine the side the player is going to play on.
* @param message displayed before the kb input
* @return the SIDE enum selected by the player
*/
private SIDE getSide(String message) {
int valueEntered = getNumberFromKeyboard(message);
for(SIDE side : SIDE.values()) {
if(side.getValue() == valueEntered) {
return side;
}
}
// Input out of range
return null;
}
/**
* Determine the target the player is going for.
* @param message displayed before the kb input
* @return the TARGET enum selected by the player
*/
private TARGET getTarget(String message) {
int valueEntered = getNumberFromKeyboard(message);
for(TARGET target : TARGET.values()) {
if(target.getValue() == valueEntered) {
return target;
}
}
// Input out of range
return null;
}
/**
* Determine the airplane the player is going to fly.
* @param message displayed before the kb input
* @return the AIRCRAFT enum selected by the player
*/
private AIRCRAFT getPlane(String message) {
int valueEntered = getNumberFromKeyboard(message);
for(AIRCRAFT plane : AIRCRAFT.values()) {
if(plane.getValue() == valueEntered) {
return plane;
}
}
// Input out of range
return null;
}
/**
* Select the type of enemy defences.
*
* @param message displayed before kb input
* @return the ENEMY_DEFENCES enum as selected by player
*/
private ENEMY_DEFENCES getEnemyDefences(String message) {
int valueEntered = getNumberFromKeyboard(message);
for (ENEMY_DEFENCES enemyDefences : ENEMY_DEFENCES.values()) {
if(enemyDefences.getValue() == valueEntered) {
return enemyDefences;
}
}
// Input out of range
return null;
}
// output a specific message based on the target selected
private void displayTargetMessage(TARGET target) {
switch (target) {
case ALBANIA:
System.out.println("SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE.");
break;
case GREECE:
System.out.println("BE CAREFUL!!!");
break;
case NORTH_AFRICA:
System.out.println("YOU'RE GOING FOR THE OIL, EH?");
break;
case RUSSIA:
System.out.println("YOU'RE NEARING STALINGRAD.");
break;
case ENGLAND:
System.out.println("NEARING LONDON. BE CAREFUL, THEY'VE GOT RADAR.");
break;
case FRANCE:
System.out.println("NEARING VERSAILLES. DUCK SOUP. THEY'RE NEARLY DEFENSELESS.");
break;
}
}
/**
* Accepts a string from the keyboard, and converts to an int
*
* @param message displayed text on screen before keyboard input
*
* @return the number entered by the player
*/
private int getNumberFromKeyboard(String message) {
String answer = displayTextAndGetInput(message);
return Integer.parseInt(answer);
}
/**
* Checks whether player entered Y or YES to a question.
*
* @param text player string from kb
* @return true of Y or YES was entered, otherwise false
*/
private boolean yesEntered(String text) {
return stringIsAnyValue(text, "Y", "YES");
}
/**
* 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
* Used as a single digit of the computer player
*
* @return random number
*/
private double randomNumber(int range) {
return (Math.random()
* (range));
}
}

View File

@@ -0,0 +1,8 @@
public class BombsAwayGame {
public static void main(String[] args) {
BombsAway bombsAway = new BombsAway();
bombsAway.play();
}
}

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>BOMBARDMENT</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="bombsaway.js"></script>
</body>
</html>

View File

@@ -0,0 +1,205 @@
// BOMBS AWAY
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
// Main program
async function main()
{
while (1) {
print("YOU ARE A PILOT IN A WORLD WAR II BOMBER.\n");
while (1) {
print("WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4)");
a = parseInt(await input());
if (a < 1 || a > 4)
print("TRY AGAIN...\n");
else
break;
}
if (a == 1) {
while (1) {
print("YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)");
b = parseInt(await input());
if (b < 1 || b > 3)
print("TRY AGAIN...\n");
else
break;
}
print("\n");
if (b == 1) {
print("SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE.\n");
} else if (b == 2) {
print("BE CAREFUL!!!\n");
} else {
print("YOU'RE GOING FOR THE OIL, EH?\n");
}
} else if (a == 2) {
while (1) {
print("AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4)");
g = parseInt(await input());
if (g < 1 || g > 4)
print("TRY AGAIN...\n");
else
break;
}
print("\n");
if (g == 1) {
print("YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI.\n");
} else if (g == 2) {
print("YOU'RE DUMPING THE A-BOMB ON HIROSHIMA.\n");
} else if (g == 3) {
print("YOU'RE CHASING THE BISMARK IN THE NORTH SEA.\n");
} else {
print("YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR.\n");
}
} else if (a == 3) {
print("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.\n");
print("YOUR FIRST KAMIKAZE MISSION(Y OR N)");
str = await input();
if (str == "N") {
s = 0;
} else {
s = 1;
print("\n");
}
} else {
while (1) {
print("A NAZI, EH? OH WELL. ARE YOU GOING FOR RUSSIA(1),\n");
print("ENGLAND(2), OR FRANCE(3)");
m = parseInt(await input());
if (m < 1 || m > 3)
print("TRY AGAIN...\n");
else
break;
}
print("\n");
if (m == 1) {
print("YOU'RE NEARING STALINGRAD.\n");
} else if (m == 2) {
print("NEARING LONDON. BE CAREFUL, THEY'VE GOT RADAR.\n");
} else if (m == 3) {
print("NEARING VERSAILLES. DUCK SOUP. THEY'RE NEARLY DEFENSELESS.\n");
}
}
if (a != 3) {
print("\n");
while (1) {
print("HOW MANY MISSIONS HAVE YOU FLOWN");
d = parseInt(await input());
if (d < 160)
break;
print("MISSIONS, NOT MILES...\n");
print("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS.\n");
print("NOW THEN, ");
}
print("\n");
if (d >= 100) {
print("THAT'S PUSHING THE ODDS!\n");
} else if (d < 25) {
print("FRESH OUT OF TRAINING, EH?\n");
}
print("\n");
if (d >= 160 * Math.random())
hit = true;
else
hit = false;
} else {
if (s == 0) {
hit = false;
} else if (Math.random() > 0.65) {
hit = true;
} else {
hit = false;
s = 100;
}
}
if (hit) {
print("DIRECT HIT!!!! " + Math.floor(100 * Math.random()) + " KILLED.\n");
print("MISSION SUCCESSFUL.\n");
} else {
t = 0;
if (a != 3) {
print("MISSED TARGET BY " + Math.floor(2 + 30 * Math.random()) + " MILES!\n");
print("NOW YOU'RE REALLY IN FOR IT !!\n");
print("\n");
while (1) {
print("DOES THE ENEMY HAVE GUNS(1), MISSILE(2), OR BOTH(3)");
r = parseInt(await input());
if (r < 1 || r > 3)
print("TRY AGAIN...\n");
else
break;
}
print("\n");
if (r != 2) {
print("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)");
s = parseInt(await input());
if (s < 10)
print("YOU LIE, BUT YOU'LL PAY...\n");
print("\n");
}
print("\n");
if (r > 1)
t = 35;
}
if (s + t <= 100 * Math.random()) {
print("YOU MADE IT THROUGH TREMENDOUS FLAK!!\n");
} else {
print("* * * * BOOM * * * *\n");
print("YOU HAVE BEEN SHOT DOWN.....\n");
print("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR\n");
print("LAST TRIBUTE...\n");
}
}
print("\n");
print("\n");
print("\n");
print("ANOTHER MISSION (Y OR N)");
str = await input();
if (str != "Y")
break;
}
print("CHICKEN !!!\n");
print("\n");
}
main();

BIN
13 Bounce/javascript/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>BOUNCE</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="bounce.js"></script>
</body>
</html>

View File

@@ -0,0 +1,112 @@
// BOUNCE
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
// Main program
async function main()
{
print(tab(33) + "BOUNCE\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
ta = [];
print("THIS SIMULATION LETS YOU SPECIFY THE INITIAL VELOCITY\n");
print("OF A BALL THROWN STRAIGHT UP, AND THE COEFFICIENT OF\n");
print("ELASTICITY OF THE BALL. PLEASE USE A DECIMAL FRACTION\n");
print("COEFFICIENCY (LESS THAN 1).\n");
print("\n");
print("YOU ALSO SPECIFY THE TIME INCREMENT TO BE USED IN\n");
print("'STROBING' THE BALL'S FLIGHT (TRY .1 INITIALLY).\n");
print("\n");
while (1) {
print("TIME INCREMENT (SEC)");
s2 = parseFloat(await input());
print("\n");
print("VELOCITY (FPS)");
v = parseFloat(await input());
print("\n");
print("COEFFICIENT");
c = parseFloat(await input());
print("\n");
print("FEET\n");
print("\n");
s1 = Math.floor(70 / (v / (16 * s2)));
for (i = 1; i <= s1; i++)
ta[i] = v * Math.pow(c, i - 1) / 16;
for (h = Math.floor(-16 * Math.pow(v / 32, 2) + Math.pow(v, 2) / 32 + 0.5); h >= 0; h -= 0.5) {
str = "";
if (Math.floor(h) == h)
str += " " + h + " ";
l = 0;
for (i = 1; i <= s1; i++) {
for (t = 0; t <= ta[i]; t += s2) {
l += s2;
if (Math.abs(h - (0.5 * (-32) * Math.pow(t, 2) + v * Math.pow(c, i - 1) * t)) <= 0.25) {
while (str.length < l / s2)
str += " ";
str += "0";
}
}
t = ta[i + 1] / 2;
if (-16 * Math.pow(t, 2) + v * Math.pow(c, i - 1) * t < h)
break;
}
print(str + "\n");
}
str = " ";
for (i = 1; i < Math.floor(l + 1) / s2 + 1; i++)
str += ".";
print(str + "\n");
str = " 0";
for (i = 1; i < Math.floor(l + 0.9995); i++) {
while (str.length < Math.floor(i / s2))
str += " ";
str += i;
}
print(str + "\n");
print(tab(Math.floor(l + 1) / (2 * s2) - 2) + "SECONDS\n");
}
}
main();

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);
}
}

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -1,15 +1,26 @@
import java.util.ArrayList;
import java.util.Scanner;
/**
* Game of Bullseye
* <p>
* Based on the Basic game of Bullseye here
* https://github.com/coding-horror/basic-computer-games/blob/main/18%20Bullseye/bullseye.bas
* <p>
* Note: The idea was to create a version of 1970's Basic game in Java, without introducing
* new features - no additional text, error checking, etc has been added.
*/
public class Bullseye {
// Used for formatting output
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 };
// Used to decide throw result
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,
@@ -20,14 +31,12 @@ public class Bullseye {
private GAME_STATE gameState;
private ArrayList<Player> players;
private final ArrayList<Player> players;
private Shot[] shots;
private final Shot[] shots;
// Used for keyboard input
private Scanner kbScanner;
private int numberOfPlayers;
private final Scanner kbScanner;
private int round;
@@ -49,7 +58,6 @@ public class Bullseye {
/**
* Main game loop
*
*/
public void play() {
@@ -65,10 +73,10 @@ public class Bullseye {
// Start the game, set the number of players, names and round
case START_GAME:
this.numberOfPlayers = chooseNumberOfPlayers();
int numberOfPlayers = chooseNumberOfPlayers();
for(int i=0; i<this.numberOfPlayers; i++) {
String name = displayTextAndGetInput("NAME OF PLAYER #" + (i+1) + "? ");
for (int i = 0; i < numberOfPlayers; i++) {
String name = displayTextAndGetInput("NAME OF PLAYER #" + (i + 1) + "? ");
Player player = new Player(name);
this.players.add(player);
}
@@ -85,8 +93,7 @@ public class Bullseye {
System.out.println("=======");
// Each player takes their turn
for(int i=0; i<players.size(); i++) {
Player player = players.get(i);
for (Player player : players) {
int playerThrow = getPlayersThrow(player);
int points = calculatePlayerPoints(playerThrow);
player.addScore(points);
@@ -96,11 +103,10 @@ public class Bullseye {
boolean foundWinner = false;
// Check if any player won
for(int i=0; i<players.size(); i++) {
Player thePlayer = players.get(i);
for (Player thePlayer : players) {
int score = thePlayer.getScore();
if(score >=200) {
if(!foundWinner) {
if (score >= 200) {
if (!foundWinner) {
System.out.println("WE HAVE A WINNER!!");
System.out.println();
foundWinner = true;
@@ -110,7 +116,7 @@ public class Bullseye {
}
}
if(foundWinner) {
if (foundWinner) {
System.out.println("THANKS FOR THE GAME.");
gameState = GAME_STATE.GAME_OVER;
} else {
@@ -120,12 +126,11 @@ public class Bullseye {
break;
}
} while(gameState != GAME_STATE.GAME_OVER);
} while (gameState != GAME_STATE.GAME_OVER);
}
/**
* Display info about the game
*
*/
private void intro() {
System.out.println("BULLSEYE");
@@ -136,7 +141,7 @@ public class Bullseye {
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("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"));
}
@@ -151,16 +156,16 @@ public class Bullseye {
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 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) {
if (random >= p1) {
System.out.println("BULLSEYE!! 40 POINTS!");
points = 40;
// If the throw was 1 (bullseye or missed, then make it missed
@@ -170,13 +175,13 @@ public class Bullseye {
} else if (playerThrow == 1) {
System.out.println("MISSED THE TARGET! TOO BAD.");
points = 0;
} else if(random >= p2) {
} else if (random >= p2) {
System.out.println("30-POINT ZONE!");
points = 30;
} else if(random >= p3) {
} else if (random >= p3) {
System.out.println("20-POINT ZONE");
points = 20;
} else if(random >= p4) {
} else if (random >= p4) {
System.out.println("WHEW! 10 POINTS.");
points = 10;
} else {
@@ -190,23 +195,23 @@ public class Bullseye {
/**
* Get players shot 1,2, or 3 - ask again if invalid input
*
* @param player
* @return 1,2, or 3 indicating the players shot
* @param player the player we are calculating the throw on
* @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")) {
if (theThrow.equals("1") || theThrow.equals("2") || theThrow.equals("3")) {
inputCorrect = true;
} else {
System.out.println("INPUT 1, 2, OR 3!");
}
} while(!inputCorrect);
} while (!inputCorrect);
return Integer.valueOf(theThrow);
return Integer.parseInt(theThrow);
}
@@ -217,8 +222,9 @@ public class Bullseye {
*/
private int chooseNumberOfPlayers() {
return Integer.valueOf((displayTextAndGetInput("HOW MANY PLAYERS? ")));
return Integer.parseInt((displayTextAndGetInput("HOW MANY PLAYERS? ")));
}
/*
* Print a message on the screen, then accept input from Keyboard.
*
@@ -234,9 +240,9 @@ public class Bullseye {
* 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 first String to print in pos 1
* @param second String to print in pos 2
* @param third String to print in pos 3
* @param third String to print in pos 3
* @return formatted string
*/
private String paddedString(String first, String second, String third) {

View File

@@ -4,7 +4,8 @@
*/
public class Player {
private String name;
private final String name;
private int score;
Player(String name) {

View File

@@ -10,9 +10,7 @@ public class Shot {
// 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];
}
System.arraycopy(shots, 0, chances, 0, shots.length);
}
public double getShot(int index) {

81
19 Bunny/python/bunny.py Executable file
View File

@@ -0,0 +1,81 @@
#!/usr/bin/env python3
# This data is meant to be read-only, so we are storing it in a tuple
DATA = (2,21,14,14,25,
1,2,-1,0,2,45,50,-1,0,5,43,52,-1,0,7,41,52,-1,
1,9,37,50,-1,2,11,36,50,-1,3,13,34,49,-1,4,14,32,48,-1,
5,15,31,47,-1,6,16,30,45,-1,7,17,29,44,-1,8,19,28,43,-1,
9,20,27,41,-1,10,21,26,40,-1,11,22,25,38,-1,12,22,24,36,-1,
13,34,-1,14,33,-1,15,31,-1,17,29,-1,18,27,-1,
19,26,-1,16,28,-1,13,30,-1,11,31,-1,10,32,-1,
8,33,-1,7,34,-1,6,13,16,34,-1,5,12,16,35,-1,
4,12,16,35,-1,3,12,15,35,-1,2,35,-1,1,35,-1,
2,34,-1,3,34,-1,4,33,-1,6,33,-1,10,32,34,34,-1,
14,17,19,25,28,31,35,35,-1,15,19,23,30,36,36,-1,
14,18,21,21,24,30,37,37,-1,13,18,23,29,33,38,-1,
12,29,31,33,-1,11,13,17,17,19,19,22,22,24,31,-1,
10,11,17,18,22,22,24,24,29,29,-1,
22,23,26,29,-1,27,29,-1,28,29,-1,4096)
def display_intro():
print(tab(33) + "BUNNY")
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print("\n\n")
def tab(column):
""" Emulates the TAB command in BASIC. Returns a string with ASCII
codes for setting the cursor to the specified column. """
return "\r\33[{}C".format(column)
def play():
display_intro()
# Using an iterator will give us a similar interface to BASIC's READ
# command. Instead of READ, we will call 'next(data)' to fetch the next element.
data = iter(DATA)
# Read the first 5 numbers. These correspond to letters of the alphabet.
# B=2, U=21, N=14, N=14, Y=25
# Usually, list comprehensions are good for transforming each element in a sequence.
# In this case, we are using range to repeat the call to next(data) 5 times. The underscore (_)
# indicates that the values from range are discarded.
bunny = [next(data) for _ in range(5)]
L = 64
# Interpretting a stream of data is a very common software task. We've already intepretted
# the first 5 numbers as letters of the alphabet (with A being 1). Now, we are going to
# combine this with a different interpretation of the following data to draw on the screen.
# The drawing data is essentially a series of horizontal line segments given as begin and end
# offsets.
while True:
command = next(data)
if command < 0:
print()
continue
if command > 128:
break
# If we've reached this portion of the code, 'command' indicates the 'start'
# position of a line segment.
start = command
# Position cursor at start
print(tab(start), end="")
# The following number, indicates the end of the segment.
end = next(data)
# Unlike FOR I=X TO Y, the 'stop' argument of 'range' is non-inclusive, so we must add 1
for i in range(start, end+1, 1):
# Cycle through the letters in "BUNNY" as we draw line
j = i - 5 * int(i / 5)
print(chr(L + bunny[j]), end="")
if __name__ == "__main__":
play()

View File

@@ -0,0 +1,41 @@
import java.util.Scanner;
import static java.lang.System.out;
// This is very close to the original BASIC. Changes:
// 1) the array indexing is adjusted by 1
// 2) the user can enter a lower case "y"
// 3) moved the word list to the top 8~)
public class Buzzword {
private static final String[] A = {
"ABILITY","BASAL","BEHAVIORAL","CHILD-CENTERED",
"DIFFERENTIATED","DISCOVERY","FLEXIBLE","HETEROGENEOUS",
"HOMOGENEOUS","MANIPULATIVE","MODULAR","TAVISTOCK",
"INDIVIDUALIZED","LEARNING","EVALUATIVE","OBJECTIVE",
"COGNITIVE","ENRICHMENT","SCHEDULING","HUMANISTIC",
"INTEGRATED","NON-GRADED","TRAINING","VERTICAL AGE",
"MOTIVATIONAL","CREATIVE","GROUPING","MODIFICATION",
"ACCOUNTABILITY","PROCESS","CORE CURRICULUM","ALGORITHM",
"PERFORMANCE","REINFORCEMENT","OPEN CLASSROOM","RESOURCE",
"STRUCTURE","FACILITY","ENVIRONMENT"
};
private static Scanner scanner = new Scanner( System.in );
public static void main( final String [] args ) {
out.println( " BUZZWORD GENERATOR" );
out.println( " CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" );
out.println();out.println();out.println();
out.println( "THIS PROGRAM PRINTS HIGHLY ACCEPTABLE PHRASES IN" );
out.println( "'EDUCATOR-SPEAK' THAT YOU CAN WORK INTO REPORTS" );
out.println( "AND SPEECHES. WHENEVER A QUESTION MARK IS PRINTED," );
out.println( "TYPE A 'Y' FOR ANOTHER PHRASE OR 'N' TO QUIT." );
out.println();out.println();out.println( "HERE'S THE FIRST PHRASE:" );
do {
out.print( A[ (int)( 13 * Math.random() ) ] + " " );
out.print( A[ (int)( 13 * Math.random() + 13 ) ] + " " );
out.print( A[ (int)( 13 * Math.random() + 26 ) ] ); out.println();
out.print( "?" );
}
while ( "Y".equals( scanner.nextLine().toUpperCase() ) );
out.println( "COME BACK WHEN YOU NEED HELP WITH ANOTHER REPORT!" );
}
}

View File

@@ -0,0 +1,187 @@
import java.util.Arrays;
import java.util.Scanner;
/**
* Game of Change
* <p>
* Based on the Basic game of Change here
* https://github.com/coding-horror/basic-computer-games/blob/main/22%20Change/change.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 Change {
// Used for keyboard input
private final Scanner kbScanner;
private enum GAME_STATE {
START_GAME,
INPUT,
CALCULATE,
END_GAME,
GAME_OVER
}
// Current game state
private GAME_STATE gameState;
// Amount of change needed to be given
private double change;
public Change() {
kbScanner = new Scanner(System.in);
gameState = GAME_STATE.START_GAME;
}
/**
* Main game loop
*/
public void play() {
do {
switch (gameState) {
case START_GAME:
intro();
gameState = GAME_STATE.INPUT;
break;
case INPUT:
double costOfItem = displayTextAndGetNumber("COST OF ITEM ");
double amountPaid = displayTextAndGetNumber("AMOUNT OF PAYMENT ");
change = amountPaid - costOfItem;
if (change == 0) {
// No change needed
System.out.println("CORRECT AMOUNT, THANK YOU.");
gameState = GAME_STATE.END_GAME;
} else if (change < 0) {
System.out.println("YOU HAVE SHORT-CHANGES ME $" + (costOfItem - amountPaid));
// Don't change game state so it will loop back and try again
} else {
// Change needed.
gameState = GAME_STATE.CALCULATE;
}
break;
case CALCULATE:
System.out.println("YOUR CHANGE, $" + change);
calculateChange();
gameState = GAME_STATE.END_GAME;
break;
case END_GAME:
System.out.println("THANK YOU, COME AGAIN");
System.out.println();
gameState = GAME_STATE.INPUT;
}
} while (gameState != GAME_STATE.GAME_OVER);
}
/**
* Calculate and output the change required for the purchase based on
* what money was paid.
*/
private void calculateChange() {
double originalChange = change;
int tenDollarBills = (int) change / 10;
if (tenDollarBills > 0) {
System.out.println(tenDollarBills + " TEN DOLLAR BILL(S)");
}
change = originalChange - (tenDollarBills * 10);
int fiveDollarBills = (int) change / 5;
if (fiveDollarBills > 0) {
System.out.println(fiveDollarBills + " FIVE DOLLAR BILL(S)");
}
change = originalChange - (tenDollarBills * 10 + fiveDollarBills * 5);
int oneDollarBills = (int) change;
if (oneDollarBills > 0) {
System.out.println(oneDollarBills + " ONE DOLLAR BILL(S)");
}
change = originalChange - (tenDollarBills * 10 + fiveDollarBills * 5 + oneDollarBills);
change = change * 100;
double cents = change;
int halfDollars = (int) change / 50;
if (halfDollars > 0) {
System.out.println(halfDollars + " ONE HALF DOLLAR(S)");
}
change = cents - (halfDollars * 50);
int quarters = (int) change / 25;
if (quarters > 0) {
System.out.println(quarters + " QUARTER(S)");
}
change = cents - (halfDollars * 50 + quarters * 25);
int dimes = (int) change / 10;
if (dimes > 0) {
System.out.println(dimes + " DIME(S)");
}
change = cents - (halfDollars * 50 + quarters * 25 + dimes * 10);
int nickels = (int) change / 5;
if (nickels > 0) {
System.out.println(nickels + " NICKEL(S)");
}
change = cents - (halfDollars * 50 + quarters * 25 + dimes * 10 + nickels * 5);
int pennies = (int) (change + .5);
if (pennies > 0) {
System.out.println(pennies + " PENNY(S)");
}
}
private void intro() {
System.out.println(simulateTabs(33) + "CHANGE");
System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println("I, YOUR FRIENDLY MICROCOMPUTER, WILL DETERMINE");
System.out.println("THE CORRECT CHANGE FOR ITEMS COSTING UP TO $100.");
System.out.println();
}
/*
* 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);
}
}

View File

@@ -0,0 +1,6 @@
public class ChangeGame {
public static void main(String[] args) {
Change change = new Change();
change.play();
}
}

View File

@@ -0,0 +1,143 @@
import java.util.Arrays;
import java.util.Scanner;
/**
* Game of Chemist
* <p>
* Based on the Basic game of Chemist here
* https://github.com/coding-horror/basic-computer-games/blob/main/24%20Chemist/chemist.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 Chemist {
public static final int MAX_LIVES = 9;
// Used for keyboard input
private final Scanner kbScanner;
private enum GAME_STATE {
START_GAME,
INPUT,
BLOWN_UP,
SURVIVED,
GAME_OVER
}
// Current game state
private GAME_STATE gameState;
private int timesBlownUp;
public Chemist() {
kbScanner = new Scanner(System.in);
gameState = GAME_STATE.START_GAME;
}
/**
* Main game loop
*/
public void play() {
do {
switch (gameState) {
case START_GAME:
intro();
timesBlownUp = 0;
gameState = GAME_STATE.INPUT;
break;
case INPUT:
int amountOfAcid = (int) (Math.random() * 50);
int correctAmountOfWater = (7 * amountOfAcid) / 3;
int water = displayTextAndGetNumber(amountOfAcid + " LITERS OF KRYPTOCYANIC ACID. HOW MUCH WATER? ");
// Calculate if the player mixed enough water
int result = Math.abs(correctAmountOfWater - water);
// Ratio of water wrong?
if (result > (correctAmountOfWater / 20)) {
gameState = GAME_STATE.BLOWN_UP;
} else {
// Got the ratio correct
gameState = GAME_STATE.SURVIVED;
}
break;
case BLOWN_UP:
System.out.println(" SIZZLE! YOU HAVE JUST BEEN DESALINATED INTO A BLOB");
System.out.println(" OF QUIVERING PROTOPLASM!");
timesBlownUp++;
if (timesBlownUp < MAX_LIVES) {
System.out.println(" HOWEVER, YOU MAY TRY AGAIN WITH ANOTHER LIFE.");
gameState = GAME_STATE.INPUT;
} else {
System.out.println(" YOUR " + MAX_LIVES + " LIVES ARE USED, BUT YOU WILL BE LONG REMEMBERED FOR");
System.out.println(" YOUR CONTRIBUTIONS TO THE FIELD OF COMIC BOOK CHEMISTRY.");
gameState = GAME_STATE.GAME_OVER;
}
break;
case SURVIVED:
System.out.println(" GOOD JOB! YOU MAY BREATHE NOW, BUT DON'T INHALE THE FUMES!");
System.out.println();
gameState = GAME_STATE.INPUT;
break;
}
} while (gameState != GAME_STATE.GAME_OVER);
}
private void intro() {
System.out.println(simulateTabs(33) + "CHEMIST");
System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println("THE FICTITIOUS CHEMICAL KRYPTOCYANIC ACID CAN ONLY BE");
System.out.println("DILUTED BY THE RATIO OF 7 PARTS WATER TO 3 PARTS ACID.");
System.out.println("IF ANY OTHER RATIO IS ATTEMPTED, THE ACID BECOMES UNSTABLE");
System.out.println("AND SOON EXPLODES. GIVEN THE AMOUNT OF ACID, YOU MUST");
System.out.println("DECIDE WHO MUCH WATER TO ADD FOR DILUTION. IF YOU MISS");
System.out.println("YOU FACE THE CONSEQUENCES.");
}
/*
* Print a message on the screen, then accept input from Keyboard.
* Converts input to an Integer
*
* @param text message to be displayed on screen.
* @return what was typed by the player.
*/
private int displayTextAndGetNumber(String text) {
return Integer.parseInt(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);
}
}

View File

@@ -0,0 +1,6 @@
public class ChemistGame {
public static void main(String[] args) {
Chemist chemist = new Chemist();
chemist.play();
}
}

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -1,6 +1,15 @@
import java.util.Arrays;
import java.util.Scanner;
/**
* Game of Chief
* <p>
* Based on the Basic game of Hurkle here
* https://github.com/coding-horror/basic-computer-games/blob/main/25%20Chief/chief.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 Chief {
private enum GAME_STATE {
@@ -14,6 +23,7 @@ public class Chief {
private GAME_STATE gameState;
// The number the computer determines to be the players starting number
private double calculatedNumber;
// Used for keyboard input
@@ -43,7 +53,7 @@ public class Chief {
// show an message to start
case READY_TO_START:
if(!yesEntered(displayTextAndGetInput("ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR? "))) {
if (!yesEntered(displayTextAndGetInput("ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR? "))) {
System.out.println("SHUT UP, PALE FACE WITH WISE TONGUE.");
}
@@ -57,17 +67,17 @@ public class Chief {
displayTextAndGetInput(" WHAT DO YOU HAVE? "));
// Exact same formula used in the original game to calculate the players original number
this.calculatedNumber = (playerNumber +1-5)*5/8*5-3;
calculatedNumber = (playerNumber + 1 - 5) * 5 / 8 * 5 - 3;
this.gameState = GAME_STATE.CALCULATE_AND_SHOW;
gameState = GAME_STATE.CALCULATE_AND_SHOW;
break;
// Enter the number to be used to calculate
case CALCULATE_AND_SHOW:
if(yesEntered(
displayTextAndGetInput("I BET YOUR NUMBER WAS " + this.calculatedNumber
+ ". AM I RIGHT? "))) {
this.gameState = GAME_STATE.END_GAME;
if (yesEntered(
displayTextAndGetInput("I BET YOUR NUMBER WAS " + calculatedNumber
+ ". AM I RIGHT? "))) {
gameState = GAME_STATE.END_GAME;
} else {
// Player did not agree, so show the breakdown
@@ -76,27 +86,27 @@ public class Chief {
double f = number + 3;
double g = f / 5;
double h = g * 8;
double i = h/5 + 5;
double j = i -1;
double i = h / 5 + 5;
double j = i - 1;
System.out.println("SO YOU THINK YOU'RE SO SMART, EH?");
System.out.println("NOW WATCH.");
System.out.println(number +" PLUS 3 EQUALS " + f + ". THIS DIVIDED BY 5 EQUALS " + g);
System.out.println("THIS TIMES 8 EQUALS " + h + ". IF WE DIVIDE BY 5 AND ADD 5,");
System.out.println(number + " PLUS 3 EQUALS " + f + ". DIVIDED BY 5 EQUALS " + g);
System.out.println("TIMES 8 EQUALS " + h + ". IF WE DIVIDE BY 5 AND ADD 5,");
System.out.println("WE GET " + i + ", WHICH, MINUS 1, EQUALS " + j + ".");
if(yesEntered(displayTextAndGetInput("NOW DO YOU BELIEVE ME? "))) {
this.gameState = GAME_STATE.END_GAME;
if (yesEntered(displayTextAndGetInput("NOW DO YOU BELIEVE ME? "))) {
gameState = GAME_STATE.END_GAME;
} else {
// Time for a lightning bolt.
System.out.println("YOU HAVE MADE ME MAD!!!");
System.out.println("THERE MUST BE A GREAT LIGHTNING BOLT!");
System.out.println();
for(int x=30; x>=22; x--) {
for (int x = 30; x >= 22; x--) {
System.out.println(tabbedSpaces(x) + "X X");
}
System.out.println(tabbedSpaces(21) + "X XXX");
System.out.println(tabbedSpaces(20) + "X X");
System.out.println(tabbedSpaces(19) + "XX X");
for(int y=20; y>=13; y--) {
for (int y = 20; y >= 13; y--) {
System.out.println(tabbedSpaces(y) + "X X");
}
System.out.println(tabbedSpaces(12) + "XX");
@@ -106,7 +116,7 @@ public class Chief {
System.out.println("#########################");
System.out.println();
System.out.println("I HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!");
this.gameState = GAME_STATE.GAME_OVER;
gameState = GAME_STATE.GAME_OVER;
}
}
@@ -115,7 +125,7 @@ public class Chief {
// Sign off message for cases where the Chief is not upset
case END_GAME:
System.out.println("BYE!!!");
this.gameState = GAME_STATE.GAME_OVER;
gameState = GAME_STATE.GAME_OVER;
break;
// GAME_OVER State does not specifically have a case
@@ -134,14 +144,14 @@ public class Chief {
Arrays.fill(repeat, ' ');
return new String(repeat);
}
private void instructions() {
System.out.println(" TAKE A NUMBER AND ADD 3. DIVIDE THIS NUMBER BY 5 AND");
System.out.println(" TAKE A NUMBER AND ADD 3. DIVIDE NUMBER BY 5 AND");
System.out.println("MULTIPLY BY 8. DIVIDE BY 5 AND ADD THE SAME. SUBTRACT 1.");
}
/**
* Basic information about the game
*
*/
private void intro() {
System.out.println("CHIEF");
@@ -165,15 +175,15 @@ public class Chief {
* Returns true if a given string contains at least one of the varargs (2nd parameter).
* Note: Case insensitive comparison.
*
* @param text string to search
* @param text string to search
* @param values varargs of type string containing values to compare
* @return true if one of the varargs arguments was found in text
*/
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)) {
for (String val : values) {
if (text.equalsIgnoreCase(val)) {
return true;
}
}

View File

@@ -99,6 +99,6 @@
1010 PRINT "YOU LOSE, PLAYER";P1
1020 PRINT
1030 PRINT "AGAIN (1=YES, 0=NO!)";
1040 INPUT R$
1040 INPUT R
1050 IF R=1 THEN 340
1060 END

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>CHOMP</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="chomp.js"></script>
</body>
</html>

View File

@@ -0,0 +1,175 @@
// CHOMP
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
var a = [];
var r;
var c;
function init_board()
{
for (i = 1; i <= r; i++)
for (j = 1; j <= c; j++)
a[i][j] = 1;
a[1][1] = -1;
}
function show_board()
{
print("\n");
print(tab(7) + "1 2 3 4 5 6 7 8 9\n");
for (i = 1; i <= r; i++) {
str = i + tab(6);
for (j = 1; j <= c; j++) {
if (a[i][j] == -1)
str += "P ";
else if (a[i][j] == 0)
break;
else
str += "* ";
}
print(str + "\n");
}
print("\n");
}
// Main program
async function main()
{
print(tab(33) + "CHOMP\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
for (i = 1; i <= 10; i++)
a[i] = [];
// *** THE GAME OF CHOMP *** COPYRIGHT PCC 1973 ***
print("\n");
print("THIS IS THE GAME OF CHOMP (SCIENTIFIC AMERICAN, JAN 1973)\n");
print("DO YOU WANT THE RULES (1=YES, 0=NO!)");
r = parseInt(await input());
if (r != 0) {
f = 1;
r = 5;
c = 7;
print("CHOMP IS FOR 1 OR MORE PLAYERS (HUMANS ONLY).\n");
print("\n");
print("HERE'S HOW A BOARD LOOKS (THIS ONE IS 5 BY 7):\n");
init_board();
show_board();
print("\n");
print("THE BOARD IS A BIG COOKIE - R ROWS HIGH AND C COLUMNS\n");
print("WIDE. YOU INPUT R AND C AT THE START. IN THE UPPER LEFT\n");
print("CORNER OF THE COOKIE IS A POISON SQUARE (P). THE ONE WHO\n");
print("CHOMPS THE POISON SQUARE LOSES. TO TAKE A CHOMP, TYPE THE\n");
print("ROW AND COLUMN OF ONE OF THE SQUARES ON THE COOKIE.\n");
print("ALL OF THE SQUARES BELOW AND TO THE RIGHT OF THAT SQUARE\n");
print("INCLUDING THAT SQUARE, TOO) DISAPPEAR -- CHOMP!!\n");
print("NO FAIR CHOMPING SQUARES THAT HAVE ALREADY BEEN CHOMPED,\n");
print("OR THAT ARE OUTSIDE THE ORIGINAL DIMENSIONS OF THE COOKIE.\n");
print("\n");
}
while (1) {
print("HERE WE GO...\n");
f = 0;
for (i = 1; i <= 10; i++) {
a[i] = [];
for (j = 1; j <= 10; j++) {
a[i][j] = 0;
}
}
print("\n");
print("HOW MANY PLAYERS");
p = parseInt(await input());
i1 = 0;
while (1) {
print("HOW MANY ROWS");
r = parseInt(await input());
if (r <= 9)
break;
print("TOO MANY ROWS (9 IS MAXIMUM). NOW ");
}
while (1) {
print("HOW MANY COLUMNS");
c = parseInt(await input());
if (c <= 9)
break;
print("TOO MANY COLUMNS (9 IS MAXIMUM). NOW ");
}
print("\n");
init_board();
while (1) {
// Print the board
show_board();
// Get chomps for each player in turn
i1++;
p1 = i1 - Math.floor(i1 / p) * p;
if (p1 == 0)
p1 = p;
while (1) {
print("PLAYER " + p1 + "\n");
print("COORDINATES OF CHOMP (ROW,COLUMN)");
str = await input();
r1 = parseInt(str);
c1 = parseInt(str.substr(str.indexOf(",") + 1));
if (r1 >= 1 && r1 <= r && c1 >= 1 && c1 <= c && a[r1][c1] != 0)
break;
print("NO FAIR. YOU'RE TRYING TO CHOMP ON EMPTY SPACE!\n");
}
if (a[r1][c1] == -1)
break;
for (i = r1; i <= r; i++)
for (j = c1; j <= c; j++)
a[i][j] = 0;
}
// End of game detected
print("YOU LOSE, PLAYER " + p1 + "\n");
print("\n");
print("AGAIN (1=YES, 0=NO!)");
r = parseInt(await input());
if (r != 1)
break;
}
}
main();

132
26 Chomp/python/chomp.py Executable file
View File

@@ -0,0 +1,132 @@
#!/usr/bin/env python3
# CHOMP
#
# Converted from BASIC to Python by Trevor Hobson
class Canvas:
""" For drawing the cookie """
def __init__(self, width=9, height=9, fill="*"):
self._buffer = []
for _ in range(height):
line = []
for _ in range(width):
line.append(fill)
self._buffer.append(line)
self._buffer[0][0] = "P"
def render(self):
lines = [" 1 2 3 4 5 6 7 8 9"]
row = 0
for line in self._buffer:
row += 1
lines.append(" " + str(row) + " " * 5 + " ".join(line))
return "\n".join(lines)
def chomp(self, r, c):
if not 1 <= r <= len(self._buffer) or not 1 <= c <= len(self._buffer[0]):
return "Empty"
elif self._buffer[r - 1][c - 1] == " ":
return "Empty"
elif self._buffer[r - 1][c - 1] == "P":
return "Poison"
else:
for row in range(r - 1, len(self._buffer)):
for column in range(c - 1, len(self._buffer[row])):
self._buffer[row][column] = " "
return "Chomp"
def play_game():
"""Play one round of the game"""
players = 0
while players == 0:
try:
players = int(input("How many players "))
except ValueError:
print("Please enter a number.")
rows = 0
while rows == 0:
try:
rows = int(input("How many rows "))
if rows > 9 or rows < 1:
rows = 0
print("Too many rows (9 is maximum).")
except ValueError:
print("Please enter a number.")
columns = 0
while columns == 0:
try:
columns = int(input("How many columns "))
if columns > 9 or columns < 1:
columns = 0
print("Too many columns (9 is maximum).")
except ValueError:
print("Please enter a number.")
cookie = Canvas(width=columns, height=rows)
player = 0
alive = True
while alive:
print("")
print(cookie.render())
print("")
player += 1
if player > players:
player = 1
while True:
print("Player", player)
player_row = -1
player_column = -1
while player_row == -1 or player_column == -1:
try:
coordinates = [int(item) for item in input(
"Coordinates of chomp (Row, Column) ").split(",")]
player_row = coordinates[0]
player_column = coordinates[1]
except (ValueError, IndexError):
print("Please enter valid coordinates.")
result = cookie.chomp(player_row, player_column)
if result == "Empty":
print("No fair. You're trying to chomp on empty space!")
elif result == "Poison":
print("\nYou lose player", player)
alive = False
break
else:
break
def main():
print(" " * 33 + "CHOMP")
print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
print("THIS IS THE GAME OF CHOMP (SCIENTIFIC AMERICAN, JAN 1973)")
if input("Do you want the rules (1=Yes, 0=No!) ") != "0":
print("Chomp is for 1 or more players (Humans only).\n")
print("Here's how a board looks (This one is 5 by 7):")
example = Canvas(width=7, height=5)
print(example.render())
print("\nThe board is a big cookie - R rows high and C columns")
print("wide. You input R and C at the start. In the upper left")
print("corner of the cookie is a poison square (P). The one who")
print("chomps the poison square loses. To take a chomp, type the")
print("row and column of one of the squares on the cookie.")
print("All of the squares below and to the right of that square")
print("(Including that square, too) disappear -- CHOMP!!")
print("No fair chomping squares that have already been chomped,")
print("or that are outside the original dimensions of the cookie.\n")
print("Here we go...")
keep_playing = True
while keep_playing:
play_game()
keep_playing = input("\nAgain (1=Yes, 0=No!) ") == "1"
if __name__ == "__main__":
main()

114
30 Cube/python/cube.py Executable file
View File

@@ -0,0 +1,114 @@
#!/usr/bin/env python3
# CUBE
#
# Converted from BASIC to Python by Trevor Hobson
import random
def mine_position():
mine = []
for _ in range(3):
mine.append(random.randint(1, 3))
return mine
def play_game():
"""Play one round of the game"""
money = 500
print("\nYou have", money, "dollars.")
while True:
mines = []
for _ in range(5):
mine = []
while True:
mine = mine_position()
if not(mine in mines or mine == [1, 1, 1] or mine == [3, 3, 3]):
break
mines.append(mine)
wager = -1
while wager == -1:
try:
wager = int(input("\nHow much do you want to wager? "))
if not 0 <= wager <= money:
wager = -1
print("Tried to fool me; bet again")
except ValueError:
print("Please enter a number.")
prompt = "\nIt's your move: "
position = [1, 1, 1]
while True:
move = [-1, -1, -1]
while move == [-1, -1, -1]:
try:
coordinates = [int(item)
for item in input(prompt).split(",")]
if len(coordinates) == 3:
move = coordinates
else:
raise ValueError
except (ValueError, IndexError):
print("Please enter valid coordinates.")
if (abs(move[0]-position[0]) + abs(move[1]-position[1]) + abs(move[2]-position[2])) > 1:
print("\nIllegal move. You lose")
money = money - wager
break
elif not move[0] in [1, 2, 3] or not move[1] in [1, 2, 3] or not move[2] in [1, 2, 3]:
print("\nIllegal move. You lose")
money = money - wager
break
elif move == [3, 3, 3]:
print("\nCongratulations!")
money = money + wager
break
elif move in mines:
print("\n******BANG******")
print("You lose!")
money = money - wager
break
else:
position = move
prompt = "\nNext move: "
if money > 0:
print("\nYou now have", money, "dollars.")
if not input("Do you want to try again ").lower().startswith("y"):
break
else:
print("\nYou bust.")
print("\nTough luck")
print("\nGoodbye.")
def main():
print(" " * 34 + "CUBE")
print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n")
if input("Do you want to see the instructions ").lower().startswith("y"):
print("\nThis is a game in which you will be playing against the")
print("random decisions of the computer. The field of play is a")
print("cube of side 3. Any of the 27 locations can be designated")
print("by inputing three numbers such as 2,3,1. At the start,")
print("you are automatically at location 1,1,1. The object of")
print("the game is to get to location 3,3,3. One minor detail:")
print("the computer will pick, at random, 5 locations at which")
print("it will plant land mines. If you hit one of these locations")
print("you lose. One other detail: You may move only one space")
print("in one direction each move. For example: From 1,1,2 you")
print("may move to 2,1,2 or 1,1,3. You may not change")
print("two of the numbers on the same move. If you make an illegal")
print("move, you lose and the computer takes the money you may")
print("have bet on that round.\n")
print("When stating the amount of a wager, print only the number")
print("of dollars (example: 250) you are automatically started with")
print("500 dollars in your account.\n")
print("Good luck!")
keep_playing = True
while keep_playing:
play_game()
keep_playing = input(
"\nPlay again? (yes or no) ").lower().startswith("y")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>DEPTH CHARGE</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="depthcharge.js"></script>
</body>
</html>

View File

@@ -0,0 +1,112 @@
// DEPTH CHARGE
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
// Main program
async function main()
{
print(tab(30) + "DEPTH CHARGE\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
print("DIMENSION OF THE SEARCH AREA");
g = Math.floor(await input());
n = Math.floor(Math.log(g) / Math.log(2)) + 1;
print("YOU ARE THE CAPTAIN OF THE DESTROYER USS COMPUTER\n");
print("AN ENEMY SUB HAS BEEN CAUSING YOU TROUBLE. YOUR\n");
print("MISSION IS TO DESTROY IT. YOU HAVE " + n + " SHOTS.\n");
print("SPECIFY DEPTH CHARGE EXPLOSION POINT WITH A\n");
print("TRIO OF NUMBERS -- THE FIRST TWO ARE THE\n");
print("SURFACE COORDINATES; THE THIRD IS THE DEPTH.\n");
do {
print("\n");
print("GOOD LUCK !\n");
print("\n");
a = Math.floor(Math.random() * g);
b = Math.floor(Math.random() * g);
c = Math.floor(Math.random() * g);
for (d = 1; d <= n; d++) {
print("\n");
print("TRIAL #" + d + " ");
str = await input();
x = parseInt(str);
y = parseInt(str.substr(str.indexOf(",") + 1));
z = parseInt(str.substr(str.lastIndexOf(",") + 1));
if (Math.abs(x - a) + Math.abs(y - b) + Math.abs(z - c) == 0)
break;
if (y > b)
print("NORTH");
if (y < b)
print("SOUTH");
if (x > a)
print("EAST");
if (x < a)
print("WEST");
if (y != b || x != a)
print(" AND");
if (z > c)
print(" TOO LOW.\n");
if (z < c)
print(" TOO HIGH.\n");
if (z == c)
print(" DEPTH OK.\n");
print("\n");
}
if (d <= n) {
print("\n");
print("B O O M ! ! YOU FOUND IT IN " + d + " TRIES!\n");
} else {
print("\n");
print("YOU HAVE BEEN TORPEDOED! ABANDON SHIP!\n");
print("THE SUBMARINE WAS AT " + a + "," + b + "," + c + "\n");
}
print("\n");
print("\n");
print("ANOTHER GAME (Y OR N)");
str = await input();
} while (str.substr(0, 1) == "Y") ;
print("OK. HOPE YOU ENJOYED YOURSELF.\n");
}
main();

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>DIAMOND</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="diamond.js"></script>
</body>
</html>

View File

@@ -0,0 +1,94 @@
// DIAMOND
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
// Main program
async function main()
{
print(tab(33) + "DIAMOND\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
print("FOR A PRETTY DIAMOND PATTERN,\n");
print("TYPE IN AN ODD NUMBER BETWEEN 5 AND 21");
r = parseInt(await input());
q = Math.floor(60 / r);
as = "CC"
x = 1;
y = r;
z = 2;
for (l = 1; l <= q; l++) {
for (n = x; z < 0 ? n >= y : n <= y; n += z) {
str = "";
while (str.length < (r - n) / 2)
str += " ";
for (m = 1; m <= q; m++) {
c = 1;
for (a = 1; a <= n; a++) {
if (c > as.length)
str += "!";
else
str += as[c++ - 1];
}
if (m == q)
break;
while (str.length < r * m + (r - n) / 2)
str += " ";
}
print(str + "\n");
}
if (x != 1) {
x = 1;
y = r;
z = 2;
} else {
x = r - 2;
y = 1;
z = -2;
l--;
}
}
}
main();

View File

@@ -0,0 +1,45 @@
def intro
print " DIAMOND
CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
FOR A PRETTY DIAMOND PATTERN,
TYPE IN AN ODD NUMBER BETWEEN 5 AND 21? "
end
def get_facets
while true
number = gets.chomp
return number.to_i if /^\d+$/.match(number)
puts "!NUMBER EXPECTED - RETRY INPUT LINE"
print "? "
end
end
def get_diamond_lines(facets)
spacers = (facets - 1) / 2
lines = [' ' * spacers + 'C' + ' ' * spacers]
lines += (1...facets).step(2).to_a.map { |v|
spacers -= 1
' ' * spacers + 'CC' + '!' * v + ' ' * spacers
}
lines + lines[0..-2].reverse
end
def draw_diamonds(lines)
repeat = 60 / lines[0].length
(0...repeat).each { lines.map { |l| l * repeat }.each { |l| puts l } }
end
def main
intro
facets = get_facets
puts
lines = get_diamond_lines(facets)
draw_diamonds(lines)
end
trap "SIGINT" do puts; exit 130 end
main

146
33 Dice/java/src/Dice.java Normal file
View File

@@ -0,0 +1,146 @@
import java.util.Arrays;
import java.util.Scanner;
/**
* Game of Dice
* <p>
* Based on the Basic game of Dice here
* https://github.com/coding-horror/basic-computer-games/blob/main/33%20Dice/dice.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 Dice {
// Used for keyboard input
private final Scanner kbScanner;
private enum GAME_STATE {
START_GAME,
INPUT_AND_CALCULATE,
RESULTS,
GAME_OVER
}
// Current game state
private GAME_STATE gameState;
private int[] spots;
public Dice() {
kbScanner = new Scanner(System.in);
gameState = GAME_STATE.START_GAME;
}
/**
* Main game loop
*/
public void play() {
do {
switch (gameState) {
case START_GAME:
intro();
spots = new int[12];
gameState = GAME_STATE.INPUT_AND_CALCULATE;
break;
case INPUT_AND_CALCULATE:
int howManyRolls = displayTextAndGetNumber("HOW MANY ROLLS? ");
for (int i = 0; i < howManyRolls; i++) {
int diceRoll = (int) (Math.random() * 6 + 1) + (int) (Math.random() * 6 + 1);
// save dice roll in zero based array
spots[diceRoll - 1]++;
}
gameState = GAME_STATE.RESULTS;
break;
case RESULTS:
System.out.println("TOTAL SPOTS" + simulateTabs(8) + "NUMBER OF TIMES");
for (int i = 1; i < 12; i++) {
// show output using zero based array
System.out.println(simulateTabs(5) + (i + 1) + simulateTabs(20) + spots[i]);
}
System.out.println();
if (yesEntered(displayTextAndGetInput("TRY AGAIN? "))) {
gameState = GAME_STATE.START_GAME;
} else {
gameState = GAME_STATE.GAME_OVER;
}
break;
}
} while (gameState != GAME_STATE.GAME_OVER);
}
private void intro() {
System.out.println(simulateTabs(34) + "DICE");
System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println("THIS PROGRAM SIMULATES THE ROLLING OF A");
System.out.println("PAIR OF DICE.");
System.out.println("YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO");
System.out.println("'ROLL' THE DICE. WATCH OUT, VERY LARGE NUMBERS TAKE");
System.out.println("A LONG TIME. IN PARTICULAR, NUMBERS OVER 5000.");
}
/*
* Print a message on the screen, then accept input from Keyboard.
* Converts input to an Integer
*
* @param text message to be displayed on screen.
* @return what was typed by the player.
*/
private int displayTextAndGetNumber(String text) {
return Integer.parseInt(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();
}
/**
* Checks whether player entered Y or YES to a question.
*
* @param text player string from kb
* @return true of Y or YES was entered, otherwise false
*/
private boolean yesEntered(String text) {
return stringIsAnyValue(text, "Y", "YES");
}
/**
* 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) {
return Arrays.stream(values).anyMatch(str -> str.equalsIgnoreCase(text));
}
/**
* 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);
}
}

View File

@@ -0,0 +1,6 @@
public class DiceGame {
public static void main(String[] args) {
Dice dice = new Dice();
dice.play();
}
}

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>DICE</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="dice.js"></script>
</body>
</html>

View File

@@ -0,0 +1,84 @@
// DICE
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
// Main program
async function main()
{
print(tab(34) + "DICE\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
f = [];
// Danny Freidus
print("THIS PROGRAM SIMULATES THE ROLLING OF A\n");
print("PAIR OF DICE.\n");
print("YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO\n");
print("'ROLL' THE DICE. WATCH OUT, VERY LARGE NUMBERS TAKE\n");
print("A LONG TIME. IN PARTICULAR, NUMBERS OVER 5000.\n");
do {
for (q = 1; q <= 12; q++)
f[q] = 0;
print("\n");
print("HOW MANY ROLLS");
x = parseInt(await input());
for (s = 1; s <= x; s++) {
a = Math.floor(Math.random() * 6 + 1);
b = Math.floor(Math.random() * 6 + 1);
r = a + b;
f[r]++;
}
print("\n");
print("TOTAL SPOTS\tNUMBER OF TIMES\n");
for (v = 2; v <= 12; v++) {
print("\t" + v + "\t" + f[v] + "\n");
}
print("\n");
print("\n");
print("TRY AGAIN");
str = await input();
} while (str.substr(0, 1) == "Y") ;
}
main();

51
33 Dice/ruby/dice.rb Normal file
View File

@@ -0,0 +1,51 @@
def intro
puts " DICE
CREATIVE COMPUTING MORRISTOWN, NEW JERSEY
THIS PROGRAM SIMULATES THE ROLLING OF A
PAIR OF DICE.
YOU ENTER THE NUMBER OF TIMES YOU WANT THE COMPUTER TO
'ROLL' THE DICE. WATCH OUT, VERY LARGE NUMBERS TAKE
A LONG TIME. IN PARTICULAR, NUMBERS OVER 5000.
"
end
def get_rolls
while true
number = gets.chomp
return number.to_i if /^\d+$/.match(number)
puts "!NUMBER EXPECTED - RETRY INPUT LINE"
print "? "
end
end
def dice_roll = rand(6) + 1 # ruby 3, woot!
def print_rolls(rolls)
values = Array.new(11, 0)
(1..rolls).each { values[dice_roll + dice_roll - 2] += 1 }
puts "\nTOTAL SPOTS NUMBER OF TIMES"
(0..10).each { |k| puts " %-2d %-2d" % [k + 2, values[k]] }
end
def main
intro
loop do
print "HOW MANY ROLLS? "
rolls = get_rolls
print_rolls(rolls)
print "\n\nTRY AGAIN? "
option = (gets || '').chomp.upcase
break unless option == 'YES'
puts
end
end
trap "SIGINT" do puts; exit 130 end
main

View File

@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30804.86
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FurTrader", "FurTrader.csproj", "{1FB826B9-8794-4DB7-B676-B51F177B7B87}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1FB826B9-8794-4DB7-B676-B51F177B7B87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1FB826B9-8794-4DB7-B676-B51F177B7B87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FB826B9-8794-4DB7-B676-B51F177B7B87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1FB826B9-8794-4DB7-B676-B51F177B7B87}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DDB24448-50EB-47C6-BDB9-465896A81779}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,506 @@
using System;
namespace FurTrader
{
public class Game
{
/// <summary>
/// random number generator; no seed to be faithful to original implementation
/// </summary>
private Random Rnd { get; } = new Random();
/// <summary>
/// Generate a price for pelts based off a factor and baseline value
/// </summary>
/// <param name="factor">Multiplier for the price</param>
/// <param name="baseline">The baseline price</param>
/// <returns>A randomised price for pelts</returns>
internal double RandomPriceGenerator(double factor, double baseline)
{
var price = (Convert.ToInt32((factor * Rnd.NextDouble() + baseline) * 100d) + 5) / 100d;
return price;
}
/// <summary>
/// Main game loop function. This will play the game endlessly until the player chooses to quit or a GameOver event occurs
/// </summary>
/// <remarks>
/// General structure followed from Adam Dawes (@AdamDawes575) implementation of Acey Ducey.");
/// </remarks>
internal void GameLoop()
{
// display instructions to the player
DisplayIntroText();
var state = new GameState();
// loop for each turn until the player decides not to continue (or has a Game Over event)
while ((!state.GameOver) && ContinueGame())
{
// clear display at start of each turn
Console.Clear();
// play the next turn; pass game state for details and updates from the turn
PlayTurn(state);
}
// end screen; show some statistics to the player
Console.Clear();
Console.WriteLine("Thanks for playing!");
Console.WriteLine("");
Console.WriteLine($"Total Expeditions: {state.ExpeditionCount}");
Console.WriteLine($"Final Amount: {state.Savings.ToString("c")}");
}
/// <summary>
/// Display instructions on how to play the game and wait for the player to press a key.
/// </summary>
private void DisplayIntroText()
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Fur Trader.");
Console.WriteLine("Creating Computing, Morristown, New Jersey.");
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine("Originally published in 1978 in the book 'Basic Computer Games' by David Ahl.");
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("You are the leader of a French fur trading expedition in 1776 leaving the Lake Ontario area to sell furs and get supplies for the next year.");
Console.WriteLine("");
Console.WriteLine("You have a choice of three forts at which you may trade. The cost of supplies and the amount you receive for your furs will depend on the fort that you choose.");
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Press any key start the game.");
Console.ReadKey(true);
}
/// <summary>
/// Prompt the player to try again, and wait for them to press Y or N.
/// </summary>
/// <returns>Returns true if the player wants to try again, false if they have finished playing.</returns>
private bool ContinueGame()
{
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Do you wish to trade furs? ");
Console.Write("Answer (Y)es or (N)o ");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("> ");
char pressedKey;
// Keep looping until we get a recognised input
do
{
// Read a key, don't display it on screen
ConsoleKeyInfo key = Console.ReadKey(true);
// Convert to upper-case so we don't need to care about capitalisation
pressedKey = Char.ToUpper(key.KeyChar);
// Is this a key we recognise? If not, keep looping
} while (pressedKey != 'Y' && pressedKey != 'N');
// Display the result on the screen
Console.WriteLine(pressedKey);
// Return true if the player pressed 'Y', false for anything else.
return (pressedKey == 'Y');
}
/// <summary>
/// Play a turn
/// </summary>
/// <param name="state">The current game state</param>
private void PlayTurn(GameState state)
{
state.UnasignedFurCount = 190; /// start with 190 furs each turn
// provide current status to user
Console.WriteLine(new string('_', 70));
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("");
Console.WriteLine($"You have {state.Savings.ToString("c")} savings and {state.UnasignedFurCount} furs to begin the expedition.");
Console.WriteLine("");
Console.WriteLine($"Your {state.UnasignedFurCount} furs are distributed among the following kinds of pelts: Mink, Beaver, Ermine, and Fox");
Console.WriteLine("");
// get input on number of pelts
Console.ForegroundColor = ConsoleColor.White;
Console.Write("How many Mink pelts do you have? ");
state.MinkPelts = GetPelts(state.UnasignedFurCount);
state.UnasignedFurCount -= state.MinkPelts;
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");
Console.Write("How many Beaver pelts do you have? ");
state.BeaverPelts = GetPelts(state.UnasignedFurCount);
state.UnasignedFurCount -= state.BeaverPelts;
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");
Console.Write("How many Ermine pelts do you have? ");
state.ErminePelts = GetPelts(state.UnasignedFurCount);
state.UnasignedFurCount -= state.ErminePelts;
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine($"You have {state.UnasignedFurCount} furs remaining for distribution");
Console.Write("How many Fox pelts do you have? ");
state.FoxPelts = GetPelts(state.UnasignedFurCount);
state.UnasignedFurCount -= state.FoxPelts;
// get input on which fort to trade with; user gets an opportunity to evaluate and re-select fort after selection until user confirms selection
do
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("");
Console.WriteLine("Do you want to trade your furs at Fort 1, Fort 2, or Fort 3");
Console.WriteLine("Fort 1 is Fort Hochelaga (Montreal) and is under the protection of the French army.");
Console.WriteLine("Fort 2 is Fort Stadacona (Quebec) and is under the protection of the French army. However, you must make a portage and cross the Lachine rapids.");
Console.WriteLine("Fort 3 is Fort New York and is under Dutch control. You must cross through Iroquois land.");
Console.WriteLine("");
state.SelectedFort = GetSelectedFort();
DisplaySelectedFortInformation(state.SelectedFort);
} while (TradeAtAnotherFort());
// process the travel to the fort
ProcessExpeditionOutcome(state);
// display results of expedition (savings change) to the user
Console.ForegroundColor = ConsoleColor.White;
Console.Write("You now have ");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write($"{state.Savings.ToString("c")}");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(" including your previous savings.");
// update the turn count now that another turn has been played
state.ExpeditionCount += 1;
}
/// <summary>
/// Method to show the expedition costs to the player with some standard formatting
/// </summary>
/// <param name="fortname">The name of the fort traded with</param>
/// <param name="supplies">The cost of the supplies at the fort</param>
/// <param name="expenses">The travel expenses for the expedition</param>
internal void DisplayCosts(string fortname, double supplies, double expenses)
{
Console.ForegroundColor = ConsoleColor.White;
Console.Write($"Supplies at {fortname} cost".PadLeft(55));
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{supplies.ToString("c").PadLeft(10)}");
Console.ForegroundColor = ConsoleColor.White;
Console.Write($"Your travel expenses to {fortname} were".PadLeft(55));
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{expenses.ToString("c").PadLeft(10)}");
Console.ForegroundColor = ConsoleColor.White;
}
/// <summary>
/// Process the results of the expedition
/// </summary>
/// <param name="state">the game state</param>
private void ProcessExpeditionOutcome(GameState state)
{
var beaverPrice = RandomPriceGenerator(0.25d, 1.00d);
var foxPrice = RandomPriceGenerator(0.2d , 0.80d);
var erminePrice = RandomPriceGenerator(0.15d, 0.95d);
var minkPrice = RandomPriceGenerator(0.2d , 0.70d);
var fortname = String.Empty;
var suppliesCost = 0.0d;
var travelExpenses = 0.0d;
// create a random value 1 to 10 for the different outcomes at each fort
var p = ((int)(10 * Rnd.NextDouble())) + 1;
Console.WriteLine("");
switch (state.SelectedFort)
{
case 1: // outcome for expedition to Fort Hochelaga
beaverPrice = RandomPriceGenerator(0.2d, 0.75d);
foxPrice = RandomPriceGenerator(0.2d, 0.80d);
erminePrice = RandomPriceGenerator(0.2d, 0.65d);
minkPrice = RandomPriceGenerator(0.2d, 0.70d);
fortname = "Fort Hochelaga";
suppliesCost = 150.0d;
travelExpenses = 10.0d;
break;
case 2: // outcome for expedition to Fort Stadacona
beaverPrice = RandomPriceGenerator(0.2d , 0.90d);
foxPrice = RandomPriceGenerator(0.2d , 0.80d);
erminePrice = RandomPriceGenerator(0.15d, 0.80d);
minkPrice = RandomPriceGenerator(0.3d , 0.85d);
fortname = "Fort Stadacona";
suppliesCost = 125.0d;
travelExpenses = 15.0d;
if (p <= 2)
{
state.BeaverPelts = 0;
Console.WriteLine("Your beaver were to heavy to carry across the portage.");
Console.WriteLine("You had to leave the pelts but found them stolen when you returned");
}
else if (p <= 6)
{
Console.WriteLine("You arrived safely at Fort Stadacona");
}
else if (p <= 8)
{
state.BeaverPelts = 0;
state.FoxPelts = 0;
state.ErminePelts = 0;
state.MinkPelts = 0;
Console.WriteLine("Your canoe upset in the Lachine Rapids.");
Console.WriteLine("Your lost all your furs");
}
else if (p <= 10)
{
state.FoxPelts = 0;
Console.WriteLine("Your fox pelts were not cured properly.");
Console.WriteLine("No one will buy them.");
}
else
{
throw new Exception($"Unexpected Outcome p = {p}");
}
break;
case 3: // outcome for expedition to Fort New York
beaverPrice = RandomPriceGenerator(0.2d , 1.00d);
foxPrice = RandomPriceGenerator(0.25d, 1.10d);
erminePrice = RandomPriceGenerator(0.2d , 0.95d);
minkPrice = RandomPriceGenerator(0.15d, 1.05d);
fortname = "Fort New York";
suppliesCost = 80.0d;
travelExpenses = 25.0d;
if (p <= 2)
{
state.BeaverPelts = 0;
state.FoxPelts = 0;
state.ErminePelts = 0;
state.MinkPelts = 0;
suppliesCost = 0.0d;
travelExpenses = 0.0d;
Console.WriteLine("You were attacked by a party of Iroquois.");
Console.WriteLine("All people in your trading group were killed.");
Console.WriteLine("This ends the game (press any key).");
Console.ReadKey(true);
state.GameOver = true;
}
else if (p <= 6)
{
Console.WriteLine("You were lucky. You arrived safely at Fort New York.");
}
else if (p <= 8)
{
state.BeaverPelts = 0;
state.FoxPelts = 0;
state.ErminePelts = 0;
state.MinkPelts = 0;
Console.WriteLine("You narrowly escaped an Iroquois raiding party.");
Console.WriteLine("However, you had to leave all your furs behind.");
}
else if (p <= 10)
{
beaverPrice = beaverPrice / 2;
minkPrice = minkPrice / 2;
Console.WriteLine("Your mink and beaver were damaged on your trip.");
Console.WriteLine("You receive only half the current price for these furs.");
}
else
{
throw new Exception($"Unexpected Outcome p = {p}");
}
break;
default:
break;
}
var beaverSale = state.BeaverPelts * beaverPrice;
var foxSale = state.FoxPelts * foxPrice;
var ermineSale = state.ErminePelts * erminePrice;
var minkSale = state.MinkPelts * minkPrice;
var profit = beaverSale + foxSale + ermineSale + minkSale - suppliesCost - travelExpenses;
state.Savings += profit;
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.White;
Console.Write($"Your {state.BeaverPelts.ToString().PadLeft(3, ' ')} beaver pelts sold @ {beaverPrice.ToString("c")} per pelt for a total");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"{beaverSale.ToString("c").PadLeft(10)}");
Console.ForegroundColor = ConsoleColor.White;
Console.Write($"Your {state.FoxPelts.ToString().PadLeft(3, ' ')} fox pelts sold @ {foxPrice.ToString("c")} per pelt for a total");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"{foxSale.ToString("c").PadLeft(10)}");
Console.ForegroundColor = ConsoleColor.White;
Console.Write($"Your {state.ErminePelts.ToString().PadLeft(3, ' ')} ermine pelts sold @ {erminePrice.ToString("c")} per pelt for a total");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"{ermineSale.ToString("c").PadLeft(10)}");
Console.ForegroundColor = ConsoleColor.White;
Console.Write($"Your {state.MinkPelts.ToString().PadLeft(3, ' ')} mink pelts sold @ {minkPrice.ToString("c")} per pelt for a total");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"{minkSale.ToString("c").PadLeft(10)}");
Console.WriteLine("");
DisplayCosts(fortname, suppliesCost, travelExpenses);
Console.WriteLine("");
Console.Write($"Profit / Loss".PadLeft(55));
Console.ForegroundColor = profit >= 0.0d ? ConsoleColor.Green : ConsoleColor.Red;
Console.WriteLine($"{profit.ToString("c").PadLeft(10)}");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("");
}
private void DisplaySelectedFortInformation(int selectedFort)
{
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.White;
switch (selectedFort)
{
case 1: // selected fort details for Fort Hochelaga
Console.WriteLine("You have chosen the easiest route.");
Console.WriteLine("However, the fort is far from any seaport.");
Console.WriteLine("The value you receive for your furs will be low.");
Console.WriteLine("The cost of supplies will be higher than at Forts Stadacona or New York");
break;
case 2: // selected fort details for Fort Stadacona
Console.WriteLine("You have chosen a hard route.");
Console.WriteLine("It is, in comparsion, harder than the route to Hochelaga but easier than the route to New York.");
Console.WriteLine("You will receive an average value for your furs.");
Console.WriteLine("The cost of your supplies will be average.");
break;
case 3: // selected fort details for Fort New York
Console.WriteLine("You have chosen the most difficult route.");
Console.WriteLine("At Fort New York you will receive the higest value for your furs.");
Console.WriteLine("The cost of your supplies will be lower than at all the other forts.");
break;
default:
break;
}
}
private bool TradeAtAnotherFort()
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("");
Console.WriteLine("Do you want to trade at another fort?");
Console.Write("Answer (Y)es or (N)o ");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("> ");
char pressedKey;
// Keep looping until we get a recognised input
do
{
// Read a key, don't display it on screen
ConsoleKeyInfo key = Console.ReadKey(true);
// Convert to upper-case so we don't need to care about capitalisation
pressedKey = Char.ToUpper(key.KeyChar);
// Is this a key we recognise? If not, keep looping
} while (pressedKey != 'Y' && pressedKey != 'N');
// Display the result on the screen
Console.WriteLine(pressedKey);
// Return true if the player pressed 'Y', false for anything else.
return (pressedKey == 'Y');
}
/// <summary>
/// Get an amount of pelts from the user
/// </summary>
/// <param name="currentMoney">The total pelts available</param>
/// <returns>Returns the amount the player selects</returns>
private int GetPelts(int furCount)
{
int peltCount;
// loop until the user enters a valid value
do
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("> ");
string input = Console.ReadLine();
// parse user information to check if it is a valid entry
if (!int.TryParse(input, out peltCount))
{
// invalid entry; message back to user
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Sorry, I didn't understand. Please enter the number of pelts.");
// continue looping
continue;
}
// check if plet amount is more than the available pelts
if (peltCount > furCount)
{
// too many pelts selected
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"You may not have that many furs. Do not try to cheat. I can add.");
// continue looping
continue;
}
// valid pelt amount entered
break;
} while (true);
// return pelt count to the user
return peltCount;
}
/// <summary>
/// Prompt the user for their selected fort
/// </summary>
/// <returns>returns the fort the user has selected</returns>
private int GetSelectedFort()
{
int selectedFort;
// loop until the user enters a valid value
do
{
Console.ForegroundColor = ConsoleColor.White;
Console.Write("Answer 1, 2, or 3 ");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("> ");
string input = Console.ReadLine();
// is the user entry valid
if (!int.TryParse(input, out selectedFort))
{
// no, invalid data
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Sorry, I didn't understand. Please answer 1, 2, or 3.");
// continue looping
continue;
}
// is the selected fort an option (one, two or three only)
if (selectedFort != 1 && selectedFort != 2 && selectedFort != 3)
{
// no, invalid for selected
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Please answer 1, 2, or 3.");
// continue looping
continue;
}
// valid fort selected, stop looping
break;
} while (true);
// return the players selected fort
return selectedFort;
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace FurTrader
{
internal class GameState
{
internal bool GameOver { get; set; }
internal double Savings { get; set; }
internal int ExpeditionCount { get; set; }
internal int UnasignedFurCount { get; set; }
internal int[] Pelts { get; private set; }
internal int MinkPelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
internal int BeaverPelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
internal int ErminePelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
internal int FoxPelts { get { return this.Pelts[0]; } set { this.Pelts[0] = value; } }
internal int SelectedFort { get; set; }
internal GameState()
{
this.Savings = 600;
this.ExpeditionCount = 0;
this.UnasignedFurCount = 190;
this.Pelts = new int[4];
this.SelectedFort = 0;
}
internal void StartTurn()
{
this.SelectedFort = 0; // reset to a default value
this.UnasignedFurCount = 190; // each turn starts with 190 furs
this.Pelts = new int[4]; // reset pelts on each turn
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
namespace FurTrader
{
public class Program
{
/// <summary>
/// This function will be called automatically when the application begins
/// </summary>
/// <param name="args"></param>
public static void Main(string[] args)
{
// Create an instance of our main Game class
var game = new Game();
// Call its GameLoop function. This will play the game endlessly in a loop until the player chooses to quit.
game.GameLoop();
}
}
}

View File

@@ -0,0 +1,161 @@
import java.util.Arrays;
import java.util.Scanner;
/**
* Game of Guess
* <p>
* Based on the Basic game of Guess here
* https://github.com/coding-horror/basic-computer-games/blob/main/41%20Guess/guess.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 Guess {
// Used for keyboard input
private final Scanner kbScanner;
private enum GAME_STATE {
STARTUP,
INPUT_RANGE,
DEFINE_COMPUTERS_NUMBER,
GUESS,
GAME_OVER
}
// Current game state
private GAME_STATE gameState;
// User supplied maximum number to guess
private int limit;
// Computers calculated number for the player to guess
private int computersNumber;
// Number of turns the player has had guessing
private int tries;
// Optimal number of turns it should take to guess
private int calculatedTurns;
public Guess() {
kbScanner = new Scanner(System.in);
gameState = GAME_STATE.STARTUP;
}
/**
* Main game loop
*/
public void play() {
do {
switch (gameState) {
case STARTUP:
intro();
gameState = GAME_STATE.INPUT_RANGE;
break;
case INPUT_RANGE:
limit = displayTextAndGetNumber("WHAT LIMIT DO YOU WANT? ");
calculatedTurns = (int) (Math.log(limit) / Math.log(2)) + 1;
gameState = GAME_STATE.DEFINE_COMPUTERS_NUMBER;
break;
case DEFINE_COMPUTERS_NUMBER:
tries = 1;
System.out.println("I'M THINKING OF A NUMBER BETWEEN 1 AND " + limit);
computersNumber = (int) (Math.random() * limit + 1);
gameState = GAME_STATE.GUESS;
break;
case GUESS:
int playersGuess = displayTextAndGetNumber("NOW YOU TRY TO GUESS WHAT IT IS ");
// Allow player to restart game with entry of 0
if (playersGuess == 0) {
linePadding();
gameState = GAME_STATE.STARTUP;
break;
}
if (playersGuess == computersNumber) {
System.out.println("THAT'S IT! YOU GOT IT IN " + tries + " TRIES.");
if (tries < calculatedTurns) {
System.out.println("VERY ");
}
System.out.println("GOOD.");
System.out.println("YOU SHOULD HAVE BEEN ABLE TO GET IT IN ONLY " + calculatedTurns);
linePadding();
gameState = GAME_STATE.DEFINE_COMPUTERS_NUMBER;
break;
} else if (playersGuess < computersNumber) {
System.out.println("TOO LOW. TRY A BIGGER ANSWER.");
} else {
System.out.println("TOO HIGH. TRY A SMALLER ANSWER.");
}
tries++;
break;
}
} while (gameState != GAME_STATE.GAME_OVER);
}
private void intro() {
System.out.println(simulateTabs(33) + "GUESS");
System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println("THIS IS A NUMBER GUESSING GAME. I'LL THINK");
System.out.println("OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT.");
System.out.println("THEN YOU HAVE TO GUESS WHAT IT IS.");
}
/**
* Print a predefined number of blank lines
*
*/
private void linePadding() {
for (int i = 1; i <= 5; i++) {
System.out.println();
}
}
/*
* Print a message on the screen, then accept input from Keyboard.
* Converts input to an Integer
*
* @param text message to be displayed on screen.
* @return what was typed by the player.
*/
private int displayTextAndGetNumber(String text) {
return Integer.parseInt(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);
}
}

View File

@@ -0,0 +1,6 @@
public class GuessGame {
public static void main(String[] args) {
Guess guess = new Guess();
guess.play();
}
}

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>GUESS</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="guess.js"></script>
</body>
</html>

View File

@@ -0,0 +1,104 @@
// GUESS
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
function make_space()
{
for (h = 1; h <= 5; h++)
print("\n");
}
// Main control section
async function main()
{
while (1) {
print(tab(33) + "GUESS\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
print("THIS IS A NUMBER GUESSING GAME. I'LL THINK\n");
print("OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT.\n");
print("THEN YOU HAVE TO GUESS WHAT IT IS.\n");
print("\n");
print("WHAT LIMIT DO YOU WANT");
l = parseInt(await input());
print("\n");
l1 = Math.floor(Math.log(l) / Math.log(2)) + 1;
while (1) {
print("I'M THINKING OF A NUMBER BETWEEN 1 AND " + l + "\n");
g = 1;
print("NOW YOU TRY TO GUESS WHAT IT IS.\n");
m = Math.floor(l * Math.random() + 1);
while (1) {
n = parseInt(await input());
if (n <= 0) {
make_space();
break;
}
if (n == m) {
print("THAT'S IT! YOU GOT IT IN " + g + " TRIES.\n");
if (g == l1) {
print("GOOD.\n");
} else if (g < l1) {
print("VERY GOOD.\n");
} else {
print("YOU SHOULD HAVE BEEN TO GET IT IN ONLY " + l1 + "\n");
}
make_space();
break;
}
g++;
if (n > m)
print("TOO HIGH. TRY A SMALLER ANSWER.\n");
else
print("TOO LOW. TRY A BIGGER ANSWER.\n");
}
if (n <= 0)
break;
}
}
}
main();

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>GUNNER</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="gunner.js"></script>
</body>
</html>

View File

@@ -0,0 +1,139 @@
// GUNNER
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
print(tab(30) + "GUNNER\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
print("YOU ARE THE OFFICER-IN-CHARGE, GIVING ORDERS TO A GUN\n");
print("CREW, TELLING THEM THE DEGREES OF ELEVATION YOU ESTIMATE\n");
print("WILL PLACE A PROJECTILE ON TARGET. A HIT WITHIN 100 YARDS\n");
print("OF THE TARGET WILL DESTROY IT.\n");
print("\n");
// Main control section
async function main()
{
while (1) {
r = Math.floor(40000 * Math.random() + 20000);
print("MAXIMUM RANGE OF YOUR GUN IS " + r + " YARDS.\n");
z = 0;
print("\n");
s1 = 0;
while (1) {
t = Math.floor(r * (0.1 + 0.8 * Math.random()));
s = 0;
print("DISTANCE TO THE TARGET IS " + t + " YARDS.\n");
print("\n");
while (1) {
print("\n");
print("ELEVATION");
b = parseFloat(await input());
if (b > 89) {
print("MAXIMUM ELEVATION IS 89 DEGREES.\n");
continue;
}
if (b < 1) {
print("MINIMUM ELEVATION IS ONE DEGREE.\n");
continue;
}
if (++s >= 6) {
print("\n");
print("BOOM !!!! YOU HAVE JUST BEEN DESTROYED BY THE ENEMY.\n");
print("\n");
print("\n");
print("\n");
e = 0;
break;
}
b2 = 2 * b / 57.3;
i = r * Math.sin(b2);
x = t - i;
e = Math.floor(x);
if (true) { //Math.abs(e) < 100) {
e = 1;
break;
}
if (e > 100) {
print("SHORT OF TARGET BY " + Math.abs(e) + " YARDS.\n");
} else {
print("OVER TARGET BY " + Math.abs(e) + " YARDS.\n");
}
}
if (e == 1) {
print("*** TARGET DESTROYED *** " + s + " ROUNDS OF AMMUNITION EXPENDED.\n");
s1 += s;
if (z == 4) {
print("\n");
print("\n");
print("TOTAL ROUND EXPENDED WERE: " + s1 + "\n");
break;
} else {
z++;
print("\n");
print("THE FORWARD OBSERVER HAS SIGHTED MORE ENEMY ACTIVITY...\n");
}
} else {
s1 = 19;
break;
}
}
if (s1 > 18) {
print("BETTER GO BACK TO FORT SILL FOR REFRESHER TRAINING!\n");
} else {
print("NICE SHOOTING !!");
}
print("\n");
print("TRY AGAIN (Y OR N)");
str = await input();
if (str.substr(0, 1) != "Y")
break;
}
print("\n");
print("OK. RETURN TO BASE CAMP.\n");
}
main();

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>HAMMURABI</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="hammurabi.js"></script>
</body>
</html>

View File

@@ -0,0 +1,253 @@
// HAMMURABI
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
var a;
var s;
function exceeded_grain()
{
print("HAMURABI: THINK AGAIN. YOU HAVE ONLY\n");
print(s + " BUSHELS OF GRAIN. NOW THEN,\n");
}
function exceeded_acres()
{
print("HAMURABI: THINK AGAIN. YOU OWN ONLY " + a + " ACRES. NOW THEN,\n");
}
// Main control section
async function main()
{
print(tab(32) + "HAMURABI\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
print("\n");
print("\n");
print("\n");
print("TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA\n");
print("FOR A TEN-YEAR TERM OF OFFICE.\n");
print("\n");
d1 = 0;
p1 = 0;
z = 0;
p = 95;
s = 2800;
h = 3000;
e = h - s;
y = 3;
a = h / y;
i = 5;
q = 1;
d = 0;
while (1) {
print("\n");
print("\n");
print("\n");
print("HAMURABI: I BEG TO REPORT TO YOU,\n");
z++;
print("IN YEAR " + z + ", " + d + " PEOPLE STARVED, " + i + " CAME TO THE CITY,\n");
p += i;
if (q <= 0) {
p = Math.floor(p / 2);
print("A HORRIBLE PLAGUE STRUCK! HALF THE PEOPLE DIED.\n");
}
print("POPULATION IS NOW " + p + "\n");
print("THE CITY NOW OWNS " + a + " ACRES.\n");
print("YOU HARVESTED " + y + " BUSHELS PER ACRE.\n");
print("THE RATS ATE " + e + " BUSHELS.\n");
print("YOU NOW HAVE " + s + " BUSHELS IN STORE.\n");
print("\n");
if (z == 11) {
q = 0;
break;
}
c = Math.floor(10 * Math.random());
y = c + 17;
print("LAND IS TRADING AT " + y + " BUSHELS PER ACRE.\n");
while (1) {
print("HOW MANY ACRES DO YOU WISH TO BUY");
q = parseInt(await input());
if (q < 0)
break;
if (y * q > s) {
exceeded_grain();
} else
break;
}
if (q < 0)
break;
if (q != 0) {
a += q;
s -= y * q;
c = 0;
} else {
while (1) {
print("HOW MANY ACRES DO YOU WISH TO SELL");
q = parseInt(await input());
if (q < 0)
break;
if (q >= a) {
exceeded_acres();
} else {
break;
}
}
if (q < 0)
break;
a -= q;
s += y * q;
c = 0;
}
print("\n");
while (1) {
print("HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE");
q = parseInt(await input());
if (q < 0)
break;
if (q > s) // Trying to use more grain than is in silos?
exceeded_grain();
else
break;
}
if (q < 0)
break;
s -= q;
c = 1;
print("\n");
while (1) {
print("HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED");
d = parseInt(await input());
if (d != 0) {
if (d < 0)
break;
if (d > a) { // Trying to plant more acres than you own?
exceeded_acres();
} else {
if (Math.floor(d / 2) > s) // Enough grain for seed?
exceeded_grain();
else {
if (d >= 10 * p) {
print("BUT YOU HAVE ONLY " + p + " PEOPLE TO TEND THE FIELDS! NOW THEN,\n");
} else {
break;
}
}
}
}
}
if (d < 0) {
q = -1;
break;
}
s -= Math.floor(d / 2);
c = Math.floor(Math.random() * 5) + 1;
// A bountiful harvest!
if (c % 2 == 0) {
// Rats are running wild!!
e = Math.floor(s / c);
}
s = s - e + h;
c = Math.floor(Math.random() * 5) + 1;
// Let's have some babies
i = Math.floor(c * (20 * a + s) / p / 100 + 1);
// How many people had full tummies?
c = Math.floor(q / 20);
// Horros, a 15% chance of plague
q = Math.floor(10 * (2 * Math.random() - 0.3));
if (p < c) {
d = 0;
continue;
}
// Starve enough for impeachment?
d = p - c;
if (d <= 0.45 * p) {
p1 = ((z - 1) * p1 + d * 100 / p) / z;
p = c;
d1 += d;
continue;
}
print("\n");
print("YOU STARVED " + d + " PEOPLE IN ONE YEAR!!!\n");
q = 0;
p1 = 34;
p = 1;
break;
}
if (q < 0) {
print("\n");
print("HAMURABI: I CANNOT DO WHAT YOU WISH.\n");
print("GET YOURSELF ANOTHER STEWARD!!!!!\n");
} else {
print("IN YOUR 10-YEAR TERM OF OFFICE, " + p1 + " PERCENT OF THE\n");
print("POPULATION STARVED PER YEAR ON THE AVERAGE, I.E. A TOTAL OF\n");
print(d1 + " PEOPLE DIED!!\n");
l = a / p;
print("YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH\n");
print(l + " ACRES PER PERSON.\n");
print("\n");
if (p1 > 33 || l < 7) {
print("DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY\n");
print("BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE\n");
print("ALSO BEEN DECLARED NATIONAL FINK!!!!\n");
} else if (p1 > 10 || l < 9) {
print("YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.\n");
print("THE PEOPLE (REMIANING) FIND YOU AN UNPLEASANT RULER, AND,\n");
print("FRANKLY, HATE YOUR GUTS!!\n");
} else if (p1 > 3 || l < 10) {
print("YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT\n");
print("REALLY WASN'T TOO BAD AT ALL. " + Math.floor(p * 0.8 * Math.random()) + " PEOPLE\n");
print("WOULD DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR\n");
print("TRIVIAL PROBLEMS.\n");
} else {
print("A FANTASTIC PERFORMANCE!!! CHARLEMANGE, DISRAELI, AND\n");
print("JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!\n");
}
}
print("\n");
print("SO LONG FOR NOW.\n");
print("\n");
}
main();

View File

@@ -0,0 +1,129 @@
using System;
namespace Hangman
{
/// <summary>
/// Represents the main "Hangman" graphic.
/// </summary>
public class Graphic
{
private readonly char[,] _graphic;
private const int Width = 12;
private const int Height = 12;
public Graphic()
{
// 12 x 12 array to represent the graphics.
_graphic = new char[Height, Width];
// Fill it with empty spaces.
for (var i = 0; i < Height; i++)
{
for (var j = 0; j < Width; j++)
{
_graphic[i, j] = ' ';
}
}
// Draw the vertical line.
for (var i = 0; i < Height; i++)
{
_graphic[i, 0] = 'X';
}
// Draw the horizontal line.
for (var i = 0; i < 7; i++)
{
_graphic[0, i] = 'X';
}
// Draw the rope.
_graphic[1, 6] = 'X';
}
public void Print()
{
for (var i = 0; i < Height; i++)
{
for (var j = 0; j < Width; j++)
{
Console.Write(_graphic[i, j]);
}
Console.Write("\n"); // New line.
}
}
public void AddHead()
{
_graphic[2, 5] = '-';
_graphic[2, 6] = '-';
_graphic[2, 7] = '-';
_graphic[3, 4] = '(';
_graphic[3, 5] = '.';
_graphic[3, 7] = '.';
_graphic[3, 8] = ')';
_graphic[4, 5] = '-';
_graphic[4, 6] = '-';
_graphic[4, 7] = '-';
}
public void AddBody()
{
for (var i = 5; i < 9; i++)
{
_graphic[i, 6] = 'X';
}
}
public void AddRightArm()
{
for (var i = 3; i < 7; i++)
{
_graphic[i, i - 1] = '\\'; // This is the escape character for the back slash.
}
}
public void AddLeftArm()
{
_graphic[3, 10] = '/';
_graphic[4, 9] = '/';
_graphic[5, 8] = '/';
_graphic[6, 7] = '/';
}
public void AddRightLeg()
{
_graphic[9, 5] = '/';
_graphic[10, 4] = '/';
}
public void AddLeftLeg()
{
_graphic[9, 7] = '\\';
_graphic[10, 8] = '\\';
}
public void AddRightHand()
{
_graphic[2, 2] = '/';
}
public void AddLeftHand()
{
_graphic[2, 10] = '\\';
}
public void AddRightFoot()
{
_graphic[11, 9] = '\\';
_graphic[11, 10] = '-';
}
public void AddLeftFoot()
{
_graphic[11, 3] = '/';
_graphic[11, 2] = '-';
}
}
}

View File

@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,16 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hangman", "Hangman.csproj", "{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C516A9E-F4F2-4C79-8C37-0162C403B1F7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,313 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
namespace Hangman
{
/// <summary>
/// C# version of the game "Hangman" from the book BASIC Computer Games.
/// </summary>
static class Program
{
static void Main()
{
Console.WriteLine(Tab(32) + "HANGMAN");
Console.WriteLine(Tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
Console.WriteLine();
Console.WriteLine();
Console.WriteLine();
MainLoop();
Console.WriteLine();
Console.WriteLine("IT'S BEEN FUN! BYE FOR NOW.");
}
static void MainLoop()
{
var words = GetWords();
var stillPlaying = true;
while (stillPlaying)
{
if (words.Count == 0)
{
Console.WriteLine("YOU DID ALL THE WORDS!!");
break;
}
// Get a random number from 0 to the number of words we have minus one (C# arrays are zero-based).
var rnd = new Random();
var randomNumber = rnd.Next(words.Count - 1);
// Pick a random word and remove it from the list.
var word = words[randomNumber];
words.Remove(word);
GameLoop(word);
// Game finished. Ask if player wants another one.
Console.WriteLine("WANT ANOTHER WORD? ");
var response = Console.ReadLine();
if (response == null || response.ToUpper() != "YES")
{
stillPlaying = false; // Exit the loop if the player didn't answer "yes".
}
}
}
static void GameLoop(string word)
{
var graphic = new Graphic();
var wrongGuesses = 0;
var numberOfGuesses = 0;
var usedLetters = new List<char>();
// The word that the user sees. Since we just started, it's just dashes.
var displayedWord = new char[word.Length];
for (var i = 0; i < word.Length; i++)
{
displayedWord[i] = '-';
}
var stillPlaying = true;
while (stillPlaying)
{
var guess = GetLetterFromPlayer(displayedWord, usedLetters);
usedLetters.Add(guess);
numberOfGuesses++;
var correctLetterCount = 0;
// Now we check every letter in the word to see if the player guessed any of them correctly.
for(var i = 0; i < word.Length; i++)
{
if (word[i] == guess)
{
correctLetterCount++;
displayedWord[i] = guess;
}
}
if (correctLetterCount == 0)
{
// Wrong guess.
Console.WriteLine("SORRY, THAT LETTER ISN'T IN THE WORD.");
wrongGuesses++;
DrawBody(graphic, wrongGuesses);
if (wrongGuesses == 10)
{
// Player exhausted all their guesses. Finish the game loop.
Console.WriteLine($"SORRY, YOU LOSE. THE WORD WAS {word}");
Console.Write("YOU MISSED THAT ONE. DO YOU ");
stillPlaying = false;
}
}
else
{
// Player guessed a correct letter. Let's see if there are any unguessed letters left in the word.
if (displayedWord.Contains('-'))
{
Console.WriteLine(displayedWord);
// Give the player a chance to guess the whole word.
var wordGuess = GetWordFromPlayer();
if (word == wordGuess)
{
// Player found the word. Mark it found.
Console.WriteLine("YOU FOUND THE WORD!");
stillPlaying = false; // Exit game loop.
}
else
{
// Player didn't guess the word. Continue the game loop.
Console.WriteLine("WRONG. TRY ANOTHER LETTER.");
}
}
else
{
// Player guessed all the letters.
Console.WriteLine("YOU FOUND THE WORD!");
stillPlaying = false; // Exit game loop.
}
}
} // End of game loop.
}
/// <summary>
/// Display the current state of the word and all the already guessed letters, and get a new guess from the player
/// </summary>
/// <param name="displayedWord">A char array that represents the current state of the guessed word</param>
/// <param name="usedLetters">A list of chars that represents all the letters guessed so far</param>
/// <returns>The letter that the player has just entered as a guess</returns>
private static char GetLetterFromPlayer(char[] displayedWord, List<char> usedLetters)
{
while (true) // Infinite loop, unless the player enters an unused letter.
{
Console.WriteLine();
Console.WriteLine(displayedWord);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("HERE ARE THE LETTERS YOU USED:");
for (var i = 0; i < usedLetters.Count; i++)
{
Console.Write(usedLetters[i]);
// If it's not the last letter, print a comma.
if (i != usedLetters.Count - 1)
{
Console.Write(",");
}
}
Console.WriteLine();
Console.WriteLine("WHAT IS YOUR GUESS?");
var guess = char.ToUpper(Console.ReadKey().KeyChar);
Console.WriteLine();
if (usedLetters.Contains(guess))
{
// After this the loop will continue.
Console.WriteLine("YOU GUESSED THAT LETTER BEFORE!");
}
else
{
// Break out of the loop by returning guessed letter.
return guess;
}
}
}
/// <summary>
/// Gets a word guess from the player.
/// </summary>
/// <returns>The guessed word.</returns>
private static string GetWordFromPlayer()
{
while (true) // Infinite loop, unless the player enters something.
{
Console.WriteLine("WHAT IS YOUR GUESS FOR THE WORD? ");
var guess = Console.ReadLine();
if (guess != null)
{
return guess.ToUpper();
}
}
}
/// <summary>
/// Draw body after wrong guess.
/// </summary>
/// <param name="graphic">The instance of the Graphic class being used.</param>
/// <param name="wrongGuesses">Number of wrong guesses.</param>
private static void DrawBody(Graphic graphic, int wrongGuesses)
{
switch (wrongGuesses)
{
case 1:
Console.WriteLine("FIRST, WE DRAW A HEAD.");
graphic.AddHead();
break;
case 2:
Console.WriteLine("NOW WE DRAW A BODY.");
graphic.AddBody();
break;
case 3:
Console.WriteLine("NEXT WE DRAW AN ARM.");
graphic.AddRightArm();
break;
case 4:
Console.WriteLine("THIS TIME IT'S THE OTHER ARM.");
graphic.AddLeftArm();
break;
case 5:
Console.WriteLine("NOW, LET'S DRAW THE RIGHT LEG.");
graphic.AddRightLeg();
break;
case 6:
Console.WriteLine("THIS TIME WE DRAW THE LEFT LEG.");
graphic.AddLeftLeg();
break;
case 7:
Console.WriteLine("NOW WE PUT UP A HAND.");
graphic.AddRightHand();
break;
case 8:
Console.WriteLine("NEXT THE OTHER HAND.");
graphic.AddLeftHand();
break;
case 9:
Console.WriteLine("NOW WE DRAW ONE FOOT.");
graphic.AddRightFoot();
break;
case 10:
Console.WriteLine("HERE'S THE OTHER FOOT -- YOU'RE HUNG!!");
graphic.AddLeftFoot();
break;
}
graphic.Print();
}
/// <summary>
/// Get a list of words to use in the game.
/// </summary>
/// <returns>List of strings.</returns>
private static List<string> GetWords() => new()
{
"GUM",
"SIN",
"FOR",
"CRY",
"LUG",
"BYE",
"FLY",
"UGLY",
"EACH",
"FROM",
"WORK",
"TALK",
"WITH",
"SELF",
"PIZZA",
"THING",
"FEIGN",
"FIEND",
"ELBOW",
"FAULT",
"DIRTY",
"BUDGET",
"SPIRIT",
"QUAINT",
"MAIDEN",
"ESCORT",
"PICKAX",
"EXAMPLE",
"TENSION",
"QUININE",
"KIDNEY",
"REPLICA",
"SLEEPER",
"TRIANGLE",
"KANGAROO",
"MAHOGANY",
"SERGEANT",
"SEQUENCE",
"MOUSTACHE",
"DANGEROUS",
"SCIENTIST",
"DIFFERENT",
"QUIESCENT",
"MAGISTRATE",
"ERRONEOUSLY",
"LOUDSPEAKER",
"PHYTOTOXIC",
"MATRIMONIAL",
"PARASYMPATHOMIMETIC",
"THIGMOTROPISM"
};
/// <summary>
/// Leave a number of spaces empty.
/// </summary>
/// <param name="length">Number of spaces.</param>
/// <returns>The result string.</returns>
private static string Tab(int length) => new string(' ', length);
}
}

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -6,7 +6,7 @@ import java.util.Scanner;
* Based on the Basic game of Hi-Lo here
* https://github.com/coding-horror/basic-computer-games/blob/main/47%20Hi-Lo/hi-lo.bas
*
* Note: The idea was to create a version of this 1970's Basic game in Java, without introducing
* 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 HiLo {
@@ -24,7 +24,7 @@ public class HiLo {
}
// Used for keyboard input
private Scanner kbScanner;
private final Scanner kbScanner;
// Current game state
private GAME_STATE gameState;
@@ -40,8 +40,8 @@ public class HiLo {
public HiLo() {
this.gameState = GAME_STATE.STARTING;
this.playerAmountWon = 0;
gameState = GAME_STATE.STARTING;
playerAmountWon = 0;
// Initialise kb scanner
kbScanner = new Scanner(System.in);
@@ -66,7 +66,7 @@ public class HiLo {
case START_GAME:
init();
System.out.println("O.K. I HAVE A NUMBER IN MIND.");
this.gameState = GAME_STATE.GUESSING;
gameState = GAME_STATE.GUESSING;
break;
// Player guesses the number until they get it or run out of guesses
@@ -75,21 +75,21 @@ public class HiLo {
// Check if the player guessed the number
if(validateGuess(guess)) {
System.out.println("GOT IT!!!!!!!!!! YOU WIN " + this.computersNumber
System.out.println("GOT IT!!!!!!!!!! YOU WIN " + computersNumber
+ " DOLLARS.");
this.playerAmountWon += this.computersNumber;
playerAmountWon += computersNumber;
System.out.println("YOUR TOTAL WINNINGS ARE NOW "
+ this.playerAmountWon + " DOLLARS.");
this.gameState = GAME_STATE.PLAY_AGAIN;
+ playerAmountWon + " DOLLARS.");
gameState = GAME_STATE.PLAY_AGAIN;
} else {
// incorrect guess
this.playersGuesses++;
playersGuesses++;
// Ran out of guesses?
if (this.playersGuesses == MAX_GUESSES) {
if (playersGuesses == MAX_GUESSES) {
System.out.println("YOU BLEW IT...TOO BAD...THE NUMBER WAS "
+ this.computersNumber);
this.playerAmountWon = 0;
this.gameState = GAME_STATE.PLAY_AGAIN;
+ computersNumber);
playerAmountWon = 0;
gameState = GAME_STATE.PLAY_AGAIN;
}
}
break;
@@ -98,11 +98,11 @@ public class HiLo {
case PLAY_AGAIN:
System.out.println();
if(yesEntered(displayTextAndGetInput("PLAY AGAIN (YES OR NO) "))) {
this.gameState = GAME_STATE.START_GAME;
gameState = GAME_STATE.START_GAME;
} else {
// Chose not to play again
System.out.println("SO LONG. HOPE YOU ENJOYED YOURSELF!!!");
this.gameState = GAME_STATE.GAME_OVER;
gameState = GAME_STATE.GAME_OVER;
}
}
} while (gameState != GAME_STATE.GAME_OVER);
@@ -111,17 +111,17 @@ public class HiLo {
/**
* Checks the players guess against the computers randomly generated number
*
* @param theGuess
* @param theGuess the players guess
* @return true if the player guessed correctly, false otherwise
*/
private boolean validateGuess(int theGuess) {
// Correct guess?
if(theGuess == this.computersNumber) {
if(theGuess == computersNumber) {
return true;
}
if(theGuess > this.computersNumber) {
if(theGuess > computersNumber) {
System.out.println("YOUR GUESS IS TOO HIGH.");
} else {
System.out.println("YOUR GUESS IS TOO LOW.");
@@ -131,8 +131,8 @@ public class HiLo {
}
private void init() {
this.playersGuesses = 0;
this.computersNumber = randomNumber();
playersGuesses = 0;
computersNumber = randomNumber();
}
public void intro() {
@@ -140,7 +140,7 @@ public class HiLo {
System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println();
System.out.println("THIS IS THE GAME OF HI LO.");
System.out.println("IS THE GAME OF HI LO.");
System.out.println();
System.out.println("YOU WILL HAVE 6 TRIES TO GUESS THE AMOUNT OF MONEY IN THE");
System.out.println("HI LO JACKPOT, WHICH IS BETWEEN 1 AND 100 DOLLARS. IF YOU");
@@ -155,7 +155,7 @@ public class HiLo {
* @return players guess as an int
*/
private int playerGuess() {
return Integer.valueOf((displayTextAndGetInput("YOUR GUESS? ")));
return Integer.parseInt((displayTextAndGetInput("YOUR GUESS? ")));
}
/**
@@ -165,7 +165,7 @@ public class HiLo {
* @return true of Y or YES was entered, otherwise false
*/
private boolean yesEntered(String text) {
return stringIsAnyValue(text, new String[] {"Y", "YES"});
return stringIsAnyValue(text, "Y", "YES");
}
/**

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -1,6 +1,14 @@
import java.util.ArrayList;
import java.util.Scanner;
/**
* Game of Hurkle
* <p>
* Based on the Basic game of Hurkle here
* https://github.com/coding-horror/basic-computer-games/blob/main/51%20Hurkle/hurkle.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 Hurkle {
public static final int GRID_SIZE = 10;
@@ -17,7 +25,7 @@ public class Hurkle {
private GAME_STATE gameState;
// Used for keyboard input
private Scanner kbScanner;
private final Scanner kbScanner;
private int guesses;
@@ -54,32 +62,31 @@ public class Hurkle {
// 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);
hurkleXPos = randomNumber();
hurkleYPos = randomNumber();
this.guesses = 1;
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);
String guess = displayTextAndGetInput("GUESS #" + guesses + "? ");
playerGuessXPos = getDelimitedValue(guess, 0);
playerGuessYPos = getDelimitedValue(guess, 1);
if (foundHurkle()) {
this.gameState = GAME_STATE.PLAY_AGAIN;
gameState = GAME_STATE.PLAY_AGAIN;
} else {
showDirectionOfHurkle();
this.guesses++;
if(this.guesses > MAX_GUESSES) {
guesses++;
if (guesses > MAX_GUESSES) {
System.out.println("SORRY, THAT'S "
+ MAX_GUESSES + " GUESSES.");
System.out.println("THE HURKLE IS AT "
+ this.hurkleXPos + "," + this.hurkleYPos);
+ hurkleXPos + "," + hurkleYPos);
System.out.println();
this.gameState = GAME_STATE.PLAY_AGAIN;
gameState = GAME_STATE.PLAY_AGAIN;
}
}
@@ -88,7 +95,7 @@ public class Hurkle {
case PLAY_AGAIN:
System.out.println("LET'S PLAY AGAIN, HURKLE IS HIDING.");
System.out.println();
this.gameState = GAME_STATE.START_GAME;
gameState = GAME_STATE.START_GAME;
break;
}
// Effectively an endless loop because the game never quits as per
@@ -98,31 +105,30 @@ public class Hurkle {
private void showDirectionOfHurkle() {
System.out.print("GO ");
if(this.playerGuessYPos == this.hurkleYPos) {
if (playerGuessYPos == 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) {
} else if (playerGuessYPos < hurkleYPos) {
System.out.print("NORTH");
} else if(this.playerGuessYPos > this.hurkleYPos) {
} else if (playerGuessYPos > hurkleYPos) {
System.out.print("SOUTH");
}
if(this.playerGuessXPos == this.hurkleXPos) {
if (playerGuessXPos == 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) {
} else if (playerGuessXPos < hurkleXPos) {
System.out.print("EAST");
} else if(this.playerGuessXPos > this.hurkleXPos) {
} else if (playerGuessXPos > 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.");
if ((playerGuessXPos - hurkleXPos)
- (playerGuessYPos - hurkleYPos) == 0) {
System.out.println("YOU FOUND HIM IN " + guesses + " GUESSES.");
return true;
}

View File

@@ -1,7 +1,7 @@
public class HurkleGame {
public static void main(String[] args) {
Hurkle hurkle = new Hurkle();
hurkle.play();
Hurkle hurkle = new Hurkle();
hurkle.play();
}
}

View 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);
}
}

View File

@@ -0,0 +1,7 @@
public class KinemaGame {
public static void main(String[] args) {
Kinema kinema = new Kinema();
kinema.play();
}
}

View File

@@ -0,0 +1,142 @@
import java.awt.*;
import java.util.Arrays;
import java.util.Scanner;
/**
* Game of Letter
* <p>
* Based on the Basic game of Letter here
* https://github.com/coding-horror/basic-computer-games/blob/main/54%20Letter/letter.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 Letter {
public static final int OPTIMAL_GUESSES = 5;
public static final int ASCII_A = 65;
public static final int ALL_LETTERS = 26;
private enum GAME_STATE {
STARTUP,
INIT,
GUESSING,
RESULTS,
GAME_OVER
}
// Used for keyboard input
private final Scanner kbScanner;
// Current game state
private GAME_STATE gameState;
// Players guess count;
private int playerGuesses;
// Computers ascii code for a random letter between A..Z
private int computersLetter;
public Letter() {
gameState = GAME_STATE.STARTUP;
// 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 STARTUP:
intro();
gameState = GAME_STATE.INIT;
break;
case INIT:
playerGuesses = 0;
computersLetter = ASCII_A + (int) (Math.random() * ALL_LETTERS);
System.out.println("O.K., I HAVE A LETTER. START GUESSING.");
gameState = GAME_STATE.GUESSING;
break;
// Player guesses the number until they get it or run out of guesses
case GUESSING:
String playerGuess = displayTextAndGetInput("WHAT IS YOUR GUESS? ").toUpperCase();
// Convert first character of input string to ascii
int toAscii = playerGuess.charAt(0);
playerGuesses++;
if (toAscii == computersLetter) {
gameState = GAME_STATE.RESULTS;
break;
}
if (toAscii > computersLetter) {
System.out.println("TOO HIGH. TRY A LOWER LETTER.");
} else {
System.out.println("TOO LOW. TRY A HIGHER LETTER.");
}
break;
// Play again, or exit game?
case RESULTS:
System.out.println();
System.out.println("YOU GOT IT IN " + playerGuesses + " GUESSES!!");
if (playerGuesses <= OPTIMAL_GUESSES) {
System.out.println("GOOD JOB !!!!!");
// Original game beeped 15 tims if you guessed in the optimal guesses or less
// Changed this to do a single beep only
Toolkit.getDefaultToolkit().beep();
} else {
// Took more than optimal number of guesses
System.out.println("BUT IT SHOULDN'T TAKE MORE THAN " + OPTIMAL_GUESSES + " GUESSES!");
}
System.out.println();
System.out.println("LET'S PLAN AGAIN.....");
gameState = GAME_STATE.INIT;
break;
}
} while (gameState != GAME_STATE.GAME_OVER);
}
public void intro() {
System.out.println(simulateTabs(33) + "LETTER");
System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println("LETTER GUESSING GAME");
System.out.println();
System.out.println("I'LL THINK OF A LETTER OF THE ALPHABET, A TO Z.");
System.out.println("TRY TO GUESS MY LETTER AND I'LL GIVE YOU CLUES");
System.out.println("AS TO HOW CLOSE YOU'RE GETTING TO MY LETTER.");
}
/**
* 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);
}
/*
* 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();
}
}

View File

@@ -0,0 +1,8 @@
public class LetterGame {
public static void main(String[] args) {
Letter letter = new Letter();
letter.play();
}
}

View File

@@ -0,0 +1,176 @@
import java.util.Arrays;
import java.util.Scanner;
/**
* Game of Literature Quiz
* <p>
* Based on the Basic game of Literature Quiz here
* https://github.com/coding-horror/basic-computer-games/blob/main/57%20Literature%20Quiz/litquiz.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 LiteratureQuiz {
// Used for keyboard input
private final Scanner kbScanner;
private enum GAME_STATE {
STARTUP,
QUESTIONS,
RESULTS,
GAME_OVER
}
// Current game state
private GAME_STATE gameState;
// Players correct answers
private int correctAnswers;
public LiteratureQuiz() {
gameState = GAME_STATE.STARTUP;
// 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 STARTUP:
intro();
correctAnswers = 0;
gameState = GAME_STATE.QUESTIONS;
break;
// Ask the player four questions
case QUESTIONS:
// Question 1
System.out.println("IN PINOCCHIO, WHAT WAS THE NAME OF THE CAT");
int question1Answer = displayTextAndGetNumber("1)TIGGER, 2)CICERO, 3)FIGARO, 4)GUIPETTO ? ");
if (question1Answer == 3) {
System.out.println("VERY GOOD! HERE'S ANOTHER.");
correctAnswers++;
} else {
System.out.println("SORRY...FIGARO WAS HIS NAME.");
}
System.out.println();
// Question 2
System.out.println("FROM WHOSE GARDEN DID BUGS BUNNY STEAL THE CARROTS?");
int question2Answer = displayTextAndGetNumber("1)MR. NIXON'S, 2)ELMER FUDD'S, 3)CLEM JUDD'S, 4)STROMBOLI'S ? ");
if (question2Answer == 2) {
System.out.println("PRETTY GOOD!");
correctAnswers++;
} else {
System.out.println("TOO BAD...IT WAS ELMER FUDD'S GARDEN.");
}
System.out.println();
// Question 3
System.out.println("IN THE WIZARD OF OS, DOROTHY'S DOG WAS NAMED");
int question3Answer = displayTextAndGetNumber("1)CICERO, 2)TRIXIA, 3)KING, 4)TOTO ? ");
if (question3Answer == 4) {
System.out.println("YEA! YOU'RE A REAL LITERATURE GIANT.");
correctAnswers++;
} else {
System.out.println("BACK TO THE BOOKS,...TOTO WAS HIS NAME.");
}
System.out.println();
// Question 4
System.out.println("WHO WAS THE FAIR MAIDEN WHO ATE THE POISON APPLE");
int question4Answer = displayTextAndGetNumber("1)SLEEPING BEAUTY, 2)CINDERELLA, 3)SNOW WHITE, 4)WENDY ? ");
if (question4Answer == 3) {
System.out.println("GOOD MEMORY!");
correctAnswers++;
} else {
System.out.println("OH, COME ON NOW...IT WAS SNOW WHITE.");
}
System.out.println();
gameState = GAME_STATE.RESULTS;
break;
// How did the player do?
case RESULTS:
if (correctAnswers == 4) {
// All correct
System.out.println("WOW! THAT'S SUPER! YOU REALLY KNOW YOUR NURSERY");
System.out.println("YOUR NEXT QUIZ WILL BE ON 2ND CENTURY CHINESE");
System.out.println("LITERATURE (HA, HA, HA)");
// one or none correct
} else if (correctAnswers < 2) {
System.out.println("UGH. THAT WAS DEFINITELY NOT TOO SWIFT. BACK TO");
System.out.println("NURSERY SCHOOL FOR YOU, MY FRIEND.");
// two or three correct
} else {
System.out.println("NOT BAD, BUT YOU MIGHT SPEND A LITTLE MORE TIME");
System.out.println("READING THE NURSERY GREATS.");
}
gameState = GAME_STATE.GAME_OVER;
break;
}
} while (gameState != GAME_STATE.GAME_OVER);
}
public void intro() {
System.out.println(simulateTabs(25) + "LITERATURE QUIZ");
System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println("LITERATURE QUIZ");
System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
System.out.println();
System.out.println("TEST YOUR KNOWLEDGE OF CHILDREN'S LITERATURE.");
System.out.println("THIS IS A MULTIPLE-CHOICE QUIZ.");
System.out.println("TYPE A 1, 2, 3, OR 4 AFTER THE QUESTION MARK.");
System.out.println();
System.out.println("GOOD LUCK!");
System.out.println();
}
/**
* 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);
}
/*
* Print a message on the screen, then accept input from Keyboard.
* Converts input to an Integer
*
* @param text message to be displayed on screen.
* @return what was typed by the player.
*/
private int displayTextAndGetNumber(String text) {
return Integer.parseInt(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();
}
}

View File

@@ -0,0 +1,8 @@
public class LiteratureQuizGame {
public static void main(String[] args) {
LiteratureQuiz literatureQuiz = new LiteratureQuiz();
literatureQuiz.play();
}
}

View File

@@ -0,0 +1,230 @@
import random, sys
def main():
global colors, color_letters, num_positions, num_colors, human_score, computer_score
colors = ["BLACK", "WHITE", "RED", "GREEN", "ORANGE", "YELLOW", "PURPLE", "TAN"]
color_letters = "BWRGOYPT"
num_colors = 100
human_score = 0
computer_score = 0
# get user inputs for game conditions
print("Mastermind")
print('Creative Computing Morristown, New Jersey')
while num_colors > 8:
num_colors = int(input("Number of colors (max 8): ")) # C9 in BASIC
num_positions = int(input("Number of positions: ")) # P9 in BASIC
num_rounds = int(input("Number of rounds: ")) # R9 in BASIC
possibilities = num_colors**num_positions
all_possibilities = [1] * possibilities
print("Number of possibilities {}".format(possibilities))
print('Color\tLetter')
print('=====\t======')
for element in range(0, num_colors):
print("{}\t{}".format(colors[element], colors[element][0]))
current_round = 1
while current_round <= num_rounds:
print('Round number {}'.format(current_round))
num_moves = 1
guesses = []
turn_over = False
print('Guess my combination ...')
answer = int(possibilities * random.random())
numeric_answer = [-1] * num_positions
for i in range(0, answer):
numeric_answer = get_possibility(numeric_answer)
#human_readable_answer = make_human_readable(numeric_answer)
while (num_moves < 10 and not turn_over ):
print('Move # {} Guess : '.format(num_moves))
user_command = input('Guess ')
if user_command == "BOARD":
print_board(guesses) #2000
elif user_command == "QUIT": #2500
human_readable_answer = make_human_readable(numeric_answer)
print('QUITTER! MY COMBINATION WAS: {}'.format(human_readable_answer))
print('GOOD BYE')
quit()
elif len(user_command) != num_positions: #410
print("BAD NUMBER OF POSITIONS")
else:
invalid_letters = get_invalid_letters(user_command)
if invalid_letters > "":
print("INVALID GUESS: {}".format(invalid_letters))
else:
guess_results = compare_two_positions(user_command, make_human_readable(numeric_answer))
print("Results: {}".format(guess_results))
if guess_results[1] == num_positions: # correct guess
turn_over = True
print("You guessed it in {} moves!".format(num_moves))
human_score = human_score + num_moves
print_score()
else:
print("You have {} blacks and {} whites".format(guess_results[1], guess_results[2]))
num_moves = num_moves + 1
guesses.append(guess_results)
if not turn_over: # RAN OUT OF MOVES
print ("YOU RAN OUT OF MOVES! THAT'S ALL YOU GET!")
print("THE ACTUAL COMBINATION WAS: {}".format(make_human_readable(numeric_answer)))
human_score = human_score + num_moves
print_score()
# COMPUTER TURN
guesses = []
turn_over = False
inconsistent_information = False
while(not turn_over and not inconsistent_information ):
all_possibilities = [1] * possibilities
num_moves = 1
inconsistent_information = False
print ("NOW I GUESS. THINK OF A COMBINATION.")
player_ready = input("HIT RETURN WHEN READY: ")
while (num_moves < 10 and not turn_over and not inconsistent_information):
found_guess = False
computer_guess = int(possibilities * random.random())
if all_possibilities[computer_guess] == 1: # random guess is possible, use it
found_guess = True
guess = computer_guess
else:
for i in range (computer_guess, possibilities):
if all_possibilities[i] == 1:
found_guess = True
guess = i
break
if not found_guess:
for i in range (0, computer_guess):
if all_possibilities[i] == 1:
found_guess = True
guess = i
break
if not found_guess: # inconsistent info from user
print('YOU HAVE GIVEN ME INCONSISTENT INFORMATION.')
print('TRY AGAIN, AND THIS TIME PLEASE BE MORE CAREFUL.')
turn_over = True
inconsistent_information = True
else:
numeric_guess = [-1] * num_positions
for i in range(0, guess):
numeric_guess = get_possibility(numeric_guess)
human_readable_guess = make_human_readable(numeric_guess)
print('My guess is: {}'.format(human_readable_guess))
blacks, whites = input("ENTER BLACKS, WHITES (e.g. 1,2): ").split(",")
blacks = int(blacks)
whites = int(whites)
if blacks == num_positions: #Correct guess
print('I GOT IT IN {} MOVES'.format(num_moves))
turn_over = True
computer_score = computer_score + num_moves
print_score()
else:
num_moves += 1
for i in range (0, possibilities):
if all_possibilities[i] == 0: #already ruled out
continue
numeric_possibility = [-1] * num_positions
for j in range (0, i):
numeric_possibility = get_possibility(numeric_possibility)
human_readable_possibility = make_human_readable(numeric_possibility) #4000
comparison = compare_two_positions(human_readable_possibility, human_readable_guess)
print(comparison)
if ((blacks != comparison[1]) or (whites != comparison[2])):
all_possibilities[i] = 0
if not turn_over: # COMPUTER DID NOT GUESS
print("I USED UP ALL MY MOVES!")
print("I GUESS MY CPU IS JUST HAVING AN OFF DAY.")
computer_score = computer_score + num_moves
print_score()
current_round += 1
print_score(is_final_score=True)
sys.exit()
#470
def get_invalid_letters(user_command):
"""Makes sure player input consists of valid colors for selected game configuration."""
valid_colors = color_letters[:num_colors]
invalid_letters = ""
for letter in user_command:
if letter not in valid_colors:
invalid_letters = invalid_letters + letter
return invalid_letters
#2000
def print_board(guesses):
"""Prints previous guesses within the round."""
print("Board")
print("Move\tGuess\tBlack White")
for idx, guess in enumerate(guesses):
print('{}\t{}\t{} {}'.format(idx+1, guess[0], guess[1], guess[2]))
#3500
# Easily the place for most optimization, since they generate every possibility
# every time when checking for potential solutions
# From the original article:
# "We did try a version that kept an actual list of all possible combinations
# (as a string array), which was significantly faster than this versionn but
# which ate tremendous amounts of memory."
def get_possibility(possibility):
#print(possibility)
if possibility[0] > -1: #3530
current_position = 0 # Python arrays are zero-indexed
while True:
if possibility[current_position] < num_colors-1: # zero-index again
possibility[current_position] += 1
return possibility
else:
possibility[current_position] = 0
current_position += 1
else: #3524
possibility = [0] * num_positions
return possibility
#4500
def compare_two_positions(guess, answer):
"""Returns blacks (correct color and position) and whites (correct color only) for candidate position (guess) versus reference position (answer)."""
increment = 0
blacks = 0
whites = 0
initial_guess = guess
for pos in range(0, num_positions):
if guess[pos] != answer[pos]:
for pos2 in range(0, num_positions):
if not(guess[pos] != answer[pos2] or guess[pos2] == answer[pos2]): # correct color but not correct place
whites = whites + 1
answer = answer[:pos2] + chr(increment) + answer[pos2+1:]
guess = guess[:pos] + chr(increment+1) + guess[pos+1:]
increment = increment + 2
else: #correct color and placement
blacks = blacks + 1
# THIS IS DEVIOUSLY CLEVER
guess = guess[:pos] + chr(increment+1) + guess[pos+1:]
answer = answer[:pos] + chr(increment) + answer[pos+1:]
increment = increment + 2
return [initial_guess, blacks, whites]
#5000 + logic from 1160
def print_score(is_final_score=False):
"""Prints score after each turn ends, including final score at end of game."""
if is_final_score:
print("GAME OVER")
print("FINAL SCORE:")
else:
print("SCORE:")
print(" COMPUTER {}".format(computer_score))
print(" HUMAN {}".format(human_score))
#4000, 5500, 6000 subroutines are all identical
def make_human_readable(num):
"""Make the numeric representation of a position human readable."""
retval = ''
for i in range(0, len(num)):
retval = retval + color_letters[int(num[i])]
return retval
if __name__ == "__main__":
main()

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

Some files were not shown because too many files have changed in this diff Show More