NCURSES程序设计之拼图游戏

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangjiaweiwei/article/details/75805487

拼图游戏是取n*n-1个数,组成n*n的方阵,然后对n*n-1个数从小到大依次排列,如果排列完成,则游戏结束。

本程序用LINUX下的NCURSES写成,先对n*n-1个数进行随机排列,然后通过移动白板来实现序列的重组与

排列。


#include <curses.h>


#define STARTX 9
#define STARTY 3
#define WIDTH  6
#define HEIGHT 4


#define BLANK 0


typedef struct _tile {
int x;
int y;
}tile;


void init_board(int **board, int n, tile *blank);
void board(WINDOW *win, int starty, int startx, int lines, int cols, 
  int tile_width, int tile_height);
void shuffle_board(int **board, int n);
void move_blank(int direction, int **s_board, int n, tile *blank);
int check_win(int **s_board, int n, tile *blank);


enum { LEFT, RIGHT, UP, DOWN };


int main(int argc, char *argv[])
{ int **s_board;
int n, i, ch;
tile blank;


if(argc != 2)
{ printf("Usage: %s <shuffle board order>\n", argv[0]);
exit(1);
}
n = atoi(argv[1]);

s_board = (int **)calloc(n, sizeof(int *));
for(i = 0;i < n; ++i)
s_board[i] = (int *)calloc(n, sizeof(int));//n*n的空间
init_board(s_board, n, &blank);
initscr();
keypad(stdscr, TRUE);
cbreak();
shuffle_board(s_board, n);
while((ch = getch()) != KEY_F(1))
{ switch(ch)
{ case KEY_LEFT:
move_blank(RIGHT, s_board, n, &blank);
break;
case KEY_RIGHT:
move_blank(LEFT, s_board, n, &blank);
break;
case KEY_UP:
move_blank(DOWN, s_board, n, &blank);
break;
case KEY_DOWN:
move_blank(UP, s_board, n, &blank);
break;
}
shuffle_board(s_board, n);
if(check_win(s_board, n, &blank) == TRUE)
{ mvprintw(24, 0, "You Win !!!\n");
refresh();
break;
}
}
endwin();
return 0;
}
//移动白板来完成数列的重组
void move_blank(int direction, int **s_board, int n, tile *blank)
{ int temp;


switch(direction)
{ case LEFT:
{ if(blank->x != 0)
{ --blank->x;
temp = s_board[blank->x][blank->y];
s_board[blank->x + 1][blank->y] = temp;
s_board[blank->x][blank->y] = BLANK;
}
}
break;
case RIGHT:
{ if(blank->x != n - 1)
{ ++blank->x;
temp = s_board[blank->x][blank->y];
s_board[blank->x - 1][blank->y] = temp;
s_board[blank->x][blank->y] = BLANK;
}
}
break;
case UP:
{ if(blank->y != 0)
{ --blank->y;
temp = s_board[blank->x][blank->y];
s_board[blank->x][blank->y + 1] = temp;
s_board[blank->x][blank->y] = BLANK;
}
}
break;
case DOWN:
{ if(blank->y != n - 1)
{ ++blank->y;
temp = s_board[blank->x][blank->y];
s_board[blank->x][blank->y - 1] = temp;
s_board[blank->x][blank->y] = BLANK;
}
}
break;
}
}
//如果所有的数是从小到大依次排列的,且最后一位为白板,则表示游戏结束
int check_win(int **s_board, int n, tile *blank)
{ int i, j;


s_board[blank->x][blank->y] = n * n;
for(i = 0;i < n; ++i)
for(j = 0;j < n; ++j)
if(s_board[i][j] != j * n + i + 1)
{ s_board[blank->x][blank->y] = BLANK;
return FALSE;
}

s_board[blank->x][blank->y] = BLANK;
return TRUE;
}


//初始化方阵,产生n - 1个随机数,填充进方阵的空格内,最后剩余一个白板
void init_board(int **s_board, int n, tile *blank)
{ int i, j, k;
int *temp_board;


temp_board = (int *)calloc(n * n, sizeof(int));
srand(time(NULL));
for(i = 0;i < n * n; ++i)
{    
repeat :
k = rand() % (n * n);
for(j = 0;j <= i - 1; ++j)
if (k == temp_board[j])
goto repeat;
else
temp_board[i] = k;
}
k = 0;
for (i = 0;i < n;++i)
for(j = 0;j < n; ++j,++k)
{
//求出空格所在的位置
if(temp_board[k] == 0)
{ blank->x = i;
blank->y = j;
}
//为n*n个空格赋值
s_board[i][j] = temp_board[k];
}
free(temp_board);
}
//绘制方阵的边框和数列的栅栏
void board(WINDOW *win, int starty, int startx, int lines, int cols, 
  int tile_width, int tile_height)
{ int endy, endx, i, j;

endy = starty + lines * tile_height;
endx = startx + cols  * tile_width;

for(j = starty; j <= endy; j += tile_height)
for(i = startx; i <= endx; ++i)
mvwaddch(win, j, i, ACS_HLINE);
for(i = startx; i <= endx; i += tile_width)
for(j = starty; j <= endy; ++j)
mvwaddch(win, j, i, ACS_VLINE);
mvwaddch(win, starty, startx, ACS_ULCORNER);
mvwaddch(win, endy, startx, ACS_LLCORNER);
mvwaddch(win, starty, endx, ACS_URCORNER);
mvwaddch(win, endy, endx, ACS_LRCORNER);
for(j = starty + tile_height; j <= endy - tile_height; j += tile_height)
{ mvwaddch(win, j, startx, ACS_LTEE);
mvwaddch(win, j, endx, ACS_RTEE);
for(i = startx + tile_width; i <= endx - tile_width; i += tile_width)
mvwaddch(win, j, i, ACS_PLUS);
}
for(i = startx + tile_width; i <= endx - tile_width; i += tile_width)
{ mvwaddch(win, starty, i, ACS_TTEE);
mvwaddch(win, endy, i, ACS_BTEE);
}
wrefresh(win);
}


//绘制shuffle的数列图形
void shuffle_board(int **s_board, int n)
{ int i,j, deltax, deltay;
int startx, starty;


starty = (LINES - n * HEIGHT) / 2;
startx = (COLS  - n * WIDTH) / 2;
clear();
mvprintw(24, 0, "Press F1 to Exit");
board(stdscr, starty, startx, n, n, WIDTH, HEIGHT);
deltay = HEIGHT / 2;
deltax = WIDTH  / 2;
for(j = 0; j < n; ++j)
for(i = 0;i < n; ++i)
if(s_board[i][j] != BLANK)
mvprintw(starty + j * HEIGHT + deltay,
startx + i * WIDTH  + deltax,
"%-2d", s_board[i][j]);
refresh();
}



猜你喜欢

转载自blog.csdn.net/wangjiaweiwei/article/details/75805487