RosettaCodeData/Task/Minesweeper-game/Ceylon/minesweeper-game.ceylon
2018-06-22 20:57:24 +00:00

134 lines
3.2 KiB
Ceylon

import ceylon.random {
DefaultRandom
}
class Cell() {
shared variable Boolean covered = true;
shared variable Boolean flagged = false;
shared variable Boolean mined = false;
shared variable Integer adjacentMines = 0;
string =>
if (covered && !flagged)
then "."
else if (covered && flagged)
then "?"
else if (!covered && mined)
then "X"
else if (!covered && adjacentMines > 0)
then adjacentMines.string
else " ";
}
"The main function of the module. Run this one."
shared void run() {
value random = DefaultRandom();
value chanceOfBomb = 0.2;
value width = 6;
value height = 4;
value grid = Array { for (j in 1..height) Array { for (i in 1..width) Cell() } };
function getCell(Integer x, Integer y) => grid[y]?.get(x);
void initializeGrid() {
for (row in grid) {
for (cell in row) {
cell.covered = true;
cell.flagged = false;
cell.mined = random.nextFloat() < chanceOfBomb;
}
}
function countAdjacentMines(Integer x, Integer y) => count {
for (j in y - 1 .. y + 1)
for (i in x - 1 .. x + 1)
if (exists cell = getCell(i, j))
cell.mined
};
for (j->row in grid.indexed) {
for (i->cell in row.indexed) {
cell.adjacentMines = countAdjacentMines(i, j);
}
}
}
void displayGrid() {
print(" " + "".join(1..width));
print(" " + "-".repeat(width));
for (j->row in grid.indexed) {
print("``j + 1``|``"".join(row)``|``j + 1``");
}
print(" " + "-".repeat(width));
print(" " + "".join(1..width));
}
Boolean won() =>
expand(grid).every((cell) => (cell.flagged && cell.mined) || (!cell.flagged && !cell.mined));
void uncoverNeighbours(Integer x, Integer y) {
for (j in y - 1 .. y + 1) {
for (i in x - 1 .. x + 1) {
if (exists cell = getCell(i, j), cell.covered, !cell.flagged, !cell.mined) {
cell.covered = false;
if (cell.adjacentMines == 0) {
uncoverNeighbours(i, j);
}
}
}
}
}
while (true) {
print("Welcome to minesweeper!
-----------------------");
initializeGrid();
while (true) {
displayGrid();
print("
The number of mines to find is ``count(expand(grid)*.mined)``.
What would you like to do?
[1] reveal a free space (or blow yourself up)
[2] mark (or unmark) a mine");
assert (exists instruction = process.readLine());
print("Please enter the coordinates. eg 2 4");
assert (exists line2 = process.readLine());
value coords = line2.split().map(Integer.parse).narrow<Integer>().sequence();
if (exists x = coords[0], exists y = coords[1], exists cell = getCell(x - 1, y - 1)) {
switch (instruction)
case ("1") {
if (cell.mined) {
print("=================
=== You lose! ===
=================");
expand(grid).each((cell) => cell.covered = false);
displayGrid();
break;
}
else if (cell.covered) {
cell.covered = false;
uncoverNeighbours(x - 1, y - 1);
}
}
case ("2") {
if (cell.covered) {
cell.flagged = !cell.flagged;
}
}
else { print("bad choice"); }
if (won()) {
print("****************
*** You win! ***
****************");
break;
}
}
}
}
}