#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; } } } }