add my battleships
This commit is contained in:
parent
e5213ca5fc
commit
d3f188e86b
203
battleships.c
203
battleships.c
|
@ -1,10 +1,15 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
enum {
|
||||
N_SHIPS,
|
||||
WIDTH = 8,
|
||||
HEIGHT = 8,
|
||||
BOARD_SIZE = 10,
|
||||
};
|
||||
|
||||
struct state {
|
||||
char board[BOARD_SIZE][BOARD_SIZE];
|
||||
int game_over;
|
||||
};
|
||||
|
||||
struct position {
|
||||
|
@ -12,69 +17,163 @@ struct position {
|
|||
int y;
|
||||
};
|
||||
|
||||
struct ship {
|
||||
int length;
|
||||
enum orientation {
|
||||
O_VERTICAL,
|
||||
O_HORIZONTAL
|
||||
};
|
||||
|
||||
struct boat {
|
||||
enum orientation orientation;
|
||||
|
||||
/** left upper corner */
|
||||
struct position position;
|
||||
char sunken;
|
||||
char alignment;
|
||||
char *hits;
|
||||
|
||||
int length;
|
||||
};
|
||||
|
||||
struct game_state {
|
||||
char running;
|
||||
char board[WIDTH][HEIGHT];
|
||||
struct ship ships[N_SHIPS];
|
||||
struct position read_position(void);
|
||||
|
||||
struct boat generate_boat(int length);
|
||||
|
||||
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);
|
||||
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();
|
||||
enum target check_hit(struct state state, struct position hit);
|
||||
|
||||
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 state state = generate_state();
|
||||
|
||||
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);
|
||||
}
|
||||
while (!state.game_over) {
|
||||
display_state(state);
|
||||
|
||||
void hit(struct game_state *game_state, struct position position);
|
||||
struct position hit = read_position();
|
||||
|
||||
struct game_state init_game_state() {
|
||||
struct game_state game_state;
|
||||
for (int i = 0; i < N_SHIPS; ++i) {
|
||||
/* generate ship */
|
||||
/* game logic */
|
||||
update_state(&state, hit);
|
||||
}
|
||||
}
|
||||
|
||||
void deinit_game_state(struct game_state *game_state) {
|
||||
for (int i = 0; i < N_SHIPS; ++i) {
|
||||
delete_ship(game_state->ships[i]);
|
||||
struct position read_position(void) {
|
||||
printf("enter coordinate: ");
|
||||
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
80
battleships_manuel.c
Normal 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();
|
Loading…
Reference in a new issue