停课不停学,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 · 访问量 934

猜你喜欢

转载自blog.csdn.net/Luckily0818/article/details/104335256