C語言遊戲之貪吃蛇--連結串列實現
早自習時突然想到怎麼寫貪吃蛇,話不多說,程式碼如下:
開發環境:vs2015
雖然開始還是出了很多指標問題。。。(很煩C語言指標)除錯了很久也大概是可以暢快的玩了。
C語言新手,有很多寫得不好的地方望大神提出
當然,我也不介意把我程式碼拿去學習(這樣就說明我的程式碼有學習價值)
標頭檔案:snake.h
/** *By Liu Yuchuan *2017.3.30 */ #ifndef SNAKE_H_INCLUDED #define SNAKE_H_INCLUDED #include<stdio.h> //遊戲中各種符號 #define CHOOSE_LOGO "->" #define SNAKE_NODE '*' #define WALL '#' #define FOOD '$' //地圖大小 #define mapWidth 50 #define mapHeight 25 //蛇狀態 #define LIVE 1 #define DEAD 0 //移動方向 enum Direction{UP, DOWN, RIGHT, LEFT}; typedef enum Direction Direction; struct Node; typedef struct Node Node; typedef Node* SnakeHead; typedef Node* PtrToNode; //蛇的連結串列節點 struct Node{ int x; int y; PtrToNode next; }; //蛇的結構體 typedef struct Snake{ SnakeHead snakeHead; int lenth; int state; Direction dir; } *Snake; //食物的結構體 typedef struct Food { int x; int y; int isEat; } *Food; //移動鍵 char key_down = 's'; char key_up = 'w'; char key_right = 'd'; char key_left = 'a'; //移動間隔時間 int moveTime = 100; //得分 int score = 0; Food food = NULL; Snake snake = NULL; void menu(); void pos(int x, int y); void startGame(); void initMap(); Snake initSnake(Snake snake); void printSnake(Snake snake); void clearSnake(Snake snake); void move(Snake snake); Snake getLonger(Snake snake); void createFood(); int isLocationOK(int x, int y); #endif // SNAKE_H_INCLUDED
原始碼:Snake.c
#include"Snake.h" #include<windows.h> #include<stdlib.h> #include<conio.h> #include<time.h> int main(){ menu:menu(); system("cls"); startGame(); goto menu; } void menu(){ pos(18, 2); printf("歡迎來到貪吃蛇!"); //列印選單 pos(18, 6); printf("%s", CHOOSE_LOGO); printf("開始遊戲"); pos(20, 10); printf("退出遊戲"); //控制選單 int option = 0; char ch = 1; //鍵入回車退出迴圈 while(1){ ch = _getch(); //下移 if(ch == key_down){ if(option == 0){ pos(18, 6+option); printf(" "); option += 4; pos(18, 6+option); printf("%s", CHOOSE_LOGO); } } //上移 else if(ch == key_up){ if(option == 4){ pos(18, 6+option); printf(" "); option -= 4; pos(18, 6+option); printf("%s", CHOOSE_LOGO); } } else if(ch == 13){ switch(option){ case 0: return; case 4: exit(0); } } } } //定位游標 void pos(int x, int y){ COORD position; position.X = x; position.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position); } void startGame(){ char ch = 1; score = 0; snake = initSnake(snake); initMap(); food = (Food)malloc(sizeof(struct Food)); food->x = 0; food->y = 0; food->isEat = 1; printSnake(snake); while (snake->state){ createFood(food); //監聽鍵盤輸入 if (_kbhit()) { ch = _getch(); if (snake->dir != UP && ch == key_down) { snake->dir = DOWN; } else if (snake->dir != DOWN && ch == key_up) { snake->dir = UP; } else if (snake->dir != LEFT && ch == key_right) { snake->dir = RIGHT; } else if (snake->dir != RIGHT && ch == key_left) { snake->dir = LEFT; } } move(snake); } pos(mapWidth + 2, mapHeight / 2 - 1); printf(" "); pos(mapWidth + 2, mapHeight / 2); printf(" "); pos(mapWidth + 2, mapHeight / 2 + 1); printf(" "); pos(mapWidth + 2, mapHeight / 2 + 2); printf(" "); pos(mapWidth + 2, mapHeight / 2 - 1); printf("遊戲結束"); pos(mapWidth + 2, mapHeight / 2); printf("最終長度: %d", snake->lenth); pos(mapWidth + 2, mapHeight / 2 + 1); printf("您的得分: %d", score); pos(mapWidth + 2, mapHeight / 2 + 2); printf("Enter鍵返回主選單"); while(ch != 13) ch = _getch(); system("cls"); } void initMap(){ for(int i = 0; i < mapWidth; i++){ for(int j = 0; j < mapHeight; j++){ if(i == 0 || j == 0 || i == mapWidth - 1 || j == mapHeight - 1){ pos(i, j); printf("%c", WALL); } } } pos(mapWidth + 2, mapHeight/2 - 1); printf("當前長度(越長吃一次食物得分越高哦):"); pos(mapWidth + 2, mapHeight/2); printf("%d", snake->lenth); pos(mapWidth + 2, mapHeight / 2 + 1); printf("當前得分:"); pos(mapWidth + 2, mapHeight / 2+2); printf("%d", score); } Snake initSnake(Snake snake){ snake = (Snake)malloc(sizeof(struct Snake)); snake->snakeHead = (SnakeHead)malloc(sizeof(Node)); SnakeHead snakeHead = snake->snakeHead; snakeHead->x = 4; snakeHead->y = 3; snakeHead->next = (PtrToNode)malloc(sizeof(Node)); snakeHead->next->x = 4; snakeHead->next->y = 2; snakeHead->next->next = (PtrToNode)malloc(sizeof(Node)); snakeHead->next->next->x = 4; snakeHead->next->next->y = 1; snakeHead->next->next->next = NULL; snake->lenth = 3; snake->dir = DOWN; snake->state = LIVE; return snake; } void printSnake(Snake snake) { PtrToNode position = snake->snakeHead; while (position) { pos(position->x, position->y); printf("%c", SNAKE_NODE); position = position->next; } } void clearSnake(Snake snake){ PtrToNode position = snake->snakeHead; while (position) { pos(position->x, position->y); printf(" "); position = position->next; } } void move(Snake snake) { //判斷是否會撞牆 if ((snake->snakeHead->x == mapWidth - 2 && snake->dir == RIGHT) || snake->snakeHead->x == 1 && snake->dir == LEFT || snake->snakeHead->y == 1 && snake->dir == UP || snake->snakeHead->y == mapHeight - 2 && snake->dir == DOWN) { snake->state = DEAD; return; } clearSnake(snake); SnakeHead head = snake->snakeHead; int x = head->x; int y = head->y; int tmpX, tmpY; switch (snake->dir) { case UP: head->y--; break; case DOWN: head->y++; break; case LEFT: head->x--; break; case RIGHT: head->x++; break; default: break; } while (head->next) { tmpX = head->next->x; tmpY = head->next->y; head->next->x = x; head->next->y = y; x = tmpX; y = tmpY; head = head->next; //判斷是否咬到自己 if (head->x == snake->snakeHead->x && head->y == snake->snakeHead->y) snake->state = DEAD; } if (snake->snakeHead->x == food->x && snake->snakeHead->y == food->y && snake->state) { score += snake->lenth / 10 + 1; food->isEat = 1; pos(food->x, food->y); printf(" "); snake = getLonger(snake); pos(mapWidth + 2, mapHeight / 2 + 2); printf("%d", score); pos(mapWidth + 2, mapHeight / 2 ); printf("%d", snake->lenth); } printSnake(snake); Sleep(moveTime); } Snake getLonger(Snake snake){ PtrToNode position = snake->snakeHead; while (position->next->next) { position = position->next; } int x1 = position->x; int y1 = position->y; position = position->next; int x2 = position->x; int y2 = position->y; position->next = (PtrToNode)malloc(sizeof(Node)); position->next->next = NULL; if (x1 == x2) { position->next->x = x1; position->next->y = y2 + y2 - y1; } else{ position->next->y = y1; position->next->x = x2 + x2 - x1; } snake->lenth++; return snake; } //生成食物 void createFood(){ if (food->isEat) { //獲取系統時間作為產生隨機數的種子 srand((unsigned)time(0)); while (1) { food->x = rand() % (mapWidth - 2) + 1; food->y = rand() % (mapHeight - 2) + 1; if (isLocationOK(food->x, food->y)) { pos(food->x, food->y); printf("%c", FOOD); food->isEat = 0; break; } } } } //判斷位置是否合理 int isLocationOK(int x, int y){ PtrToNode position = snake->snakeHead; while (position) { if (x == position->x && y == position->y) { position = position->next; return 0; } } return x > 0 && x < mapWidth - 1 && y > 0 && y < mapHeight - 1; }
相關推薦
C語言遊戲之貪吃蛇--連結串列實現
早自習時突然想到怎麼寫貪吃蛇,話不多說,程式碼如下: 開發環境:vs2015 雖然開始還是出了很多指標問題。。。(很煩C語言指標)除錯了很久也大概是可以暢快的玩了。 C語言新手,有很多寫得不好的地方望大神提出 當然,我也不介意把我程式碼拿去學習(這樣就說明我的程式碼有
字元介面的貪吃蛇--連結串列--C++
前天看了下連結串列,由於平時對連結串列的使用不多,所以對連結串列的應用也沒什麼瞭解,所以想來想去,就想用連結串列實現一下貪吃蛇。 下面言歸正傳,先看效果圖,再看程式碼,其他沒有了! 圖1: 圖2: 程式碼: #include<iostream.h> //
C語言控制臺貪吃蛇2
隨機數函數 edi mms ‘\0’ sign rand() 拷貝 printf rand 顯示遊戲邊框及蛇的位置初始化 一、顯示遊戲邊框 1、定義二位數組,例如20*48,將並邊框按行打印(運行顯示邊框會卡,暫時不會別的寫法QAQ) 註:一個方塊兩個字節。 /
C語言控制臺貪吃蛇4
eba bsp console 食物 blog pan 是否 lec ons 蛇死亡判斷、吃食物、計分 一、蛇死亡判斷:裝邊界,撞自己死亡 定義:IsSnakeDie()//蛇死亡判斷 函數,返回類型為bool型 思路: //蛇頭的下一個,是方塊 就是死亡
C語言寫的貪吃蛇(國慶任務專案)
分享寫貪吃蛇的緣起 博主大一新生,因為有任務C語言寫貪吃蛇,去網上找別人的原始碼試一試效果,可是沒有一個可以通過編譯執行,現在博主好不容易寫完了貪吃蛇,卻深感單初不易,現在分享一下原始碼,應該不會像網上大多數的C語言貪吃蛇程式碼無法編譯正確,通過執行。(我用的D
c語言課上作業——初學連結串列操作
http://www.cnblogs.com/maluning/p/7966875.html 根據上面的大佬的指導。今天完成了老師的作業。第一次完成了連結串列的建立、遍歷、插入、刪除(基本靠抄,不好意思)。 作為一個菜鳥,第一次完成100行以上的不用複製重複程式碼的程式碼。好興奮呀。 //不過還是有一點
C語言程式設計 細節總結(連結串列)
12 連結串列 12.1 連結串列概述 1.採用動態儲存分配的一種重要資料結構,一個連結串列中儲存的是一批同類型的相關聯資料 2.動態分配時,每個結點之間可以不連續,結點之間的聯絡可以用指標實現,每個結點分兩個域:資料域和指標域 12.2 處理動態連結串列所需函
leetcode C語言版 第142. 環形連結串列 II
給定一個連結串列,返回連結串列開始入環的第一個節點。 如果連結串列無環,則返回 null。說明:不允許修改給定的連結串列。進階:你是否可以不用額外空間解決此題?分析:我最開始想的是通過修改value值來判斷是否相遇,後來看見題目規定不能修改,遂涼涼。用快慢指標解答,至於為什麼
資料結構程式碼實現之佇列的連結串列實現(C/C++)
上班閒著無聊,一直想著要開始寫部落格,但又不知道寫什麼。最近又回顧了下資料結構的知識,那就從資料結構開始吧。 前言 關於C語言結構體的知識以及佇列的特性請讀者自行了解,此處不做過多解釋,嘻嘻。 同時此篇文章僅僅是關於佇列的連結串列實現。 第一步:結構體編寫 我們首先分析一下佇列的
C語言檔案讀取並寫入連結串列
C語言沒啥要逼逼的,直接上程式碼,用心體會 #include "stdio.h" #include "stdlib.h" /***************************** 連結串列節點結構體 ****************************/ typedef stru
C語言資料結構_Linux核心連結串列
C語言資料結構中,可以分為線性資料結構和非線性資料結構,其中線性資料結構非常重要的內容是連結串列,本文章從基本的連結串列過渡到Linux核心連結串列 資料與邏輯結合的連結串列 什麼是資料與邏輯結合?先回想曾經學過的各種連結串列:
面向物件之Python的連結串列實現(二)迴圈連結串列
接上一章的練習,這裡接著實現單鏈表的變型——傳說中的迴圈單鏈表。給出一個簡單的類,構造4個功能並例項化測試。 在下一篇文章中將會關注一個比較tricky的問題:如何判斷連結串列有環?以及求出環長度 # -*- coding: utf-8 -*- """ Created
C語言貪吃蛇(詳解)——連結串列實現
貪吃蛇設計思路:螢幕座標:拓展功能:1.F1,F2控制加速減速 空格暫停遊戲 Esc退出2.加速每個食物得分更高先打印出遊戲介面,還有初始化蛇,蛇的節點用字串★表示,遊戲背景用■表示,因為這些字串佔兩個位元組的寬度,所以每次x,y座標的對應關係是x=y*2。在相應位置打印
C++控制檯迴圈連結串列實現貪吃蛇
-stdafx.h 為了簡化程式定義一些巨集和全域性變數 #ifndef __STDAFX_H__ #define __STDAFX_H__ // ============上下左右=========
C語言資料結構之靜態連結串列實現(A-B)U(B-A)
時間複雜度O(3n)不是很難,直接貼程式碼:StaticLinkList.h#ifndef _STATIC_LINK_LIST_H_ #define _STATIC_LINK_LIST_H_ #define MAXSIZE 100 typedef enum {ERROR,OK
C語言---經典之雙向連結串列的實現
int dlist_ins_next(Dlist *list, DListElement *element, const void *data){ DListElement *new_element; if (element == NULL && list->size !=
資料結構與演算法分析c語言描述(Mark Allen)--佇列ADT連結串列實現
佇列ADT連結串列實現 使用連結串列儲存 操作集合 入隊 出隊 初始化 返回隊前元素 列印 #include <stdio.h> #includ
使用C語言連結串列實現商品管理系統
#include <stdio.h> #include <stdlib.h> #include <windows.h> #define bool char #define true 1 #define false 0 #define NUM 1
Leetcode中級演算法之奇偶連結串列(328)C++
給定一個單鏈表,把所有的奇數節點和偶數節點分別排在一起。請注意,這裡的奇數節點和偶數節點指的是節點編號的奇偶性,而不是節點的值的奇偶性。 請嘗試使用原地演算法完成。你的演算法的空間複雜度應為 O(1),時間複雜度應為 O(nodes),nodes 為節點總數。 示例 1: 輸入:
C#LeetCode刷題之#203-刪除連結串列中的節點(Remove Linked List Elements)
問題 刪除連結串列中等於給定值 val 的所有節點。 輸入: 1->2->6->3->4->5->6, val = 6 輸出: 1->2->3-&