#include "board.h" #include "colors.h" std::string ship_names[] = { "Aircraft Carrier", "Battleship", "Cruiser", "Submarine", "Destroyer" }; int ship_sizes[] = { 5, 4, 3, 3, 2 }; board::board(int side) : side(side) { int i, j, k; for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { guesses[i][j] = 0; } } for (i = 0; i < 5; i++) { while (true) { int dir = randrange(0, 3); int x = randrange(0, 9); int y = randrange(0, 9); int dx = 0; int dy = 0; if (dir == UP) { dy = -1; } else if (dir == DOWN) { dy = 1; } else if (dir == LEFT) { dx = -1; } else if (dir == RIGHT) { dx = 1; } bool valid = true; for (j = 0; j < ship_sizes[i]; j++) { int tmpx = x + (j * dx); int tmpy = y + (j * dy); if (tmpx < 0 || tmpx > 9 || tmpy < 0 || tmpy > 9) { valid = false; break; } bool collides = false; for (k = 0; k < (int)ships.size(); k++) { if (ships[k]->contains(tmpx, tmpy)) collides = true; } if (collides) { valid = false; break; } } if (!valid) continue; ships.push_back(new ship(x, y, dir, ship_sizes[i], ship_names[i])); break; } } cursor_x = 0; cursor_y = 0; show_cursor = false; } board::board(int side, std::string &board_description) : side(side) { int i, j; for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { guesses[i][j] = 0; } } for (i = 0; i < 5; i++) { int y = board_description[(i * 3) + 0] - 'A'; int x = board_description[(i * 3) + 1] - '0'; int dir = board_description[(i * 3) + 2] - '0'; ships.push_back(new ship(x, y, dir, ship_sizes[i], ship_names[i])); } cursor_x = 0; cursor_y = 0; show_cursor = false; } std::string board::get_description() { std::string result; for (int i = 0; i < 5; i++) { result.push_back('A' + ships[i]->get_y()); result.push_back('0' + ships[i]->get_x()); result.push_back('0' + ships[i]->get_dir()); } return result; } board::~board() { for (int i = 0; i < (int)ships.size(); i++) { delete ships[i]; } ships.clear(); } bool board::has_lost() { for (int i = 0; i < (int)ships.size(); i++) { if (!ships[i]->is_sunk()) return false; } return true; } void board::make_move(std::string position) { int y = position[0] - 'A'; int x = position[1] - '1'; for (int i = 0; i < (int)ships.size(); i++) { if (ships[i]->contains(x, y)) ships[i]->hit(); } guesses[y][x] = true; } int board::get_position_color(int x, int y) { if (side == OPPONENT) { if (show_cursor && x == cursor_x && y == cursor_y) { return BG_GREEN; } if (guesses[y][x]) { for (int i = 0; i < (int)ships.size(); i++) { if (ships[i]->contains(x, y)) { return BG_RED; } } return BG_WHITE; } return BG_BLACK; } else { if (guesses[y][x]) { for (int i = 0; i < (int)ships.size(); i++) { if (ships[i]->contains(x, y)) { return BG_RED; } } return BG_WHITE; } else { for (int i = 0; i < (int)ships.size(); i++) { if (ships[i]->contains(x, y)) { return BG_BLACK; } } return BG_CYAN; } } } void board::draw() { int x_offset = 0; if (side == PLAYER) { x_offset = 22; } attron(COLOR_PAIR(TEXT_WHITE)); mvprintw(1, x_offset, " 1 2 3 4 5 6 7 8 9 10 "); for (int i = 0; i < 10; i++) { mvaddch(2 + i, x_offset, 'A' + i); } attroff(COLOR_PAIR(TEXT_WHITE)); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { int color = get_position_color(j, i); attron(COLOR_PAIR(color)); mvprintw(i+2, x_offset + 1 + (j*2), " "); attroff(COLOR_PAIR(color)); } } refresh(); } std::string board::get_move() { show_cursor = true; draw(); while(true) { int key = getch(); if (key == 'f') { break; } else if (key == KEY_UP) cursor_y--; else if (key == KEY_DOWN) cursor_y++; else if (key == KEY_LEFT) cursor_x--; else if (key == KEY_RIGHT) cursor_x++; else continue; cursor_x = std::min(9, cursor_x); cursor_x = std::max(0, cursor_x); cursor_y = std::min(9, cursor_y); cursor_y = std::max(0, cursor_y); draw(); } std::string move; move.push_back('A' + cursor_y); move.push_back('1' + cursor_x); show_cursor = false; return move; }