#include "stdio.h" #include "windows.h" #include "conio.h" #include "stdlib.h" #define MAX 10 int box[MAX][MAX]; /* http://black4yl.blog.51cto.com Black4yL: 2015年1月4日 /---2 0 4 8 遊戲---\ (純屬練 數組 , 方向感, 測試是否瞌睡,以及 高數,大物,相對運動...) 以 left爲例說明原理: 0x01: 進入left函數 0x02: left(),(1)首先是moveleft操做,也即將全部數字左移 (2)而後是megerleft操做,也即左移後的同數字合併 合併完了,還必須執行一次移動,由於可能會有中間空隙. 好比 2 4 4 8 移動後是 2 8 空 8,須要再次移動變爲 2 8 8 空 (3)最後就是返回一個 bool 型 ret值,表示當前數字是否發生變化,變化了須要 檢查是否滿了? 變化了還須要 隨機生成一個數字,繼續遊戲~ 0x03: 詳解 mov 操做 for( ) for( ) { (1)找空閒列 (2)前移 (3)修改移動的位置爲 空 (-1) } meger操做 遍歷數組,left狀況 則 以行優先,列值由0 -> n-1 up狀況 則 以列優先,行值由0 -> n-1 其餘 同理。 尋找先後是否有相同值,有則 消除後面的,前面的數字X2 */ bool megerleft(int n) //left 合併 { bool ret = false; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(box[i][j] == -1) continue; if(box[i][j] == box[i][j+1]) { box[i][j] *= 2; box[i][j+1] = -1; ret = true; j++; } } } return ret; } bool movleft(int n) { bool ret = false; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { int k; for(k=j-1;k>=0;k--) //找到第i行 j列前面第一個不是空的位置 { if( box[i][k] != -1) break; } box[i][k+1] = box[i][j]; //插到它的前一個(這個不爲空,前一個確定是空) if( k+1 != j) //若是發生移動,也就是 k != j-1 ,也就是 k+1 ! = j { box[i][j] = -1; //移動了 ,填充爲空 ret = true; //發生變化 } } } return ret; } bool left(int n) { bool ret = false; ret = movleft(n); ret = megerleft(n); ret = movleft(n); return ret; } bool megerright(int n) { bool ret = false; for(int i=0;i<n;i++) for(int j=n-1;j>=0;j--) { if( box[i][j] == -1) continue; if( box[i][j] == box[i][j-1]) { box[i][j] *= 2; box[i][j-1] = -1; ret = true; j-- ; } } return ret; } bool movright(int n) { bool ret = false; for(int i=0;i<n;i++) for(int j=n-1;j>=0;j--) { int k; for(k=j+1;k<n;k++) { if(box[i][k]!=-1) break; } box[i][k-1] = box[i][j]; if( k-1 != j) { box[i][j] = -1; ret = true; } } return ret; } bool right(int n) { bool ret = false; ret = movright(n); ret = megerright(n); ret = movright(n); return ret; } bool megerup(int n) { bool ret = false; for( int i=0 ;i <n;i++) // 此時爲列 for(int j=0 ; j<n;j++) // 此時爲行 { if( box[j][i] == -1) continue; if( box[j][i] == box[j+1][i] ) { box[j][i] *= 2; box[j+1][i] = -1; ret = true; j++; } } return ret; } bool movup(int n) { bool ret = false; for( int i=0 ;i <n;i++) // 此時爲列 for(int j=0 ; j<n;j++) // 此時爲行 { int k ; for( k =j -1 ; k>=0 ; k--) //行變化 { if( box[k][i] != -1) break; } box[k+1][i] = box[j][i]; if(k+1 != j) { box[j][i] = -1; ret = true; } } return ret; } bool up(int n) { bool ret = false; ret = movup(n); ret = megerup(n); ret = movup(n); return ret; } bool megerdown(int n) { bool ret = false; for( int i = 0; i<n;i++) //列 for( int j = n-1; j >=0; j--) //行 { if( box[j][i] == -1) continue; if( box[j][i] == box[j-1][i]) { box[j][i] *= 2; box[j-1][i] = -1; j--; ret = true; } } return ret; } bool movdown(int n) { bool ret = false; for( int i = 0; i<n;i++) //列 for( int j = n-1;j>=0;j--) //行 { int k; for(k = j+1;k<n;k++) { if( box[k][i] != -1) break; } box[k-1][i] = box[j][i]; if( k-1 != j) { box[j][i] = -1; ret = true; } } return ret; } bool down(int n) { bool ret = false; ret = movdown(n); ret = megerdown(n); ret = movdown(n); return ret; } void line(int n) { for (int i = 0; i < n; ++i) { printf("--------"); } printf("-"); printf("\n"); } void print(int n) { for(int i=0;i<n;i++) { line(n); for(int j=0 ; j<n ; j++) { printf("|"); if( box[i][j] == -1) { printf("\t"); } else printf("%2d\t", box[i][j]); } printf("|"); printf("\n"); } line(n); } bool isfull(int n) //是否 滿 { bool ret = true; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if( box[i][j] == -1) { ret = false; return ret; } } return ret; //滿 } bool isOver(int n) //是否 結束遊戲 { if( !isfull(n)) return false; for(int i=0;i<n;i++) for( int j=0;j<n;j++) { if( box[i][j] == box[i][j+1] || box[i][j] == box[i+1][j]) //有相同的 return false; } return true; } void fillbox(int n) //隨機填充 { int i,j,num; if( isfull(n)) //格子滿 return ; while(1) { i = rand() % n; j = rand() % n; num = rand() % 2 ? 2 : 4; if(box[i][j] == -1) { box[i][j] = num; break; } } } void main() { char ch; int n = 9; memset(box,-1,sizeof(box)); bool mak = false ; fillbox(n); while(1) { system("CLS"); print(n); ch = getch(); switch(ch) { case 'a': mak = left(n); break; case 'd': mak = right(n); break; case 'w': mak = up(n); break; case 's': mak = down(n); break; default: continue; } if(mak) //有變化 { fillbox(n); if(isOver(n)) { system("CLS"); printf("Game oVer!\n"); break; } } } }