五子连珠

代码

/*
 * 玩法:wsad方向,空格选择,q退出
 */

#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <curses.h>

struct path_node {
    int row, col;
    int path;
    struct  path_node *next;
};

struct map_node {
    int y, x;
    char value;
    int path;
    int flag;
};

struct point {
    int row, col;
};

#define ROW         9
#define COL         9
#define MAX_PATH    ROW*COL
#define TICKER 150
#define CHAR_TYPE_NUM 5

#define VISITED     1
#define UNVISITED   0

#define CHAR_1      '1'
#define CHAR_2      '2'
#define CHAR_3      '3'
#define CHAR_4      '4'
#define CHAR_5      '5'
#define CHAR_NONE   ' '
#define CHAR_LINE_1     "-------------------"
#define CHAR_LINE_2     "| | | | | | | | | |"

#define bad_row(r)  ((r) < 0 || (r) > 8)
#define bad_col(c)  ((c) < 0 || (c) > 8)
#define arrive_end(r, c) ( ((r) == end_row) && ((c) == end_col) )
#define arrive_begin(r, c) ( ((r) == begin_row) && \
                            ((c) == begin_col) )

struct map_node map[ROW][COL];
char begin_char;
int no_path, blank_num;
int begin_row, begin_col, end_row, end_col, cursor_row, cursor_col;
struct path_node *head, *tail;
struct point blank_array[MAX_PATH];
char char_array[CHAR_TYPE_NUM] = {CHAR_1, CHAR_2, CHAR_3, CHAR_4, 
    CHAR_5};
struct point weiyi_around[4] = {{-1,0}, {0,1}, {1,0}, {0,-1}};
struct point weiyi_five[4][9] = {
    {{0, -4}, {0, -3}, {0, -2}, {0, -1}, {0, 0}, 
        {0, 1}, {0, 2}, {0, 3}, {0, 4}},
    {{-4, -4}, {-3, -3}, {-2, -2}, {-1, -1}, {0, 0}, 
        {1, 1}, {2, 2}, {3, 3}, {4, 4}},
    {{-4, 0}, {-3, 0}, {-2, 0}, {-1, 0}, {0, 0}, 
        {1, 0}, {2, 0}, {3, 0}, {4, 0}},
    {{-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}, {0, 0}, 
        {1, -1}, {2, -2}, {3, -3}, {4, -4}}
};

void init();
int set_ticker(int n_msec);
void sig_timer(int sig);
void play();
void show_path();
void find_path();
void reset_map_path();
void destroy_list();
void cal_path();
void init_map();
void init_screen();
void game_over();
void generate_new();
void move_up();
void move_down();
void move_left();
void move_right();
void clear_cursor();
void draw_cursor();
void init_blank_array();
int remove_five(int row, int col);
int set_ticker(int n_msec);

int main()
{
    init();
    while(1)
        play();
    return 0;
}

void play()
{
    char ch;
    int first = 1;

    while(1) {
        ch = getch();
        switch (ch) {
            case 'w':
                move_up();
                break;
            case 's':
                move_down();
                break;
            case 'a':
                move_left();
                break;
            case 'd':
                move_right();
                break;
            case ' ':
                if (first) {
                    first = 0;
                    begin_row = cursor_row;
                    begin_col = cursor_col;
                    begin_char = map[begin_row][begin_col].value;
                    draw_cursor();
                }
                else {
                    if (CHAR_NONE != 
                            map[cursor_row][cursor_col].value)
                        break;
                    first = 1;
                    end_row = cursor_row;
                    end_col = cursor_col;
                    find_path();

                    cursor_row = begin_row;
                    cursor_col = begin_col;
                    clear_cursor();
                    cursor_row = end_row;
                    cursor_col = end_col;
                    draw_cursor();
                }
                break;
            case 'q':
                game_over();
                break;
        }
    }
}

void move_up()
{
    clear_cursor();
    if (cursor_row > 0)
        cursor_row --;
    draw_cursor();
}

void move_down()
{
    clear_cursor();
    if (cursor_row < 8)
        cursor_row ++;
    draw_cursor();
}

void move_left()
{
    clear_cursor();
    if (cursor_col > 0)
        cursor_col --;
    draw_cursor();
}

void move_right()
{
    clear_cursor();
    if (cursor_col < 8)
        cursor_col ++;
    draw_cursor();
}

void draw_cursor()
{
    char c;

    move(map[cursor_row][cursor_col].y, 
            map[cursor_row][cursor_col].x);
    c = (char)inch();
    attron(A_STANDOUT);
    addch(c);
    refresh();
}

void clear_cursor()
{
    char c;

    move(map[cursor_row][cursor_col].y, 
            map[cursor_row][cursor_col].x);
    c = (char)inch();
    attroff(A_STANDOUT);
    addch(c);
    refresh();
}

void show_path()
{
    int i;

    cursor_row = begin_row;
    cursor_col = begin_col;
    set_ticker(200);
    while (!arrive_end(cursor_row, cursor_col));
    set_ticker(0);
    for (i = 0; i < blank_num; i ++) {
        if ((blank_array[i].row == end_row) && 
                (blank_array[i].col == end_col)) {
            blank_array[i].row = begin_row;
            blank_array[i].col = begin_col;
            break;
        }
    }
}

int remove_five(int row, int col)
{
    int i, j, k, r, c;

    for (i = 0; i < 4; i ++) {
        for (j = 0; j < 5; j ++) {
            for (k = j; k < j+5; k ++) {
                r = row + weiyi_five[i][k].row;
                c = col + weiyi_five[i][k].col;
                if (begin_char != map[r][c].value) 
                    break;
            }
            if (k >= j+5) {
                for (k = j; k < j+5; k ++) {
                    r = row + weiyi_five[i][k].row;
                    c = col + weiyi_five[i][k].col;
                    move(map[r][c].y, map[r][c].x);
                    attroff(A_STANDOUT);
                    addch(CHAR_NONE);
                    refresh();
                    map[r][c].value = CHAR_NONE;
                }
                return 1;
            }
        }
    }
    return 0;
}

void find_path()
{
    reset_map_path();
    no_path = 0;
    map[end_row][end_col].path = 0;
    map[end_row][end_col].flag = VISITED;
    head = (struct path_node *)malloc(sizeof(struct path_node));
    *head = (struct path_node){end_row, end_col, 0, NULL};
    tail = head;

    cal_path();
    if (!no_path) {
        show_path();
        map[begin_row][begin_col].value = CHAR_NONE;
        map[end_row][end_col].value = begin_char;
        if (!remove_five(end_row, end_col))
            generate_new();
    }
}

void destroy_list()
{
    struct path_node *p;

    while (head) {
        p = head;
        head = head->next;
        free(p);
    }
}

void cal_path()
{
    int i, r, c;
    struct path_node *p, *tmp;

    while (head) {
        p = head;
        for (i = 0; i < 4; i ++) {
            r = p->row + weiyi_around[i].row;
            c = p->col + weiyi_around[i].col;
            if ((bad_row(r)) || (bad_col(c)))
                continue;
            if (arrive_begin(r, c)) {
                no_path = 0;
                destroy_list();
                return;
            }
            if ((CHAR_NONE == map[r][c].value) && 
                    (UNVISITED == map[r][c].flag)) {
                map[r][c].path = p->path + 1;
                map[r][c].flag = VISITED;

                tmp = (struct path_node *)malloc
                    (sizeof(struct path_node));
                *tmp = (struct path_node){r, c, p->path+1, NULL};
                tail = tail->next = tmp;
            }
        }
        head = head->next;
        free(p);
    }
    no_path = 1;
    destroy_list();
}

void generate_new()
{
    int i, j, k, m, r, c;

    for (i = 0; i < 3; i ++) {
        k = rand() % blank_num;
        j = rand() % CHAR_TYPE_NUM;
        r = blank_array[k].row;
        c = blank_array[k].col;
        map[r][c].value = char_array[j];
        move(map[r][c].y, map[r][c].x);
        attroff(A_STANDOUT);
        addch(char_array[j]);
        refresh();
        remove_five(r, c);

        for (m = k+1; m < blank_num; m ++) {
            blank_array[m-1].row = blank_array[m].row;
            blank_array[m-1].col = blank_array[m].col;
        }
        blank_num --;
    }
    if (blank_num <= 1) {
        getch();
        game_over();
    }
}

void game_over()
{
    endwin();
    exit(0);
}

void sig_timer(int sig)
{
    int i, r, c;

    move(map[cursor_row][cursor_col].y, 
            map[cursor_row][cursor_col].x);
    addch(CHAR_NONE);
    refresh();
    clear_cursor();
    for (i = 0; i < 4; i ++) {
        r = cursor_row + weiyi_around[i].row;
        c = cursor_col + weiyi_around[i].col;
        if ((bad_row(r)) || (bad_col(c)))
            continue;
        if ((VISITED == map[r][c].flag) && 
                (map[r][c].path < map[cursor_row][cursor_col].path)) {
            cursor_row = r;
            cursor_col = c;
            break;
        }
    }
    move(map[cursor_row][cursor_col].y, 
            map[cursor_row][cursor_col].x);
    addch(begin_char);
    refresh();
    draw_cursor();
}

void init()
{
    initscr();
    cbreak();
    noecho();
    curs_set(0);
    srand(time(0));

    clear();
    init_map();
    init_screen();
    init_blank_array();
    generate_new();
    cursor_row = cursor_col = 0;
    signal(SIGALRM, sig_timer);
}

void init_blank_array()
{
    int i, j;

    blank_num = 0;
    for (i = 0; i < ROW; i ++) {
        for (j = 0; j < COL; j ++) {
            blank_array[blank_num ++] = (struct point){i, j};
        }
    }
}

void reset_map_path()
{
    int i, j;

    for (i = 0; i < ROW; i ++) {
        for (j = 0; j < COL; j ++) {
            map[i][j].path = MAX_PATH;
            map[i][j].flag = UNVISITED;
        }
    }   
}

void init_map()
{
    int i, j;

    for (i = 0; i < ROW; i ++) {
        for (j = 0; j < COL; j ++) {
            map[i][j] = (struct map_node)
            {i*2+1, j*2+1, CHAR_NONE, MAX_PATH, UNVISITED};
        }
    }
}

void init_screen()
{
    int i, j;

    move(0, 0);
    printw(CHAR_LINE_1);
    for (i = 1; i < ROW*2; i ++) {
        move(i, 0);
        printw(CHAR_LINE_2);
        i ++;
        move(i, 0);
        printw(CHAR_LINE_1);
    }
    refresh();

    for (i = 0; i < ROW; i ++) {
        for (j = 0; j < COL; j ++) {
            if (CHAR_NONE != map[i][j].value) {
                move(map[i][j].y, map[i][j].x);
                addch(map[i][j].value);
            }
        }
    }
    refresh();
}

int set_ticker(int n_msec)
{
    struct itimerval timeset;
    long n_sec, n_usec;

    n_sec = n_msec / 1000;
    n_usec = (n_msec % 1000) * 1000L;

    timeset.it_interval.tv_sec = n_sec;
    timeset.it_interval.tv_usec = n_usec;

    timeset.it_value.tv_sec = n_sec;
    timeset.it_value.tv_usec = n_usec;

    return setitimer(ITIMER_REAL, &timeset, NULL);
}

结果

这里写图片描述

视频

c语言小游戏

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值