add my battleships

This commit is contained in:
Benno Fünfstück 2020-01-31 14:55:34 +01:00
parent e5213ca5fc
commit d3f188e86b
2 changed files with 233 additions and 54 deletions

View file

@ -1,10 +1,15 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <ctype.h>
enum { enum {
N_SHIPS, BOARD_SIZE = 10,
WIDTH = 8, };
HEIGHT = 8,
struct state {
char board[BOARD_SIZE][BOARD_SIZE];
int game_over;
}; };
struct position { struct position {
@ -12,69 +17,163 @@ struct position {
int y; int y;
}; };
struct ship { enum orientation {
int length; O_VERTICAL,
O_HORIZONTAL
};
struct boat {
enum orientation orientation;
/** left upper corner */
struct position position; struct position position;
char sunken;
char alignment; int length;
char *hits;
}; };
struct game_state { struct position read_position(void);
char running;
char board[WIDTH][HEIGHT]; struct boat generate_boat(int length);
struct ship ships[N_SHIPS];
struct state generate_state(void);
void display_state(struct state state);
int valid_position(struct position p);
/**
* Simulates one step of battleship.
*
* Performs the following steps:
*
* - apply hit to board
* - check sunken ships
* - check game over
*/
void update_state(struct state * state, struct position hit);
enum target {
T_WATER,
T_BOAT,
}; };
struct ship create_ship(int length, struct position position); enum target check_hit(struct state state, struct position hit);
void delete_ship(struct ship ship);
void hit(struct game_state *game_state, struct position position);
struct game_state init_game_state();
void deinit_game_state(struct game_state *game_state);
char check_win_condition(struct game_state *game_state);
struct position read_position();
int main(void) { int main(void) {
struct game_state game_state = init_game_state(); struct state state = generate_state();
while (game_state.running) {
struct position hit_position = read_position();
hit(&game_state, hit_position);
if (check_win_condition(&game_state)) {
game_state.running = 0;
printf("You win!");
}
}
deinit_game_state(&game_state);
return 0;
}
struct ship create_ship(int length, struct position position) { while (!state.game_over) {
struct ship ship = {.length = length, .position = position, .sunken = 0}; display_state(state);
ship.hits = calloc(length, sizeof *ship.hits);
return ship;
}
void delete_ship(struct ship ship) {
free(ship.hits);
}
void hit(struct game_state *game_state, struct position position); struct position hit = read_position();
struct game_state init_game_state() { /* game logic */
struct game_state game_state; update_state(&state, hit);
for (int i = 0; i < N_SHIPS; ++i) {
/* generate ship */
} }
} }
void deinit_game_state(struct game_state *game_state) { struct position read_position(void) {
for (int i = 0; i < N_SHIPS; ++i) { printf("enter coordinate: ");
delete_ship(game_state->ships[i]); while (1) {
char* line = NULL;
size_t size = 0;
getline(&line, &size, stdin);
fflush(stdout);
struct position position;
char col;
sscanf("%c%d", &col, &position.y);
free(line);
position.x = tolower(col) - 'a';
if (valid_position(position)) {
return position;
}
puts("invalid input!");
} }
} }
char check_win_condition(struct game_state *game_state); struct position random_position(void) {
struct position p;
p.x = rand() % BOARD_SIZE;
p.y = rand() % BOARD_SIZE;
return p;
}
struct position read_position(); enum orientation random_orientation(void) {
return (rand() % 2);
}
struct boat generate_boat(int length) {
struct boat b;
b.length = length;
b.position = random_position();
b.orientation = random_orientation();
return b;
}
int valid_position(struct position p) {
return (p.x >= 0) && (p.x < BOARD_SIZE) && (p.y >= 0) && (p.y < BOARD_SIZE);
}
int place_boat(struct state * state, struct boat boat, char c) {
int dx = (boat.orientation == O_VERTICAL) ? 1 : 0;
int dy = (boat.orientation == O_HORIZONTAL) ? 1 : 0;
struct position curpos = boat.position;
for (int i = 0; i < boat.length; ++i) {
if (!valid_position(curpos)) return 0;
if (state->board[curpos.y][curpos.x] != 0) return 0;
if (c) {
state->board[curpos.y][curpos.x] = c;
}
curpos.x += dx;
curpos.y += dy;
}
return 1;
}
const int BOAT_LENGTHS[] = { 5, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
struct state generate_state(void) {
struct state state;
memset(state.board, 0, BOARD_SIZE*BOARD_SIZE);
state.game_over = 0;
// generate some boats
char boat_char = 'A';
for (size_t i = 0; i < sizeof(BOAT_LENGTHS) / sizeof(BOAT_LENGTHS[0]); ++i) {
int length = BOAT_LENGTHS[i];
struct boat boat;
do {
boat = generate_boat(length);
} while(!place_boat(&state, boat, '\0'));
place_boat(&state, boat, boat_char);
boat_char++;
}
return state;
}
void display_state(struct state state) {
for (int y = 0; y < BOARD_SIZE; ++y) {
for (int x = 0; x < BOARD_SIZE; ++x) {
if (state.board[y][x]) {
printf("%c", state.board[y][x]);
} else {
printf("~");
}
}
printf("\n");
}
puts("---");
}
void update_state(struct state * state, struct position hit) {
}

80
battleships_manuel.c Normal file
View file

@ -0,0 +1,80 @@
#include <stdio.h>
#include <stdlib.h>
enum {
N_SHIPS,
WIDTH = 8,
HEIGHT = 8,
};
struct position {
int x;
int y;
};
struct ship {
int length;
struct position position;
char sunken;
char alignment;
char *hits;
};
struct game_state {
char running;
char board[WIDTH][HEIGHT];
struct ship ships[N_SHIPS];
};
struct ship create_ship(int length, struct position position);
void delete_ship(struct ship ship);
void hit(struct game_state *game_state, struct position position);
struct game_state init_game_state();
void deinit_game_state(struct game_state *game_state);
char check_win_condition(struct game_state *game_state);
struct position read_position();
int main(void) {
struct game_state game_state = init_game_state();
while (game_state.running) {
struct position hit_position = read_position();
hit(&game_state, hit_position);
if (check_win_condition(&game_state)) {
game_state.running = 0;
printf("You win!");
}
}
deinit_game_state(&game_state);
return 0;
}
struct ship create_ship(int length, struct position position) {
struct ship ship = {.length = length, .position = position, .sunken = 0};
ship.hits = calloc(length, sizeof *ship.hits);
return ship;
}
void delete_ship(struct ship ship) {
free(ship.hits);
}
void hit(struct game_state *game_state, struct position position);
struct game_state init_game_state() {
struct game_state game_state;
for (int i = 0; i < N_SHIPS; ++i) {
/* generate ship */
}
}
void deinit_game_state(struct game_state *game_state) {
for (int i = 0; i < N_SHIPS; ++i) {
delete_ship(game_state->ships[i]);
}
}
char check_win_condition(struct game_state *game_state);
struct position read_position();