Time for an 2014 update…

This commit is contained in:
Ingy döt Net 2014-01-17 05:32:22 +00:00
parent 372c577f83
commit 09687c4926
2520 changed files with 34227 additions and 7318 deletions

View file

@ -1,48 +1,44 @@
import std.stdio, std.string, std.algorithm, std.conv,
std.random, std.ascii, std.array, std.range;
import std.stdio, std.string, std.algorithm, std.conv, std.random,
std.ascii, std.array, std.range, std.math;
struct GameBoard {
dchar[9] board = "123456789";
enum : char { human = 'X', computer = 'O' }
enum : dchar { human = 'X', computer = 'O' }
enum Game { going, humanWins, computerWins, draw }
const pure nothrow invariant() {
int nHuman = 0, nComputer = 0;
foreach (immutable i, immutable c; board)
if (c.isDigit)
assert(i == c - '1'); // in correct position?
else
assert(i == c - '1'); // In correct position?
else {
assert(c == human || c == computer);
(c == human ? nHuman : nComputer)++;
}
assert(abs(nHuman - nComputer) <= 1);
}
string toString() const pure {
return format("%(%-(%s|%)\n-+-+-\n%)", board.dup.chunks(3));
return format("%(%-(%s|%)\n-+-+-\n%)", board[].chunks(3));
}
bool isAvailable(in int i) const pure nothrow {
if (i < 0 || i >= 9)
return false;
return board[i].isDigit;
return i >= 0 && i < 9 && board[i].isDigit;
}
int[] availablePositions() const pure nothrow {
// not pure not nothrow:
//return 9.iota.filter!(i => board[i].isDigit).array;
int[] result;
foreach (immutable i; 0 .. 9)
if (isAvailable(i))
result ~= i;
return result;
return 9.iota.filter!(i => isAvailable(i)).array;
}
Game winner() const pure nothrow {
immutable wins = [[0, 1, 2], [3, 4, 5], [6, 7, 8],
[0, 3, 6], [1, 4, 7], [2, 5, 8],
[0, 4, 8], [2, 4, 6]];
static immutable wins = [[0, 1, 2], [3, 4, 5], [6, 7, 8],
[0, 3, 6], [1, 4, 7], [2, 5, 8],
[0, 4, 8], [2, 4, 6]];
foreach (immutable win; wins) {
immutable bw0 = board[win[0]];
if (bw0.isDigit)
continue; // nobody wins on this one
continue; // Nobody wins on this one.
if (bw0 == board[win[1]] && bw0 == board[win[2]])
return bw0 == GameBoard.human ?
@ -53,16 +49,16 @@ struct GameBoard {
return availablePositions.empty ? Game.draw: Game.going;
}
bool finished() const pure nothrow {
bool isFinished() const pure nothrow {
return winner != Game.going;
}
int computerMove() const // random move
int computerMove() const // Random move.
out(res) {
assert(res >= 0 && res < 9 && isAvailable(res));
} body {
// return choice(availablePositions());
return randomCover(availablePositions, rndGen).front;
// return availablePositions.choice;
return availablePositions[uniform(0, $)];
}
}
@ -71,7 +67,7 @@ GameBoard playGame() {
GameBoard board;
bool playsHuman = true;
while (!board.finished) {
while (!board.isFinished) {
board.writeln;
int move;
@ -85,7 +81,7 @@ GameBoard playGame() {
return board;
} while (!board.isAvailable(move));
} else
move = board.computerMove();
move = board.computerMove;
assert(board.isAvailable(move));
writefln("\n%s chose %d", playsHuman ? "You" : "I", move + 1);
@ -99,21 +95,21 @@ GameBoard playGame() {
void main() {
writeln("Tic-tac-toe game player.\n");
"Tic-tac-toe game player.\n".writeln;
immutable outcome = playGame.winner;
final switch (outcome) {
case GameBoard.Game.going:
writeln("Game stopped.");
"Game stopped.".writeln;
break;
case GameBoard.Game.humanWins:
writeln("\nYou win!");
"\nYou win!".writeln;
break;
case GameBoard.Game.computerWins:
writeln("\nI win.");
"\nI win.".writeln;
break;
case GameBoard.Game.draw:
writeln("\nDraw");
"\nDraw".writeln;
break;
}
}