mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-24 20:10:15 -08:00
81 lines
2.8 KiB
D
81 lines
2.8 KiB
D
@safe: // Make @safe the default for this file, enforcing memory-safety.
|
|
import std;
|
|
|
|
void main()
|
|
{
|
|
enum width = 50;
|
|
writeln(center("War", width));
|
|
writeln(center("(After Creative Computing Morristown, New Jersey)\n\n", width));
|
|
writeln(wrap("This is the card game of war. Each card is given by suit-# " ~
|
|
"as 7♠ for seven of spades. ", width));
|
|
|
|
if ("Do you want instructions?".yes)
|
|
writeln("\n", wrap("The computer gives you and it a 'card'. The higher card " ~
|
|
"(numerically) wins. The game ends when you choose not to " ~
|
|
"continue or when you have finished the pack.\n", width));
|
|
|
|
static const cards = cartesianProduct(["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"],
|
|
["♠", "♥", "♦", "♣"]).map!(a => a.expand.only.join).array;
|
|
const indices = iota(0, cards.length).array.randomShuffle;
|
|
int yourScore = 0, compScore = 0, i = 0;
|
|
while (i < indices.length)
|
|
{
|
|
size_t your = indices[i++], comp = indices[i++];
|
|
writeln("\nYou: ", cards[your].leftJustify(9), "Computer: ", cards[comp]);
|
|
your /= 4; comp /= 4;
|
|
if (your == comp)
|
|
writeln("Tie. No score change.");
|
|
else if (your < comp)
|
|
writeln("The computer wins!!! You have ", yourScore,
|
|
" and the computer has ", ++compScore, ".");
|
|
else
|
|
writeln("You win. You have ", ++yourScore,
|
|
" and the computer has ", compScore, ".");
|
|
if (i == indices.length)
|
|
writeln("\nWe have run out of cards. Final score: You: ", yourScore,
|
|
", the computer: ", compScore, ".");
|
|
else if (!"Do you want to continue?".yes)
|
|
break;
|
|
}
|
|
writeln("\nThanks for playing. It was fun.");
|
|
}
|
|
|
|
/// Returns whether question was answered positively.
|
|
bool yes(string question)
|
|
{
|
|
writef!"%s "(question);
|
|
try
|
|
return trustedReadln.strip.toLower.startsWith("y");
|
|
catch (Exception) // readln throws on I/O and Unicode errors, which we handle here.
|
|
return false;
|
|
}
|
|
|
|
/** An @trusted wrapper around readln.
|
|
*
|
|
* This is the only function that formally requires manual review for memory-safety.
|
|
* [Arguably readln should be safe already](https://forum.dlang.org/post/rab398$1up$1@digitalmars.com)
|
|
* which would remove the need to have any @trusted code in this program.
|
|
*/
|
|
string trustedReadln() @trusted
|
|
{
|
|
return readln;
|
|
}
|
|
|
|
version (Windows)
|
|
{
|
|
// Make the Windows console do a better job at printing UTF-8 strings,
|
|
// and restore the default upon termination.
|
|
|
|
import core.sys.windows.windows;
|
|
|
|
shared static this() @trusted
|
|
{
|
|
SetConsoleOutputCP(CP_UTF8);
|
|
}
|
|
|
|
shared static ~this() @trusted
|
|
{
|
|
SetConsoleOutputCP(GetACP);
|
|
}
|
|
}
|