c语言在linux中进行贪吃蛇小游戏

此次贪吃蛇小游戏的目的是使得我在Linux底下使用vi进行编写的
心得:
1.自己对linux中如何使用vi更加熟悉
如::wq yy pp dd u 等等
2.对c语言的指针,结构体,链表等更加的牢固
3.借此小项目也运用到多线程作为进入linux的深入学习打下坚实的基础
代码展示

#include<curses.h>
#include<stdlib.h>
#define UP    1   //1与-1的目的是使用abs()函数防止一上一下
#define DOWN  -1
#define LEFT  2
#define RIGHT -2
struct Snake{ //创建一个结构体
	int hang;
	int lie;
	struct Snake *next;
};
struct Snake *head = NULL; //全局定义一个头和尾
struct Snake *tail= NULL;
int key; //定义一个按键的整形变量
int dir;//定义一个方向的整形变量
struct Snake food;
void initFood(){   //定义一个食物## 可以随机生成
	int x = rand()%19;
	int y = rand()%19;
	food.hang = x;
	food.lie = y;
}
void initNcurse(){
	initscr();
	keypad(stdscr,1);
	noecho();
}
int hasSnakeNode(int i, int j){ //显示蛇身体
	struct Snake *p;
	p = head;
	while(p != NULL){
		if(p->hang == i && p ->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}
int hasFood(int i,int j){ //有食物
	if(food.hang == i && food.lie == j){
		return 1;
	}
	return 0;
}
void gamePic(){  //游戏图形化展示
	int hang;
	int lie;
	move(0,0);
	for(hang=0;hang<20;hang++){
		if(hang == 0){
			for(lie=0;lie<20;lie++){
			printw("--");
			}
			printw("\n");		
		}
		if(hang >=0 && hang<=19 ){
			for(lie=0;lie<=20;lie++){
				if(lie == 0 || lie == 20){
					printw("|");
				}else if(hasSnakeNode(hang,lie)){
					printw("[]");
				}else if(hasFood(hang,lie)){
					printw("##");
				}
				else{
					printw("  ");
				}
			}
			printw("\n");
		}
		if(hang == 19){
			for(lie=0;lie<20;lie++){
			printw("--");
			}
			printw("\n");		
			printw("by ricko");
		}
	}
}
void addNode(){  //加头并且方向
	struct Snake *new = (struct Snake *)malloc(sizeof(struct Snake));
	new->next = NULL;
	switch(dir){
		case UP:
			new->hang = tail->hang-1;
			new->lie = tail->lie;
			break;
		case DOWN:
			new->hang = tail->hang+1;
			new->lie = tail->lie;
			break;
		case LEFT:
			new->hang = tail->hang;
			new->lie = tail->lie-1;
			break;
		case RIGHT:
			new->hang = tail->hang;
			new->lie = tail->lie+1;
			break;
	}
	tail->next = new;
	tail = new;
}
void initSnake(){ //初始化蛇
	struct Snake *p;
	dir = RIGHT;
	while(head != NULL){
		p = head;
		head = head->next;
		free(p);
	}
	initFood();  
	head = (struct Snake *)malloc(sizeof(struct Snake));
	head->hang = 1;
	head->lie = 1;
	head->next = NULL;
	tail = head;
	addNode();
	addNode();
	addNode();
	addNode();
}
void deleNode(){  //删除最后节点
	struct Snake *p;
	p = head;
	head = head->next;
	free(p);
}
int ifSnakeDie(){  //在撞到边界以及自己迟到自己的时候会输出一个1让自己复活
	struct Snake *p;
	p = head;
	if(tail->hang < 0 || tail->lie == 0 || tail->hang == 20 || tail->lie == 20){
		return 1;
	}
	while(p->next != NULL){
		if(p->hang == tail->hang && p->lie == tail->lie){
			return 1;
		}
		p = p->next;
	}
	return 0;
}
void moveSnake(){  //蛇的移动
	addNode();
	if(hasFood(tail->hang,tail->lie)){  //如果吃到食物就不删除最后的节点
		initFood();
	}else{
	deleNode();
	}
	if(ifSnakeDie()){
		initSnake(); 
	}
}
void refreshJieMian(){   //刷新界面 线程
	while(1){
		moveSnake();
		gamePic();
		refresh();
		usleep(150000);  //刷新频率
	}
}
void turn(int direction){  //防止方向键按了上又按下
	if(abs(dir) != abs(direction)){
		dir = direction;
	}
}
void changeDir(){  //改变方向
	while(1){
		key = getch();
		switch(key){
			case KEY_DOWN:
			turn(DOWN);
				break;
			case KEY_UP:
			turn(UP);
				break;
			case KEY_LEFT:
			turn(LEFT);
				break;
			case KEY_RIGHT:
			turn(RIGHT);
				break;
		}
	}
}
int main(){
	pthread_t t1; //定义线程1
	pthread_t t2; 
	initNcurse();	//初始化ncurse
	initSnake();  //初始化蛇
	gamePic();      //初始化界面
	pthread_create(&t1,NULL,refreshJieMian,NULL);//启动线程里面的函数
	pthread_create(&t2,NULL,changeDir,NULL);
	while(1);//线程3
	getch();
	endwin();
	return 0;
}

对代码进行编译

gcc snake.c -lcurses -lpthread

生成a.out运行文件

运行代码

./a.out

图片展示
在这里插入图片描述

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一个简单贪吃蛇游戏服务器的代码实现,仅供参考: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8888 #define MAX_CLIENTS 10 #define BUFFER_SIZE 1024 typedef struct { int x; int y; } point; typedef struct { int id; int score; point pos[100]; int len; } snake; snake snakes[MAX_CLIENTS]; int num_clients = 0; int main(int argc, char *argv[]) { int server_fd, client_fds[MAX_CLIENTS]; struct sockaddr_in server_addr, client_addr; char buffer[BUFFER_SIZE]; int i, j, k, n; int max_fd, fd; fd_set read_fds; socklen_t client_len = sizeof(client_addr); // 初始化蛇的状态 for (i = 0; i < MAX_CLIENTS; i++) { snakes[i].id = i + 1; snakes[i].score = 0; snakes[i].len = 3; for (j = 0; j < snakes[i].len; j++) { snakes[i].pos[j].x = j + 1; snakes[i].pos[j].y = 1; } } // 创建服务器套接字 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } // 绑定服务器地址 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); exit(1); } // 监听客户端连接 if (listen(server_fd, MAX_CLIENTS) == -1) { perror("listen"); exit(1); } // 循环处理客户端请求 while (1) { // 初始化文件描述符集合 FD_ZERO(&read_fds); FD_SET(server_fd, &read_fds); max_fd = server_fd; for (i = 0; i < num_clients; i++) { FD_SET(client_fds[i], &read_fds); if (client_fds[i] > max_fd) { max_fd = client_fds[i]; } } // 等待事件发生 if (select(max_fd + 1, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(1); } // 处理服务器套接字有新连接 if (FD_ISSET(server_fd, &read_fds)) { if ((client_fds[num_clients] = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) == -1) { perror("accept"); continue; } printf("New client connected: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); num_clients++; } // 处理客户端有数据到达 for (i = 0; i < num_clients; i++) { if (FD_ISSET(client_fds[i], &read_fds)) { if ((n = read(client_fds[i], buffer, BUFFER_SIZE)) <= 0) { // 客户端断开连接 printf("Client disconnected: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); close(client_fds[i]); for (j = i; j < num_clients - 1; j++) { client_fds[j] = client_fds[j + 1]; } num_clients--; continue; } // 处理客户端发送的消息 buffer[n] = '\0'; printf("Received message from client %d: %s\n", i + 1, buffer); // 更新蛇的位置 for (j = 0; j < MAX_CLIENTS; j++) { if (snakes[j].id == i + 1) { for (k = snakes[j].len - 1; k > 0; k--) { snakes[j].pos[k].x = snakes[j].pos[k - 1].x; snakes[j].pos[k].y = snakes[j].pos[k - 1].y; } if (buffer[0] == 'U') { snakes[j].pos[0].y--; } else if (buffer[0] == 'D') { snakes[j].pos[0].y++; } else if (buffer[0] == 'L') { snakes[j].pos[0].x--; } else if (buffer[0] == 'R') { snakes[j].pos[0].x++; } break; } } // 发送蛇的状态给所有客户端 for (j = 0; j < num_clients; j++) { memset(buffer, 0, BUFFER_SIZE); for (k = 0; k < MAX_CLIENTS; k++) { if (snakes[k].id == j + 1) { sprintf(buffer + strlen(buffer), "%d,%d,%d;", snakes[k].id, snakes[k].score, snakes[k].len); for (n = 0; n < snakes[k].len; n++) { sprintf(buffer + strlen(buffer), "%d,%d;", snakes[k].pos[n].x, snakes[k].pos[n].y); } break; } } write(client_fds[j], buffer, strlen(buffer)); } } } } return 0; } ``` 主要思路是:创建一个服务器套接字,监听客户端连接。当有新客户端连接时,将其加入到文件描述符集合,并为其创建一个蛇的状态。当客户端发送消息时,更新相应的蛇的位置,并将所有蛇的状态发送给所有客户端。当客户端断开连接时,将其从文件描述符集合移除,并将其对应的蛇的状态从服务器删除。 这个程序只是一个简单的示例,可能还需要进行一些改进和优化,比如处理客户端之间的碰撞、吃食物等逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值