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

📄 bowl.c

📁 LTris a tetris clone for Linux
💻 C
📖 第 1 页 / 共 4 页
字号:
}/*====================================================================Add a single tile at a random position so that it doesn't hit the current block nor leads to game over nor completes a line.====================================================================*/void bowl_add_tile( Bowl *bowl ){    int j, k;    int added = 0;    int i = rand() % bowl->w;    int checks = 0;    int hole;    while ( checks < 10 ) {        i++; checks++;        if ( i == bowl->w ) i = 0;        /* get first free tile in column */        if ( bowl->contents[i][1] != -1 )            continue;        else            j = 1;        while ( j + 1 < bowl->h && bowl->contents[i][j + 1] == -1 )             j++;        /* add tile and test if this hits the block if so remove and try another one */        bowl_set_tile( bowl, i, j, 9 );        if ( !bowl_validate_block_pos( bowl, bowl->block.x, bowl->block.check_y, bowl->block.rot_id, 0 ) ) {            bowl_set_tile( bowl, i, j, -1 );            continue;        }        /* if this line was completed deny, too */        hole = 0;        for ( k = 0; k < bowl->w; k++ )            if ( bowl->contents[k][j] == -1 ) {                hole = 1;                break;            }        if ( !hole ) {            bowl_set_tile( bowl, i, j, -1 );            continue;        }        /* position worked out! */        added = 1;        bowl_draw_tile( bowl, i, j );        break;    }    /* help shadow may have changed */    if ( added )        bowl_compute_help_pos( bowl );}/*====================================================================Add a line at the bottom of a bowl and return False if bowl is filled to the top. If the block position becomes invalid by thismove it's positioned one up.====================================================================*/int bowl_add_line( Bowl * bowl, int wanted_holes ){    int i, j, holes = 0, hole_x;    /* if the first line containts a tile the game is over! */    for ( i = 0; i < bowl->w; i++ )        if ( bowl->contents[i][0] != -1 )            return 0;    /* move all lines one up */    for ( j = 0; j < bowl->h - 1; j++ )        for ( i = 0; i < bowl->w; i++ )            bowl_set_tile( bowl, i, j, bowl->contents[i][j + 1] );    /* add a random line */    for ( i = 0; i < bowl->w; i++ )        bowl_set_tile( bowl, i, bowl->h - 1, rand() % BLOCK_TILE_COUNT );    /* add holes */    while ( holes < wanted_holes ) {        hole_x = rand() % bowl->w;        if ( bowl->contents[hole_x][bowl->h - 1] != -1 ) {            bowl_set_tile( bowl, hole_x, bowl->h - 1, -1 );            holes++;        }    }    /* check if block position became invalid */    if ( !bowl_validate_block_pos( bowl, bowl->block.x, bowl->block.check_y, bowl->block.rot_id, 0 ) ) {        bowl->block.y = bowl->block.check_y / bowl->block_size - 1;        bowl->block.check_y = bowl->block.y * bowl->block_size;        bowl->block.cur_y = bowl->block.check_y;    }    /* update helping shadow */    bowl_compute_help_pos( bowl );    return 1;}/*====================================================================Initate final animation.====================================================================*/void bowl_final_animation( Bowl *bowl ) {    int i, j, k;    if ( bowl->blind ) return;        for ( j = 0; j < bowl->h; j++ )        for ( i = 0, k = 1; i < bowl->w; i++, k++ )            if ( bowl->contents[i][j] != -1 )                shrapnell_create( bowl->sx + i * bowl->block_size, bowl->sy + j * bowl->block_size, bowl->block_size, bowl->block_size, 0, -0.05, 0, 0.0002 );}/*====================================================================Finish game and set game over.====================================================================*/void bowl_finish_game( Bowl *bowl ){    float score_mod = 0;    bowl->game_over = 1;    bowl->hide_block = 1;    bowl_final_animation( bowl );    bowl->use_figures = 0;    bowl_reset_contents( bowl );    bowl_draw_contents( bowl );    bowl->font->align = ALIGN_X_CENTER | ALIGN_Y_CENTER;    write_text( bowl->font,  offscreen, bowl->sx + bowl->sw / 2, bowl->sy + bowl->sh / 2, "Game Over", OPAQUE );    write_text( bowl->font, sdl.screen, bowl->sx + bowl->sw / 2, bowl->sy + bowl->sh / 2, "Game Over", OPAQUE );#ifdef SOUND    if ( !bowl->mute ) sound_play( bowl->wav_explosion );#endif        /* gain the bonus score */    if ( !config.preview || bowl->preview_center_sx == -1 )        score_mod += 0.15;    if ( config.gametype != 2 )        score_mod += 0.015 * config.starting_level;    if ( config.expert )	score_mod += 1.0;    counter_add( &bowl->score, (int)( score_mod * counter_get( bowl->score )) );}/*====================================================================Actually insert block and remove a line if needed, create shrapnells, give score etc====================================================================*/void bowl_insert_block( Bowl *bowl ){    int i, j, l;    int line_y[4];    int line_count;    int line_score;    int full;    int old_level;    int send_count;    int shr_type;    int py;    /* move block y up so it gets to the first free place */    py = bowl->block.y * bowl->block_size;    while ( !bowl_validate_block_pos( bowl, bowl->block.x, py, bowl->block.rot_id, 0 ) )        py -= bowl->block_size;    bowl->block.y = py / bowl->block_size;    /* insert and check if block is out of screen */    for ( i = 0; i < 4; i++ ) {        for ( j = 0; j < 4; j++ ) {            if ( block_masks[bowl->block.id].mask[bowl->block.rot_id][i][j] ) {                if ( bowl->block.y + j < 0 ) bowl->game_over = 1;                if ( bowl->block.x + i >= 0 && bowl->block.x + i < bowl->w )                    if ( bowl->block.y + j >= 0 && bowl->block.y + j < bowl->h )                        bowl_set_tile( bowl, bowl->block.x + i, bowl->block.y + j, bowl->block.id );            }        }    }    /* draw block to offscreen for shrapnells */    bowl_draw_contents( bowl );#ifdef SOUND    if ( !bowl->mute ) sound_play( bowl->wav_stop );#endif        /* if game over just explode everything and return */    if ( bowl->game_over ) {          bowl_finish_game( bowl );        return;    }    /* check for completed lines */    line_count = 0;    for ( j = 0; j < bowl->h; j++ ) {        full = 1;        for ( i = 0; i < bowl->w; i++ ) {            if ( bowl->contents[i][j] == -1 ) {                full = 0;                break;            }        }        if ( full )            line_y[line_count++] = j;    }    for ( j = 0; j < line_count; j++ )        for ( i = 0; i < bowl->w; i++ ) {            for ( l = line_y[j]; l > 0; l-- )                bowl_set_tile( bowl, i, l, bowl->contents[i][l - 1] );            bowl_set_tile( bowl, i, 0, -1 );        }    /* tetris? tell him! */#ifdef SOUND    if ( line_count == 4 )        if ( !bowl->mute ) sound_play( bowl->wav_excellent );#endif    /* create shrapnells */    shr_type = rand() % SHR_TYPE_COUNT;    if ( !bowl->blind )        for ( j = 0; j < line_count; j++ )             shrapnells_create( bowl->sx, bowl->sy + line_y[j] * bowl->block_size, bowl->sw, bowl->block_size, shr_type );#ifdef SOUND    if ( line_count > 0 )        if ( !bowl->mute ) sound_play( bowl->wav_explosion );#endif        /* add score */    line_score = 100 * ( bowl->level + 1 );    for ( i = 0; i < line_count; i++ ) {        counter_add( &bowl->score, line_score );        line_score *= 2;    }    /* line and level update */    old_level = bowl->lines / 10;    bowl->lines += line_count;    if ( old_level != bowl->lines / 10 ) {#ifdef SOUND        if ( !bowl->mute ) sound_play( bowl->wav_nextlevel );#endif            /* new level */        bowl->level++;        bowl_set_vert_block_vel( bowl );        /* in advanced game reset bowl contents */        if ( config.gametype == 2 ) {            bowl_reset_contents( bowl );        }    }    /* reset delay of add_line/tile */    if ( line_count && ( bowl->add_lines || bowl->add_tiles ) && bowl->dismantle_saves )        delay_reset( &bowl->add_delay );    /* update offscreen&screen */    bowl->draw_contents = 1;    /* send completed lines to all other bowls */    if ( line_count > 1 ) {       send_count = line_count;       if ( !config.send_all )           send_count--;       if ( line_count == 4 && config.send_tetris )           send_count = 4;        for ( i = 0; i < BOWL_COUNT; i++ )            if ( bowls[i] && bowls[i] != bowl && !bowls[i]->game_over) {                for ( j = 0; j < send_count; j++ )                    if ( !bowl_add_line( bowls[i], config.holes ) ) {                        bowl_finish_game( bowls[i] );                        return;                    }                bowls[i]->draw_contents = 1;            }    }    /* get next block */    bowl_create_next_block( bowl );}/*====================================================================Check if the block collides at the current position and insert itif so.====================================================================*/int bowl_check_block_insertion( Bowl *bowl ){    int i, j;    int cy;    int collision = 0;    /* check the bottom of the lowest tile in pixel_contents      * if we drop block-by-block don't use the current position but     * compute the lowest pixel from bowl position so we may     * move a block below a neighbored one.     */    for ( i = 0; i < 4; i++ ) {        for ( j = 3; j >= 0; j-- )            if ( bowl->block.x + i >= 0 && bowl->block.x + i < bowl->w )                if ( block_masks[bowl->block.id].mask[bowl->block.rot_id][i][j] ) {                    /* if the lowest tile is still out of screen skip this column */                    if ( bowl->block.y + j < 0 ) break;                    /* check tile hit by tile bottom */                    cy = (int)bowl->block.check_y + j * bowl->block_size + bowl->block_size - 1/* last pixel of tile */;                    if ( cy < 0 ) break;                    if ( bowl->pixel_contents[bowl->block.x + i][cy] != -1 )                        collision = 1;                    /* if the bowl bottom is hit it is a collision as well */                    if ( cy >= bowl->sh ) collision = 1;                    break;                }        if ( collision ) break;    }    if ( !collision ) return 0;    /* clear the down key so we don't move the next block too far */    if ( bowl->controls && keystate[bowl->controls->down] && config.clear_keystate )        keystate[bowl->controls->down] = 0;    /* insert, gain score bla bla bla */    bowl_insert_block( bowl );    return 1;}/*====================================================================Drop block in one p-cycle.====================================================================*/void bowl_drop_block( Bowl *bowl ){    while ( !bowl_check_block_insertion( bowl ) ) {        bowl->block.cur_y += bowl->block_size >> 1;        bowl->block.y = (int)bowl->block.cur_y / bowl->block_size;        /* update check y */        if ( config.block_by_block )            bowl->block.check_y = bowl->block.y * bowl->block_size;        else            bowl->block.check_y = (int)bowl->block.cur_y;    }    bowl->stored_key = -1;}/*====================================================================Return True if CPU may drop/move down.====================================================================*/int bowl_cpu_may_move_down( Bowl *bowl ){    if ( !bowl->controls && bowl->cpu_down && bowl->block.x == bowl->cpu_dest_x && bowl->block.rot_id == bowl->cpu_dest_rot )        return 1;    return 0;}int bowl_cpu_may_drop( Bowl *bowl ){/*    if ( config.cpu_diff == 5 && bowl_cpu_may_move_down( bowl ) )        return 1;*/    return 0;}/*====================================================================Publics====================================================================*//*====================================================================Load figures from file.====================================================================*/void bowl_load_figures() {    int i, j, k;    FILE *file = 0;    char path[512];    char buf[128];    sprintf( path, "%s/figures", SRC_DIR );    if ( ( file = fopen( path, "r" ) ) == 0 ) {        fprintf( stderr, "Cannot load figures from '%s'.\n", path );        return;    }    for ( i = 0; i < FIGURE_COUNT; i++ )        for ( j = 0; j < BOWL_HEIGHT; j++ ) {            if ( feof( file ) ) {                fprintf( stderr, "Unexpected end of file when trying to read line %i of figure %i in '%s'.\n", j, i, path );                return;            }            fread( buf, sizeof( char ), BOWL_WIDTH + 1, file ); buf[BOWL_WIDTH] = 0;            for ( k = 0; k < BOWL_WIDTH; k++ ) {                if ( buf[k] == 32 )                    figures[i][k][j] = -1;                else                    figures[i][k][j] = buf[k] - 97;            }        }    fclose( file );}/*====================================================================Initate block masks.====================================================================*/void bowl_init_block_masks() {	block_masks[0].rx = 0;	block_masks[0].ry = 0;	block_masks[0].id = 0;	memset(block_masks[0].mask, 0, sizeof( int ) * 4 * 4 * 4 );	block_masks[0].mask[0][1][1] = 1;	block_masks[0].mask[0][2][1] = 1;	block_masks[0].mask[0][1][2] = 1;	block_masks[0].mask[0][2][2] = 1;	block_masks[0].mask[1][1][1] = 1;	block_masks[0].mask[1][2][1] = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -