俄罗斯方块与状态机

再是拖延症就得剁手了,很多好东西没有成文实在是对不起自己对不起这个博客   //待添加,这篇文章很久之前就想写了


写这篇文章之前我先谈谈我自己的经历吧,其实我本身本科的时候是在学校的创新实验室里的,也就是一群学生在一个屋子里,学校给点设备偶尔拨点款买点元器件什么的,这里我指的是电子设计为导向的实验室哦,和CSDN主要的程序员方向有点偏离,不过CSDN的博客系统还是相当好的,关键是大牛多!!

其实就现在的电子设计而言,世道已经远远不是十几二十年前我国的那样单片机对学生都是很稀奇的东西了,电子设计业远远不是拿着一堆电阻,电容,电感,二极管,三极管,运放,功放就能打遍天下的时候了,当然,这些也是基本功,我调过的电路绝对不少。对于我本身而言,我的起点其实是编程,专业是通信工程,在大一上时候我觉得得学点东西,于是在大一下学期开C语言课之前就啃完了一本C,于是开始开课的时候基本上就是随便学学,看看书最后的东西,BTW,我们的课本真的是十分赞的,《The First Book Of ANSI-C》,当时是个非常好的老师教我们的课,双语教学,第一次认识到了国内外教材的巨大差距。

不过后来我并没有往着ACM这个方向走,有着环境和周围的大牛影响,我觉得可以用程序做点实际可以控制现实世界的东西会比较好一点,于是不出意料的我找到了单片机这样的神器,大一暑假几乎是第一次淘宝,就买了个开发板,由于用的语言是C(C51),上手还是特别快的,当时太年轻,写个程序点亮一个LED都兴奋的不得了,就和用C写个Hello World一样,真是太Naive,哈哈!


OK,说的有点多了,思路比较散,上面的内容我应该写一篇随记,先待续了。


其实无论是在PC上,还是在嵌入式上,Coding的水平觉得也是会随着写代码量的提升而提升的。虽然我确实写过很多程序,但是绝对还是远远不够的,不过还是有点收获的,在最开始的时候,写代码的角度是着眼于一个细小的功能实现,其实那时候是完全没有什么大局观的,想到什么就写什么;写代码也不讲究格式,后来这样的代码我应该都删掉了,实在是不忍直视。

后来在写一些嵌入式程序的时候,逐渐发现了模块的重要性,编写可重构代码的重要性,于是我在实验室花了相当长的时间几乎重写了我以前的所有代码,就功能和模块划分成若干个.c和.h,这时候才开始了开始逐渐的全局考量的思维,在重构我常用的东西以后写出的代码真的十分简洁,关键在于功能的封装,变量的控制,其实和面向对象的C++的基本理念是类似的,这时候想写出一个程序,速度是非常快的,因为我需要实现的功能是少的,只需要关注核心功能即可,其实挺类似自己的一个库的。

再往以后,在写到一些复杂控制程序的时候,尤其是用户参与交互比如存在键显的时候,发现了另一个问题,如果只是很死板的按照一个菜单一个菜单这么写,逻辑会非常容易混乱,比如层级到2层以上的时候还是if if if,就菜单的设计和跳出就非常麻烦了,这显然不是我追求的,直到一天,我看到了一篇介绍状态机思路的文章,其实那篇文章只是介绍一点思路,但是看完真是思路大开,很快就写出了自己的第一个状态机程序,比以前的显然要漂亮的多。(我在本科期间至少在两门课介绍过状态机,数字电子线路和可编程逻辑电路,后来在回想这些课这些内容时真是又能品味出另一番滋味。)


状态机的核心在于状态转移图,其实关键就在于逻辑的重构或者说逻辑的清晰化。


谈到这里的俄罗斯方块,这个程序本身是跑在6410上的,是课程设计的一个作业,完全的裸机程序,其实写了也差不多一年了,记得细节不是特别清楚,有些代码现在我肯定不会这么写,比如数据结构的设计,当时设计的现在看还是太低级了,不过状态机我还是会用上的。


图1.俄罗斯方块的枚举图



图2.关键的状态迁移图

其实这个状态迁移图能够画出来程序就能写出来了,就状态机而言本身就是几个state,就这个程序而言不过5个,有了状态图,那么就是在一个状态机里switch了,根据图写出相应的switch条件即可,程序会非常清晰,而且分支严格可控,逻辑可靠,非常有魅力的程序思想。


下面简单粘一点涉及代码

int StateMachine()
{
	while (1)
	{
		switch(state)
		{
			case 0:
				Menu();
				break;
			case 1:
				SelectModel();
				break;
			case 2:
				SelectHard();
				break;
			case 3:
				HighestScore();
				break;
			case 4:
				StartGame();
				break;
			default:
				Menu();
				break;
		}

		if (TTouchFlag == 1)
		{
			Uart_Printf("\nTT=%d", TTouchFlag);
			TTouchFlag = 0;
			if (Condition1)
			{
				state = 1;
			}
			else if (Condition2)
			{
				state = 2;
			}
			else if (Condition3)
			{
				state = 3;
			}
			else if (Condition4)
			{	
				state = 4;
			} 
		}
	}
	return 0;
}

整个工程的代码量,不包括基本的硬件初始化,图片等等,也就是1300行左右。







                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值