停課不停學,C語言版33行代碼寫出俄羅斯方塊學習

新年新氣象

哪有什麼歲月靜好,只不過是有人替我們負重前行——致敬那些逆行在疫情第一線的英雄們,待春暖花開之時,願你們平安歸來。
距離上一次寫博客好像過去了很久的樣子,雖然博客沒有更新但學習上卻不敢有絲毫鬆懈,爲了能夠記錄自己每日的學習進展,也是決定堅持寫,每週兩篇,將自己所學習到的新知識,和對於一些概念的整理都通過這樣的方式來進行記錄包括每個月的GitHub的記錄,口說無憑,附上自己的:GitHub記錄

33行書寫俄羅斯方塊(學習到的)

言歸正傳今天通過其他的途徑也是學習到了一個學長所書寫出來的俄羅斯方塊,說實話還沒有全方位的搞懂,因此發表出來也是希望能夠有更多的大神能夠指點一二,對於其中存在的一系列問題大家展開討論,對於學長這樣的功底還是非常的佩服得,雖說他在書寫時候挺規範的,但是對於我們這種一行一行代碼敲出來的人還是能夠感覺到他的語言有着一些混亂,可能也是因爲要達到所謂的33行這個噱頭吧,所以在大家學習的時候也是儘可能地用自己的思維將他的解讀以下在進行敲寫。
對於我們衆多的朋友來說,既然是學習到的那就是學習到的,就像我在前面所說道的,在開始時候更多的學習其實也是爲了更好的瞭解別人的編程思維和一些所存在的習慣,這樣也是能夠更好的方便和提升我們自己。

代碼段

#include <stdio.h>
#include <windows.h>
#include <conio.h>

int T, X, Y, c, i, j, k, map[250] = { 0 }, node[28][4] = {
	//形狀,根座標,輸入&循環變量,ijk循環變量,map地圖,node節點,下面爲7種形狀*4種方向*4個節點包含寬*Y+X的數據
	-1, 0, 1, -11, 10, 0, -10, -9, 11, -1, 0, 1, 9, 10, 0, -10, -1, 0, 1, -9, 10, 11, 0, -10, 9, -1, 0, 1,
	10, 0, -10, -11, 9, 10, 0, 1, 11, 0, 1, -10, 9, 10, 0, 1, 11, 0, 1, -10, 10, 11, -1, 0, 10, 0, 1, -9,
	10, 11, -1, 0, 10, 0, 1, -9, -1, 0, 1, -10, 10, 0, 1, -10, 10, -1, 0, 1, 10, -1, 0, -10, 20, 10, 0, -10,
	-1, 0, 1, 2, 20, 10, 0, -10, -1, 0, 1, 2, 10, 11, 0, 1, 10, 11, 0, 1, 10, 11, 0, 1, 10, 11, 0, 1 };
//移動
int move(int* v, int l) {
	for (*v += l, i = 0; i < 4 && (j = (node[T][i] + 11) % 10 - 1 + X, 1); i++)
		//先移動,遍歷4個節點,j=節點X座標
	if ((j < 0 || 9 < j || 24 < (node[T][i] + 11) / 10 - 1 + Y ||
		//越界判斷
		map[node[T][i] + Y * 10 + X]) && (*v -= l, 1))return 0;
	//判斷當前節點是否有方塊,如果前面有爲真,則回到移動之前的位置,並且返回0
	return 1;
}
//下落
void down() {
	if (move(&Y, 1) || Y < 2 && (exit(!_getch()), 0))return;
	//向下移動,如果爲真直接返回,爲假則再判定當前Y座標,如果<2則退出並阻塞
	for (i = 0; i < 4 && (map[node[T][i] + Y * 10 + X] = 1); i++);
	//4個節點在地圖對應的位置賦值
	for (i = 250, k = 0; i >= 10 || (c = 0); i % 10 == 0 && (k = 0))
		//i從最後一行的行尾向前遍歷,直到第一行的行尾,每遇到行頭則k復位,結束時c=0
	if (--i, (k += map[i]) == 10)
		//k累計當前行數的方塊,如果爲10,則執行消行,消行原理,上面的數據覆蓋下面的數據
	for (j = i + 9; j > 9 || (i += 10, 0); map[j] = map[j - 10], j--);
	//j從當前行尾開始,當前的數據等於上面的數據,直到第一行行尾結束,結束時i回到行尾
}
//主函數
int main() {
	srand((unsigned)malloc(!system("mode con: cols=20 lines=25")));
	//初始化隨機種子,並設置窗口大小
	for (; c || (X = 4, Y = 1, T = rand() % 7 * 4, c = 1); down(), Sleep(150)) {
		//開始循環;c=0時重置根座標和形狀及本身;固定的下落和延時
		if (_kbhit() && (c = _getch())) {
			//檢測是否有輸入,有則獲取並判斷
			if (c == 'w' || c == 'W')move(&T, (T % 4) < 3 ? 1 : -3);
			//w旋轉
			else if (c == 'd' || c == 'D')X < 9 && move(&X, 1);
			//d右移
			else if (c == 'a' || c == 'A')X > 0 && move(&X, -1);
			//a左移
			else if (c == 's' || c == 'S')down();
			//s下落
		}
		for (i = system("cls"); i < 4 && (map[node[T][i] + Y * 10 + X] = -1); i++);
		//清屏,節點賦值爲-1
		for (i = 0; i < 250; i++)_cputs(map[i] ? "[]" : "  "), map[i] += map[i] < 0;
		//打印,並復位節點
	}
}

成果圖
俄羅斯方塊GitHub鏈接 點擊其中第一個Eluosi就可以了,當然了下面也是我自己編寫出來的其他的一些小遊戲,大家也是可以借鑑的。

多交流 多溝通 和我一樣在自己學習的朋友可以一起進行交流討論哦!

發佈了18 篇原創文章 · 獲贊 12 · 訪問量 1783
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章