⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 np_board.cpp

📁 需要clanlib 库 这个改进版的 在linux 很好玩 但是一定要有clanlib
💻 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 + -