linux下俄羅斯方塊
阿新 • • 發佈:2019-02-10
在編譯的時候:執行緒版需要連線 curses庫 和pthread庫 ;程序版只要連線curses庫即可
由於這個程式碼是本人第一次編寫的,有些地方可能寫法不規範,註釋不明瞭,僅限參考。
1、程序版
2、執行緒版#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/msg.h> #include <curses.h> #include <time.h> #define BUFSIZE 1024 #define TYPE 100 #define FLAG 99 typedef struct{ long mtype; char mtext[BUFSIZE]; }msgbuf_t; int a=-1,b=-1; int an,bn; int score = 0; int scra[28][18]={0}; // show data int scrb[28][18]={ // result data 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; int model[7][4][4][4]={ { // model formate 0 { // direct 0 0,0,0,0, 0,0,0,0, 1,0,0,0, 1,1,1,0 }, { // direct 1 0,0,0,0, 1,1,0,0, 1,0,0,0, 1,0,0,0 }, { // derect 2 0,0,0,0, 0,0,0,0, 1,1,1,0, 0,0,1,0 }, { // direct 3 0,0,0,0, 0,1,0,0, 0,1,0,0, 1,1,0,0 } }, { // model formate 1 { // direct 0 0,0,0,0, 0,0,0,0, 0,0,1,0, 1,1,1,0 }, { // direct 1 0,0,0,0, 1,0,0,0, 1,0,0,0, 1,1,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 1,1,1,0, 1,0,0,0 }, { // direct 3 0,0,0,0, 1,1,0,0, 0,1,0,0, 0,1,0,0 } }, { // model formate 2 { // direct 0 0,0,0,0, 0,0,0,0, 1,1,0,0, 0,1,1,0 }, { // direct 1 0,0,0,0, 0,1,0,0, 1,1,0,0, 1,0,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 1,1,0,0, 0,1,1,0 }, { // direct 3 0,0,0,0, 0,1,0,0, 1,1,0,0, 1,0,0,0 } }, { // model formate 3 { // direct 0 0,0,0,0, 0,0,0,0, 0,1,1,0, 1,1,0,0 }, { // direct 1 0,0,0,0, 1,0,0,0, 1,1,0,0, 0,1,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 0,1,1,0, 1,1,0,0 }, { // direct 3 0,0,0,0, 1,0,0,0, 1,1,0,0, 0,1,0,0 } }, { // model formate 4 { // direct 0 0,0,0,0, 0,0,0,0, 1,1,0,0, 1,1,0,0 }, { // direct 1 0,0,0,0, 0,0,0,0, 1,1,0,0, 1,1,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 1,1,0,0, 1,1,0,0 }, { // direct 3 0,0,0,0, 0,0,0,0, 1,1,0,0, 1,1,0,0 } }, { // model formate 5 { // direct 0 0,0,0,0, 0,0,0,0, 0,1,0,0, 1,1,1,0 }, { // direct 1 0,0,0,0, 1,0,0,0, 1,1,0,0, 1,0,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 1,1,1,0, 0,1,0,0 }, { // direct 3 0,0,0,0, 0,1,0,0, 1,1,0,0, 0,1,0,0 } }, { // model formate 6 { // direct 0 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1 }, { // direct 1 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1 }, { // direct 3 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 } } }; /*-------------------------------------------------*/ void showGame(WINDOW *win) { int i,j; for(i=4;i<24;i++) { for(j=4;j<14;j++) { // wmove(win,i-3,j-3); // if(scra[i][j] > 0){ // waddch(win,'N'); // }else{ // waddch(win,' '); // } mvwprintw(win, i-3, j-3, "%c", scra[i][j]>0?'N':' '); } } wrefresh(win); } void showRem(WINDOW *win,int a,int b) { int i,j; for(i=0;i<4;i++) { for(j=0;j<4;j++) { mvwprintw(win,i+1,j+1, "%c", model[a][b][i][j]>0?'N':' '); } } wrefresh(win); } void showSco(WINDOW *win) { char arr[10] = {0}; arr[0] = (char)(score/10 + 48); arr[1] = (char)(score%10 + 48); arr[2] = '\0'; wmove(win,1,1); waddstr(win,"SCORE:"); wmove(win,2,2); waddstr(win,arr); wrefresh(win); } void randNum() { a = an; b = bn; an = (int)(rand()/(RAND_MAX+1.0)*40)%7; bn = (int)(rand()/(RAND_MAX+1.0)*40)/10; } int top() { int i,j; int count=0; int top=23; for(i=0;i<24;i++) { for(j=4;j<14;j++) { if(scra[i][j] != 0) { count++; } } if(count != 0) { top--; } count = 0; } return top; } void copy() { int i=23,j; int row,col; int count = 0; while(i != 0) { for(j=4;j<14;j++) { if(scra[i][j] > 0) { count++; } } if(count == 10) { score++; i++; for(row=i-1;row>0;row--) { for(col=4;col<14;col++) { scra[row][col] = scra[row-1][col]; } } } i--; count = 0; } for(i=0;i<28;i++) { for(j=0;j<18;j++) { scrb[i][j] = scra[i][j]; } } } int movDis(WINDOW *win,int x,int y,int z) { int i=0,j=0; z = z%4; for(i=0;i<28;i++) { for(j=0;j<18;j++) { scra[i][j] = scrb[i][j]; } } for(i=x;i<x+4;i++) { for(j=y;j<y+4;j++) { scra[i][j] += model[a][z][i-x][j-y]; if(scra[i][j] > 1) { return -1; } } } return 0; } /*-------------------------------------------------*/ void initStrscr() { initscr(); clear(); noecho(); box(stdscr,'+','+'); refresh(); } void endWin(WINDOW *gameWin,WINDOW *remWin,WINDOW *scoWin) { delwin(gameWin); delwin(remWin); delwin(scoWin); } /*-------------------------------------------------*/ void endStrscr() { echo(); endwin(); } int main() { key_t key; pid_t pid; pid_t cpid; msgbuf_t msg; int msgid; WINDOW *gameWin; WINDOW *remWin; WINDOW *scoWin; initStrscr(); gameWin = newwin(22, 12, 4, 4); box(gameWin,'|','-'); wrefresh(gameWin); remWin = newwin(6, 6, 4, 20); box(remWin,'|','-'); wrefresh(remWin); scoWin = newwin(5, 10, 10, 20); box(scoWin,'|','-'); wrefresh(scoWin); srand(time(NULL)); randNum(); showRem(remWin,an,bn); showSco(scoWin); if((key = ftok("/",'a')) == -1) { perror("ftok"); exit(1); } if((msgid = msgget(key,IPC_CREAT|0666)) == -1) { perror("msgget"); exit(2); } pid = fork(); if(pid == -1) { perror("fork"); return -1; } /*-----------------------------------------------------*/ if(pid == 0) { while(1) { msg.mtype = TYPE; msg.mtext[0] = 'k'; msgsnd(msgid, &msg, sizeof(msgbuf_t)-sizeof(long), 0); sleep(1); } } else { cpid = fork(); if(cpid == -1) { perror("fork"); return -1; } if(cpid == 0) { char ch; while(1) { ch = (char)getchar(); if(ch == 'i'|| ch=='k' || ch=='j' || ch== 'l') { msg.mtype = TYPE; msg.mtext[0] = ch; msgsnd(msgid, &msg, sizeof(msgbuf_t)-sizeof(long), 0); } } } else { int i=0,j=7; int flag=0; int high = 0; while(1) { msgrcv(msgid, &msg, sizeof(msgbuf_t)-sizeof(long), TYPE, 0); if(msg.mtext[0] == 'k'){ i++; if(movDis(gameWin,i,j,b) == -1){ movDis(gameWin,--i,j,b); flag = 1; } }else if(msg.mtext[0] == 'l'){ j++; if(movDis(gameWin,i,j,b) == -1){ movDis(gameWin,i,--j,b); } }else if(msg.mtext[0] == 'j'){ j--; if(movDis(gameWin,i,j,b) == -1){ movDis(gameWin,i,++j,b); } }else if(msg.mtext[0] == 'i'){ b++; if(movDis(gameWin,i,j,b) == -1){ movDis(gameWin,i,j,--b); } } showGame(gameWin); if(flag == 1) { if( top() == 0) { msgctl(msgid, IPC_RMID, NULL); break; } i = 0;j =7; copy(); showSco(scoWin); randNum(); showRem(remWin,an,bn); flag = 0; } } } } endWin(gameWin,remWin,scoWin); endStrscr(); return 0; } #if 0 void initWin(WINDOW *gameWin,WINDOW *remWin,WINDOW *scoWin) { gameWin = newwin(22, 12, 4, 4); box(gameWin,'|','-'); wrefresh(gameWin); remWin = newwin(6, 6, 4, 20); box(remWin,'|','-'); wrefresh(remWin); scoWin = newwin(5, 10, 10, 20); box(scoWin,'|','-'); wrefresh(scoWin); } #endif
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <time.h> #include <curses.h> #include <unistd.h> #define MESGNUM 10 #define DOWN 100 #define UP 101 #define LEFT 102 #define RIGHT 103 typedef struct queue { void (*PInit)(struct queue *,int); int (*PWrite)(struct queue *,int); int (*PRead)(struct queue *); void (*queueFree)(struct queue *); int *p; int pRead; int pWrite; int queueSort; }queue_t; /*--------------------------佇列------------------------*/ void Init(struct queue *pqueue,int len) { int i; pqueue->queueSort = len; pqueue->pRead = 0; pqueue->pWrite = 0; pqueue->p = (int *)malloc(sizeof(int) * len); for(i=0;i<len;i++) { *((pqueue->p)+i) = -1; } } int Write(struct queue *pqueue,int data) { *(pqueue->p+(pqueue->pWrite)) = data; pqueue->pWrite = (pqueue->pWrite+1)%(pqueue->queueSort); } int Read(struct queue *pqueue) { int res; res = *(pqueue->p+(pqueue->pRead)); pqueue->pRead = (pqueue->pRead+1)%(pqueue->queueSort); return res; } void queueFree(struct queue *pqueue) { free(pqueue->p); } /*-----------------------定義---------------------------*/ queue_t queue = {Init,Write,Read,queueFree}; sem_t rec,sen; int score = 0; int a = -1,b = -1; int an,bn; int threadA = 1; int threadB = 1; int threadC = 1; WINDOW *gameWin; WINDOW *remWin; WINDOW *scoWin; int scra[28][18]={0}; // show data int scrb[28][18]={ // result data 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; int model[7][4][4][4]={ { // model formate 0 { // direct 0 0,0,0,0, 0,0,0,0, 1,0,0,0, 1,1,1,0 }, { // direct 1 0,0,0,0, 1,1,0,0, 1,0,0,0, 1,0,0,0 }, { // derect 2 0,0,0,0, 0,0,0,0, 1,1,1,0, 0,0,1,0 }, { // direct 3 0,0,0,0, 0,1,0,0, 0,1,0,0, 1,1,0,0 } }, { // model formate 1 { // direct 0 0,0,0,0, 0,0,0,0, 0,0,1,0, 1,1,1,0 }, { // direct 1 0,0,0,0, 1,0,0,0, 1,0,0,0, 1,1,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 1,1,1,0, 1,0,0,0 }, { // direct 3 0,0,0,0, 1,1,0,0, 0,1,0,0, 0,1,0,0 } }, { // model formate 2 { // direct 0 0,0,0,0, 0,0,0,0, 1,1,0,0, 0,1,1,0 }, { // direct 1 0,0,0,0, 0,1,0,0, 1,1,0,0, 1,0,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 1,1,0,0, 0,1,1,0 }, { // direct 3 0,0,0,0, 0,1,0,0, 1,1,0,0, 1,0,0,0 } }, { // model formate 3 { // direct 0 0,0,0,0, 0,0,0,0, 0,1,1,0, 1,1,0,0 }, { // direct 1 0,0,0,0, 1,0,0,0, 1,1,0,0, 0,1,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 0,1,1,0, 1,1,0,0 }, { // direct 3 0,0,0,0, 1,0,0,0, 1,1,0,0, 0,1,0,0 } }, { // model formate 4 { // direct 0 0,0,0,0, 0,0,0,0, 1,1,0,0, 1,1,0,0 }, { // direct 1 0,0,0,0, 0,0,0,0, 1,1,0,0, 1,1,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 1,1,0,0, 1,1,0,0 }, { // direct 3 0,0,0,0, 0,0,0,0, 1,1,0,0, 1,1,0,0 } }, { // model formate 5 { // direct 0 0,0,0,0, 0,0,0,0, 0,1,0,0, 1,1,1,0 }, { // direct 1 0,0,0,0, 1,0,0,0, 1,1,0,0, 1,0,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 1,1,1,0, 0,1,0,0 }, { // direct 3 0,0,0,0, 0,1,0,0, 1,1,0,0, 0,1,0,0 } }, { // model formate 6 { // direct 0 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1 }, { // direct 1 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 }, { // direct 2 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1 }, { // direct 3 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 } } }; /*---------------------亂七八糟的函式--------------------*/ void initStrscr() { initscr(); clear(); noecho(); box(stdscr,0,0); refresh(); } void endWin() { delwin(gameWin); delwin(remWin); delwin(scoWin); echo(); endwin(); } void showRem(WINDOW *win,int a,int b) { int i,j; for(i=0;i<4;i++) { for(j=0;j<4;j++) { mvwprintw(win,i+1,j+1, "%c", model[a][b][i][j]>0?'N':' '); } } wrefresh(win); } void showSco(WINDOW *win) { char arr[10] = {0}; arr[0] = (char)(score/10 + 48); arr[1] = (char)(score%10 + 48); arr[2] = '\0'; wmove(win,1,1); waddstr(win,"SCORE:"); wmove(win,2,2); waddstr(win,arr); wrefresh(win); } int top() { int i,j; int count=0; int top=23; for(i=0;i<24;i++) { for(j=4;j<14;j++) { if(scra[i][j] != 0) { count++; } } if(count != 0) { top--; } count = 0; } return top; } void showGame(WINDOW *win) { int i,j; for(i=4;i<24;i++) { for(j=4;j<14;j++) { wmove(win,i-3,j-3); mvwprintw(win, i-3, j-3, "%c", scra[i][j]>0?'N':' '); } } wrefresh(win); } void copy() { int i=23,j; int row,col; int count = 0; while(i != 0) { for(j=4;j<14;j++) { if(scra[i][j] > 0) { count++; } } if(count == 10) { score++; i++; for(row=i-1;row>0;row--) { for(col=4;col<14;col++) { scra[row][col] = scra[row-1][col]; } } } i--; count = 0; } for(i=0;i<28;i++) { for(j=0;j<18;j++) { scrb[i][j] = scra[i][j]; } } } void randNum() { a = an; b = bn; an = (int)(rand()/(RAND_MAX+1.0)*40)%7; bn = (int)(rand()/(RAND_MAX+1.0)*40)/10; } int movDis(WINDOW *win,int x,int y,int z) { int i=0,j=0; z = z%4; for(i=0;i<28;i++) { for(j=0;j<18;j++) { scra[i][j] = scrb[i][j]; } } for(i=x;i<x+4;i++) { for(j=y;j<y+4;j++) { scra[i][j] += model[a][z][i-x][j-y]; if(scra[i][j] > 1) { return -1; } } } return 0; } /*-------------------------------------------------------*/ int main() { pthread_t t1,t2,t3; void *send(void *); void *control(void *); void *rece(void *); queue.PInit(&queue,MESGNUM); sem_init(&rec,0,1); sem_init(&sen,0,0); initStrscr(); pthread_create(&t1,NULL,send,NULL); pthread_create(&t2,NULL,rece,NULL); pthread_create(&t3,NULL,control,NULL); pthread_join(t1,NULL); pthread_join(t2,NULL); pthread_join(t3,NULL); endWin(); queueFree(&queue); return 0; } void *send(void *temp) { while(threadA != 0) { if( queue.pRead != (queue.pWrite+1)%MESGNUM ) { sem_wait(&rec); queue.PWrite(&queue,DOWN); sem_post(&sen); } sleep(1); } return NULL; } void *rece(void *temp) { int i = 0,j = 7; int flag = 0; int high =0; int res; gameWin = newwin(22, 12, 4, 4); box(gameWin,0,0); wrefresh(gameWin); remWin = newwin(6, 6, 4, 20); box(remWin,0,0); wrefresh(remWin); scoWin = newwin(5, 10, 10, 20); box(scoWin,0,0); wrefresh(scoWin); srand(time(NULL)); randNum(); showRem(remWin,an,bn); showSco(scoWin); while(threadC != 0) { if(flag == 1) { if(top() == 0) { threadA = 0; threadB = 0; threadC = 0; break; } i = 0;j = 7; copy(); showSco(scoWin); randNum(); showRem(remWin,an,bn); flag = 0; } sem_wait(&sen); res = queue.PRead(&queue); if(res == DOWN){ i++; if(movDis(gameWin,i,j,b) == -1){ movDis(gameWin,--i,j,b); flag = 1; } }else if(res == RIGHT){ j++; if(movDis(gameWin,i,j,b) == -1){ movDis(gameWin,i,--j,b); } }else if(res == LEFT){ j--; if(movDis(gameWin,i,j,b) == -1){ movDis(gameWin,i,++j,b); } }else if(res == UP){ b++; if(movDis(gameWin,i,j,b) == -1){ movDis(gameWin,i,j,--b); } } sem_post(&rec); showGame(gameWin); } return NULL; } void *control(void *temp) { char ch; while(threadB != 0) { ch = (char)getchar(); if(ch == 'i'){ sem_wait(&rec); queue.PWrite(&queue,UP); sem_post(&sen); }else if(ch == 'k'){ sem_wait(&rec); queue.PWrite(&queue,DOWN); sem_post(&sen); }else if(ch == 'j'){ sem_wait(&rec); queue.PWrite(&queue,LEFT); sem_post(&sen); }else if(ch == 'l'){ sem_wait(&rec); queue.PWrite(&queue,RIGHT); sem_post(&sen); } } return NULL; }