作为小白,我改了三次的2048代码,终于有点用了!!!

初学c语言,做了个小游戏,以我经常玩的解压单机小游戏2048为例,第一遍写了3天依然是错的,第二遍写了一天还是存在问题,第三遍只花了1小时,最后运行还是正确的!多练手,嘎嘎香啊 !!!

接下来我来介绍原理和每段代码的实现过程

其实细看2048主要包括几个步骤

  1. 确定是n*n的2048,一般是4*4,但是 也可以进行修改。这里可以用宏定义来作为magic number,define rows和cols,想改只要在代码的开头改rows和cols就可以。
  2. n*n首先联想到数组,所以对数组进行定义,board[rows][cols],并初始化每个单位都是0
  3. 找到两个随机的格子并对其赋值为2(2048初始值是2),这里用initBoard()函数实现
    //找到两个随机的格子并且赋值2 
    void initBoard()
    {
    	int i,j;
    	for(i=0; i<rows; i++){
    		for(j=0; j<cols; j++){
    			board[i][j] = 0;
    		} 
    	}
    	
    	srand(time(NULL));
    	int r2,c2;
    	int r1 = rand()%rows;
    	int c1 = rand()%cols;
    	do{
    		r2 = rand()%rows;
    		c2 = rand()%cols;
    	}while(r1 == r2&&c1 == c2);
    	board[r1][c1] = 2;
    	board[r2][c2] = 2;
    }

  4. 制表,就是制作出一个4*4的表格。在终端中不好实现制表,所以用“|”代替竖线,用“+----”代替每个格子的横线。这里用drawBoard()函数实现
    这里有需要注意到地方。即经过for循环最后是缺少一条横线和一条竖线的,即最后还得再画一条横线和一条竖线
    最后实现的效果大致是这样的

     
    void drawBoard()
    {
    	system("cls");
    	int i,j; 
    	for(i=0; i<rows; i++){
    		for(j=0; j<cols; j++){
    			printf("+----");
    		}
    		printf("+\n");
    		
    		for(j=0; j<cols; j++){
    			printf("|");
    			if(board[i][j]){
    				printf("%4d", board[i][j]);
    			}else{
    				printf("    ");
    			}
    		}
    		printf("|\n");
    	}
    	for(j=0; j<cols; j++){
    		printf("+----");
    	}
    	printf("+");

  5. 添加随机数。这里要注意随机数要加到随机的两个格子里,同时这两个格子还要是空的。最主要是保证随机性。所以我定义了一个k随机数,用此随机数来实现格子的随机,实现方式如下:
    int addRandomNum()
    {
    	srand(time(NULL));
    	int cnt = 0;
    	int i,j,k;
    	for(i=0; i<rows; i++){
    		for(j=0; j<cols; j++){
    			if(board[i][j] == 0){
    				cnt++;
    			}
    		}
    	}
    	if(cnt == 0)
    		return 0;
    //		printf("88");
    		
    	if(cnt>0){
    		k = rand()%cnt;
    		for(i=0; i<rows; i++){
    			for(j=0; j<cols; j++){
    				if(board[i][j] == 0){
    					if(k == 0){
    						board[i][j]=(rand()%2+1)*2;
    						return 1;
    					}
    					k--;
    				}
    		}
    	}
    	}
    }

  6. 实现上下左右的移动:
    这里以向左移动为例:向左移动主要分为3个小步骤:把所有数字移到左边、实现相同数字的相加、把加完后的数字再移到左边
    void left()
    {
    	int i,j,k;
    //	把所有数字移动到左边 
    	for(i=0; i<rows; i++){
    		k = 0;
    		for(j=0; j<cols; j++){
    			if(board[i][j]!=0){
    				board[i][k++] = board[i][j];
    			}
    		}
    		while(k<cols){
    			board[i][k] = 0;
    			k++;
    		}
    	
    //	对相同的数字进行合并
    	 	for(j=0; j<cols-1; j++){
    	 		if(board[i][j] == board[i][j+1]){
    	 			board[i][j] *= 2;
    	 			board[i][j+1] = 0;
    			 }
    		 }
    // 再把数字都移动到左边
    		k = 0;
    		for(j=0; j<cols; j++){
    			if(board[i][j]!=0){
    				board[i][k++] = board[i][j];
    			}
    		}
    		while(k<cols){
    			board[i][k] = 0;
    			k++;
    		}
      }
    }

  7. 最后,在主函数中用switch-case,实现每一步的移动
    int main()
     {	
     	initBoard();
     	drawBoard();
     	
     	int i,j,k;
     	
     	 char ch;
        while (1) {
            ch = getch();
            if (ch == 'q' || ch == 'Q')
                break;
    
            switch (ch) {
                case 'a':
                case 'A':
                    left();
                    break;
                case 'd':
                case 'D':
                    right();
                    break;
                case 'w':
                case 'W':
                    up();
                    break;
                case 's':
                case 'S':
                    down();
                    break;
                default:
                    continue;
    		
            }
    		if(addRandomNum() == 0){
    			for(i=0; i<rows; i++){
    				for(j=0; j<cols; j++){
    					if(board[i][j] != board[i][j+1]&&board[i][j] != board[i+1][j]){
    						printf("Game over\n");
    	 						break;	
    					}
    				}
    			}
     			
    		 }
    		 drawBoard();
            	
     	}
    	return 0;
     }
    以下是完整代码:
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <time.h>
    
    #define rows 4
    #define cols 4
    
    int board[rows][cols];
    
    //找到两个随机的格子并且赋值2 
    void initBoard()
    {
    	int i,j;
    	for(i=0; i<rows; i++){
    		for(j=0; j<cols; j++){
    			board[i][j] = 0;
    		} 
    	}
    	
    	srand(time(NULL));
    	int r2,c2;
    	int r1 = rand()%rows;
    	int c1 = rand()%cols;
    	do{
    		r2 = rand()%rows;
    		c2 = rand()%cols;
    	}while(r1 == r2&&c1 == c2);
    	board[r1][c1] = 2;
    	board[r2][c2] = 2;
    }
    
    void drawBoard()
    {
    	system("cls");
    	int i,j; 
    	for(i=0; i<rows; i++){
    		for(j=0; j<cols; j++){
    			printf("+----");
    		}
    		printf("+\n");
    		
    		for(j=0; j<cols; j++){
    			printf("|");
    			if(board[i][j]){
    				printf("%4d", board[i][j]);
    			}else{
    				printf("    ");
    			}
    		}
    		printf("|\n");
    	}
    	for(j=0; j<cols; j++){
    		printf("+----");
    	}
    	printf("+");
    //	for(i=0; i<rows; i++){
    //		for(j=0; j<cols; j++){
    //			if(board[i][j]){
    //				printf("%4d", board[i][j]);
    //			}else{
    //				printf("    ");
    //			}
    //		}
    //	}
     } 
     
    int addRandomNum()
    {
    	srand(time(NULL));
    	int cnt = 0;
    	int i,j,k;
    	for(i=0; i<rows; i++){
    		for(j=0; j<cols; j++){
    			if(board[i][j] == 0){
    				cnt++;
    			}
    		}
    	}
    	if(cnt == 0)
    		return 0;
    //		printf("88");
    		
    	if(cnt>0){
    		k = rand()%cnt;
    		for(i=0; i<rows; i++){
    			for(j=0; j<cols; j++){
    				if(board[i][j] == 0){
    					if(k == 0){
    						board[i][j]=(rand()%2+1)*2;
    						return 1;
    					}
    					k--;
    				}
    		}
    	}
    	}
    }
    
    void left()
    {
    	int i,j,k;
    //	把所有数字移动到左边 
    	for(i=0; i<rows; i++){
    		k = 0;
    		for(j=0; j<cols; j++){
    			if(board[i][j]!=0){
    				board[i][k++] = board[i][j];
    			}
    		}
    		while(k<cols){
    			board[i][k] = 0;
    			k++;
    		}
    	
    //	对相同的数字进行合并
    	 	for(j=0; j<cols-1; j++){
    	 		if(board[i][j] == board[i][j+1]){
    	 			board[i][j] *= 2;
    	 			board[i][j+1] = 0;
    			 }
    		 }
    // 再把数字都移动到左边
    		k = 0;
    		for(j=0; j<cols; j++){
    			if(board[i][j]!=0){
    				board[i][k++] = board[i][j];
    			}
    		}
    		while(k<cols){
    			board[i][k] = 0;
    			k++;
    		}
      }
    }
    
    void right()
    {
    	int i,j,k;
    	for(i=0; i<rows; i++){
    		k=cols-1;
    		for(j=cols-1; j>=0; j--){
    			if(board[i][j]){
    				board[i][k--] = board[i][j];
    			}
    		}
    		while(k>=0){
    			board[i][k] = 0;
    			k--;
    		}
    		
    		for(j=cols-1; j>=0; j--){
    			if(board[i][j] == board[i][j-1]){
    				board[i][j] *= 2;
    				board[i][j-1] = 0;
    			}
    		}
    		
    			k=cols-1;
    		for(j=cols-1; j>=0; j--){
    			if(board[i][j]){
    				board[i][k--] = board[i][j];
    			}
    		}
    		while(k>=0){
    			board[i][k] = 0;
    			k--;
    		}
    		
    	}
    }
    
    void up()
    {
    	int i,j,k;
    	for(j=0; j<cols; j++){
    		k=0;
    		for(i=0; i<rows; i++){
    			if(board[i][j]){
    				board[k++][j] = board[i][j];
    			}
    		}
    		while(k<rows){
    			board[k][j] = 0;
    			k++;
    		}
    		
    		for(i=0; i<rows; i++){
    			if(board[i][j] == board[i+1][j]){
    				board[i][j] *= 2;
    				board[i+1][j] = 0;
    			}
    		}
    		
    		k=0;
    		for(i=0; i<rows; i++){
    			if(board[i][j]){
    				board[k++][j] = board[i][j];
    			}
    		}
    		while(k<rows){
    			board[k][j] = 0;
    			k++;
    		}
    	}
    	
    }
    
    void down()
    {
    	int i,j,k;
    	for(j=0; j<cols; j++){
    		k=rows-1;
    		for(i=rows-1; i>=0; i--){
    			if(board[i][j]){
    				board[k--][j] = board[i][j];
    			}
    		}
    		while(k>=0){
    			board[k][j] = 0;
    			k--;
    		}
    		
    		for(i=rows-1; i>=0; i--){
    			if(board[i][j] == board[i-1][j]){
    				board[i][j] *= 2;
    				board[i-1][j] = 0;
    			}
    		}
    		
    		k=rows-1;
    		for(i=rows-1; i>=0; i--){
    			if(board[i][j]){
    				board[k--][j] = board[i][j];
    			}
    		}
    		while(k>=0){
    			board[k][j] = 0;
    			k--;
    		}
    	}
    }
     int main()
     {	
     	initBoard();
     	drawBoard();
     	
     	int i,j,k;
     	
     	 char ch;
        while (1) {
            ch = getch();
            if (ch == 'q' || ch == 'Q')
                break;
    
            switch (ch) {
                case 'a':
                case 'A':
                    left();
                    break;
                case 'd':
                case 'D':
                    right();
                    break;
                case 'w':
                case 'W':
                    up();
                    break;
                case 's':
                case 'S':
                    down();
                    break;
                default:
                    continue;
    		
            }
    		if(addRandomNum() == 0){
    			for(i=0; i<rows; i++){
    				for(j=0; j<cols; j++){
    					if(board[i][j] != board[i][j+1]&&board[i][j] != board[i+1][j]){
    						printf("Game over\n");
    	 						break;	
    					}
    				}
    			}
     			
    		 }
    		 drawBoard();
            	
     	}
    	return 0;
     }
    初学C语言,水平实在有限,如果各位发现了什么错误或者可以改善的地方,欢迎私信我。
     

 

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值