Files
basic-computer-games/94_War/d/war.d
2022-01-16 15:09:17 +01:00

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