Add files via upload

This commit is contained in:
Ki Rill 2020-01-12 10:54:01 +06:00 committed by GitHub
parent da5e0c95c6
commit dbc4e76e60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 290 additions and 0 deletions
lesson#9.3

290
lesson#9.3/main.d Normal file
View File

@ -0,0 +1,290 @@
// Finishing Battleship game
import std.stdio: writeln, write, readf;
import std.conv: to;
import std.random: uniform;
// game states
enum GameState {
MENU, PLAY, HELP, EXIT
}
/*
gameState = MENU; -> mainMenu(); // managing main menu
gameState = HELP; -> help(); // how to play
gameState = PLAY; -> play(); // game logic
gameState = EXIT; -> break out from the loop and quit
*/
immutable int NUM_SHIPS = 10;
void main() {
// gameState variable
GameState gameState = GameState.MENU;
// while gameState does not equal to EXIT, run the game
while(gameState != GameState.EXIT) {
if(gameState == GameState.MENU) {
mainMenu(gameState);
} else if(gameState == GameState.HELP) {
help(gameState);
} if(gameState == GameState.PLAY) {
gamePlay(gameState);
}
}
writeln("Thanks for playing!");
}
// print 10 empty lines (for formatting)
void clear() {
for(int i = 0; i < 30; i++) {
writeln();
}
}
// MENU state: the code for handling main menu
void mainMenu(ref GameState gameState) {
clear();
writeln("Hi and welcome!");
writeln();
writeln("(1) Play");
writeln("(2) Help");
writeln("(3) Exit");
writeln();
write("Choice >> :_");
char c;
readf(" %s", c);
if(c == '1' || c == 'p' || c == 'P') {
gameState = GameState.PLAY;
} else if(c == '2' || c == 'h' || c == 'H') {
gameState = GameState.HELP;
} else if(c == '3' || c == 'e' || c == 'E') {
gameState = GameState.EXIT;
} else {
writeln("\n\nError! Please try again!\n");
}
}
// HELP state: displaying helpful information
void help(ref GameState gameState) {
clear();
writeln("1. Each player must secretly place their ships on a grid \nof ten columns by ten rows.");
writeln("\n2. Each player will also be in possession of a second grid \nof the same size. Where the first grid is their own ships, \nthe second one (which is blank at the beginning of the game) \nis a mirror of their opponents battlefield.");
writeln("\n3. Players pick a square at random, calling it by its row and \ncolumn number. This represents their firing a missile \ndirectly at that square.");
writeln("\n4. The player who successfully locates all their opponents \nships first by hitting each square they occupy is the winner \nas all ships have been destroyed.");
write("\nChoice(2) >> :_");
char c;
readf(" %s", c);
gameState = GameState.MENU;
}
// PLAY state: game logic
void gamePlay(ref GameState gameState) {
clear();
// creating our maps
char[5][5] playerMap = ' ';
char[5][5] enemyMap = ' ';
char[5][5] territory = ' ';
// initializing ships
initShipPos(playerMap); // init player's ships (manually, by the player himself)
initEnemyShipPos(enemyMap); // init enemy's ships (randomization)
int player_ships_destroyed = 0;
int enemy_ships_destroyed = 0;
bool gameWon = false;
while(gameState != GameState.EXIT) {
// displaying player's map
writeln("Your MAP, Captain: ");
display(playerMap);
// displaying empty territory
writeln("\n", "Enemy's hiding somewhere, Captain: ");
display(territory);
writeln("Let's scout the area and attack (", player_ships_destroyed, " of ", NUM_SHIPS, " ships destroyed)!");
// reading user input
char x;
char y;
write("X coord to attack(e to exit): >>_"); readf(" %s", x);
if(x == 'e') { // if input = 'e', exit the game
gameState = GameState.EXIT;
}
write("Y coord to attack(e to exit): >>_"); readf(" %s", y);
if(y == 'e') { // if input = 'e', exit the game
gameState = GameState.EXIT;
}
// converting (x, y) coordinates to integers
int ix = to!int(x - '0');
int iy = to!int(y - '0');
clear(); // clearing the screen by inserting new lines
// if (x, y) coordinates are greater than the bounds of the map or are negative, go to the begining
if(ix < 0 || ix > territory.length-1 || iy < 0 || iy > territory.length-1) {
continue;
}
// if the coordinate isn't empty, go to the begining
if(territory[ix][iy] != ' ') {
continue;
}
// if player hit enemy's ship, mark it with 'x', otherwise mark it with'o'
if(enemyMap[ix][iy] == '1') {
territory[ix][iy] = enemyMap[ix][iy] = 'x';
player_ships_destroyed++;
} else {
territory[ix][iy] = enemyMap[ix][iy] = 'o';
}
// if player destroyed all of the enemy's ships, exit
if(player_ships_destroyed >= NUM_SHIPS) {
gameState = GameState.EXIT;
gameWon = true; // the player has won
}
enemyAttack(playerMap, enemy_ships_destroyed);
// if enemy destroyed all of the player's ships, exit
if(enemy_ships_destroyed >= NUM_SHIPS) {
gameState = GameState.EXIT;
gameWon = false; // the player has lost
}
}
clear();
if(gameWon) {
writeln("YOU WON!");
} else {
writeln("Your MAP, Captain: ");
display(playerMap);
writeln("\nYOU LOST!");
}
}
// read the comments in the gamePlay function, the code is pretty much the same
void initShipPos(ref char[5][5] array) {
int i = 0;
while(i < NUM_SHIPS) {
display(array);
writeln("Enter your ship's position(", i, " of ", NUM_SHIPS," ships):");
char x;
char y;
write("X coord: >>_"); readf(" %s", x);
write("Y coord: >>_"); readf(" %s", y);
int ix = to!int(x - '0');
int iy = to!int(y - '0');
clear();
if(ix < 0 || ix > array.length-1 || iy < 0 || iy > array.length-1) {
writeln("\nERROR! TRY AGAIN!");
continue;
}
if(array[ix][iy] != ' ') {
writeln("\nERROR! SHIP (", ix, ", ", iy, ") ALREADY EXISTS!");
writeln("TRY AGAIN!\n");
continue;
}
array[ix][iy] = '1';
i++;
}
}
// randomizing enemy's ships
void initEnemyShipPos(ref char[5][5] array) {
int i = 0;
while(i < NUM_SHIPS) {
int x = uniform(0, array.length.to!int);
int y = uniform(0, array.length.to!int);
if(array[x][y] != ' ') {
continue;
}
array[x][y] = '1';
i++;
}
}
void enemyAttack(ref char[5][5] array, ref int ships_destroyed) {
while(true) {
int x = uniform(0, array.length.to!int);
int y = uniform(0, array.length.to!int);
// if enemy has already attacked this position, go to the beginig of the loop
if(array[x][y] == 'x' || array[x][y] == 'o') {
continue;
}
// if ship is found, destroy the ship
if(array[x][y] == '1') {
array[x][y] = 'x';
ships_destroyed++;
} else {
array[x][y] = 'o'; // otherwise, mark it with 'o'
}
break;
}
}
// printing the entire array in a table-like format
void display(char[5][5] array) {
write(" ");
for(int i = 0; i < array.length; i++) {
write(" ", i); // '\t' character means tab
}
writeln();
writeln("_ _ _ _ _ _ _ _ _ _ _ _");
for(int i = 0; i < array.length; i++) {
write(i, " ");
for(int j = 0; j < array[i].length; j++) {
write(" | ", array[i][j]);
}
writeln();
writeln("_ _ _ _ _ _ _ _ _ _ _ _");
}
writeln();
writeln();
}