mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 23:26:40 -08:00
Merge branch 'coding-horror:main' into main
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -31,3 +31,7 @@ Pipfile
|
|||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.vs/
|
.vs/
|
||||||
|
**/target/
|
||||||
|
Cargo.lock
|
||||||
|
**/*.rs.bk
|
||||||
|
/target
|
||||||
|
|||||||
9
01_Acey_Ducey/rust/Cargo.toml
Normal file
9
01_Acey_Ducey/rust/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "rust"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rand = "0.8.5"
|
||||||
3
01_Acey_Ducey/rust/README.md
Normal file
3
01_Acey_Ducey/rust/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
|
||||||
|
|
||||||
|
Conversion to [Rust](https://www.rust-lang.org/) by Alex Kotov [mur4ik18@github](https://github.com/mur4ik18).
|
||||||
131
01_Acey_Ducey/rust/src/main.rs
Normal file
131
01_Acey_Ducey/rust/src/main.rs
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
use rand::{prelude::ThreadRng, Rng};
|
||||||
|
use std::{fmt, io, mem};
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
struct Card(u8);
|
||||||
|
|
||||||
|
impl Card {
|
||||||
|
fn new_random(rng: &mut ThreadRng) -> Card {
|
||||||
|
Card(rng.gen_range(2..15))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Card {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{}",
|
||||||
|
match self.0 {
|
||||||
|
11 => String::from("JACK"),
|
||||||
|
12 => String::from("QUEEN"),
|
||||||
|
13 => String::from("KING"),
|
||||||
|
14 => String::from("ACE"),
|
||||||
|
otherwise => otherwise.to_string(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CardsPool(Card, Card, Card);
|
||||||
|
|
||||||
|
impl CardsPool {
|
||||||
|
fn new() -> CardsPool {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let mut first = Card::new_random(&mut rng);
|
||||||
|
let mut second = Card::new_random(&mut rng);
|
||||||
|
let third = Card::new_random(&mut rng);
|
||||||
|
|
||||||
|
if first > second {
|
||||||
|
mem::swap(&mut first, &mut second);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardsPool(first, second, third)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_in_win_range(&self) -> bool {
|
||||||
|
self.0 <= self.2 && self.2 <= self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
hello();
|
||||||
|
// user start bank
|
||||||
|
let mut user_bank: u16 = 100;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
println!("YOU NOW HAVE {} DOLLARS.", &mut user_bank);
|
||||||
|
println!("HERE ARE YOUR NEXT TWO CARDS:");
|
||||||
|
// get new random cards
|
||||||
|
let cards = CardsPool::new();
|
||||||
|
|
||||||
|
println!("{}", cards.0);
|
||||||
|
println!("{}", cards.1);
|
||||||
|
|
||||||
|
let user_bet: u16 = get_bet(user_bank);
|
||||||
|
|
||||||
|
if user_bet == 0 {
|
||||||
|
println!("CHICKEN!!!\n");
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
println!("THANK YOU! YOUR BET IS {} DOLLARS.", user_bet);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\nTHE THIRD CARD IS:");
|
||||||
|
println!("{}", cards.2);
|
||||||
|
|
||||||
|
if cards.is_in_win_range() {
|
||||||
|
println!("YOU WIN!!!\n");
|
||||||
|
user_bank += user_bet;
|
||||||
|
} else {
|
||||||
|
println!("SORRY, YOU LOSE\n");
|
||||||
|
user_bank -= user_bet;
|
||||||
|
}
|
||||||
|
|
||||||
|
if user_bank == 0 {
|
||||||
|
println!("\nSORRY, FRIEND, BUT YOU BLEW YOUR WAD.\n");
|
||||||
|
println!("TRY AGAIN? (yes OR no)");
|
||||||
|
let mut input = String::new();
|
||||||
|
io::stdin().read_line(&mut input).expect("Incorrect input");
|
||||||
|
|
||||||
|
if "yes" == input {
|
||||||
|
user_bank = 100;
|
||||||
|
} else {
|
||||||
|
println!("O.K., HOPE YOU HAD FUN!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hello() {
|
||||||
|
println!(" 🂡 ACEY DUCEY CARD GAME 🂱");
|
||||||
|
println!("CREATIVE COMPUTING - MORRISTOWN, NEW JERSEY");
|
||||||
|
println!(" ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER");
|
||||||
|
println!("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP");
|
||||||
|
println!("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING");
|
||||||
|
println!("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE");
|
||||||
|
println!("A VALUE BETWEEN THE FIRST TWO.");
|
||||||
|
println!("IF YOU DO NOT WANT TO BET IN A ROUND, ENTER 0");
|
||||||
|
println!("\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_bet(user_bank: u16) -> u16 {
|
||||||
|
println!("WHAT IS YOUR BET? ENTER 0 IF YOU DON'T WANT TO BET (CTRL+C TO EXIT)");
|
||||||
|
let bet: u16;
|
||||||
|
let mut input = String::new();
|
||||||
|
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut input)
|
||||||
|
.expect("Sorry your input incorrect");
|
||||||
|
|
||||||
|
// XXX: Unhandled input
|
||||||
|
bet = input.trim().parse::<u16>().unwrap();
|
||||||
|
match bet {
|
||||||
|
0 => bet,
|
||||||
|
bet if bet < user_bank => bet,
|
||||||
|
_ => {
|
||||||
|
println!("SORRY, MY FRIEND, BUT YOU BET TOO MUCH.");
|
||||||
|
println!("YOU HAVE ONLY {} DOLLARS TO BET.", user_bank);
|
||||||
|
get_bet(user_bank)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
41_Guess/rust/Cargo.toml
Normal file
9
41_Guess/rust/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "guess"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rand = "0.8.4"
|
||||||
3
41_Guess/rust/README.md
Normal file
3
41_Guess/rust/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
|
||||||
|
|
||||||
|
Conversion to [Rust](https://www.rust-lang.org/)
|
||||||
109
41_Guess/rust/src/main.rs
Normal file
109
41_Guess/rust/src/main.rs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
//#######################################################
|
||||||
|
//
|
||||||
|
// Guess
|
||||||
|
//
|
||||||
|
// From: Basic Computer Games (1978)
|
||||||
|
//
|
||||||
|
// "In program Guess, the computer chooses a random
|
||||||
|
// integer between 0 and any limit and any limit you
|
||||||
|
// set. You must then try to guess the number the
|
||||||
|
// computer has choosen using the clues provideed by
|
||||||
|
// the computer.
|
||||||
|
// You should be able to guess the number in one less
|
||||||
|
// than the number of digits needed to represent the
|
||||||
|
// number in binary notation - i.e. in base 2. This ought
|
||||||
|
// to give you a clue as to the optimum search technique.
|
||||||
|
// Guess converted from the original program in FOCAL
|
||||||
|
// which appeared in the book "Computers in the Classroom"
|
||||||
|
// by Walt Koetke of Lexington High School, Lexington,
|
||||||
|
// Massaschusetts.
|
||||||
|
//
|
||||||
|
//#######################################################
|
||||||
|
|
||||||
|
|
||||||
|
use rand::Rng;
|
||||||
|
use std::io;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
// Rust haven't log2 in the standard library so I added fn log_2
|
||||||
|
const fn num_bits<T>() -> usize { std::mem::size_of::<T>() * 8 }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let mut still_guessing = true;
|
||||||
|
let limit = set_limit();
|
||||||
|
let limit_goal = 1+(log_2(limit.try_into().unwrap())/log_2(2)) ;
|
||||||
|
loop{
|
||||||
|
|
||||||
|
let mut won = false;
|
||||||
|
let mut guess_count = 1;
|
||||||
|
let my_guess = rng.gen_range(1..limit);
|
||||||
|
|
||||||
|
println!("I'm thinking of a number between 1 and {}",limit);
|
||||||
|
println!("Now you try to guess what it is.");
|
||||||
|
|
||||||
|
while still_guessing {
|
||||||
|
let inp = get_input()
|
||||||
|
.trim()
|
||||||
|
.parse::<i64>().unwrap();
|
||||||
|
println!("\n\n\n");
|
||||||
|
if inp < my_guess {
|
||||||
|
println!("Too low. Try a bigger answer");
|
||||||
|
guess_count+=1;
|
||||||
|
}
|
||||||
|
else if inp > my_guess {
|
||||||
|
println!("Too high. Try a smaller answer");
|
||||||
|
guess_count+=1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println!("That's it! You got it in {} tries", guess_count);
|
||||||
|
won = true;
|
||||||
|
still_guessing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if won {
|
||||||
|
match guess_count.cmp(&limit_goal) {
|
||||||
|
Ordering::Less => println!("Very good."),
|
||||||
|
Ordering::Equal => println!("Good."),
|
||||||
|
Ordering::Greater => println!("You should have been able to get it in only {}", limit_goal),
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\n\n\n");
|
||||||
|
still_guessing = true;
|
||||||
|
} else {
|
||||||
|
println!("\n\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_2(x:i32) -> u32 {
|
||||||
|
assert!(x > 0);
|
||||||
|
num_bits::<i32>() as u32 - x.leading_zeros() - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_limit() -> i64 {
|
||||||
|
|
||||||
|
println!(" Guess");
|
||||||
|
println!("\n\n\n");
|
||||||
|
println!("This is a number guessing game. I'll think");
|
||||||
|
println!("of a number between 1 and any limit you want.\n");
|
||||||
|
println!("Then you have to guess what it is\n");
|
||||||
|
println!("What limit do you want?");
|
||||||
|
|
||||||
|
let inp = get_input().trim().parse::<i64>().unwrap();
|
||||||
|
|
||||||
|
if inp >= 2 {
|
||||||
|
inp
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
set_limit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_input() -> String {
|
||||||
|
let mut input = String::new();
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut input)
|
||||||
|
.expect("Your input is not correct");
|
||||||
|
input
|
||||||
|
}
|
||||||
137
54_Letter/csharp/Game.cs
Normal file
137
54_Letter/csharp/Game.cs
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
namespace Letter
|
||||||
|
{
|
||||||
|
internal static class Game
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum number of guesses.
|
||||||
|
/// Note the program doesn't enforce this - it just displays a message if this is exceeded.
|
||||||
|
/// </summary>
|
||||||
|
private const int MaximumGuesses = 5;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Main game loop.
|
||||||
|
/// </summary>
|
||||||
|
public static void Play()
|
||||||
|
{
|
||||||
|
DisplayIntroductionText();
|
||||||
|
|
||||||
|
// Keep playing forever, or until the user quits.
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
PlayRound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Play a single round.
|
||||||
|
/// </summary>
|
||||||
|
internal static void PlayRound()
|
||||||
|
{
|
||||||
|
var gameState = new GameState();
|
||||||
|
DisplayRoundIntroduction();
|
||||||
|
|
||||||
|
char letterInput = '\0'; // Set the initial character to something that's not A-Z.
|
||||||
|
while (letterInput != gameState.Letter)
|
||||||
|
{
|
||||||
|
letterInput = GetCharacterFromKeyboard();
|
||||||
|
gameState.GuessesSoFar++;
|
||||||
|
DisplayGuessResult(gameState.Letter, letterInput);
|
||||||
|
}
|
||||||
|
DisplaySuccessMessage(gameState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display an introduction when the game loads.
|
||||||
|
/// </summary>
|
||||||
|
internal static void DisplayIntroductionText()
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.WriteLine("LETTER");
|
||||||
|
Console.WriteLine("Creative Computing, Morristown, New Jersey.");
|
||||||
|
Console.WriteLine("");
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||||
|
Console.WriteLine("Letter Guessing Game");
|
||||||
|
Console.WriteLine("I'll think of a letter of the alphabet, A to Z.");
|
||||||
|
Console.WriteLine("Try to guess my letter and I'll give you clues");
|
||||||
|
Console.WriteLine("as to how close you're getting to my letter.");
|
||||||
|
Console.WriteLine("");
|
||||||
|
|
||||||
|
Console.ResetColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display introductionary text for each round.
|
||||||
|
/// </summary>
|
||||||
|
internal static void DisplayRoundIntroduction()
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.WriteLine("O.K., I have a letter. Start guessing.");
|
||||||
|
|
||||||
|
Console.ResetColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display text depending whether the guess is lower or higher.
|
||||||
|
/// </summary>
|
||||||
|
internal static void DisplayGuessResult(char letterToGuess, char letterInput)
|
||||||
|
{
|
||||||
|
Console.BackgroundColor = ConsoleColor.White;
|
||||||
|
Console.ForegroundColor = ConsoleColor.Black;
|
||||||
|
Console.Write(" " + letterInput + " ");
|
||||||
|
|
||||||
|
Console.ResetColor();
|
||||||
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
|
Console.Write(" ");
|
||||||
|
if (letterInput != letterToGuess)
|
||||||
|
{
|
||||||
|
if (letterInput > letterToGuess)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Too high. Try a lower letter");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Too low. Try a higher letter");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Console.ResetColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display success, and the number of guesses.
|
||||||
|
/// </summary>
|
||||||
|
internal static void DisplaySuccessMessage(GameState gameState)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
Console.WriteLine($"You got it in {gameState.GuessesSoFar} guesses!!");
|
||||||
|
if (gameState.GuessesSoFar > MaximumGuesses)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine($"But it shouldn't take more than {MaximumGuesses} guesses!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Good job !!!!!");
|
||||||
|
}
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.WriteLine("");
|
||||||
|
Console.WriteLine("Let's play again.....");
|
||||||
|
|
||||||
|
Console.ResetColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get valid input from the keyboard: must be an alpha character. Converts to upper case if necessary.
|
||||||
|
/// </summary>
|
||||||
|
internal static char GetCharacterFromKeyboard()
|
||||||
|
{
|
||||||
|
char letterInput;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
var keyPressed = Console.ReadKey(true);
|
||||||
|
letterInput = Char.ToUpper(keyPressed.KeyChar); // Convert to upper case immediately.
|
||||||
|
} while (!Char.IsLetter(letterInput)); // If the input is not a letter, wait for another letter to be pressed.
|
||||||
|
return letterInput;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
54_Letter/csharp/GameState.cs
Normal file
37
54_Letter/csharp/GameState.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
namespace Letter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Holds the current state.
|
||||||
|
/// </summary>
|
||||||
|
internal class GameState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initialise the game state with a random letter.
|
||||||
|
/// </summary>
|
||||||
|
public GameState()
|
||||||
|
{
|
||||||
|
Letter = GetRandomLetter();
|
||||||
|
GuessesSoFar = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The letter that the user is guessing.
|
||||||
|
/// </summary>
|
||||||
|
public char Letter { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of guesses the user has had so far.
|
||||||
|
/// </summary>
|
||||||
|
public int GuessesSoFar { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a random character (A-Z) for the user to guess.
|
||||||
|
/// </summary>
|
||||||
|
internal static char GetRandomLetter()
|
||||||
|
{
|
||||||
|
var random = new Random();
|
||||||
|
var randomNumber = random.Next(0, 26);
|
||||||
|
return (char)('A' + randomNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
54_Letter/csharp/Program.cs
Normal file
3
54_Letter/csharp/Program.cs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
using Letter;
|
||||||
|
|
||||||
|
Game.Play();
|
||||||
Reference in New Issue
Block a user