初学c语言,做了个小游戏,以我经常玩的解压单机小游戏2048为例,第一遍写了3天依然是错的,第二遍写了一天还是存在问题,第三遍只花了1小时,最后运行还是正确的!多练手,嘎嘎香啊 !!!
接下来我来介绍原理和每段代码的实现过程
其实细看2048主要包括几个步骤
- 确定是n*n的2048,一般是4*4,但是 也可以进行修改。这里可以用宏定义来作为magic number,define rows和cols,想改只要在代码的开头改rows和cols就可以。
- n*n首先联想到数组,所以对数组进行定义,board[rows][cols],并初始化每个单位都是0
- 找到两个随机的格子并对其赋值为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的表格。在终端中不好实现制表,所以用“|”代替竖线,用“+----”代替每个格子的横线。这里用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("+");
- 添加随机数。这里要注意随机数要加到随机的两个格子里,同时这两个格子还要是空的。最主要是保证随机性。所以我定义了一个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--; } } } } }
- 实现上下左右的移动:
这里以向左移动为例:向左移动主要分为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++; } } }
- 最后,在主函数中用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; }
初学C语言,水平实在有限,如果各位发现了什么错误或者可以改善的地方,欢迎私信我。#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; }