﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-C/C++图形图像的世界-文章分类-头脑风暴</title><link>http://www.cppblog.com/misakamm/category/15819.html</link><description>图形与游戏编程</description><language>zh-cn</language><lastBuildDate>Mon, 26 Dec 2011 18:33:23 GMT</lastBuildDate><pubDate>Mon, 26 Dec 2011 18:33:23 GMT</pubDate><ttl>60</ttl><item><title>[原创] 88行代码实现俄罗斯方块游戏（含讲解）</title><link>http://www.cppblog.com/misakamm/articles/137901.html</link><dc:creator>御坂美琴</dc:creator><author>御坂美琴</author><pubDate>Sun, 02 Jan 2011 15:12:00 GMT</pubDate><guid>http://www.cppblog.com/misakamm/articles/137901.html</guid><wfw:comment>http://www.cppblog.com/misakamm/comments/137901.html</wfw:comment><comments>http://www.cppblog.com/misakamm/articles/137901.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/misakamm/comments/commentRss/137901.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/misakamm/services/trackbacks/137901.html</trackback:ping><description><![CDATA[<p style="font-family: 宋体; ">在正式阅读本文之前，请你记得你应该用娱乐的心态来看，<br />
本代码所使用到的技巧，在工作了的人眼里会觉得很纠结，很蛋疼，很不可理喻，很丑，<br />
注意，是你蛋疼，不关我的事</p>
<p style="font-family: 宋体">通常，写一个俄罗斯方块，往往动不动就几百行，甚至上千行，而这里只有88行<br />
正所谓头脑风暴，打破常规。这里将使用很多不平常的手段来减少代码</p>
<p style="font-family: 宋体">以下是Win-TC可以成功编译并执行的代码（代码保证单行长度不超过80字符，如果你是Win7系统，那请看后文）：<br />
#include "graphics.h"<br />
#include &lt;conio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
int gcW = 20, gcColor[] = {DARKGRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN,<br />
&nbsp;&nbsp;&nbsp; LIGHTRED, LIGHTMAGENTA,MAGENTA, YELLOW};<br />
struct tetris {<br />
&nbsp;&nbsp;&nbsp; int _pool[16][32], (*pool)[32], tmap[8][4][16];<br />
&nbsp;&nbsp;&nbsp; int x, y, s, st, t;<br />
}gt;</p>
<p style="font-family: 宋体">void trsInit() {<br />
&nbsp;&nbsp;&nbsp; int sp[8][4] = {{15,4369},{23,785,116,547},{71,275,113,802},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {39,305,114,562},{54,561},{99,306},{51,51},{-1}};<br />
&nbsp;&nbsp;&nbsp; int *p, i, j, b;<br />
&nbsp;&nbsp;&nbsp; for (p = sp[0]; *p &gt;= 0; ++p) if ( *p == 0 ) *p = p[-2];<br />
&nbsp;&nbsp;&nbsp; gt.pool = &amp;gt._pool[4];<br />
&nbsp;&nbsp;&nbsp; for (j = 0; j &lt; 7; ++j)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 4; ++i)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (b = 0; b &lt; 16; ++b)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gt.tmap[j+1][i][b] = (sp[j][i] &amp; 1) * (j + 1),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sp[j][i] &gt;&gt;= 1;<br />
&nbsp;&nbsp;&nbsp; memset(gt._pool, -1, sizeof(gt._pool));<br />
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 10; ++i)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(&amp;gt.pool[i], 0, sizeof(int[21]));<br />
&nbsp;&nbsp;&nbsp; return ;<br />
}</p>
<p style="font-family: 宋体">int trsCopy(int sp[], int x, int y, int c) {<br />
&nbsp;&nbsp;&nbsp; int m[] = {0,32,64,96,1,33,65,97,2,34,66,98,3,35,67,99}, i, cx, cy;<br />
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 16; ++i) if (sp[i]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cx = x + (m[i] &gt;&gt; 5), cy = y + (m[i] &amp; 31);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (gt.pool[cx][cy]) if (c == 2) gt.pool[cx][cy] = 0; else return 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (c==1) gt.pool[cx][cy] = sp[i];<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return 1;<br />
}</p>
<p style="font-family: 宋体">int trsScene() {<br />
&nbsp;&nbsp;&nbsp; int x, y = 0;<br />
&nbsp;&nbsp;&nbsp; gt.s = random(7) + 1, gt.st = gt.t = 0;<br />
&nbsp;&nbsp;&nbsp; gt.x = 4, gt.y = 0;<br />
&nbsp;&nbsp;&nbsp; for (--gt.t ; ; delay(10), --gt.t) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int k = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (kbhit()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; k = getch();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (k == 27) return 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (k == 'A' || k == 'a') {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (trsCopy(gt.tmap[gt.s][gt.st], gt.x-1, gt.y, 0)) --gt.x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (k == 'D' || k == 'd') {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (trsCopy(gt.tmap[gt.s][gt.st], gt.x+1, gt.y, 0)) ++gt.x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (k == 'W' || k == 'w') {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (trsCopy(gt.tmap[gt.s][(gt.st+1) % 4], gt.x, gt.y, 0))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gt.st = (gt.st+1) % 4;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (k == 'S' || k == 's' || gt.t &lt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y+1, 0))++gt.y,gt.t=50;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (--y; y &gt; 0; --y) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (x = 0; gt.pool[x][y] &gt; 0; ++x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (gt.pool[x][y] &lt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (k = y++; k &gt; 0; --k)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (x = 0; gt.pool[x][0] &gt;= 0; ++x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gt.pool[x][k] = gt.pool[x][k-1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (x = 0; gt.pool[x][0] &gt;= 0; ++x) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (y = 1; gt.pool[x][y] &gt;= 0; ++y) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setfillstyle(1, gcColor[gt.pool[x][y]]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bar(201 + x*gcW, 1 + y*gcW, 200 + gcW + x*gcW, gcW + y*gcW);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 2);<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p style="font-family: 宋体">int main() {<br />
&nbsp;&nbsp;&nbsp; int g = DETECT, m = 0;<br />
&nbsp;&nbsp;&nbsp; initgraph(&amp;g, &amp;m, "");<br />
&nbsp;&nbsp;&nbsp; randomize();<br />
&nbsp;&nbsp;&nbsp; trsInit();<br />
&nbsp;&nbsp;&nbsp; while (trsScene());<br />
&nbsp;&nbsp;&nbsp; return 0;<br />
}</p>
<p style="font-family: 宋体">&nbsp;</p>
<p style="font-family: 宋体">如果你没有Win-TC，或者你是Win7系统，可以用这个能用VC6编译的工程包：<br />
<a href="http://www.cppblog.com/Files/misakamm/tetris.zip">http://www.cppblog.com/Files/misakamm/tetris.zip</a></p>
<p style="font-family: 宋体">以上是图形界面版本，显示看起来好看一些<br />
但为了能更通用，还有一份控制台版本的代码，同样是88行，直接复制到VC即可编译：<br />
#include &lt;windows.h&gt;<br />
#include &lt;stdio.h&gt;<br />
#include &lt;time.h&gt;<br />
#include &lt;conio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
char gcText[] = " 1LJTSZ#";<br />
struct tetris {<br />
&nbsp;&nbsp;&nbsp; int _pool[16][32], (*pool)[32], tmap[8][4][16];<br />
&nbsp;&nbsp;&nbsp; int x, y, s, st, t;<br />
}gt;</p>
<p style="font-family: 宋体">void trsInit() {<br />
&nbsp;&nbsp;&nbsp; int sp[8][4] = {{15,4369},{23,785,116,547},{71,275,113,802},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {39,305,114,562},{54,561},{99,306},{51,51},{-1}};<br />
&nbsp;&nbsp;&nbsp; int *p, i, j, b;<br />
&nbsp;&nbsp;&nbsp; for (p = sp[0]; *p &gt;= 0; ++p) if ( *p == 0 ) *p = p[-2];<br />
&nbsp;&nbsp;&nbsp; gt.pool = &amp;gt._pool[4];<br />
&nbsp;&nbsp;&nbsp; for (j = 0; j &lt; 7; ++j)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 4; ++i)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (b = 0; b &lt; 16; ++b)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gt.tmap[j+1][i][b] = (sp[j][i] &amp; 1) * (j + 1),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sp[j][i] &gt;&gt;= 1;<br />
&nbsp;&nbsp;&nbsp; memset(gt._pool, -1, sizeof(gt._pool));<br />
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 10; ++i)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(&amp;gt.pool[i], 0, sizeof(int[21]));<br />
&nbsp;&nbsp;&nbsp; return ;<br />
}</p>
<p style="font-family: 宋体">int trsCopy(int sp[], int x, int y, int c) {<br />
&nbsp;&nbsp;&nbsp; int i, cx, cy;<br />
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 16; ++i) if (sp[i]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cx = x + (i &amp; 3), cy = y + (i &gt;&gt; 2);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (gt.pool[cx][cy])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (c == 2) gt.pool[cx][cy] = 0; else return 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (c==1) gt.pool[cx][cy] = sp[i];<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return 1;<br />
}</p>
<p style="font-family: 宋体">int trsScene() {<br />
&nbsp;&nbsp;&nbsp; int x, y = 0;<br />
&nbsp;&nbsp;&nbsp; COORD pos = {0};<br />
&nbsp;&nbsp;&nbsp; gt.s = rand() % 7 + 1, gt.st = gt.t = 0;<br />
&nbsp;&nbsp;&nbsp; gt.x = 3, gt.y = 0;<br />
&nbsp;&nbsp;&nbsp; for (--gt.t; ; Sleep(1), --gt.t) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int k = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (kbhit()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; k = getch();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (k == 27) return 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (k == 'A' || k == 'a') {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (trsCopy(gt.tmap[gt.s][gt.st], gt.x-1, gt.y, 0)) --gt.x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (k == 'D' || k == 'd') {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (trsCopy(gt.tmap[gt.s][gt.st], gt.x+1, gt.y, 0)) ++gt.x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (k == 'W' || k == 'w') {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (trsCopy(gt.tmap[gt.s][(gt.st+1) % 4], gt.x, gt.y, 0))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gt.st = (gt.st+1) % 4;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (k == 'S' || k == 's' || gt.t &lt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y+1, 0))++gt.y,gt.t=50;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (--y; y &gt; 0; --y) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (x = 0; gt.pool[x][y] &gt; 0; ++x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (gt.pool[x][y] &lt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (k = y++; k &gt; 0; --k)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (x = 0; gt.pool[x][0] &gt;= 0; ++x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gt.pool[x][k] = gt.pool[x][k-1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (y = 1; gt.pool[0][y] &gt;= 0; ++y,putchar(10)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (x = 0; gt.pool[x][0] &gt;= 0; ++x) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; putchar(gcText[gt.pool[x][y]]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 2);<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p style="font-family: 宋体">int main() {<br />
&nbsp;&nbsp;&nbsp; srand((unsigned)time(NULL));<br />
&nbsp;&nbsp;&nbsp; for (trsInit(); trsScene(); );<br />
&nbsp;&nbsp;&nbsp; return 0;<br />
}</p>
<p style="font-family: 宋体">区别仅仅是绘画用的函数不同而已，不过控制台版显示效果自然会差很多了<br />
当你玩下去，你如果堆放到最顶，输了的话，程序就会以最为华丽的方式：Crash（程序崩溃） 谢幕</p>
<p style="font-family: 宋体"><br />
======================================华丽的分割线========================================<br />
以下是对代码的压缩方法进行分析</p>
<p style="font-family: 宋体">首先，通常我们需要准备7种方块，4个方向的形状表，相当多的俄罗斯方块程序就是在开头写了这样一个很长的数组定义，<br />
有的光这个定义就直接超100行了，这个程序是怎么实现的呢？</p>
<p style="font-family: 宋体">其实这个程序，同样是使用一个7*4*16的数组来保存这个形状表，但是，它没有直接初始化，见这个数组的定义：<br />
int sp[8][4] = {{15,4369},{23,785,116,547},{71,275,113,802},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {39,305,114,562},{54,561},{99,306},{51,51},{-1}};<br />
这个莫名其妙的数组的值是什么意思呢？其实很好猜的，我们尝试把这些数化为二进制：<br />
15 = 1111<br />
4369 = 1000100010001</p>
<p style="font-family: 宋体">合理地四位四位拆开，从低位到高位，从左到右，从上到下排列一下：<br />
1111<br />
0000<br />
0000<br />
0000</p>
<p style="font-family: 宋体">1000<br />
1000<br />
1000<br />
1000</p>
<p style="font-family: 宋体">你终于发现，这就是长条方块的两个形状<br />
后面类似</p>
<p style="font-family: 宋体">然后你会发现，这个数组并不完整，有的只定义了两个形状，有的是四个形状，没定义的数会默认置0的，这个怎么解释？<br />
看这个数组定义的下面第二行：<br />
for (p = sp[0]; *p &gt;= 0; ++p) if ( *p == 0 ) *p = p[-2];<br />
意思是找出这个数组为0的元素，用它前面的元素值填上即*p = p[-2]<br />
而数组中最后一个元素值-1起监督头的作用，用于让这个循环跳出<br />
虽然可以把这些常数全直接写在数组里，但常数太多显得不太好，就这样写了</p>
<p style="font-family: 宋体">之后你看到这行代码：<br />
gt.pool = &amp;gt._pool[4];<br />
为什么定义两个pool呢？因为我们需要在原来的pool的界外用-1值填充，以便后面做碰撞检测减少不必要的代码<br />
但如果直接用原来的_pool，那每次访问都要加上一个偏移常数，不美观且显得代码长，就用另一个指针直接指向开始的位置</p>
<p style="font-family: 宋体">然后，后面的三重循环就是解开那个位压缩数组以初始化gt.tmap数组，这个数组就是记录7*4种形状的数组<br />
再下面三行，就是初始化pool，游戏区为0，界外为-1<br />
而其中，i &lt; 10决定了游戏池的宽度为10，sizeof(int[21])决定了游戏池的高度是20 （0我们不使用，这一行有特殊作用，后文会讲）<br />
用memset也是为了免写二重循环而已。整个初始化流程就到这里了</p>
<p style="font-family: 宋体">然后，是一个trsCopy函数，这个函数综合了碰撞检测，复制到游戏池和反复制，行为由参数c （是control缩写字母）控制<br />
c为0就单纯的碰撞检测，c为1是复制，c为2就是反复制，细心分析一下，这个函数功能就清楚了，这里不详细展开</p>
<p style="font-family: 宋体">好了，到了trsScene函数，整个游戏的主逻辑流程就在这里了<br />
我们先看第75行的那个二重循环，只有那个地方是根据pool保存的值来输出<br />
所以，这个时候，你应该明白为什么trsCopy函数还要复制和反复制了，<br />
它把你正在控制的方块，复制到pool里，统一输出，这样就不需要另加一个函数来绘画你的控制块了</p>
<p style="font-family: 宋体">而绘图之前，就是键盘处理等的逻辑控制，这里就没有什么复杂难懂的代码了，<br />
唯一要讲讲的是，if (k == 'S' || k == 's' || gt.t &lt; 0)<br />
这一段是判断下落键的按下，和是否到时间强制下落<br />
里面for (--y; y &gt; 0; --y)开始是消行计算<br />
你可能会奇怪这个y没有明显的初始值，直接就来一个 --y，初始从哪里来？<br />
其实就在之前讲的输出绘画那个循环里，循环结束后，y的值一定是最后一行+1<br />
所以我们只要--y就得到最底下一行，因为消行计算，从下往上，只要一次就解决了，代码较少</p>
<p style="font-family: 宋体">好了，现在解释之前说的，为什么不是从0，而是从1开始<br />
消行计算这里，每消除一行，最顶的一行就应该用0填充，但如果你因为这个多写一个for循环就不值得了<br />
我们改成从1开始，那么把第0行的内容复制到第一行，就完成0填充了，就可以少写一个for</p>
<p style="font-family: 宋体">好了，差不多接近尾声了，最后说说trsScene的返回值<br />
trsScene返回值的意思很简单，如果是1就继续循环，如果是0就退出<br />
所以你可以在代码里看到，当按下ESC(值为27)的时候才返回0<br />
而方块落下一个的时候，返回1，让主函数重新调用它，就能再次初始化当前控制块的位置和形状了，<br />
达到免除状态管理的代码的作用</p>
<p style="font-family: 宋体">最后，在主循环除了初始化，只要华丽的一行for (trsInit(); trsScene(); ); 就可以玩这个游戏了</p>
<p style="font-family: 宋体"><br />
看不懂？说明你也是个正常人<br />
看得懂？说明你已经脑殘了。。。</p><img src ="http://www.cppblog.com/misakamm/aggbug/137901.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/misakamm/" target="_blank">御坂美琴</a> 2011-01-02 23:12 <a href="http://www.cppblog.com/misakamm/articles/137901.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>