123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /***********************************************************************
- *
- * This file is a part of Minesweeper - a computer game
- * Copyright (C) 2020, 2021 Andrew Tokarskiy <tokarskiy.a@keemail.me>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- *************************************************************************/
- #include "mines.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #include <string.h>
- #define COMMAND_BUFFER_SIZE 32
- #define DEFAULT_WIDTH 10
- #define DEFAULT_HEIGHT 10
- #define DEFAULT_MINES 20
- void outputGameConsole(Game* const game) {
- int** statuses = game->statuses;
- {
- printf(" ");
- for (int j = 0; j < game->width; j++)
- {
- const int jLastDigit = (j + 1) % 10;
- printf("%d ", jLastDigit);
- }
- printf("\n");
- }
- for (int i = 0; i < game->height; i++) {
- const int iLastDigit = (i + 1) % 10;
- printf("%d ", iLastDigit);
-
- for (int j = 0; j < game->width; j++) {
- const int status = statuses[i][j];
- switch (status) {
- case STATUS_NULL:
- printf("_ ");
- break;
- case STATUS_FLAG:
- printf("F ");
- break;
- case STATUS_MINE:
- printf("M ");
- break;
- case 0:
- printf(" ");
- break;
- default:
- printf("%d ", status);
- break;
- }
- }
- printf("\n");
- }
- }
- typedef struct {
- int i;
- int j;
- ActionType command;
- int parseStatus;
- }
- Turn;
- Turn parseTurn(Game* const game, char* command, const int n) {
- char* token = strtok(command, " ");
- if (token == NULL) {
- Turn turn;
- turn.parseStatus = 0;
- return turn;
- }
- char* commandStr = token;
- token = strtok(NULL, " ");
- if (token == NULL) {
- Turn turn;
- turn.parseStatus = 0;
- return turn;
- }
- char* xStr = token;
- token = strtok(NULL, " ");
- if (token == NULL) {
- Turn turn;
- turn.parseStatus = 0;
- return turn;
- }
- char* yStr = token;
- const int x = atoi(xStr);
- const int y = atoi(yStr);
- if (x <= 0 || x > game->width || y <= 0 || y > game->height) {
- Turn turn;
- turn.parseStatus = 0;
- return turn;
- }
- ActionType type;
- if (strcmp(commandStr, "flag") == 0) {
- type = MarkMine;
- }
- else if (strcmp(commandStr, "click") == 0) {
- type = Click;
- }
- else {
- Turn turn;
- turn.parseStatus = 0;
- return turn;
- }
- Turn turn;
- turn.i = y - 1;
- turn.j = x - 1;
- turn.command = type;
- turn.parseStatus = 1;
- return turn;
- }
- typedef struct {
- int width;
- int height;
- int mines;
- } InitData;
- InitData parseArgs(char* args[], int n) {
- InitData data;
- data.width = DEFAULT_WIDTH;
- data.height = DEFAULT_HEIGHT;
- data.mines = DEFAULT_MINES;
- int i = 1;
- while (i < n - 1) {
- if (strcmp("--width", args[i]) == 0) {
- const int w = atoi(args[i + 1]);
- if (w > 0) {
- data.width = w;
- }
- i++;
- }
- if (strcmp("--height", args[i]) == 0) {
- const int h = atoi(args[i + 1]);
- if (h > 0) {
- data.height = h;
- }
- i++;
- }
- if (strcmp("--mines", args[i]) == 0) {
- const int m = atoi(args[i + 1]);
- if (m > 0) {
- data.mines = m;
- }
- i++;
- }
- i++;
- }
- return data;
- }
- void printGreetings() {
- printf("--- MINESWEEPER ---\n");
- printf("\n");
- printf("How to play: \n");
- printf(" click <x> <y>: click on cell with coords x and y.\n");
- printf(" flag <x> <y>: flag mine on cell with coords x and y.\n");
- printf("Numeration of coords starts from 1\n");
- printf("\n");
- printf("Good luck!\n");
- }
- int main(int argc, char* argv[]) {
- char command[COMMAND_BUFFER_SIZE];
- printGreetings();
- srand(time(NULL));
- const InitData parse = parseArgs(argv, argc);
- Game* game = initGame(parse.height, parse.width, parse.mines);
- outputGameConsole(game);
- while (1) {
- printf("> ");
- fgets(command, COMMAND_BUFFER_SIZE, stdin);
- const Turn turnData = parseTurn(game, command, COMMAND_BUFFER_SIZE);
- if (turnData.parseStatus == 0) {
- printf("Error!\n");
- continue;
- }
- ActionResult actionStatus = action(game, turnData.i, turnData.j, turnData.command);
- outputGameConsole(game);
- if (actionStatus == Lose) {
- printf("Lose...\n");
- break;
- }
- if (actionStatus == Win) {
- printf("WIN!!!\n");
- break;
- }
- }
- freeGame(game);
- }
|