📄 np_board.cpp
字号:
#include "NP_core.h"NP_board::NP_board() {}NP_board::NP_board( CL_ResourceManager *_resources, int _base_x, int _base_y, int _next_x, int _next_y, int _speed, int _bad_units, int _seed) : resources(_resources), base_x(_base_x), base_y(_base_y), next_x(_next_x), next_y(_next_y), speed(_speed), num_bad_units(_bad_units) { reset_game(_seed);}int NP_board::myrand() { int now_rand = (25173 * last_rand + 13849) % 65536; return last_rand = now_rand;}void NP_board::reset_game(int _seed){ memset(board, 0, sizeof(board)); last_rand = _seed; state = waiting; next_state = waiting; block_active = false; set_speed(speed); slot_timer = timer.sig_timer().connect(this, &NP_board::on_timer); timer.enable(); next_face[0] = NP_unit_face(myrand() % 5 + 1); next_face[1] = NP_unit_face(myrand() % 5 + 1); combo = 0; cnt_eliminated = 0; num_bad_units = 0; for (int i = 1; i <= 4; i++) { string tmp = "Game/Sound/sample_combo0"; tmp[tmp.size() - 1] += i; sample_combo[i] = CL_SoundBuffer(tmp, resources); }}NP_board::~NP_board() { }int NP_board::get_speed() { return speed;}void NP_board::set_speed(int _speed) { if (_speed > 9) speed = 9; else speed = _speed; timer.set_interval(1000 - speed * 100);}void NP_board::on_timer() { if (get_state() == falling) { block_move_down(); }}void NP_board::new_block(NP_unit_face face[2]) { block = NP_block(resources, 0, face, 0, 2); next_state = falling; block_active = true; combo = 0;}NP_board_state NP_board::get_state() { return state;}void NP_board::block_rotate() { if (get_state() == falling) block.rotate(*this); next_state = state;}void NP_board::block_move_down() { if (get_state() == falling) { if (!block.move(*this, 1, 0)) { next_state = adjusting; return; } } next_state = state;}void NP_board::block_move_left() { if (get_state() == falling) block.move(*this, 0, -1); next_state = state;}void NP_board::block_move_right() { if (get_state() == falling) block.move(*this, 0, 1); next_state = state;}void NP_board::adjust() { //let the units fall down if (block_active) { block_active = false; block.stick_to(*this); block.disable(); next_state = adjusting; } else { //check game_over for (int i = 0; i < 2; i++) for (int j = 0; j < BOARD_WIDTH; j++) if (board[i][j] != blank && board[i][j] != bad) { next_state = game_over; return; } //wait for units dropping bool waiting = false; for (int i = BOARD_HEIGHT - 1; i >= 0 && !waiting; i--) for (int j = BOARD_WIDTH - 1; j >= 0 && !waiting; j--) if (unit_board[i][j].get_state() == dropping) waiting = true; if (waiting) { next_state = adjusting; return; } //play combo sample if (combo >= 2 && combo <= 5) sample_combo[combo - 1].play(); else if (combo > 5) sample_combo[4].play(); //drop units bool flag = false; for (int i = BOARD_HEIGHT - 2; i >= 0; i--) for (int j = BOARD_WIDTH - 1; j >= 0; j--) if (board[i][j] != blank && board[i + 1][j] == blank) { flag = true; unit_board[i][j].drop(*this); unit_board[i + 1][j] = unit_board[i][j]; unit_board[i][j] = NP_unit(); board[i + 1][j] = board[i][j]; board[i][j] = blank; } if (!flag) { next_state = eliminating; } else next_state = adjusting; }}int bfs(NP_unit_face tmp[BOARD_HEIGHT][BOARD_WIDTH], int sx, int sy) { const int dx[] = {-1, 0, 1, 0}; const int dy[] = {0, 1, 0, -1}; struct node { int x, y; }; node q[BOARD_HEIGHT * BOARD_WIDTH]; int visited[BOARD_HEIGHT][BOARD_WIDTH]; memset(visited, 0, sizeof(visited)); int l, r; q[0].x = sx, q[0].y = sy; visited[sx][sy] = 1; for (l = 0, r = 1; l < r; l++) { int nx = q[l].x, ny = q[l].y; for (int i = 0; i < 4; i++) { if (nx + dx[i] >= 0 && nx + dx[i] < BOARD_HEIGHT && ny + dy[i] >= 0 && ny + dy[i] < BOARD_WIDTH && !visited[nx + dx[i]][ny + dy[i]] && tmp[nx + dx[i]][ny + dy[i]] == tmp[sx][sy]) { q[r].x = nx + dx[i]; q[r].y = ny + dy[i]; visited[q[r].x][q[r].y] = 1; r++; } } } int ret = 0; if (r >= 4) for (int i = 0; i < r; i++) tmp[q[i].x][q[i].y] = NP_unit_face(-1); if (r >= 4) return r; else return 0;}int NP_board::to_bad_units(int x) { return max(0, x - 3 + BOARD_WIDTH * (combo - 1));}int NP_board::to_score(int x) { return (BOARD_WIDTH + x) * combo * combo;}void NP_board::eliminate() { const int dx[] = {-1, 0, 1, 0}; const int dy[] = {0, 1, 0, -1}; bool tdead = true; for (int i = 0; i < BOARD_HEIGHT && tdead; i++) for (int j = 0; j < BOARD_WIDTH && tdead; j++) if (unit_board[i][j].get_state() == dying) tdead = false; if (!tdead) { next_state = eliminating; return; } NP_unit_face tmp[BOARD_HEIGHT][BOARD_WIDTH]; memcpy(tmp, board, sizeof(board)); // if four or more units are together, they can be eliminated int tmp_cnt_eliminated = 0; for (int i = 0; i < BOARD_HEIGHT; i++) for (int j = 0; j < BOARD_WIDTH; j++) if (tmp[i][j] != NP_unit_face(-1) && tmp[i][j] != blank && tmp[i][j] != bad) { tmp_cnt_eliminated += bfs(tmp, i, j); } // add combo and cnt_eliminated if (tmp_cnt_eliminated >= 4) { combo++; } for (int i = 0; i < BOARD_HEIGHT; i++) for (int j = 0; j < BOARD_WIDTH; j++) if (tmp[i][j] == NP_unit_face(-1) && board[i][j] != NP_unit_face(-1)) { for (int k = 0; k < 4; k++) { if (i + dx[k] >= 0 && i + dx[k] < BOARD_HEIGHT && j + dy[k] >= 0 && j + dy[k] < BOARD_WIDTH) { if (tmp[i + dx[k]][j + dy[k]] == bad) tmp[i + dx[k]][j + dy[k]] = NP_unit_face(-2); } } } for (int i = 0; i < BOARD_HEIGHT; i++) for (int j = 0; j < BOARD_WIDTH; j++) if (tmp[i][j] == NP_unit_face(-2)) tmp[i][j] = NP_unit_face(-1); for (int i = 0; i < BOARD_HEIGHT; i++) for (int j = 0; j < BOARD_WIDTH; j++) if (tmp[i][j] == NP_unit_face(-1)) board[i][j] = NP_unit_face(-1); bool exit_eliminating = true; for (int i = 0; i < BOARD_HEIGHT && exit_eliminating; i++) for (int j = 0; j < BOARD_WIDTH && exit_eliminating; j++) if (tmp[i][j] == NP_unit_face(-1)) exit_eliminating = false; if (exit_eliminating) { if (num_bad_units > 0) next_state = adding_bad_units; else next_state = start; return; } for (int i = 0; i < BOARD_HEIGHT; i++) for (int j = 0; j < BOARD_WIDTH; j++) if (tmp[i][j] == NP_unit_face(-1)) { if (unit_board[i][j].get_state() == normal) unit_board[i][j].set_state(dying); if (unit_board[i][j].get_state() == dead) { if (board[i][j] != bad) cnt_eliminated++; unit_board[i][j] = NP_unit(); board[i][j] = blank; } } bool flag = true; for (int i = 0; i < BOARD_HEIGHT && flag; i++) for (int j = 0; j < BOARD_WIDTH && flag; j++) if (unit_board[i][j].get_state() == dying) flag = false; if (flag) next_state = adjusting; else next_state = eliminating;}void NP_board::start_game() { next_state = adding_bad_units;}void NP_board::add_bad_units(int num) { num_bad_units += num;}void NP_board::add_bad_units_actual() { num_bad_units = max(0, num_bad_units - to_bad_units(cnt_eliminated)); int tmp[BOARD_WIDTH]; memset(tmp, 0, sizeof(tmp)); if (num_bad_units >= BOARD_WIDTH) { for (int i = 0; i < BOARD_WIDTH; i++) tmp[i] = 1; num_bad_units -= BOARD_WIDTH; } else { for (int i = 0; i < num_bad_units; i++) tmp[i] = 1; for (int q = 0; q < 100; q++) { int i = rand() % BOARD_WIDTH; int j = rand() % BOARD_WIDTH; swap(tmp[i], tmp[j]); } num_bad_units = 0; } for (int i = 0; i < BOARD_WIDTH; i++) if (tmp[i] == 1) { board[2][i] = bad; unit_board[2][i] = NP_unit(resources, bad, 2, i); } next_state = adjusting;}void NP_board::update() { if (block_active) block.update(*this); for (int i = 0; i < BOARD_HEIGHT; i++) for (int j = 0; j < BOARD_WIDTH; j++) if (board[i][j] != blank) unit_board[i][j].update(*this); if (next_state == waiting) { //waiting } else if (next_state == adding_bad_units) { add_bad_units_actual(); } else if (next_state == start) { if (cnt_eliminated > 0) { sig_send_bad_units(max(0, to_bad_units(cnt_eliminated) - num_bad_units)); sig_get_score(to_score(cnt_eliminated)); } cnt_eliminated = 0; combo = 0; new_block(next_face); for (int i = 0; i < 2; i++) next_face[i] = NP_unit_face(myrand() % 5 + 1); next_block = NP_block(resources, 0, next_face, 0, 2); } else if (next_state == falling) { //fall } else if (next_state == adjusting) { adjust(); } else if (next_state == eliminating) { eliminate(); } else if (next_state == game_over) { sig_game_over(); } state = next_state;}void NP_board::draw() { if (block_active) { block.draw(*this); next_block.draw(next_x, next_y); } for (int i = 2; i < BOARD_HEIGHT; i++) for (int j = 0; j < BOARD_WIDTH; j++) if (board[i][j] != blank) unit_board[i][j].draw(*this);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -