mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2026-02-05 11:26:37 -08:00
Merge branch 'main' into 84-super-star-trek-csharp
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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();
|
||||
@@ -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) {
|
||||
121
02 Amazing/python/amazing.py
Normal file
121
02 Amazing/python/amazing.py
Normal 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
95
03 Animal/ruby/animal.rb
Normal 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
|
||||
121
05 Bagels/csharp/BagelNumber.cs
Normal file
121
05 Bagels/csharp/BagelNumber.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
05 Bagels/csharp/Bagels.csproj
Normal file
13
05 Bagels/csharp/Bagels.csproj
Normal 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
124
05 Bagels/csharp/Game.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
39
05 Bagels/csharp/GameBase.cs
Normal file
39
05 Bagels/csharp/GameBase.cs
Normal 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');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
14
05 Bagels/csharp/Program.cs
Normal file
14
05 Bagels/csharp/Program.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
9
07 Basketball/javascript/basketball.html
Normal file
9
07 Basketball/javascript/basketball.html
Normal 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>
|
||||
384
07 Basketball/javascript/basketball.js
Normal file
384
07 Basketball/javascript/basketball.js
Normal 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();
|
||||
292
08 Batnum/java/src/BatNum.java
Normal file
292
08 Batnum/java/src/BatNum.java
Normal 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]);
|
||||
}
|
||||
}
|
||||
8
08 Batnum/java/src/BatNumGame.java
Normal file
8
08 Batnum/java/src/BatNumGame.java
Normal file
@@ -0,0 +1,8 @@
|
||||
public class BatNumGame {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
BatNum batNum = new BatNum();
|
||||
batNum.play();
|
||||
}
|
||||
}
|
||||
9
08 Batnum/javascript/batnum.html
Normal file
9
08 Batnum/javascript/batnum.html
Normal 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>
|
||||
161
08 Batnum/javascript/batnum.js
Normal file
161
08 Batnum/javascript/batnum.js
Normal 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();
|
||||
9
10 Blackjack/csharp/Blackjack.csproj
Normal file
9
10 Blackjack/csharp/Blackjack.csproj
Normal file
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>Blackjack</RootNamespace>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
32
10 Blackjack/csharp/Card.cs
Normal file
32
10 Blackjack/csharp/Card.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
56
10 Blackjack/csharp/Deck.cs
Normal file
56
10 Blackjack/csharp/Deck.cs
Normal 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
232
10 Blackjack/csharp/Game.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
10 Blackjack/csharp/Hand.cs
Normal file
67
10 Blackjack/csharp/Hand.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
27
10 Blackjack/csharp/Player.cs
Normal file
27
10 Blackjack/csharp/Player.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
41
10 Blackjack/csharp/Program.cs
Normal file
41
10 Blackjack/csharp/Program.cs
Normal 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'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
58
10 Blackjack/csharp/Prompt.cs
Normal file
58
10 Blackjack/csharp/Prompt.cs
Normal 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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<>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
9
11 Bombardment/javascript/bombardment.html
Normal file
9
11 Bombardment/javascript/bombardment.html
Normal 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>
|
||||
167
11 Bombardment/javascript/bombardment.js
Normal file
167
11 Bombardment/javascript/bombardment.js
Normal 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();
|
||||
151
11 Bombardment/python/bombardment.py
Executable file
151
11 Bombardment/python/bombardment.py
Executable 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()
|
||||
505
12 Bombs Away/java/src/BombsAway.java
Normal file
505
12 Bombs Away/java/src/BombsAway.java
Normal 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));
|
||||
}
|
||||
}
|
||||
8
12 Bombs Away/java/src/BombsAwayGame.java
Normal file
8
12 Bombs Away/java/src/BombsAwayGame.java
Normal file
@@ -0,0 +1,8 @@
|
||||
public class BombsAwayGame {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
BombsAway bombsAway = new BombsAway();
|
||||
bombsAway.play();
|
||||
}
|
||||
}
|
||||
9
12 Bombs Away/javascript/bombsaway.html
Normal file
9
12 Bombs Away/javascript/bombsaway.html
Normal 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>
|
||||
205
12 Bombs Away/javascript/bombsaway.js
Normal file
205
12 Bombs Away/javascript/bombsaway.js
Normal 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
BIN
13 Bounce/javascript/.DS_Store
vendored
Normal file
Binary file not shown.
9
13 Bounce/javascript/bounce.html
Normal file
9
13 Bounce/javascript/bounce.html
Normal 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>
|
||||
112
13 Bounce/javascript/bounce.js
Normal file
112
13 Bounce/javascript/bounce.js
Normal 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
253
16 Bug/java/src/Bug.java
Normal 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);
|
||||
}
|
||||
}
|
||||
10
16 Bug/java/src/BugGame.java
Normal file
10
16 Bug/java/src/BugGame.java
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
public class BugGame {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Bug bug = new Bug();
|
||||
bug.play();
|
||||
}
|
||||
}
|
||||
15
16 Bug/java/src/ComputerBug.java
Normal file
15
16 Bug/java/src/ComputerBug.java
Normal 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
363
16 Bug/java/src/Insect.java
Normal 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);
|
||||
|
||||
}
|
||||
}
|
||||
18
16 Bug/java/src/PlayerBug.java
Normal file
18
16 Bug/java/src/PlayerBug.java
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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) {
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
*/
|
||||
public class Player {
|
||||
|
||||
private String name;
|
||||
private final String name;
|
||||
|
||||
private int score;
|
||||
|
||||
Player(String name) {
|
||||
|
||||
@@ -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
81
19 Bunny/python/bunny.py
Executable 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()
|
||||
41
20 Buzzword/java/src/Buzzword.java
Executable file
41
20 Buzzword/java/src/Buzzword.java
Executable 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!" );
|
||||
}
|
||||
}
|
||||
187
22 Change/java/src/Change.java
Normal file
187
22 Change/java/src/Change.java
Normal 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);
|
||||
}
|
||||
}
|
||||
6
22 Change/java/src/ChangeGame.java
Normal file
6
22 Change/java/src/ChangeGame.java
Normal file
@@ -0,0 +1,6 @@
|
||||
public class ChangeGame {
|
||||
public static void main(String[] args) {
|
||||
Change change = new Change();
|
||||
change.play();
|
||||
}
|
||||
}
|
||||
143
24 Chemist/java/src/Chemist.java
Normal file
143
24 Chemist/java/src/Chemist.java
Normal 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);
|
||||
}
|
||||
}
|
||||
6
24 Chemist/java/src/ChemistGame.java
Normal file
6
24 Chemist/java/src/ChemistGame.java
Normal file
@@ -0,0 +1,6 @@
|
||||
public class ChemistGame {
|
||||
public static void main(String[] args) {
|
||||
Chemist chemist = new Chemist();
|
||||
chemist.play();
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
9
26 Chomp/javascript/chomp.html
Normal file
9
26 Chomp/javascript/chomp.html
Normal 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>
|
||||
175
26 Chomp/javascript/chomp.js
Normal file
175
26 Chomp/javascript/chomp.js
Normal 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
132
26 Chomp/python/chomp.py
Executable 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
114
30 Cube/python/cube.py
Executable 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()
|
||||
9
31 Depth Charge/javascript/depthcharge.html
Normal file
9
31 Depth Charge/javascript/depthcharge.html
Normal 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>
|
||||
112
31 Depth Charge/javascript/depthcharge.js
Normal file
112
31 Depth Charge/javascript/depthcharge.js
Normal 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();
|
||||
9
32 Diamond/javascript/diamond.html
Normal file
9
32 Diamond/javascript/diamond.html
Normal 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>
|
||||
94
32 Diamond/javascript/diamond.js
Normal file
94
32 Diamond/javascript/diamond.js
Normal 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();
|
||||
45
32 Diamond/ruby/diamond.rb
Normal file
45
32 Diamond/ruby/diamond.rb
Normal 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
146
33 Dice/java/src/Dice.java
Normal 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);
|
||||
}
|
||||
}
|
||||
6
33 Dice/java/src/DiceGame.java
Normal file
6
33 Dice/java/src/DiceGame.java
Normal file
@@ -0,0 +1,6 @@
|
||||
public class DiceGame {
|
||||
public static void main(String[] args) {
|
||||
Dice dice = new Dice();
|
||||
dice.play();
|
||||
}
|
||||
}
|
||||
9
33 Dice/javascript/dice.html
Normal file
9
33 Dice/javascript/dice.html
Normal 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>
|
||||
84
33 Dice/javascript/dice.js
Normal file
84
33 Dice/javascript/dice.js
Normal 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
51
33 Dice/ruby/dice.rb
Normal 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
|
||||
8
38 Fur Trader/csharp/FurTrader.csproj
Normal file
8
38 Fur Trader/csharp/FurTrader.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
25
38 Fur Trader/csharp/FurTrader.sln
Normal file
25
38 Fur Trader/csharp/FurTrader.sln
Normal 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
|
||||
506
38 Fur Trader/csharp/Game.cs
Normal file
506
38 Fur Trader/csharp/Game.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
42
38 Fur Trader/csharp/GameState.cs
Normal file
42
38 Fur Trader/csharp/GameState.cs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
20
38 Fur Trader/csharp/Program.cs
Normal file
20
38 Fur Trader/csharp/Program.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
161
41 Guess/java/src/Guess.java
Normal file
161
41 Guess/java/src/Guess.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
6
41 Guess/java/src/GuessGame.java
Normal file
6
41 Guess/java/src/GuessGame.java
Normal file
@@ -0,0 +1,6 @@
|
||||
public class GuessGame {
|
||||
public static void main(String[] args) {
|
||||
Guess guess = new Guess();
|
||||
guess.play();
|
||||
}
|
||||
}
|
||||
9
41 Guess/javascript/guess.html
Normal file
9
41 Guess/javascript/guess.html
Normal 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>
|
||||
104
41 Guess/javascript/guess.js
Normal file
104
41 Guess/javascript/guess.js
Normal 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();
|
||||
9
42 Gunner/javascript/gunner.html
Normal file
9
42 Gunner/javascript/gunner.html
Normal 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>
|
||||
139
42 Gunner/javascript/gunner.js
Normal file
139
42 Gunner/javascript/gunner.js
Normal 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();
|
||||
9
43 Hammurabi/javascript/hammurabi.html
Normal file
9
43 Hammurabi/javascript/hammurabi.html
Normal 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>
|
||||
253
43 Hammurabi/javascript/hammurabi.js
Normal file
253
43 Hammurabi/javascript/hammurabi.js
Normal 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();
|
||||
129
44 Hangman/csharp/Hangman/Graphic.cs
Normal file
129
44 Hangman/csharp/Hangman/Graphic.cs
Normal 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] = '-';
|
||||
}
|
||||
}
|
||||
}
|
||||
8
44 Hangman/csharp/Hangman/Hangman.csproj
Normal file
8
44 Hangman/csharp/Hangman/Hangman.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
16
44 Hangman/csharp/Hangman/Hangman.sln
Normal file
16
44 Hangman/csharp/Hangman/Hangman.sln
Normal 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
|
||||
313
44 Hangman/csharp/Hangman/Program.cs
Normal file
313
44 Hangman/csharp/Hangman/Program.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
176
52 Kinema/java/src/Kinema.java
Normal file
176
52 Kinema/java/src/Kinema.java
Normal file
@@ -0,0 +1,176 @@
|
||||
import java.util.Arrays;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* Game of Kinema
|
||||
* <p>
|
||||
* Based on the Basic game of Kinema here
|
||||
* https://github.com/coding-horror/basic-computer-games/blob/main/52%20Kinema/kinema.bas
|
||||
* <p>
|
||||
* Note: The idea was to create a version of the 1970's Basic game in Java, without introducing
|
||||
* new features - no additional text, error checking, etc has been added.
|
||||
*/
|
||||
public class Kinema {
|
||||
|
||||
// Used for keyboard input
|
||||
private final Scanner kbScanner;
|
||||
|
||||
private enum GAME_STATE {
|
||||
STARTUP,
|
||||
INIT,
|
||||
HOW_HIGH,
|
||||
SECONDS_TILL_IT_RETURNS,
|
||||
ITS_VELOCITY,
|
||||
RESULTS,
|
||||
GAME_OVER
|
||||
}
|
||||
|
||||
// Current game state
|
||||
private GAME_STATE gameState;
|
||||
|
||||
private int numberAnswersCorrect;
|
||||
|
||||
// How many meters per second a ball is thrown
|
||||
private int velocity;
|
||||
|
||||
public Kinema() {
|
||||
kbScanner = new Scanner(System.in);
|
||||
|
||||
gameState = GAME_STATE.STARTUP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main game loop
|
||||
*/
|
||||
public void play() {
|
||||
|
||||
double playerAnswer;
|
||||
double correctAnswer;
|
||||
do {
|
||||
switch (gameState) {
|
||||
|
||||
case STARTUP:
|
||||
intro();
|
||||
gameState = GAME_STATE.INIT;
|
||||
break;
|
||||
|
||||
case INIT:
|
||||
numberAnswersCorrect = 0;
|
||||
|
||||
// calculate a random velocity for the player to use in the calculations
|
||||
velocity = 5 + (int) (35 * Math.random());
|
||||
System.out.println("A BALL IS THROWN UPWARDS AT " + velocity + " METERS PER SECOND.");
|
||||
gameState = GAME_STATE.HOW_HIGH;
|
||||
break;
|
||||
|
||||
case HOW_HIGH:
|
||||
|
||||
playerAnswer = displayTextAndGetNumber("HOW HIGH WILL IT GO (IN METERS)? ");
|
||||
|
||||
// Calculate the correct answer to how high it will go
|
||||
correctAnswer = 0.05 * Math.pow(velocity, 2);
|
||||
if (calculate(playerAnswer, correctAnswer)) {
|
||||
numberAnswersCorrect++;
|
||||
}
|
||||
gameState = GAME_STATE.ITS_VELOCITY;
|
||||
break;
|
||||
|
||||
case ITS_VELOCITY:
|
||||
|
||||
playerAnswer = displayTextAndGetNumber("HOW LONG UNTIL IT RETURNS (IN SECONDS)? ");
|
||||
|
||||
// Calculate current Answer for how long until it returns to the ground in seconds
|
||||
correctAnswer = (double) velocity / 5;
|
||||
if (calculate(playerAnswer, correctAnswer)) {
|
||||
numberAnswersCorrect++;
|
||||
}
|
||||
gameState = GAME_STATE.SECONDS_TILL_IT_RETURNS;
|
||||
break;
|
||||
|
||||
case SECONDS_TILL_IT_RETURNS:
|
||||
|
||||
// Calculate random number of seconds for 3rd question
|
||||
double seconds = 1 + (Math.random() * (2 * velocity)) / 10;
|
||||
|
||||
// Round to one decimal place.
|
||||
double scale = Math.pow(10, 1);
|
||||
seconds = Math.round(seconds * scale) / scale;
|
||||
|
||||
playerAnswer = displayTextAndGetNumber("WHAT WILL ITS VELOCITY BE AFTER " + seconds + " SECONDS? ");
|
||||
|
||||
// Calculate the velocity after the given number of seconds
|
||||
correctAnswer = velocity - (10 * seconds);
|
||||
if (calculate(playerAnswer, correctAnswer)) {
|
||||
numberAnswersCorrect++;
|
||||
}
|
||||
gameState = GAME_STATE.RESULTS;
|
||||
break;
|
||||
|
||||
case RESULTS:
|
||||
System.out.println(numberAnswersCorrect + " RIGHT OUT OF 3");
|
||||
if (numberAnswersCorrect > 1) {
|
||||
System.out.println(" NOT BAD.");
|
||||
}
|
||||
gameState = GAME_STATE.STARTUP;
|
||||
break;
|
||||
}
|
||||
} while (gameState != GAME_STATE.GAME_OVER);
|
||||
}
|
||||
|
||||
private void intro() {
|
||||
System.out.println(simulateTabs(33) + "KINEMA");
|
||||
System.out.println(simulateTabs(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private boolean calculate(double playerAnswer, double correctAnswer) {
|
||||
|
||||
boolean gotItRight = false;
|
||||
|
||||
if (Math.abs((playerAnswer - correctAnswer) / correctAnswer) < 0.15) {
|
||||
System.out.println("CLOSE ENOUGH");
|
||||
gotItRight = true;
|
||||
} else {
|
||||
System.out.println("NOT EVEN CLOSE");
|
||||
}
|
||||
System.out.println("CORRECT ANSWER IS " + correctAnswer);
|
||||
System.out.println();
|
||||
|
||||
return gotItRight;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a message on the screen, then accept input from Keyboard.
|
||||
* Converts input to a Double
|
||||
*
|
||||
* @param text message to be displayed on screen.
|
||||
* @return what was typed by the player.
|
||||
*/
|
||||
private double displayTextAndGetNumber(String text) {
|
||||
return Double.parseDouble(displayTextAndGetInput(text));
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a message on the screen, then accept input from Keyboard.
|
||||
*
|
||||
* @param text message to be displayed on screen.
|
||||
* @return what was typed by the player.
|
||||
*/
|
||||
private String displayTextAndGetInput(String text) {
|
||||
System.out.print(text);
|
||||
return kbScanner.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate the old basic tab(xx) command which indented text by xx spaces.
|
||||
*
|
||||
* @param spaces number of spaces required
|
||||
* @return String with number of spaces
|
||||
*/
|
||||
private String simulateTabs(int spaces) {
|
||||
char[] spacesTemp = new char[spaces];
|
||||
Arrays.fill(spacesTemp, ' ');
|
||||
return new String(spacesTemp);
|
||||
}
|
||||
|
||||
}
|
||||
7
52 Kinema/java/src/KinemaGame.java
Normal file
7
52 Kinema/java/src/KinemaGame.java
Normal file
@@ -0,0 +1,7 @@
|
||||
public class KinemaGame {
|
||||
public static void main(String[] args) {
|
||||
|
||||
Kinema kinema = new Kinema();
|
||||
kinema.play();
|
||||
}
|
||||
}
|
||||
142
54 Letter/java/src/Letter.java
Normal file
142
54 Letter/java/src/Letter.java
Normal 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();
|
||||
}
|
||||
}
|
||||
8
54 Letter/java/src/LetterGame.java
Normal file
8
54 Letter/java/src/LetterGame.java
Normal file
@@ -0,0 +1,8 @@
|
||||
public class LetterGame {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Letter letter = new Letter();
|
||||
letter.play();
|
||||
}
|
||||
}
|
||||
176
57 Literature Quiz/java/src/LiteratureQuiz.java
Normal file
176
57 Literature Quiz/java/src/LiteratureQuiz.java
Normal 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();
|
||||
}
|
||||
}
|
||||
8
57 Literature Quiz/java/src/LiteratureQuizGame.java
Normal file
8
57 Literature Quiz/java/src/LiteratureQuizGame.java
Normal file
@@ -0,0 +1,8 @@
|
||||
public class LiteratureQuizGame {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
LiteratureQuiz literatureQuiz = new LiteratureQuiz();
|
||||
literatureQuiz.play();
|
||||
}
|
||||
}
|
||||
230
60 Mastermind/python/mastermind.py
Normal file
230
60 Mastermind/python/mastermind.py
Normal 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()
|
||||
@@ -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
Reference in New Issue
Block a user